Implement generator and type for packet IDs
This commit is contained in:
196
data/gen_packetIDs.go
Normal file
196
data/gen_packetIDs.go
Normal file
@ -0,0 +1,196 @@
|
||||
// gen_packetIDs.go generates the enumeration of packet IDs used on the wire.
|
||||
|
||||
//+build ignore
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/iancoleman/strcase"
|
||||
)
|
||||
|
||||
const (
|
||||
protocolURL = "https://raw.githubusercontent.com/PrismarineJS/minecraft-data/master/data/pc/1.16.2/protocol.json"
|
||||
)
|
||||
|
||||
// unnest is a utility function to unpack a value from a nested map, given
|
||||
// an arbitrary set of keys to reach through.
|
||||
func unnest(input map[string]interface{}, keys ...string) (map[string]interface{}, error) {
|
||||
for _, k := range keys {
|
||||
sub, ok := input[k]
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("key %q not found", k)
|
||||
}
|
||||
next, ok := sub.(map[string]interface{})
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("key %q was %T, expected a string map", k, sub)
|
||||
}
|
||||
input = next
|
||||
}
|
||||
return input, nil
|
||||
}
|
||||
|
||||
type duplexMappings struct {
|
||||
Clientbound map[string]string
|
||||
Serverbound map[string]string
|
||||
}
|
||||
|
||||
func (m *duplexMappings) EnsureUniqueNames() {
|
||||
// Assemble a slice of keys to check across both maps, because we cannot
|
||||
// mutate a map while iterating it.
|
||||
clientKeys := make([]string, 0, len(m.Clientbound))
|
||||
for k, _ := range m.Clientbound {
|
||||
clientKeys = append(clientKeys, k)
|
||||
}
|
||||
|
||||
for _, k := range clientKeys {
|
||||
if _, alsoServerKey := m.Serverbound[k]; alsoServerKey {
|
||||
cVal, sVal := m.Clientbound[k], m.Serverbound[k]
|
||||
delete(m.Clientbound, k)
|
||||
delete(m.Serverbound, k)
|
||||
m.Clientbound[k+"Clientbound"] = cVal
|
||||
m.Serverbound[k+"Serverbound"] = sVal
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// unpackMapping returns the set of packet IDs and their names for a given
|
||||
// game state.
|
||||
func unpackMapping(data map[string]interface{}, gameState string) (duplexMappings, error) {
|
||||
out := duplexMappings{
|
||||
Clientbound: make(map[string]string),
|
||||
Serverbound: make(map[string]string),
|
||||
}
|
||||
|
||||
info, err := unnest(data, gameState, "toClient", "types")
|
||||
if err != nil {
|
||||
return duplexMappings{}, err
|
||||
}
|
||||
pType := info["packet"].([]interface{})[1].([]interface{})[0].(map[string]interface{})["type"]
|
||||
mappings := pType.([]interface{})[1].(map[string]interface{})["mappings"].(map[string]interface{})
|
||||
for k, v := range mappings {
|
||||
out.Clientbound[strcase.ToCamel(v.(string))] = k
|
||||
}
|
||||
info, err = unnest(data, gameState, "toServer", "types")
|
||||
if err != nil {
|
||||
return duplexMappings{}, err
|
||||
}
|
||||
pType = info["packet"].([]interface{})[1].([]interface{})[0].(map[string]interface{})["type"]
|
||||
mappings = pType.([]interface{})[1].(map[string]interface{})["mappings"].(map[string]interface{})
|
||||
for k, v := range mappings {
|
||||
out.Serverbound[strcase.ToCamel(v.(string))] = k
|
||||
}
|
||||
|
||||
return out, nil
|
||||
}
|
||||
|
||||
type protocolIDs struct {
|
||||
Login duplexMappings
|
||||
Play duplexMappings
|
||||
Status duplexMappings
|
||||
// Handshake state has no packets
|
||||
}
|
||||
|
||||
func (p protocolIDs) MaxLen() int {
|
||||
var max int
|
||||
for _, m := range []duplexMappings{p.Login, p.Play, p.Status} {
|
||||
for k, _ := range m.Clientbound {
|
||||
if len(k) > max {
|
||||
max = len(k)
|
||||
}
|
||||
}
|
||||
for k, _ := range m.Serverbound {
|
||||
if len(k) > max {
|
||||
max = len(k)
|
||||
}
|
||||
}
|
||||
}
|
||||
return max
|
||||
}
|
||||
|
||||
func downloadInfo() (*protocolIDs, error) {
|
||||
resp, err := http.Get(protocolURL)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
var data map[string]interface{}
|
||||
if err := json.NewDecoder(resp.Body).Decode(&data); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var out protocolIDs
|
||||
if out.Login, err = unpackMapping(data, "login"); err != nil {
|
||||
return nil, fmt.Errorf("login: %v", err)
|
||||
}
|
||||
out.Login.EnsureUniqueNames()
|
||||
if out.Play, err = unpackMapping(data, "play"); err != nil {
|
||||
return nil, fmt.Errorf("play: %v", err)
|
||||
}
|
||||
out.Play.EnsureUniqueNames()
|
||||
if out.Status, err = unpackMapping(data, "status"); err != nil {
|
||||
return nil, fmt.Errorf("play: %v", err)
|
||||
}
|
||||
out.Status.EnsureUniqueNames()
|
||||
|
||||
return &out, nil
|
||||
}
|
||||
|
||||
func main() {
|
||||
pIDs, err := downloadInfo()
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "Error: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
maxLen := pIDs.MaxLen()
|
||||
|
||||
fmt.Println("package data")
|
||||
fmt.Println()
|
||||
fmt.Println("//go:generate bash -c \"go run gen_packetIDs.go > packetIDs.go\"")
|
||||
fmt.Println()
|
||||
fmt.Println("// This file is automatically generated by gen_packetIDs.go. DO NOT EDIT.")
|
||||
fmt.Println()
|
||||
fmt.Println("// PktID represents a packet ID used in the minecraft protocol.")
|
||||
fmt.Println("type PktID int32")
|
||||
fmt.Println()
|
||||
fmt.Println("// Valid PktID values.")
|
||||
fmt.Println("const (")
|
||||
|
||||
fmt.Println(" // Clientbound packets for connections in the login state.")
|
||||
for k, v := range pIDs.Login.Clientbound {
|
||||
fmt.Printf(" %s%s PktID = %s\n", k, strings.Repeat(" ", maxLen-len(k)), v)
|
||||
}
|
||||
fmt.Println(" // Serverbound packets for connections in the login state.")
|
||||
for k, v := range pIDs.Login.Serverbound {
|
||||
fmt.Printf(" %s%s PktID = %s\n", k, strings.Repeat(" ", maxLen-len(k)), v)
|
||||
}
|
||||
fmt.Println()
|
||||
|
||||
fmt.Println(" // Clientbound packets for connections in the play state.")
|
||||
for k, v := range pIDs.Play.Clientbound {
|
||||
fmt.Printf(" %s%s PktID = %s\n", k, strings.Repeat(" ", maxLen-len(k)), v)
|
||||
}
|
||||
fmt.Println(" // Serverbound packets for connections in the play state.")
|
||||
for k, v := range pIDs.Play.Serverbound {
|
||||
fmt.Printf(" %s%s PktID = %s\n", k, strings.Repeat(" ", maxLen-len(k)), v)
|
||||
}
|
||||
fmt.Println()
|
||||
|
||||
fmt.Println(" // Clientbound packets used to respond to ping/status requests.")
|
||||
for k, v := range pIDs.Status.Clientbound {
|
||||
fmt.Printf(" %s%s PktID = %s\n", k, strings.Repeat(" ", maxLen-len(k)), v)
|
||||
}
|
||||
fmt.Println(" // Serverbound packets used to ping or read server status.")
|
||||
for k, v := range pIDs.Status.Serverbound {
|
||||
fmt.Printf(" %s%s PktID = %s\n", k, strings.Repeat(" ", maxLen-len(k)), v)
|
||||
}
|
||||
fmt.Println()
|
||||
|
||||
fmt.Println(")")
|
||||
}
|
@ -1,156 +1,173 @@
|
||||
package data
|
||||
|
||||
// Clientbound packet IDs
|
||||
//go:generate bash -c "go run gen_packetIDs.go > packetIDs.go"
|
||||
|
||||
// This file is automatically generated by gen_packetIDs.go. DO NOT EDIT.
|
||||
|
||||
// PktID represents a packet ID used in the minecraft protocol.
|
||||
type PktID int32
|
||||
|
||||
// Valid PktID values.
|
||||
const (
|
||||
SpawnObject int32 = iota //0x00
|
||||
SpawnExperienceOrb
|
||||
SpawnLivingEntity
|
||||
SpawnPainting
|
||||
SpawnPlayer
|
||||
EntityAnimationClientbound
|
||||
Statistics
|
||||
AcknowledgePlayerDigging
|
||||
BlockBreakAnimation
|
||||
BlockEntityData
|
||||
BlockAction
|
||||
BlockChange
|
||||
BossBar
|
||||
ServerDifficulty
|
||||
ChatMessageClientbound
|
||||
TabComplete
|
||||
// Clientbound packets for connections in the login state.
|
||||
EncryptionBeginClientbound PktID = 0x01
|
||||
Success PktID = 0x02
|
||||
Compress PktID = 0x03
|
||||
LoginPluginRequest PktID = 0x04
|
||||
Disconnect PktID = 0x00
|
||||
// Serverbound packets for connections in the login state.
|
||||
EncryptionBeginServerbound PktID = 0x01
|
||||
LoginPluginResponse PktID = 0x02
|
||||
LoginStart PktID = 0x00
|
||||
|
||||
DeclareCommands //0x10
|
||||
WindowConfirmationClientbound
|
||||
CloseWindowClientbound
|
||||
WindowItems
|
||||
WindowProperty
|
||||
SetSlot
|
||||
SetCooldown
|
||||
PluginMessageClientbound
|
||||
NamedSoundEffect
|
||||
DisconnectPlay
|
||||
EntityStatus
|
||||
Explosion
|
||||
UnloadChunk
|
||||
ChangeGameState
|
||||
OpenHorseWindow
|
||||
KeepAliveClientbound
|
||||
// Clientbound packets for connections in the play state.
|
||||
EntityMetadata PktID = 0x44
|
||||
Teams PktID = 0x4c
|
||||
BossBar PktID = 0x0c
|
||||
Map PktID = 0x25
|
||||
Difficulty PktID = 0x0d
|
||||
Camera PktID = 0x3e
|
||||
WindowItems PktID = 0x13
|
||||
ScoreboardObjective PktID = 0x4a
|
||||
RelEntityMove PktID = 0x27
|
||||
DeclareCommands PktID = 0x10
|
||||
CombatEvent PktID = 0x31
|
||||
SpawnEntityPainting PktID = 0x03
|
||||
EntityMoveLook PktID = 0x28
|
||||
ScoreboardScore PktID = 0x4d
|
||||
Title PktID = 0x4f
|
||||
CraftProgressBar PktID = 0x14
|
||||
NamedEntitySpawn PktID = 0x04
|
||||
ScoreboardDisplayObjective PktID = 0x43
|
||||
WorldParticles PktID = 0x22
|
||||
OpenWindow PktID = 0x2d
|
||||
MultiBlockChange PktID = 0x3b
|
||||
EntitySoundEffect PktID = 0x50
|
||||
Tags PktID = 0x5b
|
||||
EntityUpdateAttributes PktID = 0x58
|
||||
NamedSoundEffect PktID = 0x18
|
||||
GameStateChange PktID = 0x1d
|
||||
PlayerInfo PktID = 0x32
|
||||
Advancements PktID = 0x57
|
||||
Explosion PktID = 0x1b
|
||||
KeepAliveClientbound PktID = 0x1f
|
||||
MapChunk PktID = 0x20
|
||||
AttachEntity PktID = 0x45
|
||||
TradeList PktID = 0x26
|
||||
Respawn PktID = 0x39
|
||||
EntityDestroy PktID = 0x36
|
||||
Experience PktID = 0x48
|
||||
EntityLook PktID = 0x29
|
||||
OpenBook PktID = 0x2c
|
||||
WorldEvent PktID = 0x21
|
||||
DeclareRecipes PktID = 0x5a
|
||||
UnlockRecipes PktID = 0x35
|
||||
EntityEquipment PktID = 0x47
|
||||
EntityVelocity PktID = 0x46
|
||||
Animation PktID = 0x05
|
||||
UpdateViewDistance PktID = 0x41
|
||||
HeldItemSlotClientbound PktID = 0x3f
|
||||
NbtQueryResponse PktID = 0x54
|
||||
Entity PktID = 0x2a
|
||||
UpdateViewPosition PktID = 0x40
|
||||
AbilitiesClientbound PktID = 0x30
|
||||
OpenSignEntity PktID = 0x2e
|
||||
SetSlot PktID = 0x15
|
||||
PlayerlistHeader PktID = 0x53
|
||||
ResourcePackSend PktID = 0x38
|
||||
SpawnEntityExperienceOrb PktID = 0x01
|
||||
Collect PktID = 0x55
|
||||
Statistics PktID = 0x06
|
||||
TileEntityData PktID = 0x09
|
||||
ChatClientbound PktID = 0x0e
|
||||
WorldBorder PktID = 0x3d
|
||||
UnloadChunk PktID = 0x1c
|
||||
UpdateLight PktID = 0x23
|
||||
UpdateHealth PktID = 0x49
|
||||
RemoveEntityEffect PktID = 0x37
|
||||
KickDisconnect PktID = 0x19
|
||||
CustomPayloadClientbound PktID = 0x17
|
||||
SpawnPosition PktID = 0x42
|
||||
EntityStatus PktID = 0x1a
|
||||
SpawnEntity PktID = 0x00
|
||||
SetPassengers PktID = 0x4b
|
||||
FacePlayer PktID = 0x33
|
||||
TransactionClientbound PktID = 0x11
|
||||
BlockAction PktID = 0x0a
|
||||
BlockBreakAnimation PktID = 0x08
|
||||
BlockChange PktID = 0x0b
|
||||
Login PktID = 0x24
|
||||
VehicleMoveClientbound PktID = 0x2b
|
||||
CraftRecipeResponse PktID = 0x2f
|
||||
SetCooldown PktID = 0x16
|
||||
StopSound PktID = 0x52
|
||||
EntityEffect PktID = 0x59
|
||||
CloseWindowClientbound PktID = 0x12
|
||||
AcknowledgePlayerDigging PktID = 0x07
|
||||
SelectAdvancementTab PktID = 0x3c
|
||||
EntityHeadRotation PktID = 0x3a
|
||||
TabCompleteClientbound PktID = 0x0f
|
||||
PositionClientbound PktID = 0x34
|
||||
OpenHorseWindow PktID = 0x1e
|
||||
UpdateTime PktID = 0x4e
|
||||
SpawnEntityLiving PktID = 0x02
|
||||
EntityTeleport PktID = 0x56
|
||||
SoundEffect PktID = 0x51
|
||||
// Serverbound packets for connections in the play state.
|
||||
SetBeaconEffect PktID = 0x24
|
||||
UpdateStructureBlock PktID = 0x2a
|
||||
EnchantItem PktID = 0x08
|
||||
Spectate PktID = 0x2d
|
||||
ArmAnimation PktID = 0x2c
|
||||
QueryEntityNbt PktID = 0x0d
|
||||
Flying PktID = 0x15
|
||||
ResourcePackReceive PktID = 0x21
|
||||
BlockDig PktID = 0x1b
|
||||
AbilitiesServerbound PktID = 0x1a
|
||||
SelectTrade PktID = 0x23
|
||||
UpdateJigsawBlock PktID = 0x29
|
||||
SteerVehicle PktID = 0x1d
|
||||
Settings PktID = 0x05
|
||||
SteerBoat PktID = 0x17
|
||||
UseItem PktID = 0x2f
|
||||
TeleportConfirm PktID = 0x00
|
||||
PickItem PktID = 0x18
|
||||
CraftRecipeRequest PktID = 0x19
|
||||
Look PktID = 0x14
|
||||
TabCompleteServerbound PktID = 0x06
|
||||
AdvancementTab PktID = 0x22
|
||||
ClientCommand PktID = 0x04
|
||||
EntityAction PktID = 0x1c
|
||||
PositionServerbound PktID = 0x12
|
||||
TransactionServerbound PktID = 0x07
|
||||
UpdateSign PktID = 0x2b
|
||||
QueryBlockNbt PktID = 0x01
|
||||
PositionLook PktID = 0x13
|
||||
HeldItemSlotServerbound PktID = 0x25
|
||||
EditBook PktID = 0x0c
|
||||
UpdateCommandBlock PktID = 0x26
|
||||
UseEntity PktID = 0x0e
|
||||
GenerateStructure PktID = 0x0f
|
||||
NameItem PktID = 0x20
|
||||
RecipeBook PktID = 0x1f
|
||||
KeepAliveServerbound PktID = 0x10
|
||||
CustomPayloadServerbound PktID = 0x0b
|
||||
VehicleMoveServerbound PktID = 0x16
|
||||
CloseWindowServerbound PktID = 0x0a
|
||||
UpdateCommandBlockMinecart PktID = 0x27
|
||||
WindowClick PktID = 0x09
|
||||
ChatServerbound PktID = 0x03
|
||||
SetCreativeSlot PktID = 0x28
|
||||
DisplayedRecipe PktID = 0x1e
|
||||
BlockPlace PktID = 0x2e
|
||||
LockDifficulty PktID = 0x11
|
||||
SetDifficulty PktID = 0x02
|
||||
|
||||
ChunkData //0x20
|
||||
Effect
|
||||
Particle
|
||||
UpdateLight
|
||||
JoinGame
|
||||
MapData
|
||||
TradeList
|
||||
EntityRelativeMove
|
||||
EntityLookAndRelativeMove
|
||||
EntityLook
|
||||
Entity
|
||||
VehicleMoveClientbound
|
||||
OpenBook
|
||||
OpenWindow
|
||||
OpenSignEditor
|
||||
CraftRecipeResponse
|
||||
// Clientbound packets used to respond to ping/status requests.
|
||||
ServerInfo PktID = 0x00
|
||||
PingClientbound PktID = 0x01
|
||||
// Serverbound packets used to ping or read server status.
|
||||
PingStart PktID = 0x00
|
||||
PingServerbound PktID = 0x01
|
||||
|
||||
PlayerAbilitiesClientbound //0x30
|
||||
CombatEvent
|
||||
PlayerInfo
|
||||
FacePlayer
|
||||
PlayerPositionAndLookClientbound
|
||||
UnlockRecipes
|
||||
DestroyEntities
|
||||
RemoveEntityEffect
|
||||
ResourcePackSend
|
||||
Respawn
|
||||
EntityHeadLook
|
||||
MultiBlockChange
|
||||
SelectAdvancementTab
|
||||
WorldBorder
|
||||
Camera
|
||||
HeldItemChangeClientbound
|
||||
|
||||
UpdateViewPosition //0x40
|
||||
UpdateViewDistance
|
||||
SpawnPosition
|
||||
DisplayScoreboard
|
||||
EntityMetadata
|
||||
AttachEntity
|
||||
EntityVelocity
|
||||
EntityEquipment
|
||||
SetExperience
|
||||
UpdateHealth
|
||||
ScoreboardObjective
|
||||
SetPassengers
|
||||
Teams
|
||||
UpdateScore
|
||||
TimeUpdate
|
||||
Title
|
||||
|
||||
EntitySoundEffect //0x50
|
||||
SoundEffect
|
||||
StopSound
|
||||
PlayerListHeaderAndFooter
|
||||
NBTQueryResponse
|
||||
CollectItem
|
||||
EntityTeleport
|
||||
Advancements
|
||||
EntityProperties
|
||||
EntityEffect
|
||||
DeclareRecipes
|
||||
Tags //0x5B
|
||||
)
|
||||
|
||||
// Serverbound packet IDs
|
||||
const (
|
||||
TeleportConfirm int32 = iota //0x00
|
||||
QueryBlockNBT
|
||||
SetDifficulty
|
||||
ChatMessageServerbound
|
||||
ClientStatus
|
||||
ClientSettings
|
||||
TabCompleteServerbound
|
||||
ConfirmTransactionServerbound
|
||||
ClickWindowButton
|
||||
ClickWindow
|
||||
CloseWindowServerbound
|
||||
PluginMessageServerbound
|
||||
EditBook
|
||||
QueryEntityNBT
|
||||
UseEntity
|
||||
GenerateStructure
|
||||
|
||||
KeepAliveServerbound //0x10
|
||||
LockDifficulty
|
||||
PlayerPosition
|
||||
PlayerPositionAndLookServerbound
|
||||
PlayerLook
|
||||
Player
|
||||
VehicleMoveServerbound
|
||||
SteerBoat
|
||||
PickItem
|
||||
CraftRecipeRequest
|
||||
PlayerAbilitiesServerbound
|
||||
PlayerDigging
|
||||
EntityAction
|
||||
SteerVehicle
|
||||
DisplayedRecipe
|
||||
RecipeBookData
|
||||
|
||||
NameItem //0x20
|
||||
ResourcePackStatus
|
||||
AdvancementTab
|
||||
SelectTrade
|
||||
SetBeaconEffect
|
||||
HeldItemChangeServerbound
|
||||
UpdateCommandBlock
|
||||
UpdateCommandBlockMinecart
|
||||
CreativeInventoryAction
|
||||
UpdateJigsawBlock
|
||||
UpdateStructureBlock
|
||||
UpdateSign
|
||||
AnimationServerbound
|
||||
Spectate
|
||||
PlayerBlockPlacement
|
||||
UseItem //0x2F
|
||||
)
|
||||
|
Reference in New Issue
Block a user