Skip to content

Commit

Permalink
Add send command
Browse files Browse the repository at this point in the history
  • Loading branch information
robinbraemer committed Dec 28, 2023
1 parent b246623 commit f7389c9
Show file tree
Hide file tree
Showing 4 changed files with 104 additions and 14 deletions.
2 changes: 1 addition & 1 deletion .web/docs/guide/builtin-commands.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ If you want to add custom commands refer to the [Developers Guide](/developers/)
|------------------|-----------------------|-----------------------------------------------------------------------------------------|
| `/server` | `gate.command.server` | Players can use the command to view and switch to another server. |
| `/glist` | `gate.command.glist` | View the number of players on the Gate instance. `/glist all` lists players per server. |

| `/send` | `gate.command.send` | Send one or all players to another server. |

## Permission

Expand Down
71 changes: 71 additions & 0 deletions pkg/edition/java/proxy/builtin_cmd_send.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
package proxy

import (
"fmt"
"go.minekube.com/brigodier"
. "go.minekube.com/common/minecraft/color"
. "go.minekube.com/common/minecraft/component"
"go.minekube.com/gate/pkg/command"
"go.minekube.com/gate/pkg/command/suggest"
"strings"
)

const sendCmdPermission = "gate.command.send"

func newSendCmd(proxy *Proxy) brigodier.LiteralNodeBuilder {
const sendPlayerArg = "player"
const sendServerArg = "server"
return brigodier.Literal("send").
Requires(hasCmdPerm(proxy, sendCmdPermission)).
Then(brigodier.Argument(sendPlayerArg, brigodier.String).
Suggests(playerSuggestionProvider(proxy, "all", "current")).
Then(brigodier.Argument(sendServerArg, brigodier.String).
Suggests(serverSuggestionProvider(proxy)).
Executes(command.Command(func(c *command.Context) error {
return sendToServer(proxy, c, c.String(sendPlayerArg), c.String(sendServerArg))
})),
),
)
}

func sendToServer(proxy *Proxy, c *command.Context, playerName, serverName string) error {
if strings.EqualFold(playerName, "all") {
return connectPlayersToServer(c, proxy, serverName, proxy.Players()...)
}

if strings.EqualFold(playerName, "current") {
if player, ok := c.Source.(Player); ok {
if currentServer := player.CurrentServer(); currentServer != nil {
return connectPlayersToServer(c, proxy, serverName, PlayersToSlice[Player](currentServer.Server().Players())...)
}
} else {
return c.Source.SendMessage(&Text{S: Style{Color: Red}, Content: "Only players can use 'current'!"})
}
return nil
}

player := proxy.PlayerByName(playerName)
if player == nil {
return c.Source.SendMessage(&Text{S: Style{Color: Red}, Content: fmt.Sprintf("Player %q doesn't exist.", playerName)})
}

return connectPlayersToServer(c, proxy, serverName, player)
}
func playerSuggestionProvider(proxy *Proxy, additionalPlayers ...string) brigodier.SuggestionProvider {
return command.SuggestFunc(func(
_ *command.Context,
b *brigodier.SuggestionsBuilder,
) *brigodier.Suggestions {
candidates := append(playerNames(proxy), additionalPlayers...)
return suggest.Similar(b, candidates).Build()
})
}

func playerNames(proxy *Proxy) []string {
list := proxy.Players()
n := make([]string, len(list))
for i, player := range list {
n[i] = player.Username()
}
return n
}
44 changes: 31 additions & 13 deletions pkg/edition/java/proxy/builtin_cmd_server.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"context"
"fmt"
"sort"
"sync"
"time"

"go.minekube.com/brigodier"
Expand All @@ -17,14 +18,15 @@ const serverCmdPermission = "gate.command.server"

// command to list and connect to registered servers
func newServerCmd(proxy *Proxy) brigodier.LiteralNodeBuilder {
const serverNameArg = "name"
return brigodier.Literal("server").
Requires(hasCmdPerm(proxy, serverCmdPermission)).
// List registered server.
Executes(command.Command(func(c *command.Context) error {
return c.SendMessage(serversInfo(proxy, c.Source))
})).
// Switch server
Then(brigodier.Argument("name", brigodier.String).
Then(brigodier.Argument(serverNameArg, brigodier.String).
Suggests(serverSuggestionProvider(proxy)).
Executes(command.Command(func(c *command.Context) error {
player, ok := c.Source.(Player)
Expand All @@ -33,22 +35,38 @@ func newServerCmd(proxy *Proxy) brigodier.LiteralNodeBuilder {
Content: "Only players can connect to a server!"})
}

name := c.String("name")
rs := proxy.Server(name)
if rs == nil {
return c.Source.SendMessage(&Text{S: Style{Color: Red},
Content: fmt.Sprintf("Server %q doesn't exist.", name)})
}

ctx, cancel := context.WithTimeout(context.Background(),
time.Millisecond*time.Duration(proxy.cfg.ConnectionTimeout))
defer cancel()
player.CreateConnectionRequest(rs).ConnectWithIndication(ctx)
return nil
name := c.String(serverNameArg)
return connectPlayersToServer(c, proxy, name, player)
})),
)
}

func connectPlayersToServer(c *command.Context, proxy *Proxy, serverName string, players ...Player) error {
server := proxy.Server(serverName)
if server == nil {
return c.Source.SendMessage(&Text{S: Style{Color: Red},
Content: fmt.Sprintf("Server %q doesn't exist.", serverName)})
}

go func() {
ctx, cancel := context.WithTimeout(context.Background(),
time.Millisecond*time.Duration(proxy.cfg.ConnectionTimeout))
defer cancel()

wg := new(sync.WaitGroup)
wg.Add(len(players))
for _, player := range players {
go func(player Player) {
defer wg.Done()
player.CreateConnectionRequest(server).ConnectWithIndication(ctx)
}(player)
}
wg.Wait()
}()

return nil
}

const maxServersToList = 50

func serversInfo(proxy *Proxy, s command.Source) (c Component) {
Expand Down
1 change: 1 addition & 0 deletions pkg/edition/java/proxy/builtin_commands.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
func (p *Proxy) registerBuiltinCommands() {
p.command.Register(newServerCmd(p))
p.command.Register(newGlistCmd(p))
p.command.Register(newSendCmd(p))
}

func hasCmdPerm(proxy *Proxy, perm string) brigodier.RequireFn {
Expand Down

0 comments on commit f7389c9

Please sign in to comment.