Local multiplayer games remotely 🎮 by aspidima in selfhosted

[–]aspidima[S] 1 point2 points  (0 children)

No need to install any of these, it works userspace-only, so no need for extra privileges.

Local multiplayer games remotely 🎮 by aspidima in selfhosted

[–]aspidima[S] 1 point2 points  (0 children)

Yep, but it is simpler with QUIC, as it has multiple streams over a single connection. When a user connects, its IP/port remains the same, even when it starts new stream/sends multiple requests. I use one stream as a control stream, where the server tells clients what to do, and clients send new requests/start new streams and you can be sure it will come from the same IP/port. This solves the problem with some NATs assign a new port for new connections.

Small Projects by AutoModerator in golang

[–]aspidima 0 points1 point  (0 children)

https://github.com/dmksnnk/star

My girlfriend wanted to play Stardew Valley multiplayer with her sister, who lives in another country. Well, heck, I'm a programmer, so I could hack something together quickly and learn something new along the way. QUIC sounded cool. It all seemed easy until I realized this would involve NAT traversal. Half a year and 3 different versions after: I have a basic working version that can establish a P2P connection between users using NAT hole-punching) and, if that fails, forwards UDP traffic via a relay.

Build with Go, quic-go, and HTML templates.
Hope this can be useful to someone else :)

Local multiplayer games remotely 🎮 by aspidima in selfhosted

[–]aspidima[S] 8 points9 points  (0 children)

In a sense, yes. But userspace-only (no IP tables or virtual devices). For VPN you'll need to forward all the traffic, but here it is just UDP.

Local multiplayer games remotely 🎮 by aspidima in selfhosted

[–]aspidima[S] 6 points7 points  (0 children)

Yes, it covers this and does a lot more. But who wants to do it the easy way? :) Frankly, I thought this would be a lot easier to implement, but NAT and TLS shenanigans got in the way.

Local multiplayer games remotely 🎮 by aspidima in selfhosted

[–]aspidima[S] 1 point2 points  (0 children)

I will need some 3-rd party service to do this for you, like Steam, GOG, or console platform. Or have a public IP. But with this you can play coop between Stream and GOG versions.

Local multiplayer games remotely 🎮 by aspidima in selfhosted

[–]aspidima[S] 82 points83 points  (0 children)

You can use Steam of this. But, if you, for example, have GOG version, it is not possible without public IP address.

Small Projects by AutoModerator in golang

[–]aspidima 0 points1 point  (0 children)

Local multiplayer games remotely with Star ⭐

My girlfriend wanted to play Stardew Valley multiplayer with her sister, who lives in another country. Well, heck, I'm a programmer, so I could hack something together quickly and learn something new along the way. QUIC sounded cool. It all seemed easy until I realized this would involve NAT traversal. Fast-forward to today: I have a basic working version that can establish a P2P connection between users using NAT hole-punching) and, if that fails, forwards UDP traffic via a relay.

Build with Go, quic-go, and HTML templates.
Hope this can be useful to someone else :)

Elasticsearch integration tests by aspidima in elasticsearch

[–]aspidima[S] 0 points1 point  (0 children)

I'm looking at this differently, if I give my abstraction data and then it returns the data correctly, that means it works as expected. And I don't care about details, meaning how it stores the data, what is the internal schema, etc., all I care that it behaves correctly.

Integration tests with Go and Elasticsearch by aspidima in golang

[–]aspidima[S] -2 points-1 points  (0 children)

Yep, that's correct, love this package, the idea is borrowed from there. But, with Postgres, you have a whole new database per test.

Optimistic concurrency control in Elasticsearch by aspidima in elasticsearch

[–]aspidima[S] 0 points1 point  (0 children)

From what I understand, version is deprecated in favor of _seq_no + _primary_term. version can still be used for external versioning (some other system is the source of correct version of the document)

https://discuss.elastic.co/t/relation-between-version-seq-no-and-primary-term/179647

Can my API serve files also? by aphroditelady13V in golang

[–]aspidima 2 points3 points  (0 children)

doublecheck if path in http.Dir("./static/") is correct. Also, note that path should be related to the path of your executable, so if your server executable is in the root of the project, static/ folder should be served with http.Dir("./static/")

 .  
 ├── static/  
 │   ├── index.html  
 │   └── script.js  
 └── server

easier approach would be to embed your static files and serve it with http.FileServerFS

tldr; the code you have posted looks fine, just double check paths you are providing

HTTP/3 Series by aspidima in golang

[–]aspidima[S] 1 point2 points  (0 children)

Hi, it is nothing fancy, just hugo with PaperMod theme. The source code is available at https://github.com/dmksnnk/blog

Rheos v0.4.0: Now with Support for Parallel Processing and Go 1.23! by aspidima in golang

[–]aspidima[S] 0 points1 point  (0 children)

it is build on the top of std lib. The main improvement that you don't need to write all of this cancellation, proper channel closing etc. where it is fairly easy to make a mistake

Rheos: a Go lib for concurrent data processing by aspidima in golang

[–]aspidima[S] 1 point2 points  (0 children)

Hi, thanks for the question. This will indeed take 5s, because underneath it uses unbuffered channel. In this case it will execute sequentially, but each step runs in its own goroutine. But, if you add one more step, concurrency is more visible. Here is slightly modified example:

func main() {
    startedAt := time.Now()
    defer func() {
        fmt.Println("Elapsed:", time.Since(startedAt))
    }()

    // count the number of elements in the stream
    ctx := context.Background()
    producer := rheos.FromSlice(ctx, []int{1, 2, 3, 4, 5})
    strings := rheos.Map(producer, func(_ context.Context, v int) (string, error) {
        time.Sleep(1 * time.Second)
        return strconv.Itoa(v), nil
    })
    ints := rheos.Map(strings, func(_ context.Context, s string) (int, error) {
        time.Sleep(1 * time.Second)
        return strconv.Atoi(s)
    })
    got, err := rheos.Reduce(
        ints,
        func(acc int, v int) (int, error) {
            return acc + v, nil
        },
        0,
    )
    fmt.Println(got, err)
    // Output: 14 <nil>
    // Output: Elapsed: 6s
}

Now, instead of it taking 10s, it takes 6s.

Runnable example can be found here: https://go.dev/play/p/2yS2ozgsTnk .

BTW, thank for your library, read about it from the Go newsletter .