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

View File

@ -1,6 +1,8 @@
package bot
import (
"fmt"
"io"
"unsafe"
"github.com/Tnze/go-mc/chat"
@ -10,14 +12,27 @@ import (
"github.com/Tnze/go-mc/registry"
)
type ConfigData struct {
Registries registry.NetworkCodec
ResourcePack struct {
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 {
Registries registry.NetworkCodec
FeatureFlags []string
}
@ -43,7 +58,22 @@ func (c *Client) joinConfiguration(conn *net.Conn) error {
}
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 data pk.PluginMessageData
err := p.Scan(&channel, &data)
@ -52,7 +82,7 @@ func (c *Client) joinConfiguration(conn *net.Conn) error {
}
// TODO: Provide configuration custom data handling interface
case packetid.ClientboundDisconnect:
case packetid.ClientboundConfigDisconnect:
var reason chat.Message
err := p.Scan(&reason)
if err != nil {
@ -99,18 +129,29 @@ func (c *Client) joinConfiguration(conn *net.Conn) error {
return ConfigErr{"pong", err}
}
case packetid.ClientboundConfigResetChat:
// TODO
case packetid.ClientboundConfigRegistryData:
err := p.Scan(pk.NBT(&c.ConfigData.Registries))
if err != nil {
return ConfigErr{"registry data", err}
}
// err := p.Scan(pk.NBT(&c.ConfigData.Registries))
// if err != nil {
// return ConfigErr{"registry data", err}
// }
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:
var id pk.UUID
var Url, Hash pk.String
var Forced pk.Boolean
var PromptMessage pk.Option[chat.Message, *chat.Message]
err := p.Scan(
&id,
&Url,
&Hash,
&Forced,
@ -119,12 +160,34 @@ func (c *Client) joinConfiguration(conn *net.Conn) error {
if err != nil {
return ConfigErr{"resource pack", err}
}
c.ConfigData.ResourcePack.URL = string(Url)
c.ConfigData.ResourcePack.Hash = string(Hash)
c.ConfigData.ResourcePack.Forced = bool(Forced)
if PromptMessage.Has {
c.ConfigData.ResourcePack.PromptMessage = &PromptMessage.Val
res := ResourcePack{
ID: id,
URL: string(Url),
Hash: string(Hash),
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:
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:
// 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
const (
ProtocolVersion = 765
ProtocolVersion = 767
DefaultPort = mcnet.DefaultPort
)