packets upgrade
This commit is contained in:
@@ -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
@@ -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
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
+101
-101
@@ -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)
|
||||
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,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func GeneratePacketInfoFile(versions []string) (err error) {
|
||||
var packetInfos []PacketInfo
|
||||
packetInfos, err = CollectPacketInfo(versions)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
err = PrintToFile(f, w)
|
||||
|
||||
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
|
||||
}
|
||||
_, err = w.Write([]byte(helperAppend))
|
||||
return
|
||||
defer out.Close()
|
||||
|
||||
return PrintToFile(f, out)
|
||||
}
|
||||
|
||||
+16
-28
@@ -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
@@ -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,
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
Reference in New Issue
Block a user