Merge branch 'pull/62' into 1.16-dev
This commit is contained in:
@ -49,13 +49,16 @@ func NewClient() (c *Client) {
|
|||||||
|
|
||||||
//PlayInfo content player info in server.
|
//PlayInfo content player info in server.
|
||||||
type PlayInfo struct {
|
type PlayInfo struct {
|
||||||
Gamemode int //游戏模式
|
Gamemode int //游戏模式
|
||||||
Hardcore bool //是否是极限模式
|
Hardcore bool //是否是极限模式
|
||||||
Dimension int //维度
|
Dimension int //维度
|
||||||
Difficulty int //难度
|
Difficulty int //难度
|
||||||
LevelType string //地图类型
|
// LevelType string //地图类型 1.16删了
|
||||||
ViewDistance int //视距
|
ViewDistance int //视距
|
||||||
ReducedDebugInfo bool //减少调试信息
|
ReducedDebugInfo bool //减少调试信息
|
||||||
|
WorldName string //当前世界的名字
|
||||||
|
IsDebug bool //调试
|
||||||
|
IsFlat bool //超平坦世界
|
||||||
// SpawnPosition Position //主世界出生点
|
// SpawnPosition Position //主世界出生点
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9,7 +9,7 @@ import (
|
|||||||
|
|
||||||
type eventBroker struct {
|
type eventBroker struct {
|
||||||
GameStart func() error
|
GameStart func() error
|
||||||
ChatMsg func(msg chat.Message, pos byte) error
|
ChatMsg func(msg chat.Message, pos byte, sender string) error
|
||||||
Disconnect func(reason chat.Message) error
|
Disconnect func(reason chat.Message) error
|
||||||
HealthChange func() error
|
HealthChange func() error
|
||||||
Die func() error
|
Die func() error
|
||||||
|
@ -274,17 +274,18 @@ func handleSetSlotPacket(c *Client, p pk.Packet) error {
|
|||||||
|
|
||||||
func handleChatMessagePacket(c *Client, p pk.Packet) (err error) {
|
func handleChatMessagePacket(c *Client, p pk.Packet) (err error) {
|
||||||
var (
|
var (
|
||||||
s chat.Message
|
s chat.Message
|
||||||
pos pk.Byte
|
pos pk.Byte
|
||||||
|
sender pk.UUID
|
||||||
)
|
)
|
||||||
|
|
||||||
err = p.Scan(&s, &pos)
|
err = p.Scan(&s, &pos, &sender)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if c.Events.ChatMsg != nil {
|
if c.Events.ChatMsg != nil {
|
||||||
err = c.Events.ChatMsg(s, byte(pos))
|
err = c.Events.ChatMsg(s, byte(pos), string(sender.Encode()))
|
||||||
}
|
}
|
||||||
|
|
||||||
return err
|
return err
|
||||||
@ -326,17 +327,25 @@ func handleUpdateHealthPacket(c *Client, p pk.Packet) (err error) {
|
|||||||
|
|
||||||
func handleJoinGamePacket(c *Client, p pk.Packet) error {
|
func handleJoinGamePacket(c *Client, p pk.Packet) error {
|
||||||
var (
|
var (
|
||||||
eid pk.Int
|
eid pk.Int
|
||||||
gamemode pk.UnsignedByte
|
gamemode pk.UnsignedByte
|
||||||
|
previousGm pk.UnsignedByte
|
||||||
|
worldCount pk.VarInt
|
||||||
|
worldNames pk.Identifier
|
||||||
|
_ pk.NBT
|
||||||
|
//dimensionCodec pk.NBT
|
||||||
dimension pk.Int
|
dimension pk.Int
|
||||||
|
worldName pk.Identifier
|
||||||
hashedSeed pk.Long
|
hashedSeed pk.Long
|
||||||
maxPlayers pk.UnsignedByte
|
maxPlayers pk.UnsignedByte
|
||||||
levelType pk.String
|
|
||||||
viewDistance pk.VarInt
|
viewDistance pk.VarInt
|
||||||
rdi pk.Boolean // Reduced Debug Info
|
rdi pk.Boolean // Reduced Debug Info
|
||||||
ers pk.Boolean // Enable respawn screen
|
ers pk.Boolean // Enable respawn screen
|
||||||
|
isDebug pk.Boolean
|
||||||
|
isFlat pk.Boolean
|
||||||
)
|
)
|
||||||
err := p.Scan(&eid, &gamemode, &dimension, &hashedSeed, &maxPlayers, &levelType, &rdi, &ers)
|
err := p.Scan(&eid, &gamemode, &previousGm, &worldCount, &worldNames, &dimension, &worldName,
|
||||||
|
&hashedSeed, &maxPlayers, &rdi, &ers, &isDebug, &isFlat)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -345,9 +354,12 @@ func handleJoinGamePacket(c *Client, p pk.Packet) error {
|
|||||||
c.Gamemode = int(gamemode & 0x7)
|
c.Gamemode = int(gamemode & 0x7)
|
||||||
c.Hardcore = gamemode&0x8 != 0
|
c.Hardcore = gamemode&0x8 != 0
|
||||||
c.Dimension = int(dimension)
|
c.Dimension = int(dimension)
|
||||||
c.LevelType = string(levelType)
|
c.WorldName = string(worldName)
|
||||||
c.ViewDistance = int(viewDistance)
|
c.ViewDistance = int(viewDistance)
|
||||||
c.ReducedDebugInfo = bool(rdi)
|
c.ReducedDebugInfo = bool(rdi)
|
||||||
|
c.IsDebug = bool(isDebug)
|
||||||
|
c.IsFlat = bool(isFlat)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -441,13 +453,14 @@ func handleChunkDataPacket(c *Client, p pk.Packet) error {
|
|||||||
var (
|
var (
|
||||||
X, Z pk.Int
|
X, Z pk.Int
|
||||||
FullChunk pk.Boolean
|
FullChunk pk.Boolean
|
||||||
|
IgnoreOldData pk.Boolean
|
||||||
PrimaryBitMask pk.VarInt
|
PrimaryBitMask pk.VarInt
|
||||||
Heightmaps struct{}
|
Heightmaps struct{}
|
||||||
Biomes = biomesData{fullChunk: (*bool)(&FullChunk)}
|
Biomes = biomesData{fullChunk: (*bool)(&FullChunk)}
|
||||||
Data chunkData
|
Data chunkData
|
||||||
BlockEntities blockEntities
|
BlockEntities blockEntities
|
||||||
)
|
)
|
||||||
if err := p.Scan(&X, &Z, &FullChunk, &PrimaryBitMask, pk.NBT{V: &Heightmaps}, &Biomes, &Data, &BlockEntities); err != nil {
|
if err := p.Scan(&X, &Z, &FullChunk, &IgnoreOldData, &PrimaryBitMask, pk.NBT{V: &Heightmaps}, &Biomes, &Data, &BlockEntities); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
chunk, err := world.DecodeChunkColumn(int32(PrimaryBitMask), Data)
|
chunk, err := world.DecodeChunkColumn(int32(PrimaryBitMask), Data)
|
||||||
|
@ -185,6 +185,7 @@ func loginAuth(AsTk, name, UUID string, shareSecret []byte, er encryptionRequest
|
|||||||
}
|
}
|
||||||
PostRequest.Header.Set("User-agent", "go-mc")
|
PostRequest.Header.Set("User-agent", "go-mc")
|
||||||
PostRequest.Header.Set("Connection", "keep-alive")
|
PostRequest.Header.Set("Connection", "keep-alive")
|
||||||
|
PostRequest.Header.Set("Content-Type", "application/json")
|
||||||
resp, err := client.Do(PostRequest)
|
resp, err := client.Do(PostRequest)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("post fail: %v", err)
|
return fmt.Errorf("post fail: %v", err)
|
||||||
|
@ -13,7 +13,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// ProtocolVersion , the protocol version number of minecraft net protocol
|
// ProtocolVersion , the protocol version number of minecraft net protocol
|
||||||
const ProtocolVersion = 578
|
const ProtocolVersion = 736
|
||||||
|
|
||||||
// JoinServer connect a Minecraft server for playing the game.
|
// JoinServer connect a Minecraft server for playing the game.
|
||||||
func (c *Client) JoinServer(addr string, port int) (err error) {
|
func (c *Client) JoinServer(addr string, port int) (err error) {
|
||||||
|
@ -72,7 +72,7 @@ func onSound(name string, category int, x, y, z float64, volume, pitch float32)
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func onChatMsg(c chat.Message, pos byte) error {
|
func onChatMsg(c chat.Message, pos byte, uuid string) error {
|
||||||
log.Println("Chat:", c)
|
log.Println("Chat:", c)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -38,7 +38,7 @@ func onGameStart() error {
|
|||||||
return nil //if err isn't nil, HandleGame() will return it.
|
return nil //if err isn't nil, HandleGame() will return it.
|
||||||
}
|
}
|
||||||
|
|
||||||
func onChatMsg(c chat.Message, pos byte) error {
|
func onChatMsg(c chat.Message, pos byte, uuid string) error {
|
||||||
log.Println("Chat:", c.ClearString()) // output chat message without any format code (like color or bold)
|
log.Println("Chat:", c.ClearString()) // output chat message without any format code (like color or bold)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
153
cmd/simpleServer/main.go
Normal file
153
cmd/simpleServer/main.go
Normal file
@ -0,0 +1,153 @@
|
|||||||
|
// Example minecraft 1.15.2 server
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"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
|
||||||
|
const Threshold = 256
|
||||||
|
const MaxPlayer = 200
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
l, err := net.ListenMC(":25565")
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("Listen error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
for {
|
||||||
|
conn, err := l.Accept()
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("Accept error: %v", err)
|
||||||
|
}
|
||||||
|
go acceptConn(conn)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func acceptConn(conn net.Conn) {
|
||||||
|
defer conn.Close()
|
||||||
|
// handshake
|
||||||
|
protocol, intention, err := handshake(conn)
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("Handshake error: %v", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
switch intention {
|
||||||
|
default: //unknown error
|
||||||
|
log.Printf("Unknown handshake intention: %v", intention)
|
||||||
|
case 1: //for status
|
||||||
|
acceptListPing(conn)
|
||||||
|
case 2: //for login
|
||||||
|
handlePlaying(conn, protocol)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func handlePlaying(conn net.Conn, protocol int32) {
|
||||||
|
// login, get player info
|
||||||
|
info, err := acceptLogin(conn)
|
||||||
|
if err != nil {
|
||||||
|
log.Print("Login failed")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write LoginSuccess packet
|
||||||
|
err = loginSuccess(conn, info.Name, info.UUID)
|
||||||
|
if err != nil {
|
||||||
|
log.Print("Login failed on success")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
joinGame(conn)
|
||||||
|
conn.WritePacket(pk.Marshal(data.PlayerPositionAndLookClientbound,
|
||||||
|
// 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
|
||||||
|
pk.Byte(0), // flag
|
||||||
|
pk.VarInt(0), // TP ID
|
||||||
|
))
|
||||||
|
// Just for block this goroutine. Keep the connection
|
||||||
|
for {
|
||||||
|
if _, err := conn.ReadPacket(); err != nil {
|
||||||
|
log.Printf("ReadPacket error: %v", err)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
// KeepAlive packet is not handled, so client might
|
||||||
|
// exit because of "time out".
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type PlayerInfo struct {
|
||||||
|
Name string
|
||||||
|
UUID uuid.UUID
|
||||||
|
OPLevel int
|
||||||
|
}
|
||||||
|
|
||||||
|
// acceptLogin check player's account
|
||||||
|
func acceptLogin(conn net.Conn) (info PlayerInfo, err error) {
|
||||||
|
//login start
|
||||||
|
var p pk.Packet
|
||||||
|
p, err = conn.ReadPacket()
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
err = p.Scan((*pk.String)(&info.Name)) //decode username as pk.String
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
//auth
|
||||||
|
const OnlineMode = false
|
||||||
|
if OnlineMode {
|
||||||
|
log.Panic("Not Implement")
|
||||||
|
} else {
|
||||||
|
// offline-mode UUID
|
||||||
|
info.UUID = bot.OfflineUUID(info.Name)
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// handshake receive and parse Handshake packet
|
||||||
|
func handshake(conn net.Conn) (protocol, intention int32, err error) {
|
||||||
|
var (
|
||||||
|
Protocol, Intention pk.VarInt
|
||||||
|
ServerAddress pk.String // ignored
|
||||||
|
ServerPort pk.UnsignedShort // ignored
|
||||||
|
)
|
||||||
|
// receive handshake packet
|
||||||
|
p, err := conn.ReadPacket()
|
||||||
|
if err != nil {
|
||||||
|
return 0, 0, err
|
||||||
|
}
|
||||||
|
err = p.Scan(&Protocol, &ServerAddress, &ServerPort, &Intention)
|
||||||
|
return int32(Protocol), int32(Intention), err
|
||||||
|
}
|
||||||
|
|
||||||
|
// loginSuccess send LoginSuccess packet to client
|
||||||
|
func loginSuccess(conn net.Conn, name string, uuid uuid.UUID) error {
|
||||||
|
return conn.WritePacket(pk.Marshal(0x02,
|
||||||
|
pk.String(uuid.String()), //uuid as string with hyphens
|
||||||
|
pk.String(name),
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
|
func joinGame(conn net.Conn) error {
|
||||||
|
return conn.WritePacket(pk.Marshal(data.JoinGame,
|
||||||
|
pk.Int(0), // EntityID
|
||||||
|
pk.UnsignedByte(1), // Gamemode
|
||||||
|
pk.Int(0), // Dimension
|
||||||
|
pk.Long(0), // HashedSeed
|
||||||
|
pk.UnsignedByte(MaxPlayer), // MaxPlayer
|
||||||
|
pk.String("default"), // LevelType
|
||||||
|
pk.VarInt(15), // View Distance
|
||||||
|
pk.Boolean(false), // Reduced Debug Info
|
||||||
|
pk.Boolean(true), // Enable respawn screen
|
||||||
|
))
|
||||||
|
}
|
64
cmd/simpleServer/status.go
Normal file
64
cmd/simpleServer/status.go
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"github.com/Tnze/go-mc/chat"
|
||||||
|
"github.com/Tnze/go-mc/net"
|
||||||
|
pk "github.com/Tnze/go-mc/net/packet"
|
||||||
|
"github.com/google/uuid"
|
||||||
|
"log"
|
||||||
|
)
|
||||||
|
|
||||||
|
func acceptListPing(conn net.Conn) {
|
||||||
|
for i := 0; i < 2; i++ { // ping or list. Only accept twice
|
||||||
|
p, err := conn.ReadPacket()
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
switch p.ID {
|
||||||
|
case 0x00: //List
|
||||||
|
err = conn.WritePacket(pk.Marshal(0x00, pk.String(listResp())))
|
||||||
|
case 0x01: //Ping
|
||||||
|
err = conn.WritePacket(p)
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type player struct {
|
||||||
|
Name string `json:"name"`
|
||||||
|
ID uuid.UUID `json:"id"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// listResp return server status as JSON string
|
||||||
|
func listResp() string {
|
||||||
|
var list struct {
|
||||||
|
Version struct {
|
||||||
|
Name string `json:"name"`
|
||||||
|
Protocol int `json:"protocol"`
|
||||||
|
} `json:"version"`
|
||||||
|
Players struct {
|
||||||
|
Max int `json:"max"`
|
||||||
|
Online int `json:"online"`
|
||||||
|
Sample []player `json:"sample"`
|
||||||
|
} `json:"players"`
|
||||||
|
Description chat.Message `json:"description"`
|
||||||
|
FavIcon string `json:"favicon,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
list.Version.Name = "Chat Server"
|
||||||
|
list.Version.Protocol = ProtocolVersion
|
||||||
|
list.Players.Max = MaxPlayer
|
||||||
|
list.Players.Online = 123
|
||||||
|
list.Players.Sample = []player{} // must init. can't be nil
|
||||||
|
list.Description = chat.Message{Text: "Powered by go-mc", Color: "blue"}
|
||||||
|
|
||||||
|
data, err := json.Marshal(list)
|
||||||
|
if err != nil {
|
||||||
|
log.Panic("Marshal JSON for status checking fail")
|
||||||
|
}
|
||||||
|
return string(data)
|
||||||
|
}
|
@ -4,26 +4,25 @@ package data
|
|||||||
const (
|
const (
|
||||||
SpawnObject int32 = iota //0x00
|
SpawnObject int32 = iota //0x00
|
||||||
SpawnExperienceOrb
|
SpawnExperienceOrb
|
||||||
SpawnGlobalEntity
|
SpawnLivingEntity
|
||||||
SpawnMob
|
|
||||||
SpawnPainting
|
SpawnPainting
|
||||||
SpawnPlayer
|
SpawnPlayer
|
||||||
AnimationClientbound
|
EntityAnimationClientbound
|
||||||
Statistics
|
Statistics
|
||||||
AcknowledgePlayerDigging
|
AcknowledgePlayerDigging
|
||||||
BlockBreakAnimation
|
BlockBreakAnimation
|
||||||
UpdateBlockEntity
|
BlockEntityData
|
||||||
BlockAction
|
BlockAction
|
||||||
BlockChange
|
BlockChange
|
||||||
BossBar
|
BossBar
|
||||||
ServerDifficulty
|
ServerDifficulty
|
||||||
ChatMessageClientbound
|
ChatMessageClientbound
|
||||||
|
MultiBlockChange
|
||||||
|
|
||||||
MultiBlockChange //0x10
|
TabComplete //0x10
|
||||||
TabComplete
|
|
||||||
DeclareCommands
|
DeclareCommands
|
||||||
ConfirmTransaction
|
WindowConfirmationClientbound
|
||||||
CloseWindow
|
CloseWindowClientbound
|
||||||
WindowItems
|
WindowItems
|
||||||
WindowProperty
|
WindowProperty
|
||||||
SetSlot
|
SetSlot
|
||||||
@ -35,9 +34,9 @@ const (
|
|||||||
Explosion
|
Explosion
|
||||||
UnloadChunk
|
UnloadChunk
|
||||||
ChangeGameState
|
ChangeGameState
|
||||||
|
OpenHorseWindow
|
||||||
|
|
||||||
OpenHorseWindow //0x20
|
KeepAliveClientbound //0x20
|
||||||
KeepAliveClientbound
|
|
||||||
ChunkData
|
ChunkData
|
||||||
Effect
|
Effect
|
||||||
Particle
|
Particle
|
||||||
@ -52,9 +51,9 @@ const (
|
|||||||
VehicleMoveClientbound
|
VehicleMoveClientbound
|
||||||
OpenBook
|
OpenBook
|
||||||
OpenWindow
|
OpenWindow
|
||||||
|
OpenSignEditor
|
||||||
|
|
||||||
OpenSignEditor //0x30
|
CraftRecipeResponse //0x30
|
||||||
CraftRecipeResponse
|
|
||||||
PlayerAbilitiesClientbound
|
PlayerAbilitiesClientbound
|
||||||
CombatEvent
|
CombatEvent
|
||||||
PlayerInfo
|
PlayerInfo
|
||||||
@ -69,10 +68,11 @@ const (
|
|||||||
SelectAdvancementTab
|
SelectAdvancementTab
|
||||||
WorldBorder
|
WorldBorder
|
||||||
Camera
|
Camera
|
||||||
|
HeldItemChangeClientbound
|
||||||
|
|
||||||
HeldItemChangeClientbound //0x40
|
UpdateViewPosition //0x40
|
||||||
UpdateViewPosition
|
|
||||||
UpdateViewDistance
|
UpdateViewDistance
|
||||||
|
SpawnPosition
|
||||||
DisplayScoreboard
|
DisplayScoreboard
|
||||||
EntityMetadata
|
EntityMetadata
|
||||||
AttachEntity
|
AttachEntity
|
||||||
@ -84,11 +84,10 @@ const (
|
|||||||
SetPassengers
|
SetPassengers
|
||||||
Teams
|
Teams
|
||||||
UpdateScore
|
UpdateScore
|
||||||
SpawnPosition
|
|
||||||
TimeUpdate
|
TimeUpdate
|
||||||
|
Title
|
||||||
|
|
||||||
Title //0x50
|
EntitySoundEffect //0x50
|
||||||
EntitySoundEffect
|
|
||||||
SoundEffect
|
SoundEffect
|
||||||
StopSound
|
StopSound
|
||||||
PlayerListHeaderAndFooter
|
PlayerListHeaderAndFooter
|
||||||
@ -99,7 +98,7 @@ const (
|
|||||||
EntityProperties
|
EntityProperties
|
||||||
EntityEffect
|
EntityEffect
|
||||||
DeclareRecipes
|
DeclareRecipes
|
||||||
Tags //0x5C
|
Tags //0x5B
|
||||||
)
|
)
|
||||||
|
|
||||||
// Serverbound packet IDs
|
// Serverbound packet IDs
|
||||||
@ -119,9 +118,10 @@ const (
|
|||||||
EditBook
|
EditBook
|
||||||
QueryEntityNBT
|
QueryEntityNBT
|
||||||
UseEntity
|
UseEntity
|
||||||
KeepAliveServerbound
|
GenerateStructure
|
||||||
|
|
||||||
LockDifficulty //0x10
|
KeepAliveServerbound //0x10
|
||||||
|
LockDifficulty
|
||||||
PlayerPosition
|
PlayerPosition
|
||||||
PlayerPositionAndLookServerbound
|
PlayerPositionAndLookServerbound
|
||||||
PlayerLook
|
PlayerLook
|
||||||
@ -136,9 +136,9 @@ const (
|
|||||||
SteerVehicle
|
SteerVehicle
|
||||||
RecipeBookData
|
RecipeBookData
|
||||||
NameItem
|
NameItem
|
||||||
ResourcePackStatus
|
|
||||||
|
|
||||||
AdvancementTab //0x20
|
ResourcePackStatus //0x20
|
||||||
|
AdvancementTab
|
||||||
SelectTrade
|
SelectTrade
|
||||||
SetBeaconEffect
|
SetBeaconEffect
|
||||||
HeldItemChangeServerbound
|
HeldItemChangeServerbound
|
||||||
@ -151,5 +151,5 @@ const (
|
|||||||
AnimationServerbound
|
AnimationServerbound
|
||||||
Spectate
|
Spectate
|
||||||
PlayerBlockPlacement
|
PlayerBlockPlacement
|
||||||
UseItem //0x2D
|
UseItem //0x2E
|
||||||
)
|
)
|
||||||
|
Reference in New Issue
Block a user