package client import ( "context" "slices" "forge.cadoles.com/arcad/arcast/pkg/server" "github.com/grandcat/zeroconf" "github.com/pkg/errors" ) func (c *Client) Scan(ctx context.Context, funcs ...ScanOptionFunc) ([]*Player, error) { opts := NewScanOptions(funcs...) resolver, err := zeroconf.NewResolver(nil) if err != nil { return nil, errors.WithStack(err) } done := make(chan struct{}) players := make([]*Player, 0) entries := make(chan *zeroconf.ServiceEntry) go func(results <-chan *zeroconf.ServiceEntry) { defer close(done) for entry := range results { addPlayer := func() { players = append(players, &Player{ ID: entry.Instance, IPs: entry.AddrIPv4, Port: entry.Port, }) } searchedLen := len(opts.PlayerIDs) if searchedLen == 0 { addPlayer() continue } if slices.Contains(opts.PlayerIDs, entry.Instance) { addPlayer() } if searchedLen == len(players) { break } } done <- struct{}{} }(entries) err = resolver.Browse(ctx, server.MDNSService, server.MDNSDomain, entries) if err != nil { return nil, errors.WithStack(err) } select { case <-done: return players, nil case <-ctx.Done(): if err := ctx.Err(); err != nil { return players, errors.WithStack(err) } return players, nil } }