func (p *Player) Messagef(f string, a ...interface{}) {
	msg := fmt.Sprintf(f, a...)
	p.session().SendMessage(msg)
}
Messagef sends a formatted message using a specific format to the player. The message is formatted
according to the fmt.Sprintf formatting rules.
package player
import (
	"fmt"
	"github.com/df-mc/dragonfly/server/block"
	blockAction "github.com/df-mc/dragonfly/server/block/action"
	"github.com/df-mc/dragonfly/server/block/cube"
	"github.com/df-mc/dragonfly/server/cmd"
	"github.com/df-mc/dragonfly/server/entity"
	"github.com/df-mc/dragonfly/server/entity/action"
	"github.com/df-mc/dragonfly/server/entity/damage"
	"github.com/df-mc/dragonfly/server/entity/effect"
	"github.com/df-mc/dragonfly/server/entity/healing"
	"github.com/df-mc/dragonfly/server/entity/physics"
	"github.com/df-mc/dragonfly/server/event"
	"github.com/df-mc/dragonfly/server/item"
	"github.com/df-mc/dragonfly/server/item/armour"
	"github.com/df-mc/dragonfly/server/item/enchantment"
	"github.com/df-mc/dragonfly/server/item/inventory"
	"github.com/df-mc/dragonfly/server/item/tool"
	"github.com/df-mc/dragonfly/server/player/bossbar"
	"github.com/df-mc/dragonfly/server/player/chat"
	"github.com/df-mc/dragonfly/server/player/form"
	"github.com/df-mc/dragonfly/server/player/scoreboard"
	"github.com/df-mc/dragonfly/server/player/skin"
	"github.com/df-mc/dragonfly/server/player/title"
	"github.com/df-mc/dragonfly/server/session"
	"github.com/df-mc/dragonfly/server/world"
	"github.com/df-mc/dragonfly/server/world/particle"
	"github.com/df-mc/dragonfly/server/world/sound"
	"github.com/go-gl/mathgl/mgl64"
	"github.com/google/uuid"
	"go.uber.org/atomic"
	"golang.org/x/text/language"
	"math"
	"math/rand"
	"net"
	"strings"
	"sync"
	"time"
)
type Player struct {
	name                                string
	uuid                                uuid.UUID
	xuid                                string
	locale                              language.Tag
	pos, vel                            atomic.Value
	nameTag                             atomic.String
	yaw, pitch, absorptionHealth, scale atomic.Float64
	gameModeMu sync.RWMutex
	gameMode   world.GameMode
	skinMu sync.RWMutex
	skin   skin.Skin
	sMutex sync.RWMutex
	s *session.Session
	hMutex sync.RWMutex
	h Handler
	inv, offHand *inventory.Inventory
	armour       *inventory.Armour
	heldSlot     *atomic.Uint32
	sneaking, sprinting, swimming, flying,
	invisible, immobile, onGround, usingItem atomic.Bool
	usingSince atomic.Int64
	fireTicks    atomic.Int64
	fallDistance atomic.Float64
	speed    atomic.Float64
	health   *entity.HealthManager
	effects  *entity.EffectManager
	immunity atomic.Value
	mc *entity.MovementComputer
	breaking          atomic.Bool
	breakingPos       atomic.Value
	lastBreakDuration time.Duration
	breakParticleCounter atomic.Uint32
	hunger *hungerManager
}
func New(name string, skin skin.Skin, pos mgl64.Vec3) *Player {
	p := &Player{}
	*p = Player{
		inv: inventory.New(36, func(slot int, item item.Stack) {
			if slot == int(p.heldSlot.Load()) {
				p.broadcastItems(slot, item)
			}
		}),
		uuid:     uuid.New(),
		offHand:  inventory.New(1, p.broadcastItems),
		armour:   inventory.NewArmour(p.broadcastArmour),
		hunger:   newHungerManager(),
		health:   entity.NewHealthManager(),
		effects:  entity.NewEffectManager(),
		gameMode: world.GameModeAdventure{},
		h:        NopHandler{},
		name:     name,
		skin:     skin,
		speed:    *atomic.NewFloat64(0.1),
		nameTag:  *atomic.NewString(name),
		heldSlot: atomic.NewUint32(0),
		locale:   language.BritishEnglish,
		scale:    *atomic.NewFloat64(1),
	}
	p.mc = &entity.MovementComputer{Gravity: 0.08, Drag: 0.02, DragBeforeGravity: true}
	p.pos.Store(pos)
	p.vel.Store(mgl64.Vec3{})
	p.immunity.Store(time.Now())
	p.breakingPos.Store(cube.Pos{})
	return p
}
func NewWithSession(name, xuid string, uuid uuid.UUID, skin skin.Skin, s *session.Session, pos mgl64.Vec3, data *Data) *Player {
	p := New(name, skin, pos)
	p.s, p.uuid, p.xuid, p.skin = s, uuid, xuid, skin
	p.inv, p.offHand, p.armour, p.heldSlot = s.HandleInventories()
	p.locale, _ = language.Parse(strings.Replace(s.ClientData().LanguageCode, "_", "-", 1))
	chat.Global.Subscribe(p)
	if data != nil {
		p.load(*data)
	}
	return p
}
func (p *Player) Name() string {
	return p.name
}
func (p *Player) UUID() uuid.UUID {
	return p.uuid
}
func (p *Player) XUID() string {
	return p.xuid
}
func (p *Player) Addr() net.Addr {
	if p.session() == session.Nop {
		return nil
	}
	return p.session().Addr()
}
func (p *Player) Skin() skin.Skin {
	p.skinMu.RLock()
	defer p.skinMu.RUnlock()
	return p.skin
}
func (p *Player) SetSkin(skin skin.Skin) {
	if p.Dead() {
		return
	}
	ctx := event.C()
	p.handler().HandleSkinChange(ctx, skin)
	ctx.Continue(func() {
		p.skinMu.Lock()
		p.skin = skin
		p.skinMu.Unlock()
		for _, v := range p.viewers() {
			v.ViewSkin(p)
		}
	})
	ctx.Stop(func() {
		p.session().ViewSkin(p)
	})
}
func (p *Player) Locale() language.Tag {
	return p.locale
}
func (p *Player) Handle(h Handler) {
	p.hMutex.Lock()
	defer p.hMutex.Unlock()
	if h == nil {
		h = NopHandler{}
	}
	p.h = h
}
func (p *Player) Message(a ...interface{}) {
	p.session().SendMessage(format(a))
}