Implement packet decoding for entities
This commit is contained in:
177
bot/ingame.go
177
bot/ingame.go
@ -132,36 +132,60 @@ func (c *Client) handlePacket(p pk.Packet) (disconnect bool, err error) {
|
||||
}
|
||||
case data.AbilitiesClientbound:
|
||||
err = handlePlayerAbilitiesPacket(c, p)
|
||||
case data.UpdateHealth:
|
||||
err = handleUpdateHealthPacket(c, p)
|
||||
case data.ChatClientbound:
|
||||
err = handleChatMessagePacket(c, p)
|
||||
|
||||
case data.HeldItemSlotClientbound:
|
||||
err = handleHeldItemPacket(c, p)
|
||||
case data.WindowItems:
|
||||
err = handleWindowItemsPacket(c, p)
|
||||
|
||||
case data.DeclareRecipes:
|
||||
// handleDeclareRecipesPacket(g, reader)
|
||||
case data.KeepAliveClientbound:
|
||||
err = handleKeepAlivePacket(c, p)
|
||||
|
||||
case data.SpawnEntity:
|
||||
err = handleSpawnEntityPacket(c, p)
|
||||
case data.NamedEntitySpawn:
|
||||
err = handleSpawnPlayerPacket(c, p)
|
||||
case data.SpawnEntityLiving:
|
||||
err = handleSpawnLivingEntityPacket(c, p)
|
||||
case data.Animation:
|
||||
err = handleEntityAnimationPacket(c, p)
|
||||
case data.EntityStatus:
|
||||
err = handleEntityStatusPacket(c, p)
|
||||
case data.EntityDestroy:
|
||||
err = handleDestroyEntitiesPacket(c, p)
|
||||
case data.RelEntityMove:
|
||||
err = handleEntityPositionPacket(c, p)
|
||||
case data.EntityMoveLook:
|
||||
err = handleEntityPositionLookPacket(c, p)
|
||||
case data.EntityLook:
|
||||
err = handleEntityLookPacket(c, p)
|
||||
case data.Entity:
|
||||
err = handleEntityMovePacket(c, p)
|
||||
|
||||
case data.UpdateLight:
|
||||
err = c.Events.updateSeenPackets(seenUpdateLight)
|
||||
case data.MapChunk:
|
||||
err = handleChunkDataPacket(c, p)
|
||||
case data.BlockChange:
|
||||
err = handleBlockChangePacket(c, p)
|
||||
case data.MultiBlockChange:
|
||||
err = handleMultiBlockChangePacket(c, p)
|
||||
case data.UnloadChunk:
|
||||
err = handleUnloadChunkPacket(c, p)
|
||||
|
||||
case data.PositionClientbound:
|
||||
err = handlePlayerPositionAndLookPacket(c, p)
|
||||
sendPlayerPositionAndLookPacket(c) // to confirm the position
|
||||
if err2 := c.Events.updateSeenPackets(seenPlayerPositionAndLook); err == nil {
|
||||
err = err2
|
||||
}
|
||||
case data.DeclareRecipes:
|
||||
// handleDeclareRecipesPacket(g, reader)
|
||||
case data.KeepAliveClientbound:
|
||||
err = handleKeepAlivePacket(c, p)
|
||||
case data.Entity:
|
||||
//handleEntityPacket(g, reader)
|
||||
case data.NamedEntitySpawn:
|
||||
// err = handleSpawnPlayerPacket(g, reader)
|
||||
case data.WindowItems:
|
||||
err = handleWindowItemsPacket(c, p)
|
||||
case data.UpdateHealth:
|
||||
err = handleUpdateHealthPacket(c, p)
|
||||
case data.ChatClientbound:
|
||||
err = handleChatMessagePacket(c, p)
|
||||
case data.BlockChange:
|
||||
err = handleBlockChangePacket(c, p)
|
||||
case data.MultiBlockChange:
|
||||
err = handleMultiBlockChangePacket(c, p)
|
||||
|
||||
case data.KickDisconnect:
|
||||
err = handleDisconnectPacket(c, p)
|
||||
disconnect = true
|
||||
@ -179,6 +203,110 @@ func (c *Client) handlePacket(p pk.Packet) (disconnect bool, err error) {
|
||||
return
|
||||
}
|
||||
|
||||
func handleSpawnEntityPacket(c *Client, p pk.Packet) error {
|
||||
var se ptypes.SpawnEntity
|
||||
if err := se.Decode(p); err != nil {
|
||||
return err
|
||||
}
|
||||
fmt.Printf("SpawnEntity: %+v\n", se)
|
||||
return nil
|
||||
}
|
||||
|
||||
func handleSpawnLivingEntityPacket(c *Client, p pk.Packet) error {
|
||||
var se ptypes.SpawnLivingEntity
|
||||
if err := se.Decode(p); err != nil {
|
||||
return err
|
||||
}
|
||||
fmt.Printf("SpawnLivingEntity: %+v\n", se)
|
||||
return nil
|
||||
}
|
||||
|
||||
func handleSpawnPlayerPacket(c *Client, p pk.Packet) error {
|
||||
var se ptypes.SpawnPlayer
|
||||
if err := se.Decode(p); err != nil {
|
||||
return err
|
||||
}
|
||||
fmt.Printf("SpawnPlayer: %+v\n", se)
|
||||
return nil
|
||||
}
|
||||
|
||||
func handleEntityPositionPacket(c *Client, p pk.Packet) error {
|
||||
var se ptypes.EntityPosition
|
||||
if err := se.Decode(p); err != nil {
|
||||
return err
|
||||
}
|
||||
fmt.Printf("EntityPosition: %+v\n", se)
|
||||
return nil
|
||||
}
|
||||
|
||||
func handleEntityPositionLookPacket(c *Client, p pk.Packet) error {
|
||||
var se ptypes.EntityPositionLook
|
||||
if err := se.Decode(p); err != nil {
|
||||
return err
|
||||
}
|
||||
fmt.Printf("EntityPositionLook: %+v\n", se)
|
||||
return nil
|
||||
}
|
||||
|
||||
func handleEntityLookPacket(c *Client, p pk.Packet) error {
|
||||
var se ptypes.EntityRotation
|
||||
if err := se.Decode(p); err != nil {
|
||||
return err
|
||||
}
|
||||
fmt.Printf("EntityRotation: %+v\n", se)
|
||||
return nil
|
||||
}
|
||||
|
||||
func handleEntityMovePacket(c *Client, p pk.Packet) error {
|
||||
var id pk.VarInt
|
||||
if err := p.Scan(&id); err != nil {
|
||||
return err
|
||||
}
|
||||
fmt.Printf("EntityMove (probs didnt for players): %+v\n", id)
|
||||
return nil
|
||||
}
|
||||
|
||||
func handleEntityAnimationPacket(c *Client, p pk.Packet) error {
|
||||
var se ptypes.EntityAnimationClientbound
|
||||
if err := se.Decode(p); err != nil {
|
||||
return err
|
||||
}
|
||||
fmt.Printf("EntityAnimationClientbound: %+v\n", se)
|
||||
return nil
|
||||
}
|
||||
|
||||
func handleEntityStatusPacket(c *Client, p pk.Packet) error {
|
||||
var (
|
||||
id pk.Int
|
||||
status pk.Byte
|
||||
)
|
||||
if err := p.Scan(&id, &status); err != nil {
|
||||
return err
|
||||
}
|
||||
fmt.Printf("EntityStatus: %v, %v\n", id, status)
|
||||
return nil
|
||||
}
|
||||
|
||||
func handleDestroyEntitiesPacket(c *Client, p pk.Packet) error {
|
||||
var (
|
||||
count pk.VarInt
|
||||
r = bytes.NewReader(p.Data)
|
||||
)
|
||||
if err := count.Decode(r); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
entities := make([]pk.VarInt, int(count))
|
||||
for i := 0; i < int(count); i++ {
|
||||
if err := entities[i].Decode(r); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
fmt.Printf("DestroyEntities: %v\n", entities)
|
||||
return nil
|
||||
}
|
||||
|
||||
func handleSoundEffect(c *Client, p pk.Packet) error {
|
||||
var s ptypes.SoundEffect
|
||||
if err := s.Decode(p); err != nil {
|
||||
@ -463,6 +591,19 @@ func handleHeldItemPacket(c *Client, p pk.Packet) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func handleUnloadChunkPacket(c *Client, p pk.Packet) error {
|
||||
if !c.settings.ReceiveMap {
|
||||
return nil
|
||||
}
|
||||
|
||||
var x, z pk.Int
|
||||
if err := p.Scan(&x, &z); err != nil {
|
||||
return err
|
||||
}
|
||||
c.Wd.UnloadChunk(world.ChunkLoc{X: int(x) >> 4, Z: int(z) >> 4})
|
||||
return nil
|
||||
}
|
||||
|
||||
func handleChunkDataPacket(c *Client, p pk.Packet) error {
|
||||
if err := c.Events.updateSeenPackets(seenChunkData); err != nil {
|
||||
return err
|
||||
|
@ -68,6 +68,10 @@ func (w *World) GetBlockStatus(x, y, z int) BlockStatus {
|
||||
return 0
|
||||
}
|
||||
|
||||
func (w *World) UnloadChunk(loc ChunkLoc) {
|
||||
delete(w.Chunks, loc)
|
||||
}
|
||||
|
||||
func (w *World) UnaryBlockUpdate(pos pk.Position, bStateID BlockStatus) bool {
|
||||
c := w.Chunks[ChunkLoc{X: pos.X >> 4, Z: pos.Z >> 4}]
|
||||
if c == nil {
|
||||
|
@ -2,10 +2,11 @@ package packet
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"github.com/google/uuid"
|
||||
"io"
|
||||
"math"
|
||||
|
||||
"github.com/google/uuid"
|
||||
|
||||
"github.com/Tnze/go-mc/nbt"
|
||||
)
|
||||
|
||||
@ -364,6 +365,16 @@ func (p *Position) Decode(r DecodeReader) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
//Decodes an Angle
|
||||
func (b *Angle) Decode(r DecodeReader) error {
|
||||
v, err := r.ReadByte()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
*b = Angle(v)
|
||||
return nil
|
||||
}
|
||||
|
||||
//Encode a Float
|
||||
func (f Float) Encode() []byte {
|
||||
return Int(math.Float32bits(float32(f))).Encode()
|
||||
|
95
net/ptypes/entities.go
Normal file
95
net/ptypes/entities.go
Normal file
@ -0,0 +1,95 @@
|
||||
package ptypes
|
||||
|
||||
import pk "github.com/Tnze/go-mc/net/packet"
|
||||
|
||||
// SpawnEntity is a clientbound packet used to spawn a non-mob entity.
|
||||
type SpawnEntity struct {
|
||||
ID pk.VarInt
|
||||
UUID pk.UUID
|
||||
Type pk.VarInt
|
||||
X, Y, Z pk.Int
|
||||
Pitch, Yaw pk.Angle
|
||||
Data pk.Int
|
||||
VelX, VelY, VelZ pk.Short
|
||||
}
|
||||
|
||||
func (p *SpawnEntity) Decode(pkt pk.Packet) error {
|
||||
return pkt.Scan(&p.ID, &p.UUID, &p.Type,
|
||||
&p.X, &p.Y, &p.Z, &p.Pitch, &p.Yaw,
|
||||
&p.Data, &p.VelX, &p.VelY, &p.VelZ)
|
||||
}
|
||||
|
||||
// SpawnPlayer is a clientbound packet used to describe a player entering
|
||||
// visible range.
|
||||
type SpawnPlayer struct {
|
||||
ID pk.VarInt
|
||||
UUID pk.UUID
|
||||
X, Y, Z pk.Double
|
||||
Yaw, Pitch pk.Angle
|
||||
}
|
||||
|
||||
func (p *SpawnPlayer) Decode(pkt pk.Packet) error {
|
||||
return pkt.Scan(&p.ID, &p.UUID, &p.X, &p.Y, &p.Z, &p.Yaw, &p.Pitch)
|
||||
}
|
||||
|
||||
// SpawnLivingEntity is a clientbound packet used to spawn a mob.
|
||||
type SpawnLivingEntity struct {
|
||||
ID pk.VarInt
|
||||
UUID pk.UUID
|
||||
Type pk.VarInt
|
||||
X, Y, Z pk.Double
|
||||
Yaw, Pitch pk.Angle
|
||||
HeadPitch pk.Angle
|
||||
VelX, VelY, VelZ pk.Short
|
||||
}
|
||||
|
||||
func (p *SpawnLivingEntity) Decode(pkt pk.Packet) error {
|
||||
return pkt.Scan(&p.ID, &p.UUID, &p.Type,
|
||||
&p.X, &p.Y, &p.Z, &p.Yaw, &p.Pitch,
|
||||
&p.HeadPitch, &p.VelX, &p.VelY, &p.VelZ)
|
||||
}
|
||||
|
||||
// EntityAnimationClientbound updates the animationf state of an entity.
|
||||
type EntityAnimationClientbound struct {
|
||||
ID pk.VarInt
|
||||
Animation pk.UnsignedByte
|
||||
}
|
||||
|
||||
func (p *EntityAnimationClientbound) Decode(pkt pk.Packet) error {
|
||||
return pkt.Scan(&p.ID, &p.Animation)
|
||||
}
|
||||
|
||||
// EntityPosition is a clientbound packet used to update an entities position.
|
||||
type EntityPosition struct {
|
||||
ID pk.VarInt
|
||||
X, Y, Z pk.Short // Deltas
|
||||
OnGround pk.Boolean
|
||||
}
|
||||
|
||||
func (p *EntityPosition) Decode(pkt pk.Packet) error {
|
||||
return pkt.Scan(&p.ID, &p.X, &p.Y, &p.Z, &p.OnGround)
|
||||
}
|
||||
|
||||
// EntityPosition is a clientbound packet used to update an entities position
|
||||
// and its rotation.
|
||||
type EntityPositionLook struct {
|
||||
ID pk.VarInt
|
||||
X, Y, Z pk.Short // Deltas
|
||||
Yaw, Pitch pk.Angle
|
||||
OnGround pk.Boolean
|
||||
}
|
||||
|
||||
func (p *EntityPositionLook) Decode(pkt pk.Packet) error {
|
||||
return pkt.Scan(&p.ID, &p.X, &p.Y, &p.Z, &p.Yaw, &p.Pitch, &p.OnGround)
|
||||
}
|
||||
|
||||
// EntityRotation is a clientbound packet used to update an entities rotation.
|
||||
type EntityRotation struct {
|
||||
ID pk.VarInt
|
||||
Yaw, Pitch pk.Angle
|
||||
OnGround pk.Boolean
|
||||
}
|
||||
|
||||
func (p *EntityRotation) Decode(pkt pk.Packet) error {
|
||||
return pkt.Scan(&p.ID, &p.Yaw, &p.Pitch, &p.OnGround)
|
||||
}
|
Reference in New Issue
Block a user