Update packetid name
This commit is contained in:
@ -18,9 +18,9 @@ type Player struct {
|
|||||||
func NewPlayer(c *bot.Client, settings Settings) *Player {
|
func NewPlayer(c *bot.Client, settings Settings) *Player {
|
||||||
b := &Player{c: c, Settings: settings}
|
b := &Player{c: c, Settings: settings}
|
||||||
c.Events.AddListener(
|
c.Events.AddListener(
|
||||||
bot.PacketHandler{Priority: 0, ID: packetid.Login, F: b.handleJoinGamePacket},
|
bot.PacketHandler{Priority: 0, ID: packetid.ClientboundLogin, F: b.handleJoinGamePacket},
|
||||||
bot.PacketHandler{Priority: 0, ID: packetid.KeepAliveClientbound, F: b.handleKeepAlivePacket},
|
bot.PacketHandler{Priority: 0, ID: packetid.ClientboundKeepAlive, F: b.handleKeepAlivePacket},
|
||||||
bot.PacketHandler{Priority: 0, ID: packetid.PositionClientbound, F: b.handlePlayerPositionAndLook},
|
bot.PacketHandler{Priority: 0, ID: packetid.ClientboundPlayerPosition, F: b.handlePlayerPositionAndLook},
|
||||||
)
|
)
|
||||||
return b
|
return b
|
||||||
}
|
}
|
||||||
@ -29,7 +29,7 @@ func (p *Player) Respawn() error {
|
|||||||
const PerformRespawn = 0
|
const PerformRespawn = 0
|
||||||
|
|
||||||
err := p.c.Conn.WritePacket(pk.Marshal(
|
err := p.c.Conn.WritePacket(pk.Marshal(
|
||||||
packetid.ClientCommand,
|
packetid.ServerboundClientCommand,
|
||||||
pk.VarInt(PerformRespawn),
|
pk.VarInt(PerformRespawn),
|
||||||
))
|
))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -19,10 +19,10 @@ type EventsListener struct {
|
|||||||
|
|
||||||
func (e EventsListener) Attach(c *bot.Client) {
|
func (e EventsListener) Attach(c *bot.Client) {
|
||||||
c.Events.AddListener(
|
c.Events.AddListener(
|
||||||
bot.PacketHandler{Priority: 64, ID: packetid.Login, F: e.onJoinGame},
|
bot.PacketHandler{Priority: 64, ID: packetid.ClientboundLogin, F: e.onJoinGame},
|
||||||
bot.PacketHandler{Priority: 64, ID: packetid.ChatClientbound, F: e.onChatMsg},
|
bot.PacketHandler{Priority: 64, ID: packetid.ClientboundChat, F: e.onChatMsg},
|
||||||
bot.PacketHandler{Priority: 64, ID: packetid.KickDisconnect, F: e.onDisconnect},
|
bot.PacketHandler{Priority: 64, ID: packetid.ClientboundDisconnect, F: e.onDisconnect},
|
||||||
bot.PacketHandler{Priority: 64, ID: packetid.UpdateHealth, F: e.onUpdateHealth},
|
bot.PacketHandler{Priority: 64, ID: packetid.ClientboundSetHealth, F: e.onUpdateHealth},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -73,7 +73,7 @@ func (p *Player) handleJoinGamePacket(packet pk.Packet) error {
|
|||||||
p.WorldNames = *(*[]string)(unsafe.Pointer(&WorldNames))
|
p.WorldNames = *(*[]string)(unsafe.Pointer(&WorldNames))
|
||||||
|
|
||||||
err = p.c.Conn.WritePacket(pk.Marshal( //PluginMessage packet
|
err = p.c.Conn.WritePacket(pk.Marshal( //PluginMessage packet
|
||||||
packetid.CustomPayloadServerbound,
|
packetid.ServerboundCustomPayload,
|
||||||
pk.Identifier("minecraft:brand"),
|
pk.Identifier("minecraft:brand"),
|
||||||
pk.String(p.Settings.Brand),
|
pk.String(p.Settings.Brand),
|
||||||
))
|
))
|
||||||
@ -82,7 +82,7 @@ func (p *Player) handleJoinGamePacket(packet pk.Packet) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
err = p.c.Conn.WritePacket(pk.Marshal(
|
err = p.c.Conn.WritePacket(pk.Marshal(
|
||||||
packetid.Settings, // Client settings
|
packetid.ServerboundClientInformation, // Client settings
|
||||||
pk.String(p.Settings.Locale),
|
pk.String(p.Settings.Locale),
|
||||||
pk.Byte(p.Settings.ViewDistance),
|
pk.Byte(p.Settings.ViewDistance),
|
||||||
pk.VarInt(p.Settings.ChatMode),
|
pk.VarInt(p.Settings.ChatMode),
|
||||||
|
@ -12,7 +12,7 @@ func (p Player) handleKeepAlivePacket(packet pk.Packet) error {
|
|||||||
}
|
}
|
||||||
// Response
|
// Response
|
||||||
err := p.c.Conn.WritePacket(pk.Packet{
|
err := p.c.Conn.WritePacket(pk.Packet{
|
||||||
ID: packetid.KeepAliveServerbound,
|
ID: packetid.ServerboundKeepAlive,
|
||||||
Data: packet.Data,
|
Data: packet.Data,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -35,7 +35,7 @@ func (p *Player) handlePlayerPositionAndLook(packet pk.Packet) error {
|
|||||||
|
|
||||||
// Teleport Confirm
|
// Teleport Confirm
|
||||||
err := p.c.Conn.WritePacket(pk.Marshal(
|
err := p.c.Conn.WritePacket(pk.Marshal(
|
||||||
packetid.TeleportConfirm,
|
packetid.ServerboundAcceptTeleportation,
|
||||||
TeleportID,
|
TeleportID,
|
||||||
))
|
))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -45,7 +45,7 @@ func (p *Player) handlePlayerPositionAndLook(packet pk.Packet) error {
|
|||||||
if !p.isSpawn {
|
if !p.isSpawn {
|
||||||
// PlayerPositionAndRotation to confirm the spawn position
|
// PlayerPositionAndRotation to confirm the spawn position
|
||||||
err = p.c.Conn.WritePacket(pk.Marshal(
|
err = p.c.Conn.WritePacket(pk.Marshal(
|
||||||
packetid.PositionLook,
|
packetid.ServerboundMoveVehicle,
|
||||||
X, Y-1.62, Z,
|
X, Y-1.62, Z,
|
||||||
Yaw, Pitch,
|
Yaw, Pitch,
|
||||||
pk.Boolean(true),
|
pk.Boolean(true),
|
||||||
|
@ -111,7 +111,7 @@ func (c *Client) join(d *net.Dialer, addr string) error {
|
|||||||
|
|
||||||
//Handle Packet
|
//Handle Packet
|
||||||
switch p.ID {
|
switch p.ID {
|
||||||
case packetid.Disconnect: //Disconnect
|
case packetid.LoginDisconnect: //LoginDisconnect
|
||||||
var reason chat.Message
|
var reason chat.Message
|
||||||
err = p.Scan(&reason)
|
err = p.Scan(&reason)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -119,12 +119,12 @@ func (c *Client) join(d *net.Dialer, addr string) error {
|
|||||||
}
|
}
|
||||||
return LoginErr{"disconnect", DisconnectErr(reason)}
|
return LoginErr{"disconnect", DisconnectErr(reason)}
|
||||||
|
|
||||||
case packetid.EncryptionBeginClientbound: //Encryption Request
|
case packetid.LoginEncryptionRequest: //Encryption Request
|
||||||
if err := handleEncryptionRequest(c, p); err != nil {
|
if err := handleEncryptionRequest(c, p); err != nil {
|
||||||
return LoginErr{"encryption", err}
|
return LoginErr{"encryption", err}
|
||||||
}
|
}
|
||||||
|
|
||||||
case packetid.Success: //Login Success
|
case packetid.LoginSuccess: //Login Success
|
||||||
err := p.Scan(
|
err := p.Scan(
|
||||||
(*pk.UUID)(&c.UUID),
|
(*pk.UUID)(&c.UUID),
|
||||||
(*pk.String)(&c.Name),
|
(*pk.String)(&c.Name),
|
||||||
@ -134,7 +134,7 @@ func (c *Client) join(d *net.Dialer, addr string) error {
|
|||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
|
||||||
case packetid.Compress: //Set Compression
|
case packetid.SetCompression: //Set Compression
|
||||||
var threshold pk.VarInt
|
var threshold pk.VarInt
|
||||||
if err := p.Scan(&threshold); err != nil {
|
if err := p.Scan(&threshold); err != nil {
|
||||||
return LoginErr{"compression", err}
|
return LoginErr{"compression", err}
|
||||||
|
@ -77,7 +77,7 @@ func pingAndList(addr string, conn *mcnet.Conn) ([]byte, time.Duration, error) {
|
|||||||
//LIST
|
//LIST
|
||||||
//请求服务器状态
|
//请求服务器状态
|
||||||
err = conn.WritePacket(pk.Marshal(
|
err = conn.WritePacket(pk.Marshal(
|
||||||
packetid.PingStart,
|
packetid.StatusRequest,
|
||||||
))
|
))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, 0, fmt.Errorf("bot: send list packect fail: %v", err)
|
return nil, 0, fmt.Errorf("bot: send list packect fail: %v", err)
|
||||||
@ -97,7 +97,7 @@ func pingAndList(addr string, conn *mcnet.Conn) ([]byte, time.Duration, error) {
|
|||||||
//PING
|
//PING
|
||||||
startTime := time.Now()
|
startTime := time.Now()
|
||||||
err = conn.WritePacket(pk.Marshal(
|
err = conn.WritePacket(pk.Marshal(
|
||||||
packetid.PingServerbound,
|
packetid.StatusPing,
|
||||||
pk.Long(startTime.Unix()),
|
pk.Long(startTime.Unix()),
|
||||||
))
|
))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -25,10 +25,10 @@ func NewManager(c *bot.Client, e EventsListener) *Manager {
|
|||||||
}
|
}
|
||||||
m.Screens[0] = &m.Inventory
|
m.Screens[0] = &m.Inventory
|
||||||
c.Events.AddListener(
|
c.Events.AddListener(
|
||||||
bot.PacketHandler{Priority: 0, ID: packetid.OpenWindow, F: m.onOpenScreen},
|
bot.PacketHandler{Priority: 0, ID: packetid.ClientboundOpenScreen, F: m.onOpenScreen},
|
||||||
bot.PacketHandler{Priority: 0, ID: packetid.WindowItems, F: m.onSetContentPacket},
|
bot.PacketHandler{Priority: 0, ID: packetid.ClientboundContainerSetContent, F: m.onSetContentPacket},
|
||||||
bot.PacketHandler{Priority: 0, ID: packetid.CloseWindowClientbound, F: m.onCloseScreen},
|
bot.PacketHandler{Priority: 0, ID: packetid.ClientboundContainerClose, F: m.onCloseScreen},
|
||||||
bot.PacketHandler{Priority: 0, ID: packetid.SetSlot, F: m.onSetSlot},
|
bot.PacketHandler{Priority: 0, ID: packetid.ClientboundContainerSetSlot, F: m.onSetSlot},
|
||||||
)
|
)
|
||||||
return m
|
return m
|
||||||
}
|
}
|
||||||
|
@ -1,187 +0,0 @@
|
|||||||
//go:build generate
|
|
||||||
// +build generate
|
|
||||||
|
|
||||||
//gen_packetid.go generates the enumeration of packet IDs used on the wire.
|
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
"net/http"
|
|
||||||
"os"
|
|
||||||
"strconv"
|
|
||||||
"text/template"
|
|
||||||
|
|
||||||
"github.com/iancoleman/strcase"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
version = "1.17.1"
|
|
||||||
protocolURL = "https://raw.githubusercontent.com/PrismarineJS/minecraft-data/master/data/pc/" + version + "/protocol.json"
|
|
||||||
//language=gohtml
|
|
||||||
packetidTmpl = `// This file is automatically generated by gen_packetIDs.go. DO NOT EDIT.
|
|
||||||
|
|
||||||
package packetid
|
|
||||||
|
|
||||||
// Login state
|
|
||||||
const (
|
|
||||||
// Clientbound
|
|
||||||
{{range $ID, $Name := .Login.Clientbound}} {{$Name}} = {{$ID | printf "%#x"}}
|
|
||||||
{{end}}
|
|
||||||
// Serverbound
|
|
||||||
{{range $ID, $Name := .Login.Serverbound}} {{$Name}} = {{$ID | printf "%#x"}}
|
|
||||||
{{end}}
|
|
||||||
)
|
|
||||||
|
|
||||||
// Ping state
|
|
||||||
const (
|
|
||||||
// Clientbound
|
|
||||||
{{range $ID, $Name := .Status.Clientbound}} {{$Name}} = {{$ID | printf "%#x"}}
|
|
||||||
{{end}}
|
|
||||||
// Serverbound
|
|
||||||
{{range $ID, $Name := .Status.Serverbound}} {{$Name}} = {{$ID | printf "%#x"}}
|
|
||||||
{{end}}
|
|
||||||
)
|
|
||||||
|
|
||||||
// Play state
|
|
||||||
const (
|
|
||||||
// Clientbound
|
|
||||||
{{range $ID, $Name := .Play.Clientbound}} {{$Name}} = {{$ID | printf "%#x"}}
|
|
||||||
{{end}}
|
|
||||||
// Serverbound
|
|
||||||
{{range $ID, $Name := .Play.Serverbound}} {{$Name}} = {{$ID | printf "%#x"}}
|
|
||||||
{{end}}
|
|
||||||
)
|
|
||||||
`
|
|
||||||
)
|
|
||||||
|
|
||||||
// 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[int32]string
|
|
||||||
Serverbound map[int32]string
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *duplexMappings) EnsureUniqueNames() {
|
|
||||||
// Assemble a slice of keys to check across both maps, because we cannot
|
|
||||||
// mutate a map while iterating it.
|
|
||||||
clientBounds := make(map[string]int32)
|
|
||||||
for sk, sv := range m.Clientbound {
|
|
||||||
clientBounds[sv] = sk
|
|
||||||
}
|
|
||||||
for sk, sv := range m.Serverbound {
|
|
||||||
if ck, ok := clientBounds[sv]; ok {
|
|
||||||
m.Clientbound[ck] = sv + "Clientbound"
|
|
||||||
m.Serverbound[sk] = sv + "Serverbound"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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[int32]string),
|
|
||||||
Serverbound: make(map[int32]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[mustAtoi(k)] = strcase.ToCamel(v.(string))
|
|
||||||
}
|
|
||||||
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[mustAtoi(k)] = strcase.ToCamel(v.(string))
|
|
||||||
}
|
|
||||||
|
|
||||||
return out, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func mustAtoi(num string) int32 {
|
|
||||||
if n, err := strconv.ParseInt(num, 0, 32); err != nil {
|
|
||||||
panic(err)
|
|
||||||
} else {
|
|
||||||
return int32(n)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
type protocolIDs struct {
|
|
||||||
Login duplexMappings
|
|
||||||
Play duplexMappings
|
|
||||||
Status duplexMappings
|
|
||||||
// Handshake state has no packets
|
|
||||||
}
|
|
||||||
|
|
||||||
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
|
|
||||||
}
|
|
||||||
|
|
||||||
//go:generate go run $GOFILE
|
|
||||||
//go:generate go fmt packetid.go
|
|
||||||
func main() {
|
|
||||||
fmt.Println("generating packetid.go")
|
|
||||||
pIDs, err := downloadInfo()
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
f, err := os.Create("packetid.go")
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
defer f.Close()
|
|
||||||
|
|
||||||
tmpl := template.Must(template.New("packetIDs").Parse(packetidTmpl))
|
|
||||||
if err := tmpl.Execute(f, pIDs); err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,187 +1,179 @@
|
|||||||
// This file is automatically generated by gen_packetIDs.go. DO NOT EDIT.
|
|
||||||
|
|
||||||
package packetid
|
package packetid
|
||||||
|
|
||||||
// Login state
|
// Login Clientbound
|
||||||
const (
|
const (
|
||||||
// Clientbound
|
LoginDisconnect = iota
|
||||||
Disconnect = 0x0
|
LoginEncryptionRequest
|
||||||
EncryptionBeginClientbound = 0x1
|
LoginSuccess
|
||||||
Success = 0x2
|
SetCompression
|
||||||
Compress = 0x3
|
LoginPluginRequest
|
||||||
LoginPluginRequest = 0x4
|
|
||||||
|
|
||||||
// Serverbound
|
|
||||||
LoginStart = 0x0
|
|
||||||
EncryptionBeginServerbound = 0x1
|
|
||||||
LoginPluginResponse = 0x2
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Ping state
|
// Login Serverbound
|
||||||
const (
|
const (
|
||||||
// Clientbound
|
LoginStart = iota
|
||||||
ServerInfo = 0x0
|
LoginEncryptionResponse
|
||||||
PingClientbound = 0x1
|
LoginPluginResponse
|
||||||
|
|
||||||
// Serverbound
|
|
||||||
PingStart = 0x0
|
|
||||||
PingServerbound = 0x1
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Play state
|
// Status Clientbound
|
||||||
const (
|
const (
|
||||||
// Clientbound
|
StatusResponse = iota
|
||||||
SpawnEntity = 0x0
|
StatusPong
|
||||||
SpawnEntityExperienceOrb = 0x1
|
)
|
||||||
SpawnEntityLiving = 0x2
|
|
||||||
SpawnEntityPainting = 0x3
|
// Game Serverbound
|
||||||
NamedEntitySpawn = 0x4
|
const (
|
||||||
SculkVibrationSignal = 0x5
|
StatusRequest = iota
|
||||||
Animation = 0x6
|
StatusPing
|
||||||
Statistics = 0x7
|
)
|
||||||
AcknowledgePlayerDigging = 0x8
|
|
||||||
BlockBreakAnimation = 0x9
|
// Game Clientbound
|
||||||
TileEntityData = 0xa
|
const (
|
||||||
BlockAction = 0xb
|
ClientboundAddEntity = iota
|
||||||
BlockChange = 0xc
|
ClientboundAddExperienceOrb
|
||||||
BossBar = 0xd
|
ClientboundAddMob
|
||||||
Difficulty = 0xe
|
ClientboundAddPainting
|
||||||
ChatClientbound = 0xf
|
ClientboundAddPlayer
|
||||||
ClearTitles = 0x10
|
ClientboundAddVibrationSignal
|
||||||
TabCompleteClientbound = 0x11
|
ClientboundAnimate
|
||||||
DeclareCommands = 0x12
|
ClientboundAwardStats
|
||||||
CloseWindowClientbound = 0x13
|
ClientboundBlockBreakAck
|
||||||
WindowItems = 0x14
|
ClientboundBlockDestruction
|
||||||
CraftProgressBar = 0x15
|
ClientboundBlockEntityData
|
||||||
SetSlot = 0x16
|
ClientboundBlockEvent
|
||||||
SetCooldown = 0x17
|
ClientboundBlockUpdate
|
||||||
CustomPayloadClientbound = 0x18
|
ClientboundBossEvent
|
||||||
NamedSoundEffect = 0x19
|
ClientboundChangeDifficulty
|
||||||
KickDisconnect = 0x1a
|
ClientboundChat
|
||||||
EntityStatus = 0x1b
|
ClientboundClearTitles
|
||||||
Explosion = 0x1c
|
ClientboundCommandSuggestions
|
||||||
UnloadChunk = 0x1d
|
ClientboundCommands
|
||||||
GameStateChange = 0x1e
|
ClientboundContainerClose
|
||||||
OpenHorseWindow = 0x1f
|
ClientboundContainerSetContent
|
||||||
InitializeWorldBorder = 0x20
|
ClientboundContainerSetData
|
||||||
KeepAliveClientbound = 0x21
|
ClientboundContainerSetSlot
|
||||||
MapChunk = 0x22
|
ClientboundCooldown
|
||||||
WorldEvent = 0x23
|
ClientboundCustomPayload
|
||||||
WorldParticles = 0x24
|
ClientboundCustomSound
|
||||||
UpdateLight = 0x25
|
ClientboundDisconnect
|
||||||
Login = 0x26
|
ClientboundEntityEvent
|
||||||
Map = 0x27
|
ClientboundExplode
|
||||||
TradeList = 0x28
|
ClientboundForgetLevelChunk
|
||||||
RelEntityMove = 0x29
|
ClientboundGameEvent
|
||||||
EntityMoveLook = 0x2a
|
ClientboundHorseScreenOpen
|
||||||
EntityLook = 0x2b
|
ClientboundInitializeBorder
|
||||||
VehicleMoveClientbound = 0x2c
|
ClientboundKeepAlive
|
||||||
OpenBook = 0x2d
|
ClientboundLevelChunk
|
||||||
OpenWindow = 0x2e
|
ClientboundLevelEvent
|
||||||
OpenSignEntity = 0x2f
|
ClientboundLevelParticles
|
||||||
Ping = 0x30
|
ClientboundLightUpdate
|
||||||
CraftRecipeResponse = 0x31
|
ClientboundLogin
|
||||||
AbilitiesClientbound = 0x32
|
ClientboundMapItemData
|
||||||
EndCombatEvent = 0x33
|
ClientboundMerchantOffers
|
||||||
EnterCombatEvent = 0x34
|
ClientboundMoveVehicle
|
||||||
DeathCombatEvent = 0x35
|
ClientboundOpenBook
|
||||||
PlayerInfo = 0x36
|
ClientboundOpenScreen
|
||||||
FacePlayer = 0x37
|
ClientboundOpenSignEditor
|
||||||
PositionClientbound = 0x38
|
ClientboundPing
|
||||||
UnlockRecipes = 0x39
|
ClientboundPlaceGhostRecipe
|
||||||
DestroyEntity = 0x3a
|
ClientboundPlayerAbilities
|
||||||
RemoveEntityEffect = 0x3b
|
ClientboundPlayerCombatEnd
|
||||||
ResourcePackSend = 0x3c
|
ClientboundPlayerCombatEnter
|
||||||
Respawn = 0x3d
|
ClientboundPlayerCombatKill
|
||||||
EntityHeadRotation = 0x3e
|
ClientboundPlayerInfo
|
||||||
MultiBlockChange = 0x3f
|
ClientboundPlayerLookAt
|
||||||
SelectAdvancementTab = 0x40
|
ClientboundPlayerPosition
|
||||||
ActionBar = 0x41
|
ClientboundRecipe
|
||||||
WorldBorderCenter = 0x42
|
ClientboundRemoveEntities
|
||||||
WorldBorderLerpSize = 0x43
|
ClientboundRemoveMobEffect
|
||||||
WorldBorderSize = 0x44
|
ClientboundResourcePack
|
||||||
WorldBorderWarningDelay = 0x45
|
ClientboundRespawn
|
||||||
WorldBorderWarningReach = 0x46
|
ClientboundRotateHead
|
||||||
Camera = 0x47
|
ClientboundSectionBlocksUpdate
|
||||||
HeldItemSlotClientbound = 0x48
|
ClientboundSelectAdvancementsTab
|
||||||
UpdateViewPosition = 0x49
|
ClientboundSetActionBarText
|
||||||
UpdateViewDistance = 0x4a
|
ClientboundSetBorderCenter
|
||||||
SpawnPosition = 0x4b
|
ClientboundSetBorderLerpSize
|
||||||
ScoreboardDisplayObjective = 0x4c
|
ClientboundSetBorderSize
|
||||||
EntityMetadata = 0x4d
|
ClientboundSetBorderWarningDelay
|
||||||
AttachEntity = 0x4e
|
ClientboundSetBorderWarningDistance
|
||||||
EntityVelocity = 0x4f
|
ClientboundSetCamera
|
||||||
EntityEquipment = 0x50
|
ClientboundSetCarriedItem
|
||||||
Experience = 0x51
|
ClientboundSetChunkCacheCenter
|
||||||
UpdateHealth = 0x52
|
ClientboundSetChunkCacheRadius
|
||||||
ScoreboardObjective = 0x53
|
ClientboundSetDefaultSpawnPosition
|
||||||
SetPassengers = 0x54
|
ClientboundSetDisplayObjective
|
||||||
Teams = 0x55
|
ClientboundSetEntityData
|
||||||
ScoreboardScore = 0x56
|
ClientboundSetEntityLink
|
||||||
SetTitleSubtitle = 0x57
|
ClientboundSetEntityMotion
|
||||||
UpdateTime = 0x58
|
ClientboundSetEquipment
|
||||||
SetTitleText = 0x59
|
ClientboundSetExperience
|
||||||
SetTitleTime = 0x5a
|
ClientboundSetHealth
|
||||||
EntitySoundEffect = 0x5b
|
ClientboundSetObjective
|
||||||
SoundEffect = 0x5c
|
ClientboundSetPassengers
|
||||||
StopSound = 0x5d
|
ClientboundSetPlayerTeam
|
||||||
PlayerlistHeader = 0x5e
|
ClientboundSetScore
|
||||||
NbtQueryResponse = 0x5f
|
ClientboundSetSubtitleText
|
||||||
Collect = 0x60
|
ClientboundSetTime
|
||||||
EntityTeleport = 0x61
|
ClientboundSetTitleText
|
||||||
Advancements = 0x62
|
ClientboundSetTitlesAnimation
|
||||||
EntityUpdateAttributes = 0x63
|
ClientboundSoundEntity
|
||||||
EntityEffect = 0x64
|
ClientboundSound
|
||||||
DeclareRecipes = 0x65
|
ClientboundStopSound
|
||||||
Tags = 0x66
|
ClientboundTabList
|
||||||
|
ClientboundTagQuery
|
||||||
// Serverbound
|
ClientboundTakeItemEntity
|
||||||
TeleportConfirm = 0x0
|
ClientboundTeleportEntity
|
||||||
QueryBlockNbt = 0x1
|
ClientboundUpdateAdvancements
|
||||||
SetDifficulty = 0x2
|
ClientboundUpdateAttributes
|
||||||
ChatServerbound = 0x3
|
ClientboundUpdateMobEffect
|
||||||
ClientCommand = 0x4
|
ClientboundUpdateRecipes
|
||||||
Settings = 0x5
|
ClientboundUpdateTags
|
||||||
TabCompleteServerbound = 0x6
|
)
|
||||||
EnchantItem = 0x7
|
|
||||||
WindowClick = 0x8
|
// Game Serverbound
|
||||||
CloseWindowServerbound = 0x9
|
const (
|
||||||
CustomPayloadServerbound = 0xa
|
ServerboundAcceptTeleportation = iota
|
||||||
EditBook = 0xb
|
ServerboundChangeDifficulty
|
||||||
QueryEntityNbt = 0xc
|
ServerboundChat
|
||||||
UseEntity = 0xd
|
ServerboundClientCommand
|
||||||
GenerateStructure = 0xe
|
ServerboundClientInformation
|
||||||
KeepAliveServerbound = 0xf
|
ServerboundCommandSuggestion
|
||||||
LockDifficulty = 0x10
|
ServerboundContainerButtonClick
|
||||||
PositionServerbound = 0x11
|
ServerboundContainerClick
|
||||||
PositionLook = 0x12
|
ServerboundContainerClose
|
||||||
Look = 0x13
|
ServerboundCustomPayload
|
||||||
Flying = 0x14
|
ServerboundEditBook
|
||||||
VehicleMoveServerbound = 0x15
|
ServerboundInteract
|
||||||
SteerBoat = 0x16
|
ServerboundJigsawGenerate
|
||||||
PickItem = 0x17
|
ServerboundKeepAlive
|
||||||
CraftRecipeRequest = 0x18
|
ServerboundLockDifficulty
|
||||||
AbilitiesServerbound = 0x19
|
ServerboundMoveVehicle
|
||||||
BlockDig = 0x1a
|
ServerboundPaddleBoat
|
||||||
EntityAction = 0x1b
|
ServerboundPickItem
|
||||||
SteerVehicle = 0x1c
|
ServerboundPlaceRecipe
|
||||||
Pong = 0x1d
|
ServerboundPlayerAbilities
|
||||||
DisplayedRecipe = 0x1e
|
ServerboundPlayerAction
|
||||||
RecipeBook = 0x1f
|
ServerboundPlayerCommand
|
||||||
NameItem = 0x20
|
ServerboundPlayerInput
|
||||||
ResourcePackReceive = 0x21
|
ServerboundPong
|
||||||
AdvancementTab = 0x22
|
ServerboundRecipeBookChangeSettings
|
||||||
SelectTrade = 0x23
|
ServerboundRecipeBookSeenRecipe
|
||||||
SetBeaconEffect = 0x24
|
ServerboundRenameItem
|
||||||
HeldItemSlotServerbound = 0x25
|
ServerboundResourcePack
|
||||||
UpdateCommandBlock = 0x26
|
ServerboundSeenAdvancements
|
||||||
UpdateCommandBlockMinecart = 0x27
|
ServerboundSelectTrade
|
||||||
SetCreativeSlot = 0x28
|
ServerboundSetBeacon
|
||||||
UpdateJigsawBlock = 0x29
|
ServerboundSetCarriedItem
|
||||||
UpdateStructureBlock = 0x2a
|
ServerboundSetCommandBlock
|
||||||
UpdateSign = 0x2b
|
ServerboundSetCommandMinecart
|
||||||
ArmAnimation = 0x2c
|
ServerboundSetCreativeModeSlot
|
||||||
Spectate = 0x2d
|
ServerboundSetJigsawBlock
|
||||||
BlockPlace = 0x2e
|
ServerboundSetStructureBlock
|
||||||
UseItem = 0x2f
|
ServerboundSignUpdate
|
||||||
|
ServerboundSwing
|
||||||
|
ServerboundTeleportToEntity
|
||||||
|
ServerboundUseItemOn
|
||||||
|
ServerboundUseItem
|
||||||
)
|
)
|
||||||
|
@ -68,7 +68,7 @@ func onGameStart() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var soundListener = bot.PacketHandler{
|
var soundListener = bot.PacketHandler{
|
||||||
ID: packetid.SoundEffect,
|
ID: packetid.ClientboundSound,
|
||||||
Priority: 0,
|
Priority: 0,
|
||||||
F: func(p pk.Packet) error {
|
F: func(p pk.Packet) error {
|
||||||
var (
|
var (
|
||||||
@ -86,7 +86,7 @@ var soundListener = bot.PacketHandler{
|
|||||||
|
|
||||||
func UseItem(hand int32) error {
|
func UseItem(hand int32) error {
|
||||||
return c.Conn.WritePacket(pk.Marshal(
|
return c.Conn.WritePacket(pk.Marshal(
|
||||||
packetid.UseItem,
|
packetid.ServerboundUseItem,
|
||||||
pk.VarInt(hand),
|
pk.VarInt(hand),
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
@ -45,7 +45,7 @@ func (m *MyServer) AcceptPlayer(name string, id uuid.UUID, protocol int32, conn
|
|||||||
ID: id,
|
ID: id,
|
||||||
})
|
})
|
||||||
if remove == nil {
|
if remove == nil {
|
||||||
err := conn.WritePacket(pk.Marshal(packetid.KickDisconnect,
|
err := conn.WritePacket(pk.Marshal(packetid.ClientboundDisconnect,
|
||||||
chat.TranslateMsg("multiplayer.disconnect.server_full"),
|
chat.TranslateMsg("multiplayer.disconnect.server_full"),
|
||||||
))
|
))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -83,7 +83,7 @@ var dimensionCodecSNBT string
|
|||||||
var dimensionSNBT string
|
var dimensionSNBT string
|
||||||
|
|
||||||
func (m *MyServer) joinGame(conn *net.Conn) error {
|
func (m *MyServer) joinGame(conn *net.Conn) error {
|
||||||
return conn.WritePacket(pk.Marshal(packetid.Login,
|
return conn.WritePacket(pk.Marshal(packetid.ClientboundLogin,
|
||||||
pk.Int(0), // EntityID
|
pk.Int(0), // EntityID
|
||||||
pk.Boolean(false), // Is hardcore
|
pk.Boolean(false), // Is hardcore
|
||||||
pk.UnsignedByte(1), // Gamemode
|
pk.UnsignedByte(1), // Gamemode
|
||||||
@ -105,8 +105,7 @@ func (m *MyServer) joinGame(conn *net.Conn) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (m *MyServer) playerPositionAndLook(conn *net.Conn) error {
|
func (m *MyServer) playerPositionAndLook(conn *net.Conn) error {
|
||||||
return conn.WritePacket(pk.Marshal(packetid.PositionClientbound,
|
return conn.WritePacket(pk.Marshal(packetid.ClientboundPlayerPosition,
|
||||||
// https://wiki.vg/index.php?title=Protocol&oldid=16067#Player_Position_And_Look_.28clientbound.29
|
|
||||||
pk.Double(0), pk.Double(0), pk.Double(0), // XYZ
|
pk.Double(0), pk.Double(0), pk.Double(0), // XYZ
|
||||||
pk.Float(0), pk.Float(0), // Yaw Pitch
|
pk.Float(0), pk.Float(0), // Yaw Pitch
|
||||||
pk.Byte(0), // flag
|
pk.Byte(0), // flag
|
||||||
|
@ -1,12 +1,8 @@
|
|||||||
package save
|
package save
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
|
||||||
"github.com/Tnze/go-mc/data/packetid"
|
|
||||||
pk "github.com/Tnze/go-mc/net/packet"
|
|
||||||
"github.com/Tnze/go-mc/save/region"
|
"github.com/Tnze/go-mc/save/region"
|
||||||
"testing"
|
"testing"
|
||||||
"unsafe"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestColumn(t *testing.T) {
|
func TestColumn(t *testing.T) {
|
||||||
@ -54,74 +50,3 @@ func BenchmarkColumn_Load(b *testing.B) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func ExampleColumn_send() {
|
|
||||||
r, err := region.Open("/path/to/r.0.0.mca")
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
chunkPos := [2]int{0, 0}
|
|
||||||
data, err := r.ReadSector(chunkPos[0], chunkPos[1])
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
var c Column
|
|
||||||
if err := c.Load(data); err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
var buf bytes.Buffer
|
|
||||||
var PrimaryBitMask pk.VarInt
|
|
||||||
for _, v := range c.Level.Sections {
|
|
||||||
if int8(v.Y) >= 0 && int8(v.Y) < 16 {
|
|
||||||
PrimaryBitMask |= 1 << v.Y
|
|
||||||
|
|
||||||
bpb := len(v.BlockStates) * 64 / (16 * 16 * 16)
|
|
||||||
hasPalette := pk.Boolean(bpb >= 9)
|
|
||||||
paletteLength := pk.VarInt(len(v.Palette))
|
|
||||||
dataArrayLength := pk.VarInt(len(v.BlockStates))
|
|
||||||
dataArray := (*[]pk.Long)(unsafe.Pointer(&v.BlockStates))
|
|
||||||
_, err := pk.Tuple{
|
|
||||||
pk.Short(0), // Block count
|
|
||||||
pk.UnsignedByte(bpb), // Bits Per Block
|
|
||||||
hasPalette, pk.Opt{
|
|
||||||
Has: &hasPalette,
|
|
||||||
Field: pk.Tuple{
|
|
||||||
paletteLength, pk.Ary{
|
|
||||||
Len: &paletteLength,
|
|
||||||
Ary: nil, // TODO: We need translate v.Palette (with type of []Block) to state ID
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}, // Palette
|
|
||||||
dataArrayLength, pk.Ary{
|
|
||||||
Len: &dataArrayLength,
|
|
||||||
Ary: dataArray,
|
|
||||||
}, // Data Array
|
|
||||||
}.WriteTo(&buf)
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
size := pk.VarInt(buf.Len())
|
|
||||||
bal := pk.VarInt(len(c.Level.Biomes))
|
|
||||||
_ = pk.Marshal(
|
|
||||||
packetid.WorldParticles,
|
|
||||||
pk.Int(chunkPos[0]), // Chunk X
|
|
||||||
pk.Int(chunkPos[1]), // Chunk Y
|
|
||||||
pk.Boolean(true), // Full chunk
|
|
||||||
PrimaryBitMask, // PrimaryBitMask
|
|
||||||
pk.NBT(c.Level.Heightmaps), // Heightmaps
|
|
||||||
bal, pk.Ary{
|
|
||||||
Len: bal, // Biomes array length
|
|
||||||
Ary: *(*[]pk.VarInt)(unsafe.Pointer(&c.Level.Biomes)), // Biomes
|
|
||||||
},
|
|
||||||
size, pk.Ary{
|
|
||||||
Len: size, // Size
|
|
||||||
Ary: pk.ByteArray(buf.Bytes()), // Data
|
|
||||||
},
|
|
||||||
pk.VarInt(0), // Block entities array length
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
@ -89,7 +89,7 @@ func encryptionRequest(conn *net.Conn, publicKey []byte) ([]byte, error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
err = conn.WritePacket(pk.Marshal(
|
err = conn.WritePacket(pk.Marshal(
|
||||||
packetid.EncryptionBeginClientbound,
|
packetid.LoginEncryptionRequest,
|
||||||
pk.String(""),
|
pk.String(""),
|
||||||
pk.ByteArray(publicKey),
|
pk.ByteArray(publicKey),
|
||||||
pk.ByteArray(verifyToken[:]),
|
pk.ByteArray(verifyToken[:]),
|
||||||
@ -103,7 +103,7 @@ func encryptionResponse(conn *net.Conn) ([]byte, []byte, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
if p.ID != packetid.EncryptionBeginServerbound {
|
if p.ID != packetid.LoginEncryptionResponse {
|
||||||
return nil, nil, fmt.Errorf("0x%02X is not Encryption Response", p.ID)
|
return nil, nil, fmt.Errorf("0x%02X is not Encryption Response", p.ID)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -55,7 +55,7 @@ func (d *MojangLoginHandler) AcceptLogin(conn *net.Conn, protocol int32) (name s
|
|||||||
//set compression
|
//set compression
|
||||||
if d.Threshold >= 0 {
|
if d.Threshold >= 0 {
|
||||||
err = conn.WritePacket(pk.Marshal(
|
err = conn.WritePacket(pk.Marshal(
|
||||||
packetid.Compress, pk.VarInt(d.Threshold),
|
packetid.SetCompression, pk.VarInt(d.Threshold),
|
||||||
))
|
))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
@ -64,7 +64,7 @@ func (d *MojangLoginHandler) AcceptLogin(conn *net.Conn, protocol int32) (name s
|
|||||||
}
|
}
|
||||||
|
|
||||||
// send login success
|
// send login success
|
||||||
err = conn.WritePacket(pk.Marshal(packetid.Success,
|
err = conn.WritePacket(pk.Marshal(packetid.LoginSuccess,
|
||||||
pk.UUID(id),
|
pk.UUID(id),
|
||||||
pk.String(name),
|
pk.String(name),
|
||||||
))
|
))
|
||||||
|
@ -33,14 +33,14 @@ func (s *Server) acceptListPing(conn *net.Conn) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
switch p.ID {
|
switch p.ID {
|
||||||
case packetid.ServerInfo: //List
|
case packetid.StatusResponse: //List
|
||||||
var resp []byte
|
var resp []byte
|
||||||
resp, err = s.listResp()
|
resp, err = s.listResp()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
err = conn.WritePacket(pk.Marshal(0x00, pk.String(resp)))
|
err = conn.WritePacket(pk.Marshal(0x00, pk.String(resp)))
|
||||||
case packetid.PingClientbound: //Ping
|
case packetid.StatusPong: //Ping
|
||||||
err = conn.WritePacket(p)
|
err = conn.WritePacket(p)
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
Reference in New Issue
Block a user