packets upgrade

This commit is contained in:
adman
2025-12-28 17:58:47 +01:00
parent 3ddf830d31
commit 0b493d43f3
9 changed files with 174 additions and 1798 deletions
+10
View File
@@ -4,6 +4,7 @@ import (
"encoding/binary"
"errors"
"io"
"reflect"
)
type Direction int
@@ -210,3 +211,12 @@ type EncodeDecodeAble interface {
Encode(w io.Writer) (err error)
Decode(r io.Reader) (err error)
}
type PacketInfo struct {
Type reflect.Type
Name string
Direction Direction
State State
PacketId int
ProtocolVersion int
}
File diff suppressed because it is too large Load Diff
-37
View File
@@ -1,37 +0,0 @@
package proto_generated
import (
"github.com/admin-else/strom/proto_base"
"github.com/admin-else/strom/proto_generated/v1_21_8"
"io"
)
func PacketIdentifierToType(v string, d proto_base.Direction, s proto_base.State, i string) (t any) {
switch v {
case "1.21.8":
t = v1_21_8.PacketIdentifierToType(d, s, i)
default:
}
return
}
func TypeToPacketIdentifier(v string, d proto_base.Direction, s proto_base.State, t any) (i string) {
switch v {
case "1.21.8":
i = v1_21_8.TypeToPacketIdentifier(d, s, t)
}
return
}
func DecodePacket(v string, d proto_base.Direction, s proto_base.State, r io.Reader) (packet any, err error) {
switch v {
case "1.21.8":
packet, err = v1_21_8.DecodePacket(d, s, r)
}
return
}
func EncodePacket(v string, d proto_base.Direction, s proto_base.State, i string, p any, w io.Writer) (err error) {
switch v {
case "1.21.8":
err = v1_21_8.EncodePacket(d, s, i, p, w)
}
return
}
-178
View File
@@ -1,178 +0,0 @@
func TypeToPacketIdentifier(d proto_base.Direction, s proto_base.State, t any) (i string) {
switch d {
case proto_base.ToServer:
switch s {
case proto_base.Handshaking:
i = HandshakingToServerTypeToPacketIdentifier(t)
case proto_base.Status:
i = StatusToServerTypeToPacketIdentifier(t)
case proto_base.Login:
i = LoginToServerTypeToPacketIdentifier(t)
case proto_base.Configuration:
i = ConfigurationToServerTypeToPacketIdentifier(t)
case proto_base.Play:
i = PlayToServerTypeToPacketIdentifier(t)
}
case proto_base.ToClient:
switch s {
case proto_base.Handshaking:
i = HandshakingToClientTypeToPacketIdentifier(t)
case proto_base.Status:
i = StatusToClientTypeToPacketIdentifier(t)
case proto_base.Login:
i = LoginToClientTypeToPacketIdentifier(t)
case proto_base.Configuration:
i = ConfigurationToClientTypeToPacketIdentifier(t)
case proto_base.Play:
i = PlayToClientTypeToPacketIdentifier(t)
}
}
return
}
func PacketIdentifierToType(d proto_base.Direction, s proto_base.State, i string) (t any) {
switch d {
case proto_base.ToServer:
switch s {
case proto_base.Handshaking:
t = HandshakingToServerPacketIdentifierToType(i)
case proto_base.Status:
t = StatusToServerPacketIdentifierToType(i)
case proto_base.Login:
t = LoginToServerPacketIdentifierToType(i)
case proto_base.Configuration:
t = ConfigurationToServerPacketIdentifierToType(i)
case proto_base.Play:
t = PlayToServerPacketIdentifierToType(i)
}
case proto_base.ToClient:
switch s {
case proto_base.Handshaking:
t = HandshakingToClientPacketIdentifierToType(i)
case proto_base.Status:
t = StatusToClientPacketIdentifierToType(i)
case proto_base.Login:
t = LoginToClientPacketIdentifierToType(i)
case proto_base.Configuration:
t = ConfigurationToClientPacketIdentifierToType(i)
case proto_base.Play:
t = PlayToClientPacketIdentifierToType(i)
}
}
return
}
func DecodePacket(d proto_base.Direction, s proto_base.State, r io.Reader) (params any, err error) {
switch d {
case proto_base.ToServer:
switch s {
case proto_base.Handshaking:
var packet HandshakingToServerPacket
packet, err = HandshakingToServerPacket{}.Decode(r)
if err != nil {
return
}
params = packet.Params
case proto_base.Status:
var packet StatusToServerPacket
packet, err = StatusToServerPacket{}.Decode(r)
if err != nil {
return
}
params = packet.Params
case proto_base.Login:
var packet LoginToServerPacket
packet, err = LoginToServerPacket{}.Decode(r)
if err != nil {
return
}
params = packet.Params
case proto_base.Configuration:
var packet ConfigurationToServerPacket
packet, err = ConfigurationToServerPacket{}.Decode(r)
if err != nil {
return
}
params = packet.Params
case proto_base.Play:
var packet PlayToServerPacket
packet, err = PlayToServerPacket{}.Decode(r)
if err != nil {
return
}
params = packet.Params
}
case proto_base.ToClient:
switch s {
case proto_base.Handshaking:
var packet HandshakingToClientPacket
packet, err = HandshakingToClientPacket{}.Decode(r)
if err != nil {
return
}
params = packet.Params
case proto_base.Status:
var packet StatusToClientPacket
packet, err = StatusToClientPacket{}.Decode(r)
if err != nil {
return
}
params = packet.Params
case proto_base.Login:
var packet LoginToClientPacket
packet, err = LoginToClientPacket{}.Decode(r)
if err != nil {
return
}
params = packet.Params
case proto_base.Configuration:
var packet ConfigurationToClientPacket
packet, err = ConfigurationToClientPacket{}.Decode(r)
if err != nil {
return
}
params = packet.Params
case proto_base.Play:
var packet PlayToClientPacket
packet, err = PlayToClientPacket{}.Decode(r)
if err != nil {
return
}
params = packet.Params
}
}
return
}
func EncodePacket(d proto_base.Direction, s proto_base.State, i string, p any, w io.Writer) (err error) {
switch d {
case proto_base.ToServer:
switch s {
case proto_base.Handshaking:
err = HandshakingToServerPacket{i, p}.Encode(w)
case proto_base.Status:
err = StatusToServerPacket{i, p}.Encode(w)
case proto_base.Login:
err = LoginToServerPacket{i, p}.Encode(w)
case proto_base.Configuration:
err = ConfigurationToServerPacket{i, p}.Encode(w)
case proto_base.Play:
err = PlayToServerPacket{i, p}.Encode(w)
}
case proto_base.ToClient:
switch s {
case proto_base.Handshaking:
err = HandshakingToClientPacket{i, p}.Encode(w)
case proto_base.Status:
err = StatusToClientPacket{i, p}.Encode(w)
case proto_base.Login:
err = LoginToClientPacket{i, p}.Encode(w)
case proto_base.Configuration:
err = ConfigurationToClientPacket{i, p}.Encode(w)
case proto_base.Play:
err = PlayToClientPacket{i, p}.Encode(w)
}
}
return
}
+104 -104
View File
@@ -2,128 +2,128 @@ package main
import (
"go/ast"
"io"
"os"
"strconv"
"strings"
_ "embed"
"github.com/admin-else/strom/data"
)
//go:embed helper_append.txt
var helperAppend string
func GenerateHelperTypes(t Types, prefix string, f *ast.File) (err error) {
for k, v := range t.Types {
if k != "packet" {
continue
}
v := v.([]any)[1].([]any)[1].(map[string]any)["type"].([]any)[1].(map[string]any)["fields"].(map[string]any)
m := make(map[string]string)
for k2, v2 := range v {
v2 := v2.(string)
if strings.HasPrefix(v2, "packet_common") {
m[k2] = CamelCase(v2)
} else if v2 == "void" {
m[k2] = "proto_base.Void"
} else {
m[k2] = prefix + CamelCase(v2)
}
}
err = PacketIdentifierToTypeGenerator(prefix, f, m)
if err != nil {
return
}
m = ReverseMap(m)
err = TypeToPacketIdentifierGenerator(prefix, f, m)
if err != nil {
return
}
}
return
type TypesInfo struct {
Types
Direction string
State string
}
func GenerateHelperState(s State, prefix string, f *ast.File) (err error) {
err = GenerateHelperTypes(s.ToServer, prefix+"ToServer", f)
if err != nil {
return
}
return GenerateHelperTypes(s.ToClient, prefix+"ToClient", f)
type PacketInfo struct {
TName, Name, Direction, State, PacketId, ProtocolVersion, MinecraftVersion string
}
func GenerateHelperProtocol(p Protocol, f *ast.File) (err error) {
err = GenerateHelperState(p.Handshaking, "Handshaking", f)
func CollectPacketInfo(versions []string) (packetInfos []PacketInfo, err error) {
var versionData data.ProtocolVersion
for _, version := range versions {
versionData, err = data.LookUpProtocolVersionByName(version)
if err != nil {
return
}
err = GenerateHelperState(p.Status, "Status", f)
if err != nil {
return
}
err = GenerateHelperState(p.Login, "Login", f)
if err != nil {
return
}
err = GenerateHelperState(p.Configuration, "Configuration", f)
if err != nil {
return
}
err = GenerateHelperState(p.Play, "Play", f)
if err != nil {
return
}
return
}
// PacketIdentifierToTypeGenerator func PacketIdentifierToType(s string) any {
// switch s {
// case "abilities":
// return PlayToClientPacketAbilities{}
// default:
// return nil
// }
// }
func PacketIdentifierToTypeGenerator(funcNamePrefix string, f *ast.File, m map[string]string) (err error) {
var s []ast.Stmt
for _, k := range OrderedKeys(m) {
v := m[k]
s = append(s, Case(Exprs(StrLit(k)), Stmts(Assign121(Ident("t"), CompLit(Ident(v), nil)))))
}
s = append(s, Case(nil, Stmts(Assign121(Ident("t"), Nil()))))
fn := NewFunc(funcNamePrefix+"PacketIdentifierToType", []NameAndType{{"s", Ident("string")}}, []NameAndType{{"t", Ident("any")}})
fn.Body = NewBlockEllipsis(SwitchStmt(Ident("s"), NewBlock(s)), Return())
AppendDecl(f, fn)
return
}
func TypeToPacketIdentifierGenerator(funcNamePrefix string, f *ast.File, m map[string]string) (err error) {
var s []ast.Stmt
for _, k := range OrderedKeys(m) {
v := m[k]
s = append(s, Case(Exprs(Ident(k)), Stmts(Assign121(Ident("s"), StrLit(v)))))
}
fn := NewFunc(funcNamePrefix+"TypeToPacketIdentifier", []NameAndType{{"t", Ident("any")}}, []NameAndType{{"s", Ident("string")}})
fn.Body = NewBlockEllipsis(TypeSwitch(ExprStmt(TypeAssert(Ident("t"), Ident("type"))), NewBlock(s)), Return())
AppendDecl(f, fn)
return
}
func GenerateHelpers(version string, w io.Writer) (err error) {
protocol := Protocol{}
err = data.LoadVersionedJson(version, "protocol", &protocol)
if err != nil {
return
}
f := NewFile("v" + strings.ReplaceAll(version, ".", "_"))
AppendDecl(f, Import("io", "github.com/admin-else/strom/proto_base"))
err = GenerateHelperProtocol(protocol, f)
if err != nil {
return
prefixTypeMap := map[string]TypesInfo{
"HandshakingToServer": {protocol.Handshaking.ToServer, "ToServer", "Handshaking"},
"HandshakingToClient": {protocol.Handshaking.ToClient, "ToClient", "Handshaking"},
"StatusToServer": {protocol.Status.ToServer, "ToServer", "Status"},
"StatusToClient": {protocol.Status.ToClient, "ToClient", "Status"},
"LoginToServer": {protocol.Login.ToServer, "ToServer", "Login"},
"LoginToClient": {protocol.Login.ToClient, "ToClient", "Login"},
"ConfigurationToServer": {protocol.Configuration.ToServer, "ToServer", "Configuration"},
"ConfigurationToClient": {protocol.Configuration.ToClient, "ToClient", "Configuration"},
"PlayToServer": {protocol.Play.ToServer, "ToServer", "Play"},
"PlayToClient": {protocol.Play.ToClient, "ToClient", "Play"},
}
for prefix, types := range prefixTypeMap {
for k, v := range types.Types.Types {
if k != "packet" {
continue
}
packetIds := v.([]any)[1].([]any)[0].(map[string]any)["type"].([]any)[1].(map[string]any)["mappings"].(map[string]any)
packetIdsStrings := AssertAndConvertMapValues[string](packetIds)
packetIdsRev := ReverseMap(packetIdsStrings)
v := v.([]any)[1].([]any)[1].(map[string]any)["type"].([]any)[1].(map[string]any)["fields"].(map[string]any)
for k2, v2 := range v {
v2 := v2.(string)
var typeName string
if strings.HasPrefix(v2, "packet_common") {
typeName = CamelCase(v2)
} else if v2 == "void" {
typeName = "struct{}"
} else {
typeName = prefix + CamelCase(v2)
}
packetInfos = append(packetInfos, PacketInfo{
TName: typeName,
Name: k2,
Direction: types.Direction,
State: types.State,
PacketId: packetIdsRev[k2],
ProtocolVersion: strconv.Itoa(versionData.Version),
MinecraftVersion: version,
})
}
}
}
err = PrintToFile(f, w)
if err != nil {
return
}
_, err = w.Write([]byte(helperAppend))
return
}
func GeneratePacketInfoFile(versions []string) (err error) {
var packetInfos []PacketInfo
packetInfos, err = CollectPacketInfo(versions)
if err != nil {
return
}
f := NewFile("proto_generated")
imports := []string{"reflect", "github.com/admin-else/strom/proto_base"}
for _, v := range versions {
vUnderscore := strings.ReplaceAll(v, ".", "_")
imports = append(imports, "github.com/admin-else/strom/proto_generated/v"+vUnderscore)
}
AppendDecl(f, Import(imports...))
var packetInfoExprs []ast.Expr
for _, p := range packetInfos {
vUnderscore := "v" + strings.ReplaceAll(p.MinecraftVersion, ".", "_")
typeName := p.TName
var typeExpr ast.Expr
if typeName == "struct{}" {
typeExpr = &ast.StructType{Fields: &ast.FieldList{}}
} else if strings.HasPrefix(typeName, "proto_base.") {
typeExpr = Selector("proto_base", strings.TrimPrefix(typeName, "proto_base."))
} else {
typeExpr = Selector(vUnderscore, typeName)
}
packetId, _ := strconv.ParseInt(p.PacketId, 0, 32)
protocolVersion, _ := strconv.Atoi(p.ProtocolVersion)
packetInfoExprs = append(packetInfoExprs, CompLit(Selector("proto_base", "PacketInfo"), []ast.Expr{
KeyValueExpr(Ident("Type"), Call(Selector("reflect", "TypeOf"), CompLit(typeExpr, nil))),
KeyValueExpr(Ident("Name"), StrLit(p.Name)),
KeyValueExpr(Ident("Direction"), Selector("proto_base", p.Direction)),
KeyValueExpr(Ident("State"), Selector("proto_base", p.State)),
KeyValueExpr(Ident("PacketId"), NumLit(int(packetId))),
KeyValueExpr(Ident("ProtocolVersion"), NumLit(protocolVersion)),
}))
}
AppendDecl(f, VarValues("Packets", CompLit(Slice(Selector("proto_base", "PacketInfo")), packetInfoExprs)))
out, err := os.Create("proto_generated/packet_info.go")
if err != nil {
return
}
defer out.Close()
return PrintToFile(f, out)
}
+16 -28
View File
@@ -197,7 +197,7 @@ func FixPointerReceivers(e ast.Expr) (td ast.Expr, ret ast.Expr) {
return
}
func (g *Generator) GenerateTypes(prefix string, types Types) error {
func (g *Generator) GenerateTypes(prefix string, types Types) (err error) {
g.CurrentlyGeneratingTypes = types
g.CurrentlyGeneratingTypesPrefix = prefix
for _, k := range OrderedKeys(types.Types) {
@@ -207,13 +207,13 @@ func (g *Generator) GenerateTypes(prefix string, types Types) error {
}
g.Depth = 0
e, err := g.VisitType(v)
if errors.Is(err, ToDoError) {
e, err2 := g.VisitType(v)
if errors.Is(err2, ToDoError) {
e = Selector("proto_base", "ToDo")
err = nil
err2 = nil
}
if err != nil {
return err
if err2 != nil {
return err2
}
if e == nil { // This is for types we implement ourselves
continue
@@ -229,11 +229,11 @@ func (g *Generator) GenerateTypes(prefix string, types Types) error {
rets := []NameAndType{{"err", Ident("error")}}
decodeFunction := NewFuncWithReceiver("Decode", "ret", Pointer(Ident(tName)), args, rets)
g.Depth = 0
s, err := g.VisitDecoder(retExpr, v, tName)
if err != nil {
s, err2 := g.VisitDecoder(retExpr, v, tName)
if err2 != nil {
s = ToDoStmts
if !errors.Is(err, ToDoError) {
fmt.Println("failed to make decoder for", k, err)
if !errors.Is(err2, ToDoError) {
fmt.Println("failed to make decoder for", k, err2)
}
}
decodeFunction.Body = NewBlock(append(s, Return()))
@@ -243,18 +243,18 @@ func (g *Generator) GenerateTypes(prefix string, types Types) error {
rets = []NameAndType{{"err", Ident("error")}}
encodeFunction := NewFuncWithReceiver("Encode", "ret", Pointer(Ident(tName)), args, rets)
g.Depth = 0
s, err = g.VisitEncoder(retExpr, v, tName)
if err != nil {
s, err2 = g.VisitEncoder(retExpr, v, tName)
if err2 != nil {
s = ToDoStmts
if !errors.Is(err, ToDoError) {
fmt.Println("failed to make encoder for", k, err)
if !errors.Is(err2, ToDoError) {
fmt.Println("failed to make encoder for", k, err2)
}
}
encodeFunction.Body = NewBlock(append(s, Return()))
AppendDecl(g.File, encodeFunction)
}
return nil
return
}
func (g *Generator) GenerateState(prefix string, state State) (err error) {
@@ -331,12 +331,6 @@ func generateVersion(v string) (err error) {
if err != nil {
return
}
helperF, err := os.Create("proto_generated/v" + vUnderscore + "/helpers.go")
if err != nil {
return
}
defer f.Close()
err = GenerateHelpers(v, helperF)
return
}
@@ -349,12 +343,6 @@ func GenerateVersions(versions []string) (err error) {
if err != nil {
return
}
f, err := os.Create("proto_generated/version_switcher.go")
if err != nil {
return
}
defer f.Close()
err = GenerateVersionSwitcher(versions, f)
for _, version := range versions {
fmt.Println("generating", version)
err = generateVersion(version)
@@ -362,7 +350,7 @@ func GenerateVersions(versions []string) (err error) {
return
}
}
return
return GeneratePacketInfoFile(versions)
}
func main() {
+23 -12
View File
@@ -8,13 +8,12 @@ import (
"io"
)
func NewStruct() *ast.StructType {
func NewStruct() (s *ast.StructType) {
return &ast.StructType{
Fields: &ast.FieldList{
List: []*ast.Field{},
},
}
}
func AddFieldToStruct(s *ast.StructType, fieldName string, t ast.Expr) {
@@ -48,7 +47,7 @@ func Import(path ...string) ast.Decl {
}
}
func Ident(name string) *ast.Ident {
func Ident(name string) (id *ast.Ident) {
return ast.NewIdent(name)
}
@@ -56,6 +55,18 @@ func VarStmt(name string, t ast.Expr) *ast.DeclStmt {
return &ast.DeclStmt{Decl: Var(name, t)}
}
func VarValues(name string, v ...ast.Expr) ast.Decl {
return &ast.GenDecl{
Tok: token.VAR,
Specs: []ast.Spec{
&ast.ValueSpec{
Names: []*ast.Ident{Ident(name)},
Values: v,
},
},
}
}
func Var(name string, t ast.Expr) ast.Decl {
return &ast.GenDecl{
Tok: token.VAR,
@@ -72,7 +83,7 @@ func Var(name string, t ast.Expr) ast.Decl {
}
}
func Slice(elementType ast.Expr) ast.Expr {
func Slice(elementType ast.Expr) (e ast.Expr) {
return &ast.ArrayType{
Len: nil, // nil Length means it's a slice, not an array
Elt: elementType,
@@ -116,34 +127,34 @@ func TypeDecl(name string, t ast.Expr) ast.Decl {
}
}
func Selector(x, sel string) ast.Expr {
func Selector(x, sel string) (e ast.Expr) {
return &ast.SelectorExpr{
X: Ident(x),
Sel: Ident(sel),
}
}
func SelectorExprAndStr(x ast.Expr, sel string) ast.Expr {
func SelectorExprAndStr(x ast.Expr, sel string) (e ast.Expr) {
return &ast.SelectorExpr{
X: x,
Sel: Ident(sel),
}
}
func Pointer(elementType ast.Expr) ast.Expr {
func Pointer(elementType ast.Expr) (e ast.Expr) {
return &ast.StarExpr{
X: elementType,
}
}
func Call(fn ast.Expr, args ...ast.Expr) *ast.CallExpr {
func Call(fn ast.Expr, args ...ast.Expr) (e *ast.CallExpr) {
return &ast.CallExpr{
Fun: fn,
Args: args,
}
}
func Assign121(lhs, rhs ast.Expr) *ast.AssignStmt {
func Assign121(lhs, rhs ast.Expr) (s *ast.AssignStmt) {
return &ast.AssignStmt{
Lhs: []ast.Expr{lhs},
Tok: token.ASSIGN,
@@ -151,7 +162,7 @@ func Assign121(lhs, rhs ast.Expr) *ast.AssignStmt {
}
}
func Assign(lhs, rhs []ast.Expr) *ast.AssignStmt {
func Assign(lhs, rhs []ast.Expr) (s *ast.AssignStmt) {
return &ast.AssignStmt{
Lhs: lhs,
Tok: token.ASSIGN,
@@ -159,7 +170,7 @@ func Assign(lhs, rhs []ast.Expr) *ast.AssignStmt {
}
}
func Define(lhs, rhs []ast.Expr) *ast.AssignStmt {
func Define(lhs, rhs []ast.Expr) (s *ast.AssignStmt) {
return &ast.AssignStmt{
Lhs: lhs,
Tok: token.DEFINE,
@@ -167,7 +178,7 @@ func Define(lhs, rhs []ast.Expr) *ast.AssignStmt {
}
}
func Define121(lhs, rhs ast.Expr) *ast.AssignStmt {
func Define121(lhs, rhs ast.Expr) (s *ast.AssignStmt) {
return &ast.AssignStmt{
Lhs: []ast.Expr{lhs},
Tok: token.DEFINE,
+17 -7
View File
@@ -9,7 +9,8 @@ import (
var boundaries = []rune{' ', '_', '-', '.', ',', ';', ':', '(', ')', '[', ']', '{', '}'}
func CamelCase(s string) (ret string) {
func CamelCase(s string) string {
ret := ""
atWordBoundary := true
for _, c := range s {
if slices.Contains(boundaries, c) {
@@ -22,7 +23,7 @@ func CamelCase(s string) (ret string) {
atWordBoundary = false
ret += string(c)
}
return
return ret
}
func OrderedKeys[Map map[K]V, K cmp.Ordered, V any](m Map) []K {
@@ -32,12 +33,20 @@ func OrderedKeys[Map map[K]V, K cmp.Ordered, V any](m Map) []K {
return keys
}
func ReverseMap[M map[K]V, K cmp.Ordered, V cmp.Ordered](m M) (ret map[V]K) {
ret = map[V]K{}
func AssertAndConvertMapValues[T any, M map[K]any, K cmp.Ordered](m M) map[K]T {
ret := map[K]T{}
for k, v := range m {
ret[k] = v.(T)
}
return ret
}
func ReverseMap[M map[K]V, K cmp.Ordered, V cmp.Ordered](m M) map[V]K {
ret := map[V]K{}
for k, v := range m {
ret[v] = k
}
return
return ret
}
func must(err error) {
@@ -46,9 +55,10 @@ func must(err error) {
}
}
func PopFront[T any](s []T) (front T, rest []T, ok bool) {
func PopFront[T any](s []T) (T, []T, bool) {
if len(s) == 0 {
return front, s, false
var zero T
return zero, s, false
}
return s[0], s[1:], true
}
-143
View File
@@ -1,143 +0,0 @@
package main
import (
"go/ast"
"io"
"strings"
)
func GeneratePacketIdentifierToType(versions []string) (decl ast.Decl) {
var s []ast.Stmt
for _, version := range versions {
s = append(s, Case(Exprs(StrLit(version)), Stmts(
Assign121(Ident("t"), Call(SelectorExprAndStr(Ident("v"+strings.ReplaceAll(version, ".", "_")), "PacketIdentifierToType"), Ident("d"), Ident("s"), Ident("i"))),
)))
}
s = append(s, Case(nil, Stmts()))
fn := NewFunc("PacketIdentifierToType", []NameAndType{
{"v", Ident("string")},
{"d", Ident("proto_base.Direction")},
{"s", Ident("proto_base.State")},
{"i", Ident("string")},
}, []NameAndType{
{"t", Ident("any")},
})
fn.Body = NewBlockEllipsis(SwitchStmt(Ident("v"), NewBlock(s)), Return())
decl = fn
return
}
/*
func PacketIdentifierToType(v string, d proto_base.Direction, s proto_base.State, i string) (t any) {
switch v {
case "1.21.8":
t = v1_21_8.PacketIdentifierToType(d, s, i)
default:
}
return
}
func TypeToPacketIdentifier(v string, d proto_base.Direction, s proto_base.State, t any) (i string) {
switch v {
case "1.21.8":
i = v1_21_8.TypeToPacketIdentifier(d, s, t)
}
return
}
func DecodePacket(v string, d proto_base.Direction, s proto_base.State, r io.Reader) (packet any, err error) {
switch v {
case "1.21.8":
packet, err = v1_21_8.DecodePacket(d, s, r)
}
return
}
func EncodePacket(v string, d proto_base.Direction, s proto_base.State, i string, p any, w io.Writer) (err error) {
switch v {
case "1.21.8":
err = v1_21_8.EncodePacket(d, s, i, p, w)
}
return
}
*/
func GenerateTypeToPacketIdentifier(versions []string) (decl ast.Decl) {
var s []ast.Stmt
for _, version := range versions {
s = append(s, Case(Exprs(StrLit(version)), Stmts(
Assign121(Ident("i"), Call(SelectorExprAndStr(Ident("v"+strings.ReplaceAll(version, ".", "_")), "TypeToPacketIdentifier"), Ident("d"), Ident("s"), Ident("t"))),
)))
}
fn := NewFunc("TypeToPacketIdentifier", []NameAndType{
{"v", Ident("string")},
{"d", Ident("proto_base.Direction")},
{"s", Ident("proto_base.State")},
{"t", Ident("any")},
}, []NameAndType{
{"i", Ident("string")},
})
fn.Body = NewBlockEllipsis(SwitchStmt(Ident("v"), NewBlock(s)), Return())
decl = fn
return
}
func GenerateDecodePacket(versions []string) (decl ast.Decl) {
var s []ast.Stmt
for _, version := range versions {
s = append(s, Case(Exprs(StrLit(version)), Stmts(
Assign([]ast.Expr{Ident("packet"), Ident("err")}, []ast.Expr{Call(SelectorExprAndStr(Ident("v"+strings.ReplaceAll(version, ".", "_")), "DecodePacket"), Ident("d"), Ident("s"), Ident("r"))}),
)))
}
fn := NewFunc("DecodePacket", []NameAndType{
{"v", Ident("string")},
{"d", Ident("proto_base.Direction")},
{"s", Ident("proto_base.State")},
{"r", Ident("io.Reader")},
}, []NameAndType{
{"packet", Ident("any")},
{"err", Ident("error")},
})
fn.Body = NewBlockEllipsis(SwitchStmt(Ident("v"), NewBlock(s)), Return())
decl = fn
return
}
func GenerateEncodePacket(versions []string) (decl ast.Decl) {
var s []ast.Stmt
for _, version := range versions {
s = append(s, Case(Exprs(StrLit(version)), Stmts(
Assign121(Ident("err"), Call(SelectorExprAndStr(Ident("v"+strings.ReplaceAll(version, ".", "_")), "EncodePacket"), Ident("d"), Ident("s"), Ident("i"), Ident("p"), Ident("w"))),
)))
}
fn := NewFunc("EncodePacket", []NameAndType{
{"v", Ident("string")},
{"d", Ident("proto_base.Direction")},
{"s", Ident("proto_base.State")},
{"i", Ident("string")},
{"p", Ident("any")},
{"w", Ident("io.Writer")},
}, []NameAndType{
{"err", Ident("error")},
})
fn.Body = NewBlockEllipsis(SwitchStmt(Ident("v"), NewBlock(s)), Return())
decl = fn
return
}
func GenerateVersionSwitcher(versions []string, printTo io.Writer) (err error) {
f := NewFile("proto_generated")
importPaths := []string{"io", "github.com/admin-else/strom/proto_base"}
for _, version := range versions {
importPaths = append(importPaths, "github.com/admin-else/strom/proto_generated/v"+strings.ReplaceAll(version, ".", "_"))
}
AppendDecl(f, Import(importPaths...))
AppendDecl(f, GeneratePacketIdentifierToType(versions))
AppendDecl(f, GenerateTypeToPacketIdentifier(versions))
AppendDecl(f, GenerateDecodePacket(versions))
AppendDecl(f, GenerateEncodePacket(versions))
return PrintToFile(f, printTo)
}