Implement generator and type for packet IDs

This commit is contained in:
Tom
2020-09-12 13:38:45 -07:00
parent 0ec82d90a7
commit 358fb7b659
12 changed files with 406 additions and 187 deletions

View File

@ -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),

View File

@ -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),

View File

@ -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 {

View File

@ -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"

View File

@ -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"

View File

@ -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")

View File

@ -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

196
data/gen_packetIDs.go Normal file
View 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(")")
}

View File

@ -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
)

5
go.mod
View File

@ -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
)

2
go.sum
View File

@ -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=

View File

@ -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()...)