Add tags implement
This commit is contained in:
@ -43,6 +43,7 @@ func NewPlayer(c *bot.Client, settings Settings, events EventsListener) *Player
|
|||||||
bot.PacketHandler{Priority: 0, ID: packetid.ClientboundPing, F: p.handlePingPacket},
|
bot.PacketHandler{Priority: 0, ID: packetid.ClientboundPing, F: p.handlePingPacket},
|
||||||
bot.PacketHandler{Priority: 0, ID: packetid.ClientboundCookieRequest, F: p.handleCookieRequestPacket},
|
bot.PacketHandler{Priority: 0, ID: packetid.ClientboundCookieRequest, F: p.handleCookieRequestPacket},
|
||||||
bot.PacketHandler{Priority: 0, ID: packetid.ClientboundStoreCookie, F: p.handleStoreCookiePacket},
|
bot.PacketHandler{Priority: 0, ID: packetid.ClientboundStoreCookie, F: p.handleStoreCookiePacket},
|
||||||
|
bot.PacketHandler{Priority: 0, ID: packetid.ClientboundUpdateTags, F: p.handleUpdateTags},
|
||||||
)
|
)
|
||||||
events.attach(p)
|
events.attach(p)
|
||||||
return p
|
return p
|
||||||
|
37
bot/basic/tags.go
Normal file
37
bot/basic/tags.go
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
package basic
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"errors"
|
||||||
|
|
||||||
|
pk "github.com/Tnze/go-mc/net/packet"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (p *Player) handleUpdateTags(packet pk.Packet) error {
|
||||||
|
r := bytes.NewReader(packet.Data)
|
||||||
|
|
||||||
|
var length pk.VarInt
|
||||||
|
_, err := length.ReadFrom(r)
|
||||||
|
if err != nil {
|
||||||
|
return Error{err}
|
||||||
|
}
|
||||||
|
|
||||||
|
var registryID pk.Identifier
|
||||||
|
for i := 0; i < int(length); i++ {
|
||||||
|
_, err = registryID.ReadFrom(r)
|
||||||
|
if err != nil {
|
||||||
|
return Error{err}
|
||||||
|
}
|
||||||
|
|
||||||
|
registry := p.c.Registries.Registry(string(registryID))
|
||||||
|
if registry == nil {
|
||||||
|
return Error{errors.New("unknown registry: " + string(registryID))}
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = registry.ReadTagsFrom(r)
|
||||||
|
if err != nil {
|
||||||
|
return Error{err}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
@ -153,9 +153,8 @@ func (c *Client) joinConfiguration(conn *net.Conn) error {
|
|||||||
if registry == nil {
|
if registry == nil {
|
||||||
return ConfigErr{ErrStage, errors.New("unknown registry: " + string(registryID))}
|
return ConfigErr{ErrStage, errors.New("unknown registry: " + string(registryID))}
|
||||||
}
|
}
|
||||||
fmt.Println(registry)
|
|
||||||
|
|
||||||
_, err = registry.(pk.FieldDecoder).ReadFrom(r)
|
_, err = registry.ReadFrom(r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return ConfigErr{ErrStage, fmt.Errorf("failed to read registry %s: %w", registryID, err)}
|
return ConfigErr{ErrStage, fmt.Errorf("failed to read registry %s: %w", registryID, err)}
|
||||||
}
|
}
|
||||||
@ -207,7 +206,7 @@ func (c *Client) joinConfiguration(conn *net.Conn) error {
|
|||||||
var port pk.VarInt
|
var port pk.VarInt
|
||||||
err := p.Scan(&host, &port)
|
err := p.Scan(&host, &port)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return ConfigErr{"store cookie", err}
|
return ConfigErr{"transfer", err}
|
||||||
}
|
}
|
||||||
// TODO: trnasfer to the specific server
|
// TODO: trnasfer to the specific server
|
||||||
// How does it work? Just connect the new server, and re-start at handshake?
|
// How does it work? Just connect the new server, and re-start at handshake?
|
||||||
@ -221,7 +220,39 @@ func (c *Client) joinConfiguration(conn *net.Conn) error {
|
|||||||
c.ConfigHandler.EnableFeature(features)
|
c.ConfigHandler.EnableFeature(features)
|
||||||
|
|
||||||
case packetid.ClientboundConfigUpdateTags:
|
case packetid.ClientboundConfigUpdateTags:
|
||||||
// TODO: Handle Tags
|
const ErrStage = "update tags"
|
||||||
|
r := bytes.NewReader(p.Data)
|
||||||
|
|
||||||
|
var length pk.VarInt
|
||||||
|
_, err := length.ReadFrom(r)
|
||||||
|
if err != nil {
|
||||||
|
return ConfigErr{ErrStage, err}
|
||||||
|
}
|
||||||
|
|
||||||
|
var registryID pk.Identifier
|
||||||
|
for i := 0; i < int(length); i++ {
|
||||||
|
_, err = registryID.ReadFrom(r)
|
||||||
|
if err != nil {
|
||||||
|
return ConfigErr{ErrStage, err}
|
||||||
|
}
|
||||||
|
|
||||||
|
registry := c.Registries.Registry(string(registryID))
|
||||||
|
if registry == nil {
|
||||||
|
// TODO: Sice our registry system is incompelted, ignore all tags bind to non-exist registry
|
||||||
|
_, err = idleTagsDecoder{}.ReadFrom(r)
|
||||||
|
if err != nil {
|
||||||
|
return ConfigErr{ErrStage, err}
|
||||||
|
}
|
||||||
|
continue
|
||||||
|
// return ConfigErr{ErrStage, errors.New("unknown registry: " + string(registryID))}
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = registry.ReadTagsFrom(r)
|
||||||
|
if err != nil {
|
||||||
|
return ConfigErr{ErrStage, err}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
case packetid.ClientboundConfigSelectKnownPacks:
|
case packetid.ClientboundConfigSelectKnownPacks:
|
||||||
const ErrStage = "select known packs"
|
const ErrStage = "select known packs"
|
||||||
packs := []DataPack{}
|
packs := []DataPack{}
|
||||||
@ -329,3 +360,37 @@ func (d *DefaultConfigHandler) PopAllResourcePack() {
|
|||||||
func (d *DefaultConfigHandler) SelectDataPacks(packs []DataPack) []DataPack {
|
func (d *DefaultConfigHandler) SelectDataPacks(packs []DataPack) []DataPack {
|
||||||
return []DataPack{}
|
return []DataPack{}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type idleTagsDecoder struct{}
|
||||||
|
|
||||||
|
func (idleTagsDecoder) ReadFrom(r io.Reader) (int64, error) {
|
||||||
|
var count pk.VarInt
|
||||||
|
var tag pk.Identifier
|
||||||
|
var length pk.VarInt
|
||||||
|
n, err := count.ReadFrom(r)
|
||||||
|
if err != nil {
|
||||||
|
return n, err
|
||||||
|
}
|
||||||
|
for i := 0; i < int(count); i++ {
|
||||||
|
var n1, n2, n3 int64
|
||||||
|
n1, err = tag.ReadFrom(r)
|
||||||
|
if err != nil {
|
||||||
|
return n + n1, err
|
||||||
|
}
|
||||||
|
n2, err = length.ReadFrom(r)
|
||||||
|
if err != nil {
|
||||||
|
return n + n1 + n2, err
|
||||||
|
}
|
||||||
|
n += n1 + n2
|
||||||
|
|
||||||
|
var id pk.VarInt
|
||||||
|
for i := 0; i < int(length); i++ {
|
||||||
|
n3, err = id.ReadFrom(r)
|
||||||
|
if err != nil {
|
||||||
|
return n + n3, err
|
||||||
|
}
|
||||||
|
n += n3
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return n, nil
|
||||||
|
}
|
||||||
|
33
registry/README.md
Normal file
33
registry/README.md
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
# Registry System
|
||||||
|
|
||||||
|
instance {
|
||||||
|
ResourceLocation {
|
||||||
|
namespace: string
|
||||||
|
path: string
|
||||||
|
}
|
||||||
|
|
||||||
|
ResourceKey<T> {
|
||||||
|
registryName: ResourceLocation
|
||||||
|
location: ResourceLocation
|
||||||
|
}
|
||||||
|
|
||||||
|
registry<T> {
|
||||||
|
getId(T): int
|
||||||
|
byId(int): T
|
||||||
|
|
||||||
|
getKey(T): ResourceLocation
|
||||||
|
getResourceKey(T): ResourceKey<T>
|
||||||
|
get(ResourceKey<T>): T
|
||||||
|
get(ResourceLocation): T
|
||||||
|
|
||||||
|
getTags(TagKey<T>): (TagKey<T>, *T[])[]
|
||||||
|
getTagNames(): TagKey<T>[]
|
||||||
|
resetTags()
|
||||||
|
bindTags((TagKey<T>, *T[])[])
|
||||||
|
}[]
|
||||||
|
|
||||||
|
TagKey<T> {
|
||||||
|
*Registry<T>
|
||||||
|
ResourceLocation
|
||||||
|
}
|
||||||
|
}
|
@ -1,10 +1,12 @@
|
|||||||
package registry
|
package registry
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"io"
|
||||||
"reflect"
|
"reflect"
|
||||||
|
|
||||||
"github.com/Tnze/go-mc/chat"
|
"github.com/Tnze/go-mc/chat"
|
||||||
"github.com/Tnze/go-mc/nbt"
|
"github.com/Tnze/go-mc/nbt"
|
||||||
|
pk "github.com/Tnze/go-mc/net/packet"
|
||||||
)
|
)
|
||||||
|
|
||||||
type NetworkCodec struct {
|
type NetworkCodec struct {
|
||||||
@ -72,7 +74,12 @@ type Dimension struct {
|
|||||||
MonsterSpawnBlockLightLimit int32 `nbt:"monster_spawn_block_light_limit"`
|
MonsterSpawnBlockLightLimit int32 `nbt:"monster_spawn_block_light_limit"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *NetworkCodec) Registry(id string) any {
|
type RegistryCodec interface {
|
||||||
|
pk.FieldDecoder
|
||||||
|
ReadTagsFrom(r io.Reader) (int64, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *NetworkCodec) Registry(id string) RegistryCodec {
|
||||||
codecVal := reflect.ValueOf(c).Elem()
|
codecVal := reflect.ValueOf(c).Elem()
|
||||||
codecTyp := codecVal.Type()
|
codecTyp := codecVal.Type()
|
||||||
numField := codecVal.NumField()
|
numField := codecVal.NumField()
|
||||||
@ -82,7 +89,7 @@ func (c *NetworkCodec) Registry(id string) any {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if registryID == id {
|
if registryID == id {
|
||||||
return codecVal.Field(i).Addr().Interface()
|
return codecVal.Field(i).Addr().Interface().(RegistryCodec)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
@ -1,14 +1,15 @@
|
|||||||
package registry
|
package registry
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
"io"
|
"io"
|
||||||
|
"strconv"
|
||||||
|
|
||||||
pk "github.com/Tnze/go-mc/net/packet"
|
pk "github.com/Tnze/go-mc/net/packet"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (reg *Registry[E]) ReadFrom(r io.Reader) (int64, error) {
|
func (reg *Registry[E]) ReadFrom(r io.Reader) (int64, error) {
|
||||||
var length pk.VarInt
|
var length pk.VarInt
|
||||||
|
|
||||||
n, err := length.ReadFrom(r)
|
n, err := length.ReadFrom(r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return n, err
|
return n, err
|
||||||
@ -33,7 +34,7 @@ func (reg *Registry[E]) ReadFrom(r io.Reader) (int64, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if hasData {
|
if hasData {
|
||||||
n3, err = pk.NBTField{V:&data, AllowUnknownFields: true}.ReadFrom(r)
|
n3, err = pk.NBTField{V: &data, AllowUnknownFields: true}.ReadFrom(r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return n + n1 + n2 + n3, err
|
return n + n1 + n2 + n3, err
|
||||||
}
|
}
|
||||||
@ -44,3 +45,49 @@ func (reg *Registry[E]) ReadFrom(r io.Reader) (int64, error) {
|
|||||||
}
|
}
|
||||||
return n, nil
|
return n, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (reg *Registry[E]) ReadTagsFrom(r io.Reader) (int64, error) {
|
||||||
|
var count pk.VarInt
|
||||||
|
n, err := count.ReadFrom(r)
|
||||||
|
if err != nil {
|
||||||
|
return n, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var tag pk.Identifier
|
||||||
|
var length pk.VarInt
|
||||||
|
for i := 0; i < int(count); i++ {
|
||||||
|
var n1, n2, n3 int64
|
||||||
|
|
||||||
|
n1, err = tag.ReadFrom(r)
|
||||||
|
if err != nil {
|
||||||
|
return n + n1, err
|
||||||
|
}
|
||||||
|
|
||||||
|
n2, err = length.ReadFrom(r)
|
||||||
|
if err != nil {
|
||||||
|
return n + n1 + n2, err
|
||||||
|
}
|
||||||
|
|
||||||
|
n += n1 + n2
|
||||||
|
values := make([]*E, length)
|
||||||
|
|
||||||
|
var id pk.VarInt
|
||||||
|
for i := 0; i < int(length); i++ {
|
||||||
|
n3, err = id.ReadFrom(r)
|
||||||
|
if err != nil {
|
||||||
|
return n + n3, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if id < 0 || int(id) >= len(reg.values) {
|
||||||
|
err = errors.New("invalid id: " + strconv.Itoa(int(id)))
|
||||||
|
return n + n3, err
|
||||||
|
}
|
||||||
|
|
||||||
|
values[i] = ®.values[id]
|
||||||
|
n += n3
|
||||||
|
}
|
||||||
|
|
||||||
|
reg.tags[string(tag)] = values
|
||||||
|
}
|
||||||
|
return n, nil
|
||||||
|
}
|
||||||
|
@ -4,6 +4,7 @@ type Registry[E any] struct {
|
|||||||
keys map[string]int32
|
keys map[string]int32
|
||||||
values []E
|
values []E
|
||||||
indices map[*E]int32
|
indices map[*E]int32
|
||||||
|
tags map[string][]*E
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewRegistry[E any]() Registry[E] {
|
func NewRegistry[E any]() Registry[E] {
|
||||||
@ -11,9 +12,17 @@ func NewRegistry[E any]() Registry[E] {
|
|||||||
keys: make(map[string]int32),
|
keys: make(map[string]int32),
|
||||||
values: make([]E, 0, 256),
|
values: make([]E, 0, 256),
|
||||||
indices: make(map[*E]int32),
|
indices: make(map[*E]int32),
|
||||||
|
tags: make(map[string][]*E),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (r *Registry[E]) Clear() {
|
||||||
|
r.keys = make(map[string]int32)
|
||||||
|
r.values = r.values[:0]
|
||||||
|
r.indices = make(map[*E]int32)
|
||||||
|
r.tags = make(map[string][]*E)
|
||||||
|
}
|
||||||
|
|
||||||
func (r *Registry[E]) Get(key string) (int32, *E) {
|
func (r *Registry[E]) Get(key string) (int32, *E) {
|
||||||
id, ok := r.keys[key]
|
id, ok := r.keys[key]
|
||||||
if !ok {
|
if !ok {
|
||||||
@ -38,8 +47,14 @@ func (r *Registry[E]) Put(name string, data E) (id int32, val *E) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *Registry[E]) Clear() {
|
// func (r *Registry[E]) BindTags(tag string, ids []int32) error {
|
||||||
r.keys = make(map[string]int32)
|
// values := make([]*E, len(ids))
|
||||||
r.values = r.values[:0]
|
// for i, id := range ids {
|
||||||
r.indices = make(map[*E]int32)
|
// if id < 0 || id >= int32(len(r.values)) {
|
||||||
}
|
// return errors.New("invalid id: " + strconv.Itoa(int(id)))
|
||||||
|
// }
|
||||||
|
// values[i] = &r.values[id]
|
||||||
|
// }
|
||||||
|
// r.tags[tag] = values
|
||||||
|
// return nil
|
||||||
|
// }
|
||||||
|
Reference in New Issue
Block a user