upgrade bot configuration protocol

This commit is contained in:
Tnze
2024-06-15 23:59:23 +08:00
parent 8be84104f1
commit ee23172e0a
3 changed files with 176 additions and 19 deletions

View File

@ -18,15 +18,18 @@ type Client struct {
Auth Auth Auth Auth
// These are filled when login process // These are filled when login process
Name string Name string
UUID uuid.UUID UUID uuid.UUID
ConfigData ConfigData
// Ingame packet handlers // Ingame packet handlers
Events Events Events Events
// Login plugins // Login plugins
LoginPlugin map[string]func(data []byte) ([]byte, error) LoginPlugin map[string]func(data []byte) ([]byte, error)
// Configuration handler
ConfigHandler
} }
func (c *Client) Close() error { func (c *Client) Close() error {
@ -44,6 +47,7 @@ func NewClient() *Client {
return &Client{ return &Client{
Auth: Auth{Name: "Steve"}, Auth: Auth{Name: "Steve"},
Events: Events{handlers: make([][]PacketHandler, packetid.ClientboundPacketIDGuard)}, Events: Events{handlers: make([][]PacketHandler, packetid.ClientboundPacketIDGuard)},
ConfigHandler: NewDefaultConfigHandler(),
} }
} }

View File

@ -1,6 +1,8 @@
package bot package bot
import ( import (
"fmt"
"io"
"unsafe" "unsafe"
"github.com/Tnze/go-mc/chat" "github.com/Tnze/go-mc/chat"
@ -10,14 +12,27 @@ import (
"github.com/Tnze/go-mc/registry" "github.com/Tnze/go-mc/registry"
) )
type ConfigHandler interface {
GetCookie(key pk.Identifier) []byte
SetCookie(key pk.Identifier, payload []byte)
PushResourcePack(res ResourcePack)
PopResourcePack(id pk.UUID)
PopAllResourcePack()
SelectDataPacks(packs []DataPack) []DataPack
}
type ResourcePack struct {
ID pk.UUID
URL string
Hash string
Forced bool
PromptMessage *chat.Message // Optional
}
type ConfigData struct { type ConfigData struct {
Registries registry.NetworkCodec Registries registry.NetworkCodec
ResourcePack struct {
URL string
Hash string
Forced bool
PromptMessage *chat.Message // Optional
}
FeatureFlags []string FeatureFlags []string
} }
@ -43,7 +58,22 @@ func (c *Client) joinConfiguration(conn *net.Conn) error {
} }
switch packetid.ClientboundPacketID(p.ID) { switch packetid.ClientboundPacketID(p.ID) {
case packetid.ClientboundCustomPayload: case packetid.ClientboundConfigCookieRequest:
var key pk.Identifier
err := p.Scan(&key)
if err != nil {
return ConfigErr{"cookie request", err}
}
cookieContent := c.ConfigHandler.GetCookie(key)
err = conn.WritePacket(pk.Marshal(
packetid.ServerboundConfigCookieResponse,
pk.ByteArray(cookieContent),
))
if err != nil {
return ConfigErr{"cookie response", err}
}
case packetid.ClientboundConfigCustomPayload:
var channel pk.Identifier var channel pk.Identifier
var data pk.PluginMessageData var data pk.PluginMessageData
err := p.Scan(&channel, &data) err := p.Scan(&channel, &data)
@ -52,7 +82,7 @@ func (c *Client) joinConfiguration(conn *net.Conn) error {
} }
// TODO: Provide configuration custom data handling interface // TODO: Provide configuration custom data handling interface
case packetid.ClientboundDisconnect: case packetid.ClientboundConfigDisconnect:
var reason chat.Message var reason chat.Message
err := p.Scan(&reason) err := p.Scan(&reason)
if err != nil { if err != nil {
@ -99,18 +129,29 @@ func (c *Client) joinConfiguration(conn *net.Conn) error {
return ConfigErr{"pong", err} return ConfigErr{"pong", err}
} }
case packetid.ClientboundConfigResetChat:
// TODO
case packetid.ClientboundConfigRegistryData: case packetid.ClientboundConfigRegistryData:
err := p.Scan(pk.NBT(&c.ConfigData.Registries)) // err := p.Scan(pk.NBT(&c.ConfigData.Registries))
if err != nil { // if err != nil {
return ConfigErr{"registry data", err} // return ConfigErr{"registry data", err}
} // }
case packetid.ClientboundConfigResourcePackPop: // TODO case packetid.ClientboundConfigResourcePackPop: // TODO
var id pk.Option[pk.UUID, *pk.UUID]
err := p.Scan(&id)
if err != nil {
return ConfigErr{"resource pack pop", err}
}
case packetid.ClientboundConfigResourcePackPush: case packetid.ClientboundConfigResourcePackPush:
var id pk.UUID
var Url, Hash pk.String var Url, Hash pk.String
var Forced pk.Boolean var Forced pk.Boolean
var PromptMessage pk.Option[chat.Message, *chat.Message] var PromptMessage pk.Option[chat.Message, *chat.Message]
err := p.Scan( err := p.Scan(
&id,
&Url, &Url,
&Hash, &Hash,
&Forced, &Forced,
@ -119,12 +160,34 @@ func (c *Client) joinConfiguration(conn *net.Conn) error {
if err != nil { if err != nil {
return ConfigErr{"resource pack", err} return ConfigErr{"resource pack", err}
} }
c.ConfigData.ResourcePack.URL = string(Url) res := ResourcePack{
c.ConfigData.ResourcePack.Hash = string(Hash) ID: id,
c.ConfigData.ResourcePack.Forced = bool(Forced) URL: string(Url),
if PromptMessage.Has { Hash: string(Hash),
c.ConfigData.ResourcePack.PromptMessage = &PromptMessage.Val Forced: bool(Forced),
} }
if PromptMessage.Has {
res.PromptMessage = &PromptMessage.Val
}
c.ConfigHandler.PushResourcePack(res)
case packetid.ClientboundConfigStoreCookie:
var key pk.Identifier
var payload pk.ByteArray
err := p.Scan(&key, &payload)
if err != nil {
return ConfigErr{"store cookie", err}
}
c.ConfigHandler.SetCookie(key, []byte(payload))
case packetid.ClientboundConfigTransfer:
var host pk.String
var port pk.VarInt
err := p.Scan(&host, &port)
if err != nil {
return ConfigErr{"store cookie", err}
}
// TODO: trnasfer to the server
case packetid.ClientboundConfigUpdateEnabledFeatures: case packetid.ClientboundConfigUpdateEnabledFeatures:
err := p.Scan(pk.Array((*[]pk.Identifier)(unsafe.Pointer(&c.ConfigData.FeatureFlags)))) err := p.Scan(pk.Array((*[]pk.Identifier)(unsafe.Pointer(&c.ConfigData.FeatureFlags))))
@ -134,6 +197,96 @@ func (c *Client) joinConfiguration(conn *net.Conn) error {
case packetid.ClientboundConfigUpdateTags: case packetid.ClientboundConfigUpdateTags:
// TODO: Handle Tags // TODO: Handle Tags
case packetid.ClientboundConfigSelectKnownPacks:
packs := []DataPack{}
err := p.Scan(pk.Array(&packs))
if err != nil {
return ConfigErr{"select known packs", err}
}
knwonPacks := c.ConfigHandler.SelectDataPacks(packs)
err = conn.WritePacket(pk.Marshal(
packetid.ServerboundConfigSelectKnownPacks,
pk.Array(knwonPacks),
))
if err != nil {
return ConfigErr{"select known packs", err}
}
case packetid.ClientboundConfigCustomReportDetails:
case packetid.ClientboundConfigServerLinks:
} }
} }
} }
type DataPack struct {
Namespace string
ID string
Version string
}
func (d DataPack) WriteTo(w io.Writer) (n int64, err error) {
n, err = pk.String(d.Namespace).WriteTo(w)
if err != nil {
return n, err
}
n1, err := pk.String(d.ID).WriteTo(w)
if err != nil {
return n + n1, err
}
n2, err := pk.String(d.Version).WriteTo(w)
return n + n1 + n2, err
}
func (d *DataPack) ReadFrom(r io.Reader) (n int64, err error) {
n, err = (*pk.String)(&d.Namespace).ReadFrom(r)
if err != nil {
return n, err
}
n1, err := (*pk.String)(&d.ID).ReadFrom(r)
if err != nil {
return n + n1, err
}
n2, err := (*pk.String)(&d.Version).ReadFrom(r)
return n + n1 + n2, err
}
type DefaultConfigHandler struct {
cookies map[pk.Identifier][]byte
resourcesPack []ResourcePack
}
func NewDefaultConfigHandler() *DefaultConfigHandler {
return &DefaultConfigHandler{
cookies: make(map[pk.String][]byte),
resourcesPack: make([]ResourcePack, 0),
}
}
func (d *DefaultConfigHandler) GetCookie(key pk.Identifier) []byte {
return d.cookies[key]
}
func (d *DefaultConfigHandler) SetCookie(key pk.Identifier, payload []byte) {
d.cookies[key] = payload
}
func (d *DefaultConfigHandler) PushResourcePack(res ResourcePack) {
d.resourcesPack = append(d.resourcesPack, res)
}
func (d *DefaultConfigHandler) PopResourcePack(id pk.UUID) {
for i, v := range d.resourcesPack {
if id == v.ID {
d.resourcesPack = append(d.resourcesPack[:i], d.resourcesPack[i+1:]...)
break
}
}
}
func (d *DefaultConfigHandler) PopAllResourcePack() {
d.resourcesPack = d.resourcesPack[:0]
}
func (d *DefaultConfigHandler) SelectDataPacks(packs []DataPack) []DataPack {
return []DataPack{}
}

View File

@ -19,7 +19,7 @@ import (
// ProtocolVersion is the protocol version number of minecraft net protocol // ProtocolVersion is the protocol version number of minecraft net protocol
const ( const (
ProtocolVersion = 765 ProtocolVersion = 767
DefaultPort = mcnet.DefaultPort DefaultPort = mcnet.DefaultPort
) )