From 7f536dcd2d5847d7741f59dc09b42485db030ade Mon Sep 17 00:00:00 2001 From: Sandertv Date: Tue, 11 Jul 2023 18:29:10 +0200 Subject: [PATCH] go.mod: Updated to latest gophertunnel commit, changed command sending. --- go.mod | 2 +- go.sum | 4 +- server/session/command.go | 92 ++++++++++++++++++++++++++++++++++----- 3 files changed, 85 insertions(+), 13 deletions(-) diff --git a/go.mod b/go.mod index bfb61f4f8..266085e52 100644 --- a/go.mod +++ b/go.mod @@ -12,7 +12,7 @@ require ( github.com/google/uuid v1.3.0 github.com/pelletier/go-toml v1.9.5 github.com/rogpeppe/go-internal v1.9.0 - github.com/sandertv/gophertunnel v1.30.1-0.20230613200308-a4bc2f93fb3d + github.com/sandertv/gophertunnel v1.30.1-0.20230711115546-de9f23871800 github.com/sirupsen/logrus v1.9.0 go.uber.org/atomic v1.10.0 golang.org/x/exp v0.0.0-20230206171751-46f607a40771 diff --git a/go.sum b/go.sum index 0833d2d2c..49fcb0ec1 100644 --- a/go.sum +++ b/go.sum @@ -48,8 +48,8 @@ github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZV github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= github.com/sandertv/go-raknet v1.12.0 h1:olUzZlIJyX/pgj/mrsLCZYjKLNDsYiWdvQ4NIm3z0DA= github.com/sandertv/go-raknet v1.12.0/go.mod h1:Gx+WgZBMQ0V2UoouGoJ8Wj6CDrMBQ4SB2F/ggpl5/+Y= -github.com/sandertv/gophertunnel v1.30.1-0.20230613200308-a4bc2f93fb3d h1:jZ1A/qqk01UuBjDxWA7HjS/90t7oy8TxMP7irCOqg8g= -github.com/sandertv/gophertunnel v1.30.1-0.20230613200308-a4bc2f93fb3d/go.mod h1:ekREo7U9TPHh86kbuPMaWA93NMyWsfVvP/iNT3XhAb8= +github.com/sandertv/gophertunnel v1.30.1-0.20230711115546-de9f23871800 h1:BeTkZThrcuteSgYJA9ObqFXr06dD2FoCimuMGpjDdXo= +github.com/sandertv/gophertunnel v1.30.1-0.20230711115546-de9f23871800/go.mod h1:ekREo7U9TPHh86kbuPMaWA93NMyWsfVvP/iNT3XhAb8= github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0= github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72 h1:qLC7fQah7D6K1B0ujays3HV9gkFtllcxhzImRR7ArPQ= diff --git a/server/session/command.go b/server/session/command.go index 1d72c0176..fe10ee508 100644 --- a/server/session/command.go +++ b/server/session/command.go @@ -5,6 +5,7 @@ import ( "github.com/go-gl/mathgl/mgl64" "github.com/sandertv/gophertunnel/minecraft/protocol" "github.com/sandertv/gophertunnel/minecraft/protocol/packet" + "math" ) // SendCommandOutput sends the output of a command to the player. It will be shown to the caller of the @@ -42,6 +43,14 @@ func (s *Session) sendAvailableCommands() map[string]map[int]cmd.Runnable { m := make(map[string]map[int]cmd.Runnable, len(commands)) pk := &packet.AvailableCommands{} + var enums []commandEnum + enumIndices := map[string]uint32{} + + var dynamicEnums []commandEnum + dynamicEnumIndices := map[string]uint32{} + + suffixIndices := map[string]uint32{} + for alias, c := range commands { if c.Name() != alias { // Don't add duplicate entries for aliases. @@ -53,41 +62,104 @@ func (s *Session) sendAvailableCommands() map[string]map[int]cmd.Runnable { params := c.Params(s.c) overloads := make([]protocol.CommandOverload, len(params)) + + aliasesIndex := uint32(math.MaxUint32) + if len(c.Aliases()) > 0 { + aliasesIndex = uint32(len(enumIndices)) + enumIndices[c.Name()+"Aliases"] = aliasesIndex + enums = append(enums, commandEnum{Type: c.Name() + "Aliases", Options: c.Aliases()}) + } + for i, params := range params { for _, paramInfo := range params { t, enum := valueToParamType(paramInfo, s.c) t |= protocol.CommandArgValid + suffix := paramInfo.Suffix opt := byte(0) if _, ok := paramInfo.Value.(bool); ok { opt |= protocol.ParamOptionCollapseEnum } + if len(enum.Options) > 0 { + if !enum.Dynamic { + index, ok := enumIndices[enum.Type] + if !ok { + index = uint32(len(enums)) + enumIndices[enum.Type] = index + enums = append(enums, enum) + } + t |= protocol.CommandArgEnum | index + } else { + index, ok := dynamicEnumIndices[enum.Type] + if !ok { + index = uint32(len(dynamicEnums)) + dynamicEnumIndices[enum.Type] = index + dynamicEnums = append(dynamicEnums, enum) + } + t |= protocol.CommandArgSoftEnum | index + } + } + if suffix != "" { + index, ok := suffixIndices[suffix] + if !ok { + index = uint32(len(pk.Suffixes)) + suffixIndices[suffix] = index + pk.Suffixes = append(pk.Suffixes, suffix) + } + t |= protocol.CommandArgSuffixed | index + } overloads[i].Parameters = append(overloads[i].Parameters, protocol.CommandParameter{ Name: paramInfo.Name, Type: t, Optional: paramInfo.Optional, Options: opt, - Enum: enum, - Suffix: paramInfo.Suffix, }) } } if len(params) > 0 { pk.Commands = append(pk.Commands, protocol.Command{ - Name: c.Name(), - Description: c.Description(), - Aliases: c.Aliases(), - Overloads: overloads, + Name: c.Name(), + Description: c.Description(), + AliasesOffset: aliasesIndex, + Overloads: overloads, }) } } + pk.DynamicEnums = make([]protocol.DynamicEnum, 0, len(dynamicEnums)) + for _, e := range dynamicEnums { + pk.DynamicEnums = append(pk.DynamicEnums, protocol.DynamicEnum{Type: e.Type, Values: e.Options}) + } + + enumValueIndices := make(map[string]uint32, len(enums)*3) + pk.EnumValues = make([]string, len(enumValueIndices)) + + pk.Enums = make([]protocol.CommandEnum, 0, len(enums)) + for _, enum := range enums { + protoEnum := protocol.CommandEnum{Type: enum.Type} + for _, opt := range enum.Options { + index, ok := enumValueIndices[opt] + if !ok { + index = uint32(len(pk.EnumValues)) + enumValueIndices[opt] = index + pk.EnumValues = append(pk.EnumValues, opt) + } + protoEnum.ValueIndices = append(protoEnum.ValueIndices, uint(index)) + } + pk.Enums = append(pk.Enums, protoEnum) + } s.writePacket(pk) return m } +type commandEnum struct { + Type string + Options []string + Dynamic bool +} + // valueToParamType finds the command argument type of the value passed and returns it, in addition to creating // an enum if applicable. -func valueToParamType(i cmd.ParamInfo, source cmd.Source) (t uint32, enum protocol.CommandEnum) { +func valueToParamType(i cmd.ParamInfo, source cmd.Source) (t uint32, enum commandEnum) { switch i.Value.(type) { case int, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64: return protocol.CommandArgTypeInt, enum @@ -100,20 +172,20 @@ func valueToParamType(i cmd.ParamInfo, source cmd.Source) (t uint32, enum protoc case cmd.Target, []cmd.Target: return protocol.CommandArgTypeTarget, enum case bool: - return 0, protocol.CommandEnum{ + return 0, commandEnum{ Type: "bool", Options: []string{"true", "1", "false", "0"}, } case mgl64.Vec3: return protocol.CommandArgTypePosition, enum case cmd.SubCommand: - return 0, protocol.CommandEnum{ + return 0, commandEnum{ Type: "SubCommand" + i.Name, Options: []string{i.Name}, } } if enum, ok := i.Value.(cmd.Enum); ok { - return 0, protocol.CommandEnum{ + return 0, commandEnum{ Type: enum.Type(), Options: enum.Options(source), Dynamic: true,