diff --git a/.gitignore b/.gitignore index 454e8c6..77120a5 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ .devres/ .idea/ -.failed_packets/ \ No newline at end of file +.failed_packets/ +proto_generated/* \ No newline at end of file diff --git a/proto/packet_test.go b/proto/packet_test.go index 757e841..0a4910e 100644 --- a/proto/packet_test.go +++ b/proto/packet_test.go @@ -6,11 +6,7 @@ import ( "testing" - "github.com/admin-else/strom/nbt" - "github.com/admin-else/strom/proto_base" "github.com/admin-else/strom/proto_generated/v1_21_8" - "github.com/google/uuid" - "github.com/google/go-cmp/cmp" ) @@ -22,20 +18,6 @@ var nanIgnorer64 = cmp.Comparer(func(x, y float64) bool { return (math.IsNaN(x) && math.IsNaN(y)) || x == y }) -func TestChat(t *testing.T) { - //p := v1_21_8.PlayToServerPacketChatMessage{Message: "dfs", Timestamp: 1764153707364, Salt: -5634100397920314628, Signature: (*[256]uint8)(nil), Offset: 0, Acknowledged: [3]uint8{0x0, 0x0, 0x0}, Checksum: 0x1} - p := v1_21_8.PlayToClientPacketPlayerChat{GlobalIndex: 0, SenderUuid: uuid.UUID{0x1d, 0xc5, 0x57, 0x82, 0x3c, 0x0, 0x3e, 0xd4, 0xbf, 0x8b, 0x76, 0xd4, 0xc6, 0xd9, 0xcc, 0x47}, Index: 0, Signature: (*[256]uint8)(nil), PlainMessage: "csdf", Timestamp: 1764153823132, Salt: 0, PreviousMessages: v1_21_8.PreviousMessages{Val: []struct { - Id int32 - Signature interface{} - }{}}, UnsignedChatContent: (*nbt.Anon)(nil), FilterType: 0, FilterTypeMask: proto_base.Void{}, Type: v1_21_8.PlayToClientChatTypesHolder{Val: 1}, NetworkName: nbt.Anon{Value: map[string]interface{}{"click_event": map[string]interface{}{"action": "suggest_command", "command": "/tell Player659 "}, "hover_event": map[string]interface{}{"action": "show_entity", "id": "minecraft:player", "name": "Player659", "uuid": []int32{499472258, 1006649044, -1081379116, -958804921}}, "insertion": "Player659", "text": "Player659"}}, NetworkTargetName: (*nbt.Anon)(nil)} - b := bytes.NewBuffer(nil) - err := p.Encode(b) - if err != nil { - t.Fatal(err) - } - t.Logf("%q", b.Bytes()) -} - func FuzzPlayPackets(f *testing.F) { f.Fuzz(func(t *testing.T, b []byte) { t.Logf("Fuzz data %q\n", b) diff --git a/proto_base/base_types.go b/proto_base/base_types.go index 71341e9..4407a11 100644 --- a/proto_base/base_types.go +++ b/proto_base/base_types.go @@ -144,7 +144,7 @@ func EncodeVarInt(w io.Writer, v int32) (err error) { if uv != 0 { b |= 0x80 } - err := binary.Write(w, binary.BigEndian, b) + err = binary.Write(w, binary.BigEndian, b) if err != nil { return err } @@ -171,6 +171,41 @@ func DecodeVarInt(r io.Reader) (ret int32, err error) { return } +func EncodeVarLong(w io.Writer, v int64) (err error) { + uv := uint64(v) + for { + b := uint8(uv & 0x7F) + uv >>= 7 + if uv != 0 { + b |= 0x80 + } + err = binary.Write(w, binary.BigEndian, b) + if err != nil { + return err + } + if uv == 0 { + break + } + } + return nil +} + +func DecodeVarLong(r io.Reader) (ret int64, err error) { + for i := range 10 { // ceil(64/7) + var b uint8 + err = binary.Read(r, binary.BigEndian, &b) + if err != nil { + return + } + ret |= int64(uint64(b&0x7F) << (7 * uint64(i))) + if b&0x80 == 0 { + return + } + } + err = errors.New("VarInt too long") + return +} + func ErroringIndex[K comparable, V any, M map[K]V](m M, i K) (v V, err error) { var ok bool v, ok = m[i] diff --git a/proto_generator/main.go b/proto_generator/main.go index 9f7bf96..b8e330e 100644 --- a/proto_generator/main.go +++ b/proto_generator/main.go @@ -301,7 +301,7 @@ func Generate(version string, w io.Writer) (err error) { g := &Generator{Protocol: protocol} // These have annoying edge cases that would require me to implement a whole new compareTo parser - g.Settings.ReplaceWithTodoNames = []string{"packet_scoreboard_score", "packet_advancements"} + g.Settings.ReplaceWithTodoNames = []string{} g.File = NewFile("v" + strings.ReplaceAll(version, ".", "_")) AppendDecl(g.File, Import("encoding/binary", "io", "github.com/admin-else/strom/proto_base", "github.com/admin-else/strom/nbt", "github.com/google/uuid")) diff --git a/proto_generator/native_decoder.go b/proto_generator/native_decoder.go index 5e74415..8882320 100644 --- a/proto_generator/native_decoder.go +++ b/proto_generator/native_decoder.go @@ -507,6 +507,11 @@ func VarIntDecoder(g *Generator, varToSet ast.Expr, dataRaw any, name string) (s return } +func VarLongDecoder(g *Generator, varToSet ast.Expr, dataRaw any, name string) (s []ast.Stmt, err error) { + s = Stmts(Assign(Exprs(varToSet, Ident("err")), Exprs(Call(Selector("proto_base", "DecodeVarLong"), Ident("r")))), IfErrNil()) + return +} + func (g *Generator) RegisterDecoderNatives() { g.DecoderNatives = map[string]FunctionGeneratorFunc{ "container": ContainerDecoder, @@ -521,6 +526,7 @@ func (g *Generator) RegisterDecoderNatives() { "void": DefaultDecoder, "varint": VarIntDecoder, + "varlong": VarLongDecoder, "anonymousNbt": DefaultDecoder, "anonOptionalNbt": DefaultDecoder, // I have no idea what the difference is between these two "UUID": UUIDDecoder, diff --git a/proto_generator/native_encoder.go b/proto_generator/native_encoder.go index c752121..6930afc 100644 --- a/proto_generator/native_encoder.go +++ b/proto_generator/native_encoder.go @@ -320,6 +320,11 @@ func VarIntEncoder(g *Generator, varToSet ast.Expr, dataRaw any, name string) (s return } +func VarLongEncoder(g *Generator, varToSet ast.Expr, dataRaw any, name string) (s []ast.Stmt, err error) { + s = Stmts(Assign121(Ident("err"), Call(Selector("proto_base", "EncodeVarLong"), Ident("w"), varToSet)), IfErrNil()) + return +} + func (g *Generator) RegisterEncoderNatives() { g.EncoderNatives = map[string]FunctionGeneratorFunc{ "container": ContainerEncoder, @@ -333,6 +338,7 @@ func (g *Generator) RegisterEncoderNatives() { "void": DefaultEncoder, "varint": VarIntEncoder, + "varlong": VarLongEncoder, "anonymousNbt": DefaultEncoder, "anonOptionalNbt": DefaultEncoder, // I have no idea what the difference is between these two "UUID": UUIDEncoder, diff --git a/proto_generator/native_type.go b/proto_generator/native_type.go index d9695dd..eeb6fc0 100644 --- a/proto_generator/native_type.go +++ b/proto_generator/native_type.go @@ -158,6 +158,7 @@ func (g *Generator) RegisterNatives() { "container": VisitContainerType, "buffer": VisitBufferType, "varint": MakeIdentVisitor("int32"), + "varlong": MakeIdentVisitor("int64"), "array": VisitArrayTypeVisitorType, "mapper": MakeIdentVisitor("string"), "native": VisitDontGenerateType,