update 1.19.2 bot, chat support
This commit is contained in:
@ -20,7 +20,7 @@
|
||||
// - HealthChange
|
||||
// - Death
|
||||
//
|
||||
// You must manully attach the [EventsListener] to the [Client] as needed.
|
||||
// You must manually attach the [EventsListener] to the [Client] as needed.
|
||||
package basic
|
||||
|
||||
import (
|
||||
@ -38,22 +38,23 @@ type Player struct {
|
||||
isSpawn bool
|
||||
}
|
||||
|
||||
func NewPlayer(c *bot.Client, settings Settings) *Player {
|
||||
b := &Player{c: c, Settings: settings}
|
||||
func NewPlayer(c *bot.Client, settings Settings, events EventsListener) *Player {
|
||||
p := &Player{c: c, Settings: settings}
|
||||
c.Events.AddListener(
|
||||
bot.PacketHandler{Priority: 0, ID: packetid.ClientboundLogin, F: b.handleLoginPacket},
|
||||
bot.PacketHandler{Priority: 0, ID: packetid.ClientboundKeepAlive, F: b.handleKeepAlivePacket},
|
||||
bot.PacketHandler{Priority: 0, ID: packetid.ClientboundPlayerPosition, F: b.handlePlayerPosition},
|
||||
bot.PacketHandler{Priority: 0, ID: packetid.ClientboundRespawn, F: b.handleRespawnPacket},
|
||||
bot.PacketHandler{Priority: 0, ID: packetid.ClientboundLogin, F: p.handleLoginPacket},
|
||||
bot.PacketHandler{Priority: 0, ID: packetid.ClientboundKeepAlive, F: p.handleKeepAlivePacket},
|
||||
bot.PacketHandler{Priority: 0, ID: packetid.ClientboundPlayerPosition, F: p.handlePlayerPosition},
|
||||
bot.PacketHandler{Priority: 0, ID: packetid.ClientboundRespawn, F: p.handleRespawnPacket},
|
||||
)
|
||||
return b
|
||||
events.attach(p)
|
||||
return p
|
||||
}
|
||||
|
||||
func (p *Player) Respawn() error {
|
||||
const PerformRespawn = 0
|
||||
|
||||
err := p.c.Conn.WritePacket(pk.Marshal(
|
||||
packetid.ServerboundClientCommand,
|
||||
int32(packetid.ServerboundClientCommand),
|
||||
pk.VarInt(PerformRespawn),
|
||||
))
|
||||
if err != nil {
|
||||
|
@ -5,35 +5,30 @@ import (
|
||||
"github.com/Tnze/go-mc/chat"
|
||||
"github.com/Tnze/go-mc/data/packetid"
|
||||
pk "github.com/Tnze/go-mc/net/packet"
|
||||
"io"
|
||||
)
|
||||
|
||||
type EventsListener struct {
|
||||
GameStart func() error
|
||||
ChatMsg func(c *PlayerMessage) error
|
||||
SystemMsg func(c chat.Message, overlay bool) error
|
||||
Disconnect func(reason chat.Message) error
|
||||
HealthChange func(health float32) error
|
||||
Death func() error
|
||||
}
|
||||
|
||||
// Attach your event listener to the client.
|
||||
// attach your event listener to the client.
|
||||
// The functions are copied when attaching, and modify on [EventListener] doesn't affect after that.
|
||||
func (e EventsListener) Attach(c *bot.Client) {
|
||||
func (e EventsListener) attach(p *Player) {
|
||||
if e.GameStart != nil {
|
||||
attachJoinGameHandler(c, e.GameStart)
|
||||
}
|
||||
if e.ChatMsg != nil {
|
||||
attachPlayerMsg(c, e.ChatMsg)
|
||||
attachJoinGameHandler(p.c, e.GameStart)
|
||||
}
|
||||
if e.SystemMsg != nil {
|
||||
attachSystemMsg(c, e.SystemMsg)
|
||||
attachSystemMsg(p.c, e.SystemMsg)
|
||||
}
|
||||
if e.Disconnect != nil {
|
||||
attachDisconnect(c, e.Disconnect)
|
||||
attachDisconnect(p.c, e.Disconnect)
|
||||
}
|
||||
if e.HealthChange != nil || e.Death != nil {
|
||||
attachUpdateHealth(c, e.HealthChange, e.Death)
|
||||
attachUpdateHealth(p.c, e.HealthChange, e.Death)
|
||||
}
|
||||
}
|
||||
|
||||
@ -46,60 +41,6 @@ func attachJoinGameHandler(c *bot.Client, handler func() error) {
|
||||
})
|
||||
}
|
||||
|
||||
type PlayerMessage struct {
|
||||
}
|
||||
|
||||
func (p *PlayerMessage) ReadFrom(r io.Reader) (n int64, err error) {
|
||||
// SignedMessageHeader
|
||||
// MessageSignature
|
||||
// SignedMessageBody
|
||||
// Optional<Component>
|
||||
// FilterMask
|
||||
panic("implement me")
|
||||
}
|
||||
|
||||
type ChatType struct {
|
||||
ID int32
|
||||
Name chat.Message
|
||||
TargetName *chat.Message
|
||||
}
|
||||
|
||||
func (c *ChatType) ReadFrom(r io.Reader) (n int64, err error) {
|
||||
var hasTargetName pk.Boolean
|
||||
n1, err := (*pk.VarInt)(&c.ID).ReadFrom(r)
|
||||
if err != nil {
|
||||
return n1, err
|
||||
}
|
||||
n2, err := c.Name.ReadFrom(r)
|
||||
if err != nil {
|
||||
return n1 + n2, err
|
||||
}
|
||||
n3, err := hasTargetName.ReadFrom(r)
|
||||
if err != nil {
|
||||
return n1 + n2 + n3, err
|
||||
}
|
||||
if hasTargetName {
|
||||
c.TargetName = new(chat.Message)
|
||||
n4, err := c.TargetName.ReadFrom(r)
|
||||
return n1 + n2 + n3 + n4, err
|
||||
}
|
||||
return n1 + n2 + n3, nil
|
||||
}
|
||||
|
||||
func attachPlayerMsg(c *bot.Client, handler func(c *PlayerMessage) error) {
|
||||
c.Events.AddListener(bot.PacketHandler{
|
||||
Priority: 64, ID: packetid.ClientboundPlayerChat,
|
||||
F: func(p pk.Packet) error {
|
||||
var message PlayerMessage
|
||||
var chatType ChatType
|
||||
if err := p.Scan(&message, &chatType); err != nil {
|
||||
return Error{err}
|
||||
}
|
||||
return handler(&message)
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func attachSystemMsg(c *bot.Client, handler func(c chat.Message, overlay bool) error) {
|
||||
c.Events.AddListener(bot.PacketHandler{
|
||||
Priority: 64, ID: packetid.ClientboundSystemChat,
|
||||
|
@ -1,6 +1,7 @@
|
||||
package basic
|
||||
|
||||
import (
|
||||
"github.com/Tnze/go-mc/chat"
|
||||
"unsafe"
|
||||
|
||||
"github.com/Tnze/go-mc/data/packetid"
|
||||
@ -46,9 +47,14 @@ type Dimension struct {
|
||||
MonsterSpawnBlockLightLimit int32 `nbt:"monster_spawn_block_light_limit"`
|
||||
}
|
||||
|
||||
type ChatType struct {
|
||||
Chat chat.Decoration `nbt:"chat"`
|
||||
Narration chat.Decoration `nbt:"narration"`
|
||||
}
|
||||
|
||||
type RegistryCodec struct {
|
||||
// What is Below? (wiki.vg)
|
||||
ChatType Registry[nbt.RawMessage] `nbt:"minecraft:chat_type"`
|
||||
ChatType Registry[ChatType] `nbt:"minecraft:chat_type"`
|
||||
DimensionType Registry[Dimension] `nbt:"minecraft:dimension_type"`
|
||||
WorldGenBiome Registry[nbt.RawMessage] `nbt:"minecraft:worldgen/biome"`
|
||||
}
|
||||
@ -71,6 +77,18 @@ func (r *Registry[E]) Find(name string) *E {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *Registry[E]) FindByID(id int32) *E {
|
||||
if id >= 0 && id < int32(len(r.Value)) && r.Value[id].ID == id {
|
||||
return &r.Value[id].Element
|
||||
}
|
||||
for i := range r.Value {
|
||||
if r.Value[i].ID == id {
|
||||
return &r.Value[i].Element
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type PlayerInfo struct {
|
||||
EID int32 // The player's Entity ID (EID).
|
||||
Hardcore bool // Is hardcore
|
||||
@ -106,7 +124,7 @@ func (p *Player) handleLoginPacket(packet pk.Packet) error {
|
||||
return Error{err}
|
||||
}
|
||||
err = p.c.Conn.WritePacket(pk.Marshal( //PluginMessage packet
|
||||
packetid.ServerboundCustomPayload,
|
||||
int32(packetid.ServerboundCustomPayload),
|
||||
pk.Identifier("minecraft:brand"),
|
||||
pk.String(p.Settings.Brand),
|
||||
))
|
||||
@ -115,7 +133,7 @@ func (p *Player) handleLoginPacket(packet pk.Packet) error {
|
||||
}
|
||||
|
||||
err = p.c.Conn.WritePacket(pk.Marshal(
|
||||
packetid.ServerboundClientInformation, // Client settings
|
||||
int32(packetid.ServerboundClientInformation), // Client settings
|
||||
pk.String(p.Settings.Locale),
|
||||
pk.Byte(p.Settings.ViewDistance),
|
||||
pk.VarInt(p.Settings.ChatMode),
|
||||
|
@ -12,7 +12,7 @@ func (p Player) handleKeepAlivePacket(packet pk.Packet) error {
|
||||
}
|
||||
// Response
|
||||
err := p.c.Conn.WritePacket(pk.Packet{
|
||||
ID: packetid.ServerboundKeepAlive,
|
||||
ID: int32(packetid.ServerboundKeepAlive),
|
||||
Data: packet.Data,
|
||||
})
|
||||
if err != nil {
|
||||
|
168
bot/chat/chat.go
Normal file
168
bot/chat/chat.go
Normal file
@ -0,0 +1,168 @@
|
||||
package chat
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"time"
|
||||
|
||||
"github.com/Tnze/go-mc/bot"
|
||||
"github.com/Tnze/go-mc/bot/basic"
|
||||
"github.com/Tnze/go-mc/chat"
|
||||
"github.com/Tnze/go-mc/data/packetid"
|
||||
pk "github.com/Tnze/go-mc/net/packet"
|
||||
"github.com/google/uuid"
|
||||
)
|
||||
|
||||
type Chat struct {
|
||||
c *bot.Client
|
||||
p *basic.Player
|
||||
}
|
||||
|
||||
func NewChat(c *bot.Client, p *basic.Player, events EventsHandler) *Chat {
|
||||
attachPlayerMsg(c, p, events.PlayerChatMessage)
|
||||
return &Chat{c, p}
|
||||
}
|
||||
|
||||
func attachPlayerMsg(c *bot.Client, p *basic.Player, handler func(msg chat.Message) error) {
|
||||
c.Events.AddListener(bot.PacketHandler{
|
||||
Priority: 64, ID: packetid.ClientboundPlayerChat,
|
||||
F: func(packet pk.Packet) error {
|
||||
var message PlayerMessage
|
||||
if err := packet.Scan(&message); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var content chat.Message
|
||||
if message.content.formatted != nil {
|
||||
content = *message.content.formatted
|
||||
} else {
|
||||
content = chat.Text(message.content.plainMsg)
|
||||
}
|
||||
|
||||
ct := p.WorldInfo.RegistryCodec.ChatType.FindByID(message.chatType.ID)
|
||||
if ct == nil {
|
||||
return fmt.Errorf("chat type %d not found", message.chatType.ID)
|
||||
}
|
||||
|
||||
msg := (*chat.Type)(&message.chatType).Decorate(content, &ct.Chat)
|
||||
return handler(msg)
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
type PlayerMessage struct {
|
||||
// SignedMessageHeader
|
||||
signature []byte
|
||||
sender uuid.UUID
|
||||
// MessageSignature
|
||||
msgSignature []byte
|
||||
// SignedMessageBody
|
||||
content msgContent
|
||||
timestamp time.Time
|
||||
salt int64
|
||||
prevMessages []prevMsg
|
||||
// Optional<Component>
|
||||
unsignedContent *chat.Message
|
||||
// FilterMask
|
||||
filterType int32
|
||||
filterSet pk.BitSet
|
||||
// ChatType
|
||||
chatType chatType
|
||||
}
|
||||
|
||||
func (p *PlayerMessage) String() string {
|
||||
return p.content.plainMsg
|
||||
}
|
||||
|
||||
func (p *PlayerMessage) ReadFrom(r io.Reader) (n int64, err error) {
|
||||
var hasMsgSign, hasUnsignedContent pk.Boolean
|
||||
var timestamp pk.Long
|
||||
var unsignedContent chat.Message
|
||||
n, err = pk.Tuple{
|
||||
&hasMsgSign, pk.Opt{Has: &hasMsgSign,
|
||||
Field: (*pk.ByteArray)(&p.signature),
|
||||
},
|
||||
(*pk.UUID)(&p.sender),
|
||||
(*pk.ByteArray)(&p.msgSignature),
|
||||
&p.content,
|
||||
×tamp,
|
||||
(*pk.Long)(&p.salt),
|
||||
pk.Array(&p.prevMessages),
|
||||
&hasUnsignedContent, pk.Opt{Has: &hasUnsignedContent,
|
||||
Field: &unsignedContent,
|
||||
},
|
||||
(*pk.VarInt)(&p.filterType),
|
||||
pk.Opt{
|
||||
Has: func() bool { return p.filterType == 2 },
|
||||
Field: &p.filterSet,
|
||||
},
|
||||
&p.chatType,
|
||||
}.ReadFrom(r)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
p.timestamp = time.UnixMilli(int64(timestamp))
|
||||
if hasUnsignedContent {
|
||||
p.unsignedContent = &unsignedContent
|
||||
}
|
||||
return n, err
|
||||
}
|
||||
|
||||
type msgContent struct {
|
||||
plainMsg string
|
||||
formatted *chat.Message
|
||||
}
|
||||
|
||||
func (m *msgContent) ReadFrom(r io.Reader) (n int64, err error) {
|
||||
var hasFormatted pk.Boolean
|
||||
n1, err := (*pk.String)(&m.plainMsg).ReadFrom(r)
|
||||
if err != nil {
|
||||
return n1, err
|
||||
}
|
||||
n2, err := hasFormatted.ReadFrom(r)
|
||||
if err != nil {
|
||||
return n1 + n2, err
|
||||
}
|
||||
if hasFormatted {
|
||||
m.formatted = new(chat.Message)
|
||||
n3, err := m.formatted.ReadFrom(r)
|
||||
return n1 + n2 + n3, err
|
||||
}
|
||||
return n1 + n2, err
|
||||
}
|
||||
|
||||
type prevMsg struct {
|
||||
sender uuid.UUID
|
||||
signature []byte
|
||||
}
|
||||
|
||||
func (p *prevMsg) ReadFrom(r io.Reader) (n int64, err error) {
|
||||
return pk.Tuple{
|
||||
(*pk.UUID)(&p.sender),
|
||||
(*pk.ByteArray)(&p.signature),
|
||||
}.ReadFrom(r)
|
||||
}
|
||||
|
||||
type chatType chat.Type
|
||||
|
||||
func (c *chatType) ReadFrom(r io.Reader) (n int64, err error) {
|
||||
var hasTargetName pk.Boolean
|
||||
n1, err := (*pk.VarInt)(&c.ID).ReadFrom(r)
|
||||
if err != nil {
|
||||
return n1, err
|
||||
}
|
||||
n2, err := c.SenderName.ReadFrom(r)
|
||||
if err != nil {
|
||||
return n1 + n2, err
|
||||
}
|
||||
n3, err := hasTargetName.ReadFrom(r)
|
||||
if err != nil {
|
||||
return n1 + n2 + n3, err
|
||||
}
|
||||
if hasTargetName {
|
||||
c.TargetName = new(chat.Message)
|
||||
n4, err := c.TargetName.ReadFrom(r)
|
||||
return n1 + n2 + n3 + n4, err
|
||||
}
|
||||
return n1 + n2 + n3, nil
|
||||
}
|
7
bot/chat/events.go
Normal file
7
bot/chat/events.go
Normal file
@ -0,0 +1,7 @@
|
||||
package chat
|
||||
|
||||
import "github.com/Tnze/go-mc/chat"
|
||||
|
||||
type EventsHandler struct {
|
||||
PlayerChatMessage func(msg chat.Message) error
|
||||
}
|
@ -1,6 +1,7 @@
|
||||
package bot
|
||||
|
||||
import (
|
||||
"github.com/Tnze/go-mc/data/packetid"
|
||||
"github.com/Tnze/go-mc/net"
|
||||
"github.com/Tnze/go-mc/yggdrasil/user"
|
||||
"github.com/google/uuid"
|
||||
@ -33,7 +34,7 @@ func (c *Client) Close() error {
|
||||
func NewClient() *Client {
|
||||
return &Client{
|
||||
Auth: Auth{Name: "Steve"},
|
||||
Events: Events{handlers: make(map[int32]*handlerHeap)},
|
||||
Events: Events{handlers: make(map[packetid.ClientboundPacketID]*handlerHeap)},
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,12 +1,13 @@
|
||||
package bot
|
||||
|
||||
import (
|
||||
"github.com/Tnze/go-mc/data/packetid"
|
||||
pk "github.com/Tnze/go-mc/net/packet"
|
||||
)
|
||||
|
||||
type Events struct {
|
||||
generic *handlerHeap // for every packet
|
||||
handlers map[int32]*handlerHeap // for specific packet id only
|
||||
generic *handlerHeap // for every packet
|
||||
handlers map[packetid.ClientboundPacketID]*handlerHeap // for specific packet id only
|
||||
}
|
||||
|
||||
func (e *Events) AddListener(listeners ...PacketHandler) {
|
||||
@ -36,7 +37,7 @@ func (e *Events) AddGeneric(listeners ...PacketHandler) {
|
||||
|
||||
type PacketHandlerFunc func(p pk.Packet) error
|
||||
type PacketHandler struct {
|
||||
ID int32
|
||||
ID packetid.ClientboundPacketID
|
||||
Priority int
|
||||
F func(p pk.Packet) error
|
||||
}
|
||||
|
@ -2,6 +2,8 @@ package bot
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/Tnze/go-mc/data/packetid"
|
||||
pk "github.com/Tnze/go-mc/net/packet"
|
||||
)
|
||||
|
||||
@ -24,12 +26,12 @@ func (c *Client) HandleGame() error {
|
||||
}
|
||||
|
||||
type PacketHandlerError struct {
|
||||
ID int32
|
||||
ID packetid.ClientboundPacketID
|
||||
Err error
|
||||
}
|
||||
|
||||
func (d PacketHandlerError) Error() string {
|
||||
return fmt.Sprintf("handle packet 0x%X error: %v", d.ID, d.Err)
|
||||
return fmt.Sprintf("handle packet %v error: %v", d.ID, d.Err)
|
||||
}
|
||||
|
||||
func (d PacketHandlerError) Unwrap() error {
|
||||
@ -37,18 +39,19 @@ func (d PacketHandlerError) Unwrap() error {
|
||||
}
|
||||
|
||||
func (c *Client) handlePacket(p pk.Packet) (err error) {
|
||||
packetID := packetid.ClientboundPacketID(p.ID)
|
||||
if c.Events.generic != nil {
|
||||
for _, handler := range *c.Events.generic {
|
||||
if err = handler.F(p); err != nil {
|
||||
return PacketHandlerError{ID: p.ID, Err: err}
|
||||
return PacketHandlerError{ID: packetID, Err: err}
|
||||
}
|
||||
}
|
||||
}
|
||||
if listeners := c.Events.handlers[p.ID]; listeners != nil {
|
||||
if listeners := c.Events.handlers[packetID]; listeners != nil {
|
||||
for _, handler := range *listeners {
|
||||
err = handler.F(p)
|
||||
if err != nil {
|
||||
return PacketHandlerError{ID: p.ID, Err: err}
|
||||
return PacketHandlerError{ID: packetID, Err: err}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
51
chat/decoration.go
Normal file
51
chat/decoration.go
Normal file
@ -0,0 +1,51 @@
|
||||
package chat
|
||||
|
||||
type Decoration struct {
|
||||
TranslationKey string `nbt:"translation_key"`
|
||||
Parameters []string `nbt:"parameters"`
|
||||
Style struct {
|
||||
Bold bool `nbt:"bold"`
|
||||
Italic bool `nbt:"italic"`
|
||||
UnderLined bool `nbt:"underlined"`
|
||||
StrikeThrough bool `nbt:"strikethrough"`
|
||||
Obfuscated bool `nbt:"obfuscated"`
|
||||
Color string `nbt:"color"`
|
||||
Insertion string `nbt:"insertion"`
|
||||
Font string `nbt:"font"`
|
||||
} `nbt:"style"`
|
||||
}
|
||||
|
||||
type Type struct {
|
||||
ID int32
|
||||
SenderName Message
|
||||
TargetName *Message
|
||||
}
|
||||
|
||||
func (t *Type) Decorate(content Message, d *Decoration) (msg Message) {
|
||||
with := make([]Message, len(d.Parameters))
|
||||
for i, para := range d.Parameters {
|
||||
switch para {
|
||||
case "sender":
|
||||
with[i] = t.SenderName
|
||||
case "target":
|
||||
with[i] = *t.TargetName
|
||||
case "content":
|
||||
with[i] = content
|
||||
default:
|
||||
with[i] = Text("<nil>")
|
||||
}
|
||||
}
|
||||
return Message{
|
||||
Translate: d.TranslationKey,
|
||||
With: with,
|
||||
|
||||
Bold: d.Style.Bold,
|
||||
Italic: d.Style.Italic,
|
||||
UnderLined: d.Style.UnderLined,
|
||||
StrikeThrough: d.Style.StrikeThrough,
|
||||
Obfuscated: d.Style.Obfuscated,
|
||||
Font: d.Style.Font,
|
||||
Color: d.Style.Color,
|
||||
Insertion: d.Style.Insertion,
|
||||
}
|
||||
}
|
@ -22,10 +22,8 @@ import (
|
||||
pk "github.com/Tnze/go-mc/net/packet"
|
||||
)
|
||||
|
||||
type Type int32
|
||||
|
||||
const (
|
||||
Chat Type = iota
|
||||
Chat = iota
|
||||
System
|
||||
GameInfo
|
||||
SayCommand
|
||||
@ -76,9 +74,9 @@ type Message struct {
|
||||
ClickEvent *ClickEvent `json:"clickEvent,omitempty"`
|
||||
HoverEvent *HoverEvent `json:"hoverEvent,omitempty"`
|
||||
|
||||
Translate string `json:"translate,omitempty"`
|
||||
With []json.RawMessage `json:"with,omitempty"`
|
||||
Extra []Message `json:"extra,omitempty"`
|
||||
Translate string `json:"translate,omitempty"`
|
||||
With []Message `json:"with,omitempty"`
|
||||
Extra []Message `json:"extra,omitempty"`
|
||||
}
|
||||
|
||||
// Same as Message, but "Text" is omitempty
|
||||
@ -98,9 +96,9 @@ type translateMsg struct {
|
||||
ClickEvent *ClickEvent `json:"clickEvent,omitempty"`
|
||||
HoverEvent *HoverEvent `json:"hoverEvent,omitempty"`
|
||||
|
||||
Translate string `json:"translate"`
|
||||
With []json.RawMessage `json:"with,omitempty"`
|
||||
Extra []Message `json:"extra,omitempty"`
|
||||
Translate string `json:"translate"`
|
||||
With []Message `json:"with,omitempty"`
|
||||
Extra []Message `json:"extra,omitempty"`
|
||||
}
|
||||
|
||||
type jsonMsg Message
|
||||
@ -180,10 +178,7 @@ func Text(str string) Message {
|
||||
|
||||
func TranslateMsg(key string, with ...Message) (m Message) {
|
||||
m.Translate = key
|
||||
m.With = make([]json.RawMessage, len(with))
|
||||
for i, v := range with {
|
||||
m.With[i], _ = json.Marshal(v)
|
||||
}
|
||||
m.With = with
|
||||
return
|
||||
}
|
||||
|
||||
@ -250,9 +245,7 @@ func (m Message) ClearString() string {
|
||||
if m.Translate != "" {
|
||||
args := make([]interface{}, len(m.With))
|
||||
for i, v := range m.With {
|
||||
var arg Message
|
||||
_ = arg.UnmarshalJSON(v) //ignore error
|
||||
args[i] = arg.ClearString()
|
||||
args[i] = v.ClearString()
|
||||
}
|
||||
|
||||
_, _ = fmt.Fprintf(&msg, translateMap[m.Translate], args...)
|
||||
@ -297,9 +290,7 @@ func (m Message) String() string {
|
||||
if m.Translate != "" {
|
||||
args := make([]interface{}, len(m.With))
|
||||
for i, v := range m.With {
|
||||
var arg Message
|
||||
_ = arg.UnmarshalJSON(v) //ignore error
|
||||
args[i] = arg
|
||||
args[i] = v
|
||||
}
|
||||
|
||||
_, _ = fmt.Fprintf(&msg, translateMap[m.Translate], args...)
|
||||
|
130
data/packetid/clientboundpacketid_string.go
Normal file
130
data/packetid/clientboundpacketid_string.go
Normal file
@ -0,0 +1,130 @@
|
||||
// Code generated by "stringer -type ClientboundPacketID"; DO NOT EDIT.
|
||||
|
||||
package packetid
|
||||
|
||||
import "strconv"
|
||||
|
||||
func _() {
|
||||
// An "invalid array index" compiler error signifies that the constant values have changed.
|
||||
// Re-run the stringer command to generate them again.
|
||||
var x [1]struct{}
|
||||
_ = x[ClientboundAddEntity-0]
|
||||
_ = x[ClientboundAddExperienceOrb-1]
|
||||
_ = x[ClientboundAddPlayer-2]
|
||||
_ = x[ClientboundAnimate-3]
|
||||
_ = x[ClientboundAwardStats-4]
|
||||
_ = x[ClientboundBlockChangedAck-5]
|
||||
_ = x[ClientboundBlockDestruction-6]
|
||||
_ = x[ClientboundBlockEntityData-7]
|
||||
_ = x[ClientboundBlockEvent-8]
|
||||
_ = x[ClientboundBlockUpdate-9]
|
||||
_ = x[ClientboundBossEvent-10]
|
||||
_ = x[ClientboundChangeDifficulty-11]
|
||||
_ = x[ClientboundChatPreview-12]
|
||||
_ = x[ClientboundClearTitles-13]
|
||||
_ = x[ClientboundCommandSuggestions-14]
|
||||
_ = x[ClientboundCommands-15]
|
||||
_ = x[ClientboundContainerClose-16]
|
||||
_ = x[ClientboundContainerSetContent-17]
|
||||
_ = x[ClientboundContainerSetData-18]
|
||||
_ = x[ClientboundContainerSetSlot-19]
|
||||
_ = x[ClientboundCooldown-20]
|
||||
_ = x[ClientboundCustomChatCompletions-21]
|
||||
_ = x[ClientboundCustomPayload-22]
|
||||
_ = x[ClientboundCustomSound-23]
|
||||
_ = x[ClientboundDeleteChat-24]
|
||||
_ = x[ClientboundDisconnect-25]
|
||||
_ = x[ClientboundEntityEvent-26]
|
||||
_ = x[ClientboundExplode-27]
|
||||
_ = x[ClientboundForgetLevelChunk-28]
|
||||
_ = x[ClientboundGameEvent-29]
|
||||
_ = x[ClientboundHorseScreenOpen-30]
|
||||
_ = x[ClientboundInitializeBorder-31]
|
||||
_ = x[ClientboundKeepAlive-32]
|
||||
_ = x[ClientboundLevelChunkWithLight-33]
|
||||
_ = x[ClientboundLevelEvent-34]
|
||||
_ = x[ClientboundLevelParticles-35]
|
||||
_ = x[ClientboundLightUpdate-36]
|
||||
_ = x[ClientboundLogin-37]
|
||||
_ = x[ClientboundMapItemData-38]
|
||||
_ = x[ClientboundMerchantOffers-39]
|
||||
_ = x[ClientboundMoveEntityPos-40]
|
||||
_ = x[ClientboundMoveEntityPosRot-41]
|
||||
_ = x[ClientboundMoveEntityRot-42]
|
||||
_ = x[ClientboundMoveVehicle-43]
|
||||
_ = x[ClientboundOpenBook-44]
|
||||
_ = x[ClientboundOpenScreen-45]
|
||||
_ = x[ClientboundOpenSignEditor-46]
|
||||
_ = x[ClientboundPing-47]
|
||||
_ = x[ClientboundPlaceGhostRecipe-48]
|
||||
_ = x[ClientboundPlayerAbilities-49]
|
||||
_ = x[ClientboundPlayerChatHeader-50]
|
||||
_ = x[ClientboundPlayerChat-51]
|
||||
_ = x[ClientboundPlayerCombatEnd-52]
|
||||
_ = x[ClientboundPlayerCombatEnter-53]
|
||||
_ = x[ClientboundPlayerCombatKill-54]
|
||||
_ = x[ClientboundPlayerInfo-55]
|
||||
_ = x[ClientboundPlayerLookAt-56]
|
||||
_ = x[ClientboundPlayerPosition-57]
|
||||
_ = x[ClientboundRecipe-58]
|
||||
_ = x[ClientboundRemoveEntities-59]
|
||||
_ = x[ClientboundRemoveMobEffect-60]
|
||||
_ = x[ClientboundResourcePack-61]
|
||||
_ = x[ClientboundRespawn-62]
|
||||
_ = x[ClientboundRotateHead-63]
|
||||
_ = x[ClientboundSectionBlocksUpdate-64]
|
||||
_ = x[ClientboundSelectAdvancementsTab-65]
|
||||
_ = x[ClientboundServerData-66]
|
||||
_ = x[ClientboundSetActionBarText-67]
|
||||
_ = x[ClientboundSetBorderCenter-68]
|
||||
_ = x[ClientboundSetBorderLerpSize-69]
|
||||
_ = x[ClientboundSetBorderSize-70]
|
||||
_ = x[ClientboundSetBorderWarningDelay-71]
|
||||
_ = x[ClientboundSetBorderWarningDistance-72]
|
||||
_ = x[ClientboundSetCamera-73]
|
||||
_ = x[ClientboundSetCarriedItem-74]
|
||||
_ = x[ClientboundSetChunkCacheCenter-75]
|
||||
_ = x[ClientboundSetChunkCacheRadius-76]
|
||||
_ = x[ClientboundSetDefaultSpawnPosition-77]
|
||||
_ = x[ClientboundSetDisplayChatPreview-78]
|
||||
_ = x[ClientboundSetDisplayObjective-79]
|
||||
_ = x[ClientboundSetEntityData-80]
|
||||
_ = x[ClientboundSetEntityLink-81]
|
||||
_ = x[ClientboundSetEntityMotion-82]
|
||||
_ = x[ClientboundSetEquipment-83]
|
||||
_ = x[ClientboundSetExperience-84]
|
||||
_ = x[ClientboundSetHealth-85]
|
||||
_ = x[ClientboundSetObjective-86]
|
||||
_ = x[ClientboundSetPassengers-87]
|
||||
_ = x[ClientboundSetPlayerTeam-88]
|
||||
_ = x[ClientboundSetScore-89]
|
||||
_ = x[ClientboundSetSimulationDistance-90]
|
||||
_ = x[ClientboundSetSubtitleText-91]
|
||||
_ = x[ClientboundSetTime-92]
|
||||
_ = x[ClientboundSetTitleText-93]
|
||||
_ = x[ClientboundSetTitlesAnimation-94]
|
||||
_ = x[ClientboundSoundEntity-95]
|
||||
_ = x[ClientboundSound-96]
|
||||
_ = x[ClientboundStopSound-97]
|
||||
_ = x[ClientboundSystemChat-98]
|
||||
_ = x[ClientboundTabList-99]
|
||||
_ = x[ClientboundTagQuery-100]
|
||||
_ = x[ClientboundTakeItemEntity-101]
|
||||
_ = x[ClientboundTeleportEntity-102]
|
||||
_ = x[ClientboundUpdateAdvancements-103]
|
||||
_ = x[ClientboundUpdateAttributes-104]
|
||||
_ = x[ClientboundUpdateMobEffect-105]
|
||||
_ = x[ClientboundUpdateRecipes-106]
|
||||
_ = x[ClientboundUpdateTags-107]
|
||||
}
|
||||
|
||||
const _ClientboundPacketID_name = "ClientboundAddEntityClientboundAddExperienceOrbClientboundAddPlayerClientboundAnimateClientboundAwardStatsClientboundBlockChangedAckClientboundBlockDestructionClientboundBlockEntityDataClientboundBlockEventClientboundBlockUpdateClientboundBossEventClientboundChangeDifficultyClientboundChatPreviewClientboundClearTitlesClientboundCommandSuggestionsClientboundCommandsClientboundContainerCloseClientboundContainerSetContentClientboundContainerSetDataClientboundContainerSetSlotClientboundCooldownClientboundCustomChatCompletionsClientboundCustomPayloadClientboundCustomSoundClientboundDeleteChatClientboundDisconnectClientboundEntityEventClientboundExplodeClientboundForgetLevelChunkClientboundGameEventClientboundHorseScreenOpenClientboundInitializeBorderClientboundKeepAliveClientboundLevelChunkWithLightClientboundLevelEventClientboundLevelParticlesClientboundLightUpdateClientboundLoginClientboundMapItemDataClientboundMerchantOffersClientboundMoveEntityPosClientboundMoveEntityPosRotClientboundMoveEntityRotClientboundMoveVehicleClientboundOpenBookClientboundOpenScreenClientboundOpenSignEditorClientboundPingClientboundPlaceGhostRecipeClientboundPlayerAbilitiesClientboundPlayerChatHeaderClientboundPlayerChatClientboundPlayerCombatEndClientboundPlayerCombatEnterClientboundPlayerCombatKillClientboundPlayerInfoClientboundPlayerLookAtClientboundPlayerPositionClientboundRecipeClientboundRemoveEntitiesClientboundRemoveMobEffectClientboundResourcePackClientboundRespawnClientboundRotateHeadClientboundSectionBlocksUpdateClientboundSelectAdvancementsTabClientboundServerDataClientboundSetActionBarTextClientboundSetBorderCenterClientboundSetBorderLerpSizeClientboundSetBorderSizeClientboundSetBorderWarningDelayClientboundSetBorderWarningDistanceClientboundSetCameraClientboundSetCarriedItemClientboundSetChunkCacheCenterClientboundSetChunkCacheRadiusClientboundSetDefaultSpawnPositionClientboundSetDisplayChatPreviewClientboundSetDisplayObjectiveClientboundSetEntityDataClientboundSetEntityLinkClientboundSetEntityMotionClientboundSetEquipmentClientboundSetExperienceClientboundSetHealthClientboundSetObjectiveClientboundSetPassengersClientboundSetPlayerTeamClientboundSetScoreClientboundSetSimulationDistanceClientboundSetSubtitleTextClientboundSetTimeClientboundSetTitleTextClientboundSetTitlesAnimationClientboundSoundEntityClientboundSoundClientboundStopSoundClientboundSystemChatClientboundTabListClientboundTagQueryClientboundTakeItemEntityClientboundTeleportEntityClientboundUpdateAdvancementsClientboundUpdateAttributesClientboundUpdateMobEffectClientboundUpdateRecipesClientboundUpdateTags"
|
||||
|
||||
var _ClientboundPacketID_index = [...]uint16{0, 20, 47, 67, 85, 106, 132, 159, 185, 206, 228, 248, 275, 297, 319, 348, 367, 392, 422, 449, 476, 495, 527, 551, 573, 594, 615, 637, 655, 682, 702, 728, 755, 775, 805, 826, 851, 873, 889, 911, 936, 960, 987, 1011, 1033, 1052, 1073, 1098, 1113, 1140, 1166, 1193, 1214, 1240, 1268, 1295, 1316, 1339, 1364, 1381, 1406, 1432, 1455, 1473, 1494, 1524, 1556, 1577, 1604, 1630, 1658, 1682, 1714, 1749, 1769, 1794, 1824, 1854, 1888, 1920, 1950, 1974, 1998, 2024, 2047, 2071, 2091, 2114, 2138, 2162, 2181, 2213, 2239, 2257, 2280, 2309, 2331, 2347, 2367, 2388, 2406, 2425, 2450, 2475, 2504, 2531, 2557, 2581, 2602}
|
||||
|
||||
func (i ClientboundPacketID) String() string {
|
||||
if i < 0 || i >= ClientboundPacketID(len(_ClientboundPacketID_index)-1) {
|
||||
return "ClientboundPacketID(" + strconv.FormatInt(int64(i), 10) + ")"
|
||||
}
|
||||
return _ClientboundPacketID_name[_ClientboundPacketID_index[i]:_ClientboundPacketID_index[i+1]]
|
||||
}
|
@ -1,5 +1,11 @@
|
||||
package packetid
|
||||
|
||||
//go:generate stringer -type ClientboundPacketID
|
||||
//go:generate stringer -type ServerboundPacketID
|
||||
|
||||
type ClientboundPacketID int32
|
||||
type ServerboundPacketID int32
|
||||
|
||||
// Login Clientbound
|
||||
const (
|
||||
LoginDisconnect = iota
|
||||
@ -30,7 +36,7 @@ const (
|
||||
|
||||
// Game Clientbound
|
||||
const (
|
||||
ClientboundAddEntity = iota
|
||||
ClientboundAddEntity ClientboundPacketID = iota
|
||||
ClientboundAddExperienceOrb
|
||||
ClientboundAddPlayer
|
||||
ClientboundAnimate
|
||||
@ -142,7 +148,7 @@ const (
|
||||
|
||||
// Game Serverbound
|
||||
const (
|
||||
ServerboundAcceptTeleportation = iota
|
||||
ServerboundAcceptTeleportation ServerboundPacketID = iota
|
||||
ServerboundBlockEntityTagQuery
|
||||
ServerboundChangeDifficulty
|
||||
ServerboundChatAck
|
||||
|
73
data/packetid/serverboundpacketid_string.go
Normal file
73
data/packetid/serverboundpacketid_string.go
Normal file
@ -0,0 +1,73 @@
|
||||
// Code generated by "stringer -type ServerboundPacketID"; DO NOT EDIT.
|
||||
|
||||
package packetid
|
||||
|
||||
import "strconv"
|
||||
|
||||
func _() {
|
||||
// An "invalid array index" compiler error signifies that the constant values have changed.
|
||||
// Re-run the stringer command to generate them again.
|
||||
var x [1]struct{}
|
||||
_ = x[ServerboundAcceptTeleportation-0]
|
||||
_ = x[ServerboundBlockEntityTagQuery-1]
|
||||
_ = x[ServerboundChangeDifficulty-2]
|
||||
_ = x[ServerboundChatAck-3]
|
||||
_ = x[ServerboundChatCommand-4]
|
||||
_ = x[ServerboundChat-5]
|
||||
_ = x[ServerboundChatPreview-6]
|
||||
_ = x[ServerboundClientCommand-7]
|
||||
_ = x[ServerboundClientInformation-8]
|
||||
_ = x[ServerboundCommandSuggestion-9]
|
||||
_ = x[ServerboundContainerButtonClick-10]
|
||||
_ = x[ServerboundContainerClick-11]
|
||||
_ = x[ServerboundContainerClose-12]
|
||||
_ = x[ServerboundCustomPayload-13]
|
||||
_ = x[ServerboundEditBook-14]
|
||||
_ = x[ServerboundEntityTagQuery-15]
|
||||
_ = x[ServerboundInteract-16]
|
||||
_ = x[ServerboundJigsawGenerate-17]
|
||||
_ = x[ServerboundKeepAlive-18]
|
||||
_ = x[ServerboundLockDifficulty-19]
|
||||
_ = x[ServerboundMovePlayerPos-20]
|
||||
_ = x[ServerboundMovePlayerPosRot-21]
|
||||
_ = x[ServerboundMovePlayerRot-22]
|
||||
_ = x[ServerboundMovePlayerStatusOnly-23]
|
||||
_ = x[ServerboundMoveVehicle-24]
|
||||
_ = x[ServerboundPaddleBoat-25]
|
||||
_ = x[ServerboundPickItem-26]
|
||||
_ = x[ServerboundPlaceRecipe-27]
|
||||
_ = x[ServerboundPlayerAbilities-28]
|
||||
_ = x[ServerboundPlayerAction-29]
|
||||
_ = x[ServerboundPlayerCommand-30]
|
||||
_ = x[ServerboundPlayerInput-31]
|
||||
_ = x[ServerboundPong-32]
|
||||
_ = x[ServerboundRecipeBookChangeSettings-33]
|
||||
_ = x[ServerboundRecipeBookSeenRecipe-34]
|
||||
_ = x[ServerboundRenameItem-35]
|
||||
_ = x[ServerboundResourcePack-36]
|
||||
_ = x[ServerboundSeenAdvancements-37]
|
||||
_ = x[ServerboundSelectTrade-38]
|
||||
_ = x[ServerboundSetBeacon-39]
|
||||
_ = x[ServerboundSetCarriedItem-40]
|
||||
_ = x[ServerboundSetCommandBlock-41]
|
||||
_ = x[ServerboundSetCommandMinecart-42]
|
||||
_ = x[ServerboundSetCreativeModeSlot-43]
|
||||
_ = x[ServerboundSetJigsawBlock-44]
|
||||
_ = x[ServerboundSetStructureBlock-45]
|
||||
_ = x[ServerboundSignUpdate-46]
|
||||
_ = x[ServerboundSwing-47]
|
||||
_ = x[ServerboundTeleportToEntity-48]
|
||||
_ = x[ServerboundUseItemOn-49]
|
||||
_ = x[ServerboundUseItem-50]
|
||||
}
|
||||
|
||||
const _ServerboundPacketID_name = "ServerboundAcceptTeleportationServerboundBlockEntityTagQueryServerboundChangeDifficultyServerboundChatAckServerboundChatCommandServerboundChatServerboundChatPreviewServerboundClientCommandServerboundClientInformationServerboundCommandSuggestionServerboundContainerButtonClickServerboundContainerClickServerboundContainerCloseServerboundCustomPayloadServerboundEditBookServerboundEntityTagQueryServerboundInteractServerboundJigsawGenerateServerboundKeepAliveServerboundLockDifficultyServerboundMovePlayerPosServerboundMovePlayerPosRotServerboundMovePlayerRotServerboundMovePlayerStatusOnlyServerboundMoveVehicleServerboundPaddleBoatServerboundPickItemServerboundPlaceRecipeServerboundPlayerAbilitiesServerboundPlayerActionServerboundPlayerCommandServerboundPlayerInputServerboundPongServerboundRecipeBookChangeSettingsServerboundRecipeBookSeenRecipeServerboundRenameItemServerboundResourcePackServerboundSeenAdvancementsServerboundSelectTradeServerboundSetBeaconServerboundSetCarriedItemServerboundSetCommandBlockServerboundSetCommandMinecartServerboundSetCreativeModeSlotServerboundSetJigsawBlockServerboundSetStructureBlockServerboundSignUpdateServerboundSwingServerboundTeleportToEntityServerboundUseItemOnServerboundUseItem"
|
||||
|
||||
var _ServerboundPacketID_index = [...]uint16{0, 30, 60, 87, 105, 127, 142, 164, 188, 216, 244, 275, 300, 325, 349, 368, 393, 412, 437, 457, 482, 506, 533, 557, 588, 610, 631, 650, 672, 698, 721, 745, 767, 782, 817, 848, 869, 892, 919, 941, 961, 986, 1012, 1041, 1071, 1096, 1124, 1145, 1161, 1188, 1208, 1226}
|
||||
|
||||
func (i ServerboundPacketID) String() string {
|
||||
if i < 0 || i >= ServerboundPacketID(len(_ServerboundPacketID_index)-1) {
|
||||
return "ServerboundPacketID(" + strconv.FormatInt(int64(i), 10) + ")"
|
||||
}
|
||||
return _ServerboundPacketID_name[_ServerboundPacketID_index[i]:_ServerboundPacketID_index[i+1]]
|
||||
}
|
@ -1,6 +1,7 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
botchat "github.com/Tnze/go-mc/bot/chat"
|
||||
"log"
|
||||
"time"
|
||||
|
||||
@ -17,8 +18,9 @@ import (
|
||||
const timeout = 45
|
||||
|
||||
var (
|
||||
c *bot.Client
|
||||
p *basic.Player
|
||||
c *bot.Client
|
||||
p *basic.Player
|
||||
bc *botchat.Chat
|
||||
|
||||
watch chan time.Time
|
||||
)
|
||||
@ -26,16 +28,16 @@ var (
|
||||
func main() {
|
||||
//log.SetOutput(colorable.NewColorableStdout()) // optional for colorable output
|
||||
c = bot.NewClient()
|
||||
p = basic.NewPlayer(c, basic.DefaultSettings)
|
||||
|
||||
//Register event handlers
|
||||
basic.EventsListener{
|
||||
p = basic.NewPlayer(c, basic.DefaultSettings, basic.EventsListener{
|
||||
GameStart: onGameStart,
|
||||
ChatMsg: onChatMsg,
|
||||
SystemMsg: onSystemMsg,
|
||||
Disconnect: onDisconnect,
|
||||
Death: onDeath,
|
||||
}.Attach(c)
|
||||
})
|
||||
bc = botchat.NewChat(c, p, botchat.EventsHandler{PlayerChatMessage: onChatMsg})
|
||||
|
||||
//Register event handlers
|
||||
|
||||
c.Events.AddListener(soundListener)
|
||||
|
||||
//Login
|
||||
@ -107,13 +109,13 @@ func onSound(id int, category int, x, y, z float64, volume, pitch float32) error
|
||||
return nil
|
||||
}
|
||||
|
||||
func onChatMsg(c *basic.PlayerMessage) error {
|
||||
log.Println("Chat:", c.SignedMessage)
|
||||
func onChatMsg(c chat.Message) error {
|
||||
log.Println("Chat:", c)
|
||||
return nil
|
||||
}
|
||||
|
||||
func onSystemMsg(c chat.Message, pos byte) error {
|
||||
log.Printf("System: %v, Location: %v", c, pos)
|
||||
func onSystemMsg(c chat.Message, overlay bool) error {
|
||||
log.Printf("System: %v, Overlay: %v", c, overlay)
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -12,6 +12,7 @@ import (
|
||||
|
||||
"github.com/Tnze/go-mc/bot"
|
||||
"github.com/Tnze/go-mc/bot/basic"
|
||||
botchat "github.com/Tnze/go-mc/bot/chat"
|
||||
"github.com/Tnze/go-mc/bot/screen"
|
||||
"github.com/Tnze/go-mc/bot/world"
|
||||
"github.com/Tnze/go-mc/chat"
|
||||
@ -27,6 +28,7 @@ var accessToken = flag.String("token", "", "AccessToken")
|
||||
|
||||
var client *bot.Client
|
||||
var player *basic.Player
|
||||
var chatHandler *botchat.Chat
|
||||
var worldManager *world.World
|
||||
var screenManager *screen.Manager
|
||||
|
||||
@ -39,15 +41,16 @@ func main() {
|
||||
UUID: *playerID,
|
||||
AsTk: *accessToken,
|
||||
}
|
||||
player = basic.NewPlayer(client, basic.DefaultSettings)
|
||||
basic.EventsListener{
|
||||
player = basic.NewPlayer(client, basic.DefaultSettings, basic.EventsListener{
|
||||
GameStart: onGameStart,
|
||||
ChatMsg: onChatMsg,
|
||||
SystemMsg: onSystemMsg,
|
||||
Disconnect: onDisconnect,
|
||||
HealthChange: onHealthChange,
|
||||
Death: onDeath,
|
||||
}.Attach(client)
|
||||
})
|
||||
chatHandler = botchat.NewChat(client, player, botchat.EventsHandler{
|
||||
PlayerChatMessage: onPlayerMsg,
|
||||
})
|
||||
worldManager = world.NewWorld(client, player, world.EventsListener{
|
||||
LoadChunk: onChunkLoad,
|
||||
UnloadChunk: onChunkUnload,
|
||||
@ -103,13 +106,13 @@ func onGameStart() error {
|
||||
return nil //if err isn't nil, HandleGame() will return it.
|
||||
}
|
||||
|
||||
func onChatMsg(c *basic.PlayerMessage) error {
|
||||
log.Println("Chat:", c.SignedMessage.String())
|
||||
func onPlayerMsg(msg chat.Message) error {
|
||||
log.Printf("Player: %v", msg)
|
||||
return nil
|
||||
}
|
||||
|
||||
func onSystemMsg(c chat.Message, pos byte) error {
|
||||
log.Printf("System: %v, Location: %v", c, pos)
|
||||
func onSystemMsg(c chat.Message, overlay bool) error {
|
||||
log.Printf("System: %v, Overlay: %v", c, overlay)
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -28,7 +28,7 @@ func main() {
|
||||
//log.SetOutput(colorable.NewColorableStdout())
|
||||
client = bot.NewClient()
|
||||
client.Auth.Name = "Daze"
|
||||
player = basic.NewPlayer(client, basic.DefaultSettings)
|
||||
player = basic.NewPlayer(client, basic.DefaultSettings, basic.EventsListener{})
|
||||
client.Events.AddListener(bot.PacketHandler{
|
||||
ID: packetid.ClientboundCommands,
|
||||
Priority: 50,
|
||||
|
@ -44,11 +44,10 @@ func newIndividual(id int, name string) (i *individual) {
|
||||
i.id = id
|
||||
i.client = bot.NewClient()
|
||||
i.client.Auth.Name = name
|
||||
i.player = basic.NewPlayer(i.client, basic.DefaultSettings)
|
||||
basic.EventsListener{
|
||||
i.player = basic.NewPlayer(i.client, basic.DefaultSettings, basic.EventsListener{
|
||||
GameStart: i.onGameStart,
|
||||
Disconnect: onDisconnect,
|
||||
}.Attach(i.client)
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -17,12 +17,12 @@ type Packet struct {
|
||||
}
|
||||
|
||||
// Marshal generate Packet with the ID and Fields
|
||||
func Marshal(id int32, fields ...FieldEncoder) (pk Packet) {
|
||||
func Marshal[ID ~int32 | int](id ID, fields ...FieldEncoder) (pk Packet) {
|
||||
var pb Builder
|
||||
for _, v := range fields {
|
||||
pb.WriteField(v)
|
||||
}
|
||||
return pb.Packet(id)
|
||||
return pb.Packet(int32(id))
|
||||
}
|
||||
|
||||
// Scan decode the packet and fill data into fields
|
||||
|
@ -2,6 +2,7 @@ package packet
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"reflect"
|
||||
)
|
||||
@ -130,10 +131,10 @@ func (t Tuple) WriteTo(w io.Writer) (n int64, err error) {
|
||||
|
||||
// ReadFrom read Tuple from io.Reader, panic when any of field don't implement FieldDecoder
|
||||
func (t Tuple) ReadFrom(r io.Reader) (n int64, err error) {
|
||||
for _, v := range t {
|
||||
for i, v := range t {
|
||||
nn, err := v.(FieldDecoder).ReadFrom(r)
|
||||
if err != nil {
|
||||
return n, err
|
||||
return n, fmt.Errorf("decode tuple[%d] error: %w", i, err)
|
||||
}
|
||||
n += nn
|
||||
}
|
||||
|
Reference in New Issue
Block a user