2023-12-13 20:07:22 +01:00
|
|
|
package client
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
|
|
|
"fmt"
|
|
|
|
"time"
|
|
|
|
|
|
|
|
"forge.cadoles.com/arcad/arcast/pkg/client"
|
2024-01-16 09:27:04 +01:00
|
|
|
"forge.cadoles.com/arcad/arcast/pkg/network"
|
2023-12-13 20:07:22 +01:00
|
|
|
"github.com/pkg/errors"
|
|
|
|
"github.com/urfave/cli/v2"
|
|
|
|
)
|
|
|
|
|
|
|
|
var (
|
|
|
|
playerScanTimeoutFlag = "scan-timeout"
|
|
|
|
flagPlayerAddr = "player-address"
|
|
|
|
flagPlayerID = "player-id"
|
|
|
|
playerFlags = []cli.Flag{
|
|
|
|
&cli.DurationFlag{
|
|
|
|
Name: playerScanTimeoutFlag,
|
|
|
|
EnvVars: []string{"ARCAST_CLIENT_CAST_TIMEOUT"},
|
|
|
|
Usage: "Use `TIMEOUT` as maximum cast duration",
|
|
|
|
Value: 5 * time.Second,
|
|
|
|
},
|
|
|
|
&cli.StringSliceFlag{
|
|
|
|
Name: flagPlayerID,
|
|
|
|
Aliases: []string{"i"},
|
|
|
|
EnvVars: []string{"ARCAST_CLIENT_PLAYER_ID"},
|
|
|
|
Usage: "Use `ID` as player id",
|
|
|
|
Value: cli.NewStringSlice(),
|
|
|
|
},
|
|
|
|
&cli.StringSliceFlag{
|
|
|
|
Name: flagPlayerAddr,
|
|
|
|
Aliases: []string{"a"},
|
|
|
|
EnvVars: []string{"ARCAST_CLIENT_PLAYER_ADDR"},
|
|
|
|
Usage: "Use `ADDR` as player address",
|
|
|
|
Value: cli.NewStringSlice(),
|
|
|
|
},
|
|
|
|
}
|
|
|
|
)
|
|
|
|
|
|
|
|
func forEachPlayer(ctx *cli.Context, fn func(cl *client.Client, playerAddr string) error) error {
|
|
|
|
playerAddrs := ctx.StringSlice(flagPlayerAddr)
|
|
|
|
|
|
|
|
cl := client.New()
|
|
|
|
|
|
|
|
if ctx.IsSet(flagPlayerID) || !ctx.IsSet(flagPlayerAddr) {
|
|
|
|
scanTimeout := ctx.Duration(playerScanTimeoutFlag)
|
|
|
|
scanCtx, cancel := context.WithTimeout(ctx.Context, scanTimeout)
|
|
|
|
defer cancel()
|
|
|
|
|
|
|
|
playerIDs := ctx.StringSlice(flagPlayerID)
|
|
|
|
|
|
|
|
players, err := cl.Scan(scanCtx, client.WithPlayerIDs(playerIDs...))
|
|
|
|
if err != nil && (!errors.Is(err, context.Canceled) && !errors.Is(err, context.DeadlineExceeded)) {
|
|
|
|
return errors.Wrap(err, "could not scan for players")
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, p := range players {
|
2024-01-16 09:27:04 +01:00
|
|
|
preferredIP, err := network.FindPreferredLocalAddress(p.IPs...)
|
2023-12-13 20:07:22 +01:00
|
|
|
if err != nil {
|
|
|
|
return errors.Errorf("could not retrieve player '%s' preferred address", p.ID)
|
|
|
|
}
|
|
|
|
|
|
|
|
playerAddr := fmt.Sprintf("%s:%d", preferredIP, p.Port)
|
|
|
|
playerAddrs = append(playerAddrs, playerAddr)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if len(playerAddrs) == 0 {
|
|
|
|
return errors.New("no players found")
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, addr := range playerAddrs {
|
|
|
|
if err := fn(cl, addr); err != nil {
|
|
|
|
return errors.WithStack(err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func AsAnySlice[T any](src ...T) []any {
|
|
|
|
dst := make([]any, len(src))
|
|
|
|
|
|
|
|
for i, s := range src {
|
|
|
|
dst[i] = s
|
|
|
|
}
|
|
|
|
|
|
|
|
return dst
|
|
|
|
}
|