Implement packet decoding for entities

This commit is contained in:
Tom
2020-09-17 00:13:08 -07:00
parent a981ab84f5
commit 8ecf08fa50
4 changed files with 270 additions and 19 deletions

View File

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

View File

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

View File

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