packets upgrade
This commit is contained in:
@@ -4,6 +4,7 @@ import (
|
|||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"errors"
|
"errors"
|
||||||
"io"
|
"io"
|
||||||
|
"reflect"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Direction int
|
type Direction int
|
||||||
@@ -210,3 +211,12 @@ type EncodeDecodeAble interface {
|
|||||||
Encode(w io.Writer) (err error)
|
Encode(w io.Writer) (err error)
|
||||||
Decode(r io.Reader) (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
|
|
||||||
}
|
|
||||||
+104
-104
@@ -2,128 +2,128 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"go/ast"
|
"go/ast"
|
||||||
"io"
|
"os"
|
||||||
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
_ "embed"
|
|
||||||
|
|
||||||
"github.com/admin-else/strom/data"
|
"github.com/admin-else/strom/data"
|
||||||
)
|
)
|
||||||
|
|
||||||
//go:embed helper_append.txt
|
type TypesInfo struct {
|
||||||
var helperAppend string
|
Types
|
||||||
|
Direction string
|
||||||
func GenerateHelperTypes(t Types, prefix string, f *ast.File) (err error) {
|
State string
|
||||||
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
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func GenerateHelperState(s State, prefix string, f *ast.File) (err error) {
|
type PacketInfo struct {
|
||||||
err = GenerateHelperTypes(s.ToServer, prefix+"ToServer", f)
|
TName, Name, Direction, State, PacketId, ProtocolVersion, MinecraftVersion string
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
return GenerateHelperTypes(s.ToClient, prefix+"ToClient", f)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func GenerateHelperProtocol(p Protocol, f *ast.File) (err error) {
|
func CollectPacketInfo(versions []string) (packetInfos []PacketInfo, err error) {
|
||||||
err = GenerateHelperState(p.Handshaking, "Handshaking", f)
|
var versionData data.ProtocolVersion
|
||||||
|
for _, version := range versions {
|
||||||
|
versionData, err = data.LookUpProtocolVersionByName(version)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
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{}
|
protocol := Protocol{}
|
||||||
err = data.LoadVersionedJson(version, "protocol", &protocol)
|
err = data.LoadVersionedJson(version, "protocol", &protocol)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
f := NewFile("v" + strings.ReplaceAll(version, ".", "_"))
|
prefixTypeMap := map[string]TypesInfo{
|
||||||
AppendDecl(f, Import("io", "github.com/admin-else/strom/proto_base"))
|
"HandshakingToServer": {protocol.Handshaking.ToServer, "ToServer", "Handshaking"},
|
||||||
err = GenerateHelperProtocol(protocol, f)
|
"HandshakingToClient": {protocol.Handshaking.ToClient, "ToClient", "Handshaking"},
|
||||||
if err != nil {
|
"StatusToServer": {protocol.Status.ToServer, "ToServer", "Status"},
|
||||||
return
|
"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
|
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
@@ -197,7 +197,7 @@ func FixPointerReceivers(e ast.Expr) (td ast.Expr, ret ast.Expr) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *Generator) GenerateTypes(prefix string, types Types) error {
|
func (g *Generator) GenerateTypes(prefix string, types Types) (err error) {
|
||||||
g.CurrentlyGeneratingTypes = types
|
g.CurrentlyGeneratingTypes = types
|
||||||
g.CurrentlyGeneratingTypesPrefix = prefix
|
g.CurrentlyGeneratingTypesPrefix = prefix
|
||||||
for _, k := range OrderedKeys(types.Types) {
|
for _, k := range OrderedKeys(types.Types) {
|
||||||
@@ -207,13 +207,13 @@ func (g *Generator) GenerateTypes(prefix string, types Types) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
g.Depth = 0
|
g.Depth = 0
|
||||||
e, err := g.VisitType(v)
|
e, err2 := g.VisitType(v)
|
||||||
if errors.Is(err, ToDoError) {
|
if errors.Is(err2, ToDoError) {
|
||||||
e = Selector("proto_base", "ToDo")
|
e = Selector("proto_base", "ToDo")
|
||||||
err = nil
|
err2 = nil
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err2 != nil {
|
||||||
return err
|
return err2
|
||||||
}
|
}
|
||||||
if e == nil { // This is for types we implement ourselves
|
if e == nil { // This is for types we implement ourselves
|
||||||
continue
|
continue
|
||||||
@@ -229,11 +229,11 @@ func (g *Generator) GenerateTypes(prefix string, types Types) error {
|
|||||||
rets := []NameAndType{{"err", Ident("error")}}
|
rets := []NameAndType{{"err", Ident("error")}}
|
||||||
decodeFunction := NewFuncWithReceiver("Decode", "ret", Pointer(Ident(tName)), args, rets)
|
decodeFunction := NewFuncWithReceiver("Decode", "ret", Pointer(Ident(tName)), args, rets)
|
||||||
g.Depth = 0
|
g.Depth = 0
|
||||||
s, err := g.VisitDecoder(retExpr, v, tName)
|
s, err2 := g.VisitDecoder(retExpr, v, tName)
|
||||||
if err != nil {
|
if err2 != nil {
|
||||||
s = ToDoStmts
|
s = ToDoStmts
|
||||||
if !errors.Is(err, ToDoError) {
|
if !errors.Is(err2, ToDoError) {
|
||||||
fmt.Println("failed to make decoder for", k, err)
|
fmt.Println("failed to make decoder for", k, err2)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
decodeFunction.Body = NewBlock(append(s, Return()))
|
decodeFunction.Body = NewBlock(append(s, Return()))
|
||||||
@@ -243,18 +243,18 @@ func (g *Generator) GenerateTypes(prefix string, types Types) error {
|
|||||||
rets = []NameAndType{{"err", Ident("error")}}
|
rets = []NameAndType{{"err", Ident("error")}}
|
||||||
encodeFunction := NewFuncWithReceiver("Encode", "ret", Pointer(Ident(tName)), args, rets)
|
encodeFunction := NewFuncWithReceiver("Encode", "ret", Pointer(Ident(tName)), args, rets)
|
||||||
g.Depth = 0
|
g.Depth = 0
|
||||||
s, err = g.VisitEncoder(retExpr, v, tName)
|
s, err2 = g.VisitEncoder(retExpr, v, tName)
|
||||||
if err != nil {
|
if err2 != nil {
|
||||||
s = ToDoStmts
|
s = ToDoStmts
|
||||||
if !errors.Is(err, ToDoError) {
|
if !errors.Is(err2, ToDoError) {
|
||||||
fmt.Println("failed to make encoder for", k, err)
|
fmt.Println("failed to make encoder for", k, err2)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
encodeFunction.Body = NewBlock(append(s, Return()))
|
encodeFunction.Body = NewBlock(append(s, Return()))
|
||||||
AppendDecl(g.File, encodeFunction)
|
AppendDecl(g.File, encodeFunction)
|
||||||
|
|
||||||
}
|
}
|
||||||
return nil
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *Generator) GenerateState(prefix string, state State) (err error) {
|
func (g *Generator) GenerateState(prefix string, state State) (err error) {
|
||||||
@@ -331,12 +331,6 @@ func generateVersion(v string) (err error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
helperF, err := os.Create("proto_generated/v" + vUnderscore + "/helpers.go")
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
defer f.Close()
|
|
||||||
err = GenerateHelpers(v, helperF)
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -349,12 +343,6 @@ func GenerateVersions(versions []string) (err error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
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 {
|
for _, version := range versions {
|
||||||
fmt.Println("generating", version)
|
fmt.Println("generating", version)
|
||||||
err = generateVersion(version)
|
err = generateVersion(version)
|
||||||
@@ -362,7 +350,7 @@ func GenerateVersions(versions []string) (err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return
|
return GeneratePacketInfoFile(versions)
|
||||||
}
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
|||||||
+23
-12
@@ -8,13 +8,12 @@ import (
|
|||||||
"io"
|
"io"
|
||||||
)
|
)
|
||||||
|
|
||||||
func NewStruct() *ast.StructType {
|
func NewStruct() (s *ast.StructType) {
|
||||||
return &ast.StructType{
|
return &ast.StructType{
|
||||||
Fields: &ast.FieldList{
|
Fields: &ast.FieldList{
|
||||||
List: []*ast.Field{},
|
List: []*ast.Field{},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func AddFieldToStruct(s *ast.StructType, fieldName string, t ast.Expr) {
|
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)
|
return ast.NewIdent(name)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -56,6 +55,18 @@ func VarStmt(name string, t ast.Expr) *ast.DeclStmt {
|
|||||||
return &ast.DeclStmt{Decl: Var(name, t)}
|
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 {
|
func Var(name string, t ast.Expr) ast.Decl {
|
||||||
return &ast.GenDecl{
|
return &ast.GenDecl{
|
||||||
Tok: token.VAR,
|
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{
|
return &ast.ArrayType{
|
||||||
Len: nil, // nil Length means it's a slice, not an array
|
Len: nil, // nil Length means it's a slice, not an array
|
||||||
Elt: elementType,
|
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{
|
return &ast.SelectorExpr{
|
||||||
X: Ident(x),
|
X: Ident(x),
|
||||||
Sel: Ident(sel),
|
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{
|
return &ast.SelectorExpr{
|
||||||
X: x,
|
X: x,
|
||||||
Sel: Ident(sel),
|
Sel: Ident(sel),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func Pointer(elementType ast.Expr) ast.Expr {
|
func Pointer(elementType ast.Expr) (e ast.Expr) {
|
||||||
return &ast.StarExpr{
|
return &ast.StarExpr{
|
||||||
X: elementType,
|
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{
|
return &ast.CallExpr{
|
||||||
Fun: fn,
|
Fun: fn,
|
||||||
Args: args,
|
Args: args,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func Assign121(lhs, rhs ast.Expr) *ast.AssignStmt {
|
func Assign121(lhs, rhs ast.Expr) (s *ast.AssignStmt) {
|
||||||
return &ast.AssignStmt{
|
return &ast.AssignStmt{
|
||||||
Lhs: []ast.Expr{lhs},
|
Lhs: []ast.Expr{lhs},
|
||||||
Tok: token.ASSIGN,
|
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{
|
return &ast.AssignStmt{
|
||||||
Lhs: lhs,
|
Lhs: lhs,
|
||||||
Tok: token.ASSIGN,
|
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{
|
return &ast.AssignStmt{
|
||||||
Lhs: lhs,
|
Lhs: lhs,
|
||||||
Tok: token.DEFINE,
|
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{
|
return &ast.AssignStmt{
|
||||||
Lhs: []ast.Expr{lhs},
|
Lhs: []ast.Expr{lhs},
|
||||||
Tok: token.DEFINE,
|
Tok: token.DEFINE,
|
||||||
|
|||||||
@@ -9,7 +9,8 @@ import (
|
|||||||
|
|
||||||
var boundaries = []rune{' ', '_', '-', '.', ',', ';', ':', '(', ')', '[', ']', '{', '}'}
|
var boundaries = []rune{' ', '_', '-', '.', ',', ';', ':', '(', ')', '[', ']', '{', '}'}
|
||||||
|
|
||||||
func CamelCase(s string) (ret string) {
|
func CamelCase(s string) string {
|
||||||
|
ret := ""
|
||||||
atWordBoundary := true
|
atWordBoundary := true
|
||||||
for _, c := range s {
|
for _, c := range s {
|
||||||
if slices.Contains(boundaries, c) {
|
if slices.Contains(boundaries, c) {
|
||||||
@@ -22,7 +23,7 @@ func CamelCase(s string) (ret string) {
|
|||||||
atWordBoundary = false
|
atWordBoundary = false
|
||||||
ret += string(c)
|
ret += string(c)
|
||||||
}
|
}
|
||||||
return
|
return ret
|
||||||
}
|
}
|
||||||
|
|
||||||
func OrderedKeys[Map map[K]V, K cmp.Ordered, V any](m Map) []K {
|
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
|
return keys
|
||||||
}
|
}
|
||||||
|
|
||||||
func ReverseMap[M map[K]V, K cmp.Ordered, V cmp.Ordered](m M) (ret map[V]K) {
|
func AssertAndConvertMapValues[T any, M map[K]any, K cmp.Ordered](m M) map[K]T {
|
||||||
ret = map[V]K{}
|
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 {
|
for k, v := range m {
|
||||||
ret[v] = k
|
ret[v] = k
|
||||||
}
|
}
|
||||||
return
|
return ret
|
||||||
}
|
}
|
||||||
|
|
||||||
func must(err error) {
|
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 {
|
if len(s) == 0 {
|
||||||
return front, s, false
|
var zero T
|
||||||
|
return zero, s, false
|
||||||
}
|
}
|
||||||
return s[0], s[1:], true
|
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