Bak
This commit is contained in:
parent
a3fa859804
commit
78b2a2f022
144
playPackets.go
144
playPackets.go
@ -3,7 +3,11 @@ package main
|
|||||||
import (
|
import (
|
||||||
"bufio"
|
"bufio"
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"errors"
|
||||||
"github.com/Tnze/go-mc/nbt"
|
"github.com/Tnze/go-mc/nbt"
|
||||||
|
"github.com/google/uuid"
|
||||||
|
"math/rand/v2"
|
||||||
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (player *Player) sendBundleDelimiter() error {
|
func (player *Player) sendBundleDelimiter() error {
|
||||||
@ -356,6 +360,140 @@ func (player *Player) sendPlayStart() error {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//func (player *Player) sendMapItemData(mapId int32) error {
|
func (player *Player) sendMapItemData(mapId int32) error {
|
||||||
// mapEntry := world.m
|
var buf bytes.Buffer
|
||||||
//}
|
mapEntry, found := world.Maps[mapId]
|
||||||
|
if found {
|
||||||
|
mapEntry.add(&buf)
|
||||||
|
}
|
||||||
|
return player.sendPacket(0x2C, &buf)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (player *Player) sendMerchantOffers(windowID int32, entity *VillagerEntity) error {
|
||||||
|
var buf bytes.Buffer
|
||||||
|
entity.addOffers(&buf, windowID)
|
||||||
|
return player.sendPacket(0x2D, &buf)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (player *Player) sendEntityPositionUpdate(entity *Entity, deltas []int16) error {
|
||||||
|
if len(deltas) != 3 {
|
||||||
|
return errors.New("invalid deltas")
|
||||||
|
}
|
||||||
|
var buf bytes.Buffer
|
||||||
|
addVarint(&buf, entity.ID)
|
||||||
|
addInt16(&buf, deltas[0])
|
||||||
|
addInt16(&buf, deltas[1])
|
||||||
|
addInt16(&buf, deltas[2])
|
||||||
|
addBool(&buf, entity.onGround())
|
||||||
|
return player.sendPacket(0x2E, &buf)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (player *Player) sendEntityPositionRotationUpdate(entity *Entity, deltas []int16) error {
|
||||||
|
if len(deltas) != 3 {
|
||||||
|
return errors.New("invalid deltas")
|
||||||
|
}
|
||||||
|
var buf bytes.Buffer
|
||||||
|
addVarint(&buf, entity.ID)
|
||||||
|
addInt16(&buf, deltas[0])
|
||||||
|
addInt16(&buf, deltas[1])
|
||||||
|
addInt16(&buf, deltas[2])
|
||||||
|
addByte(&buf, entity.Rotation.Yaw)
|
||||||
|
addByte(&buf, entity.Rotation.Pitch)
|
||||||
|
addBool(&buf, entity.onGround())
|
||||||
|
return player.sendPacket(0x2F, &buf)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (player *Player) sendEntityRotationUpdate(entity *Entity) error {
|
||||||
|
var buf bytes.Buffer
|
||||||
|
addVarint(&buf, entity.ID)
|
||||||
|
addByte(&buf, entity.Rotation.Yaw)
|
||||||
|
addByte(&buf, entity.Rotation.Pitch)
|
||||||
|
addBool(&buf, entity.onGround())
|
||||||
|
return player.sendPacket(0x30, &buf)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (player *Player) sendVehicleMove() error {
|
||||||
|
if player.Entity.Vehicle != nil {
|
||||||
|
var buf bytes.Buffer
|
||||||
|
player.Entity.Vehicle.Position.add(&buf)
|
||||||
|
addFloat32(&buf, float32(player.Entity.Vehicle.Rotation.Yaw))
|
||||||
|
addFloat32(&buf, float32(player.Entity.Vehicle.Rotation.Pitch))
|
||||||
|
return player.sendPacket(0x31, &buf)
|
||||||
|
}
|
||||||
|
return errors.New("no vehicle")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (player *Player) sendBookOpen(isOffHand bool) error {
|
||||||
|
var buf bytes.Buffer
|
||||||
|
hand := int32(0)
|
||||||
|
if isOffHand {
|
||||||
|
hand = 1
|
||||||
|
}
|
||||||
|
addVarint(&buf, hand)
|
||||||
|
return player.sendPacket(0x32, &buf)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (player *Player) sendOpenScreen(windowID int32, window *Window, title TextComponent) error {
|
||||||
|
var buf bytes.Buffer
|
||||||
|
addVarint(&buf, windowID)
|
||||||
|
addVarint(&buf, window.ID)
|
||||||
|
addTextComponent(&buf, title)
|
||||||
|
return player.sendPacket(0x33, &buf)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (player *Player) sendOpenSignEditor(blockPosition BlockPosition, front bool) error {
|
||||||
|
var buf bytes.Buffer
|
||||||
|
blockPosition.add(&buf)
|
||||||
|
addBool(&buf, front)
|
||||||
|
return player.sendPacket(0x34, &buf)
|
||||||
|
}
|
||||||
|
|
||||||
|
//0x35 is ping to client
|
||||||
|
//0x36 is pong
|
||||||
|
|
||||||
|
func (player *Player) sendGhostRecipe(windowID uint8, recipe string) error {
|
||||||
|
var buf bytes.Buffer
|
||||||
|
addByte(&buf, windowID)
|
||||||
|
addString(&buf, recipe)
|
||||||
|
return player.sendPacket(0x37, &buf)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (player *Player) sendAbilities() error {
|
||||||
|
var buf bytes.Buffer
|
||||||
|
addByte(&buf, player.Abilites.export())
|
||||||
|
addFloat32(&buf, player.FlyingSpeed)
|
||||||
|
addFloat32(&buf, player.FOVModifier)
|
||||||
|
return player.sendPacket(0x38, &buf)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (player *Player) sendChatMessage(sender *Player, message string) error {
|
||||||
|
var buf bytes.Buffer
|
||||||
|
//TODO IMPLEMENT
|
||||||
|
addUUID(&buf, sender.uuid)
|
||||||
|
addVarint(&buf, sender.MessageIndex)
|
||||||
|
addBool(&buf, false)
|
||||||
|
addString(&buf, message)
|
||||||
|
addInt64(&buf, time.Now().Unix())
|
||||||
|
addInt64(&buf, rand.Int64())
|
||||||
|
//not implementing secure chat
|
||||||
|
return player.sendPacket(0x39, &buf)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (player *Player) sendDeath(message TextComponent) error {
|
||||||
|
var buf bytes.Buffer
|
||||||
|
addVarint(&buf, player.Entity.ID)
|
||||||
|
addTextComponent(&buf, message)
|
||||||
|
return player.sendPacket(0x3C, &buf)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (player *Player) sendRemoveFromTab(playersToRemove []uuid.UUID) error {
|
||||||
|
if len(playersToRemove) > 0 {
|
||||||
|
var buf bytes.Buffer
|
||||||
|
addVarint(&buf, int32(len(playersToRemove)))
|
||||||
|
for _, playerToRemove := range playersToRemove {
|
||||||
|
addUUID(&buf, playerToRemove)
|
||||||
|
}
|
||||||
|
return player.sendPacket(0x3D, &buf)
|
||||||
|
}
|
||||||
|
return errors.New("no playersToRemove")
|
||||||
|
}
|
||||||
|
159
structs.go
159
structs.go
@ -8,6 +8,7 @@ import (
|
|||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
"math"
|
"math"
|
||||||
"net"
|
"net"
|
||||||
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Version struct {
|
type Version struct {
|
||||||
@ -38,6 +39,29 @@ type ServerStatus struct {
|
|||||||
EnforcesSecureChat bool `json:"enforcesSecureChat"`
|
EnforcesSecureChat bool `json:"enforcesSecureChat"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type PlayerAbilites struct {
|
||||||
|
Invulnerable bool
|
||||||
|
Flying bool
|
||||||
|
AllowFlying bool
|
||||||
|
CreativeMode bool
|
||||||
|
}
|
||||||
|
|
||||||
|
func (abilities *PlayerAbilites) export() (out byte) {
|
||||||
|
if abilities.Invulnerable {
|
||||||
|
out |= 0x01
|
||||||
|
}
|
||||||
|
if abilities.Flying {
|
||||||
|
out |= 0x02
|
||||||
|
}
|
||||||
|
if abilities.AllowFlying {
|
||||||
|
out |= 0x04
|
||||||
|
}
|
||||||
|
if abilities.CreativeMode {
|
||||||
|
out |= 0x08
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
type Player struct {
|
type Player struct {
|
||||||
conn net.Conn
|
conn net.Conn
|
||||||
|
|
||||||
@ -59,6 +83,14 @@ type Player struct {
|
|||||||
DeathDimension *Dimension
|
DeathDimension *Dimension
|
||||||
DeathPosition BlockPosition
|
DeathPosition BlockPosition
|
||||||
|
|
||||||
|
Abilites PlayerAbilites
|
||||||
|
FlyingSpeed float32
|
||||||
|
FOVModifier float32
|
||||||
|
MessageIndex int32
|
||||||
|
|
||||||
|
CombatStart int64
|
||||||
|
CombatEnd int64
|
||||||
|
|
||||||
Position EntityPosition
|
Position EntityPosition
|
||||||
|
|
||||||
GameMode uint8
|
GameMode uint8
|
||||||
@ -88,6 +120,21 @@ type Player struct {
|
|||||||
uuid uuid.UUID
|
uuid uuid.UUID
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (player *Player) startCombat() {
|
||||||
|
player.CombatStart = time.Now().Unix()
|
||||||
|
_ = player.sendPacket(0x3B, &bytes.Buffer{})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (player *Player) endCombat() {
|
||||||
|
player.CombatEnd = time.Now().Unix()
|
||||||
|
length := player.CombatEnd - player.CombatStart
|
||||||
|
if length >= 0 && player.CombatEnd != 0 && player.CombatStart != 0 && player.CombatEnd > player.CombatStart {
|
||||||
|
var buf bytes.Buffer
|
||||||
|
addInt64(&buf, length)
|
||||||
|
_ = player.sendPacket(0x3A, &buf)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
type Dimension struct {
|
type Dimension struct {
|
||||||
ID int32
|
ID int32
|
||||||
Name string
|
Name string
|
||||||
@ -370,6 +417,21 @@ func (slot *Slot) add(buf *bytes.Buffer) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (slot *Slot) addTrade(buf *bytes.Buffer) {
|
||||||
|
addVarint(buf, slot.Count)
|
||||||
|
if slot.Count > 0 {
|
||||||
|
addVarint(buf, slot.ItemID)
|
||||||
|
addVarint(buf, int32(len(slot.ComponentsToAdd)))
|
||||||
|
for componentID, component := range slot.ComponentsToAdd {
|
||||||
|
addVarint(buf, componentID)
|
||||||
|
component = component //TODO IMPLEMENT ALL THESE STUPID COMPONENTS
|
||||||
|
}
|
||||||
|
for _, componentID := range slot.ComponentsToRemove {
|
||||||
|
addVarint(buf, componentID)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// PalettedContainer represents a palette-based storage of entries.
|
// PalettedContainer represents a palette-based storage of entries.
|
||||||
type PalettedContainer struct {
|
type PalettedContainer struct {
|
||||||
BitsPerEntry uint8
|
BitsPerEntry uint8
|
||||||
@ -621,6 +683,7 @@ func (velocity *Velocity) add(buf *bytes.Buffer) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type Entity struct {
|
type Entity struct {
|
||||||
|
World *World
|
||||||
ID int32
|
ID int32
|
||||||
UUID uuid.UUID
|
UUID uuid.UUID
|
||||||
Type int32
|
Type int32
|
||||||
@ -631,6 +694,51 @@ type Entity struct {
|
|||||||
Animation uint8
|
Animation uint8
|
||||||
status int8
|
status int8
|
||||||
PortalCooldown int32
|
PortalCooldown int32
|
||||||
|
Vehicle *Entity
|
||||||
|
PlayersInformed []*Player
|
||||||
|
}
|
||||||
|
|
||||||
|
// Function to calculate the Euclidean distance between two points in 3D space
|
||||||
|
func distance(p1, p2 EntityPosition) float64 {
|
||||||
|
dx := p2.X - p1.X
|
||||||
|
dy := p2.Y - p1.Y
|
||||||
|
dz := p2.Z - p1.Z
|
||||||
|
return math.Sqrt(dx*dx + dy*dy + dz*dz)
|
||||||
|
}
|
||||||
|
|
||||||
|
func getDeltas(p1, p2 EntityPosition) []int16 {
|
||||||
|
return []int16{
|
||||||
|
int16((p2.X * 4096) - (p1.X * 4096)),
|
||||||
|
int16((p2.Y * 4096) - (p1.Y * 4096)),
|
||||||
|
int16((p2.Z * 4096) - (p1.Z * 4096)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (entity *Entity) move(newPos EntityPosition, withRotation bool) {
|
||||||
|
diff := distance(entity.Position, newPos)
|
||||||
|
if diff <= 7 {
|
||||||
|
if withRotation {
|
||||||
|
for _, player := range entity.PlayersInformed {
|
||||||
|
player.sendEntityPositionRotationUpdate(entity, getDeltas(entity.Position, newPos))
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for _, player := range entity.PlayersInformed {
|
||||||
|
player.sendEntityPositionUpdate(entity, getDeltas(entity.Position, newPos))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for _, player := range entity.PlayersInformed {
|
||||||
|
//TODO make entity teleport
|
||||||
|
player = player
|
||||||
|
//player.sendEntityTeleport(entity, newPos)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
entity.Position = newPos
|
||||||
|
}
|
||||||
|
|
||||||
|
func (entity *Entity) onGround() bool {
|
||||||
|
//TODO ADD THIS
|
||||||
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
func (entity *Entity) add(buf *bytes.Buffer) {
|
func (entity *Entity) add(buf *bytes.Buffer) {
|
||||||
@ -714,3 +822,54 @@ func (Map *Map) add(buf *bytes.Buffer) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type VillageTrade struct {
|
||||||
|
In1 Slot
|
||||||
|
In2 *Slot
|
||||||
|
Out Slot
|
||||||
|
Disabled bool
|
||||||
|
Uses int32
|
||||||
|
MaxUses int32
|
||||||
|
XP int32
|
||||||
|
Modifier int32
|
||||||
|
Multiplier float32
|
||||||
|
Demand int32
|
||||||
|
}
|
||||||
|
|
||||||
|
func (villageTrade *VillageTrade) add(buf *bytes.Buffer) {
|
||||||
|
villageTrade.In1.addTrade(buf)
|
||||||
|
villageTrade.Out.add(buf)
|
||||||
|
villageTrade.In2.addTrade(buf)
|
||||||
|
addBool(buf, villageTrade.Disabled)
|
||||||
|
addInt32(buf, villageTrade.Uses)
|
||||||
|
addInt32(buf, villageTrade.MaxUses)
|
||||||
|
addInt32(buf, villageTrade.XP)
|
||||||
|
addInt32(buf, villageTrade.Modifier)
|
||||||
|
addFloat32(buf, villageTrade.Multiplier)
|
||||||
|
addInt32(buf, villageTrade.Demand)
|
||||||
|
}
|
||||||
|
|
||||||
|
type VillagerEntity struct {
|
||||||
|
Entity *Entity
|
||||||
|
Trades []VillageTrade
|
||||||
|
Level int32
|
||||||
|
XP int32
|
||||||
|
Wandering bool
|
||||||
|
CanRestock bool
|
||||||
|
}
|
||||||
|
|
||||||
|
func (VillagerEntity *VillagerEntity) addOffers(buf *bytes.Buffer, windowID int32) {
|
||||||
|
addVarint(buf, windowID)
|
||||||
|
addVarint(buf, int32(len(VillagerEntity.Trades)))
|
||||||
|
for _, trade := range VillagerEntity.Trades {
|
||||||
|
trade.add(buf)
|
||||||
|
}
|
||||||
|
addVarint(buf, VillagerEntity.Level)
|
||||||
|
addVarint(buf, VillagerEntity.XP)
|
||||||
|
addBool(buf, !VillagerEntity.Wandering)
|
||||||
|
addBool(buf, VillagerEntity.CanRestock)
|
||||||
|
}
|
||||||
|
|
||||||
|
type Window struct {
|
||||||
|
ID int32
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user