From 358fb7b659322dc880dfdb16d8a50a676c1fd596 Mon Sep 17 00:00:00 2001 From: Tom Date: Sat, 12 Sep 2020 13:38:45 -0700 Subject: [PATCH] Implement generator and type for packet IDs --- bot/ingame.go | 36 ++--- bot/motion.go | 14 +- bot/world/chunk_test.go | 3 +- cmd/autofish/autofish.go | 3 +- cmd/daze/daze.go | 3 +- cmd/luncher/luncher.go | 3 +- cmd/simpleServer/main.go | 7 +- data/gen_packetIDs.go | 196 ++++++++++++++++++++++++ data/packetIDs.go | 315 +++++++++++++++++++++------------------ go.mod | 5 +- go.sum | 2 + net/packet/packet.go | 6 +- 12 files changed, 406 insertions(+), 187 deletions(-) create mode 100644 data/gen_packetIDs.go diff --git a/bot/ingame.go b/bot/ingame.go index 3dedc9c..53ac553 100644 --- a/bot/ingame.go +++ b/bot/ingame.go @@ -64,8 +64,8 @@ func (c *Client) handlePacket(p pk.Packet) (disconnect bool, err error) { } } - switch p.ID { - case data.JoinGame: + switch data.PktID(p.ID) { + case data.Login: err = handleJoinGamePacket(c, p) if err == nil && c.Events.GameStart != nil { @@ -75,7 +75,7 @@ func (c *Client) handlePacket(p pk.Packet) (disconnect bool, err error) { _ = c.conn.WritePacket( //PluginMessage packet (serverbound) - sending minecraft brand. pk.Marshal( - data.PluginMessageServerbound, + data.CustomPayloadServerbound, pk.Identifier("minecraft:brand"), pk.String(c.settings.Brand), ), @@ -83,9 +83,9 @@ func (c *Client) handlePacket(p pk.Packet) (disconnect bool, err error) { if err2 := c.Events.updateSeenPackets(seenJoinGame); err == nil { err = err2 } - case data.PluginMessageClientbound: + case data.CustomPayloadClientbound: err = handlePluginPacket(c, p) - case data.ServerDifficulty: + case data.Difficulty: err = handleServerDifficultyPacket(c, p) if err == nil && c.Events.ServerDifficultyChange != nil { err = c.Events.ServerDifficultyChange(c.Difficulty) @@ -98,12 +98,12 @@ func (c *Client) handlePacket(p pk.Packet) (disconnect bool, err error) { if err2 := c.Events.updateSeenPackets(seenSpawnPos); err == nil { err = err2 } - case data.PlayerAbilitiesClientbound: + case data.AbilitiesClientbound: err = handlePlayerAbilitiesPacket(c, p) _ = c.conn.WritePacket( //ClientSettings packet (serverbound) pk.Marshal( - data.ClientSettings, + data.Settings, pk.String(c.settings.Locale), pk.Byte(c.settings.ViewDistance), pk.VarInt(c.settings.ChatMode), @@ -115,16 +115,16 @@ func (c *Client) handlePacket(p pk.Packet) (disconnect bool, err error) { if err2 := c.Events.updateSeenPackets(seenPlayerAbilities); err == nil { err = err2 } - case data.HeldItemChangeClientbound: + case data.HeldItemSlotClientbound: err = handleHeldItemPacket(c, p) case data.UpdateLight: err = c.Events.updateSeenPackets(seenUpdateLight) - case data.ChunkData: + case data.MapChunk: err = handleChunkDataPacket(c, p) if err2 := c.Events.updateSeenPackets(seenChunkData); err == nil { err = err2 } - case data.PlayerPositionAndLookClientbound: + case data.PositionClientbound: err = handlePlayerPositionAndLookPacket(c, p) sendPlayerPositionAndLookPacket(c) // to confirm the position if err2 := c.Events.updateSeenPackets(seenPlayerPositionAndLook); err == nil { @@ -132,29 +132,23 @@ func (c *Client) handlePacket(p pk.Packet) (disconnect bool, err error) { } case data.DeclareRecipes: // handleDeclareRecipesPacket(g, reader) - case data.EntityLookAndRelativeMove: - // err = handleEntityLookAndRelativeMove(g, reader) - case data.EntityHeadLook: - // handleEntityHeadLookPacket(g, reader) - case data.EntityRelativeMove: - // err = handleEntityRelativeMovePacket(g, reader) case data.KeepAliveClientbound: err = handleKeepAlivePacket(c, p) case data.Entity: //handleEntityPacket(g, reader) - case data.SpawnPlayer: + case data.NamedEntitySpawn: // err = handleSpawnPlayerPacket(g, reader) case data.WindowItems: err = handleWindowItemsPacket(c, p) case data.UpdateHealth: err = handleUpdateHealthPacket(c, p) - case data.ChatMessageClientbound: + case data.ChatClientbound: err = handleChatMessagePacket(c, p) case data.BlockChange: ////err = handleBlockChangePacket(c, p) case data.MultiBlockChange: ////err = handleMultiBlockChangePacket(c, p) - case data.DisconnectPlay: + case data.KickDisconnect: err = handleDisconnectPacket(c, p) disconnect = true case data.SetSlot: @@ -163,7 +157,7 @@ func (c *Client) handlePacket(p pk.Packet) (disconnect bool, err error) { err = handleSoundEffect(c, p) case data.NamedSoundEffect: err = handleNamedSoundEffect(c, p) - case data.SetExperience: + case data.Experience: err = handleSetExperience(c, p) default: // fmt.Printf("ignore pack id %X\n", p.ID) @@ -694,7 +688,7 @@ func handleSetExperience(c *Client, p pk.Packet) (err error) { func sendPlayerPositionAndLookPacket(c *Client) { c.conn.WritePacket(pk.Marshal( - data.PlayerPositionAndLookServerbound, + data.PositionLook, pk.Double(c.X), pk.Double(c.Y), pk.Double(c.Z), diff --git a/bot/motion.go b/bot/motion.go index 8989411..92b7469 100644 --- a/bot/motion.go +++ b/bot/motion.go @@ -13,7 +13,7 @@ import ( // It's just animation. func (c *Client) SwingArm(hand int) error { return c.conn.WritePacket(pk.Marshal( - data.AnimationServerbound, + data.ArmAnimation, pk.VarInt(hand), )) } @@ -21,7 +21,7 @@ func (c *Client) SwingArm(hand int) error { // Respawn the player when it was dead. func (c *Client) Respawn() error { return c.conn.WritePacket(pk.Marshal( - data.ClientStatus, + data.ClientCommand, pk.VarInt(0), )) } @@ -77,7 +77,7 @@ func (c *Client) Chat(msg string) error { } return c.conn.WritePacket(pk.Marshal( - data.ChatMessageServerbound, + data.ChatServerbound, pk.String(msg), )) } @@ -85,7 +85,7 @@ func (c *Client) Chat(msg string) error { // PluginMessage is used by mods and plugins to send their data. func (c *Client) PluginMessage(channal string, msg []byte) error { return c.conn.WritePacket(pk.Marshal( - data.PluginMessageServerbound, + data.CustomPayloadServerbound, pk.Identifier(channal), pluginMessageData(msg), )) @@ -103,7 +103,7 @@ func (c *Client) PluginMessage(channal string, msg []byte) error { // insideBlock is true when the player's head is inside of a block's collision. func (c *Client) UseBlock(hand, locX, locY, locZ, face int, cursorX, cursorY, cursorZ float32, insideBlock bool) error { return c.conn.WritePacket(pk.Marshal( - data.PlayerBlockPlacement, + data.UseItem, pk.VarInt(hand), pk.Position{X: locX, Y: locY, Z: locZ}, pk.VarInt(face), @@ -120,7 +120,7 @@ func (c *Client) SelectItem(slot int) error { } return c.conn.WritePacket(pk.Marshal( - data.HeldItemChangeServerbound, + data.HeldItemSlotServerbound, pk.Short(slot), )) } @@ -144,7 +144,7 @@ func (c *Client) PickItem(slot int) error { func (c *Client) playerAction(status, locX, locY, locZ, face int) error { return c.conn.WritePacket(pk.Marshal( - data.PlayerDigging, + data.BlockDig, pk.VarInt(status), pk.Position{X: locX, Y: locY, Z: locZ}, pk.Byte(face), diff --git a/bot/world/chunk_test.go b/bot/world/chunk_test.go index 13b5fda..cf5c677 100644 --- a/bot/world/chunk_test.go +++ b/bot/world/chunk_test.go @@ -1,9 +1,10 @@ package world import ( - "github.com/Tnze/go-mc/data" "math/rand" "testing" + + "github.com/Tnze/go-mc/data" ) func newDirectSection(bpb int) Section { diff --git a/cmd/autofish/autofish.go b/cmd/autofish/autofish.go index 611090d..633c3d2 100644 --- a/cmd/autofish/autofish.go +++ b/cmd/autofish/autofish.go @@ -1,10 +1,11 @@ package main import ( - "github.com/google/uuid" "log" "time" + "github.com/google/uuid" + "github.com/Tnze/go-mc/bot" "github.com/Tnze/go-mc/chat" _ "github.com/Tnze/go-mc/data/lang/en-us" diff --git a/cmd/daze/daze.go b/cmd/daze/daze.go index 7ede457..c656245 100644 --- a/cmd/daze/daze.go +++ b/cmd/daze/daze.go @@ -2,9 +2,10 @@ package main import ( "bytes" - "github.com/google/uuid" "log" + "github.com/google/uuid" + "github.com/Tnze/go-mc/bot" "github.com/Tnze/go-mc/chat" _ "github.com/Tnze/go-mc/data/lang/en-us" diff --git a/cmd/luncher/luncher.go b/cmd/luncher/luncher.go index 9411bb8..f159049 100644 --- a/cmd/luncher/luncher.go +++ b/cmd/luncher/luncher.go @@ -3,8 +3,9 @@ package main import ( "flag" "fmt" - "github.com/Tnze/go-mc/yggdrasil" "os" + + "github.com/Tnze/go-mc/yggdrasil" ) var user = flag.String("user", "", "Can be an email address or player name for unmigrated accounts") diff --git a/cmd/simpleServer/main.go b/cmd/simpleServer/main.go index e3daffb..61e8f25 100644 --- a/cmd/simpleServer/main.go +++ b/cmd/simpleServer/main.go @@ -2,12 +2,13 @@ package main import ( + "log" + "github.com/Tnze/go-mc/bot" "github.com/Tnze/go-mc/data" "github.com/Tnze/go-mc/net" pk "github.com/Tnze/go-mc/net/packet" "github.com/google/uuid" - "log" ) const ProtocolVersion = 578 @@ -64,7 +65,7 @@ func handlePlaying(conn net.Conn, protocol int32) { } joinGame(conn) - conn.WritePacket(pk.Marshal(data.PlayerPositionAndLookClientbound, + conn.WritePacket(pk.Marshal(data.PositionClientbound, // https://wiki.vg/Protocol#Player_Position_And_Look_.28clientbound.29 pk.Double(0), pk.Double(0), pk.Double(0), // XYZ pk.Float(0), pk.Float(0), // Yaw Pitch @@ -139,7 +140,7 @@ func loginSuccess(conn net.Conn, name string, uuid uuid.UUID) error { } func joinGame(conn net.Conn) error { - return conn.WritePacket(pk.Marshal(data.JoinGame, + return conn.WritePacket(pk.Marshal(data.Login, pk.Int(0), // EntityID pk.UnsignedByte(1), // Gamemode pk.Int(0), // Dimension diff --git a/data/gen_packetIDs.go b/data/gen_packetIDs.go new file mode 100644 index 0000000..19e20ad --- /dev/null +++ b/data/gen_packetIDs.go @@ -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(")") +} diff --git a/data/packetIDs.go b/data/packetIDs.go index cfc5dc3..28a5bc5 100644 --- a/data/packetIDs.go +++ b/data/packetIDs.go @@ -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 ) diff --git a/go.mod b/go.mod index d2206fc..421f318 100644 --- a/go.mod +++ b/go.mod @@ -2,4 +2,7 @@ module github.com/Tnze/go-mc go 1.13 -require github.com/google/uuid v1.1.1 +require ( + github.com/google/uuid v1.1.1 + github.com/iancoleman/strcase v0.1.1 // indirect +) diff --git a/go.sum b/go.sum index b864886..1134786 100644 --- a/go.sum +++ b/go.sum @@ -1,2 +1,4 @@ github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/iancoleman/strcase v0.1.1 h1:2I+LRClyCYB7JgZb9U0k75VHUiQe9RfknRqDyUfzp7k= +github.com/iancoleman/strcase v0.1.1/go.mod h1:SK73tn/9oHe+/Y0h39VT4UCxmurVJkR5NA7kMEAOgSE= diff --git a/net/packet/packet.go b/net/packet/packet.go index 38912e7..0621ca7 100644 --- a/net/packet/packet.go +++ b/net/packet/packet.go @@ -5,6 +5,8 @@ import ( "compress/zlib" "fmt" "io" + + "github.com/Tnze/go-mc/data" ) // Packet define a net data package @@ -14,8 +16,8 @@ type Packet struct { } //Marshal generate Packet with the ID and Fields -func Marshal(ID int32, fields ...FieldEncoder) (pk Packet) { - pk.ID = ID +func Marshal(id data.PktID, fields ...FieldEncoder) (pk Packet) { + pk.ID = int32(id) for _, v := range fields { pk.Data = append(pk.Data, v.Encode()...)