Skip to content

Commit

Permalink
Add tags implement
Browse files Browse the repository at this point in the history
  • Loading branch information
Tnze committed Jul 27, 2024
1 parent d88ee40 commit 3137528
Show file tree
Hide file tree
Showing 7 changed files with 218 additions and 13 deletions.
1 change: 1 addition & 0 deletions bot/basic/basic.go
Original file line number Diff line number Diff line change
Expand Up @@ -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.ClientboundCookieRequest, F: p.handleCookieRequestPacket},
bot.PacketHandler{Priority: 0, ID: packetid.ClientboundStoreCookie, F: p.handleStoreCookiePacket},
bot.PacketHandler{Priority: 0, ID: packetid.ClientboundUpdateTags, F: p.handleUpdateTags},
)
events.attach(p)
return p
Expand Down
37 changes: 37 additions & 0 deletions bot/basic/tags.go
Original file line number Diff line number Diff line change
@@ -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
}
73 changes: 69 additions & 4 deletions bot/configuration.go
Original file line number Diff line number Diff line change
Expand Up @@ -153,9 +153,8 @@ func (c *Client) joinConfiguration(conn *net.Conn) error {
if registry == nil {
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 {
return ConfigErr{ErrStage, fmt.Errorf("failed to read registry %s: %w", registryID, err)}
}
Expand Down Expand Up @@ -207,7 +206,7 @@ func (c *Client) joinConfiguration(conn *net.Conn) error {
var port pk.VarInt
err := p.Scan(&host, &port)
if err != nil {
return ConfigErr{"store cookie", err}
return ConfigErr{"transfer", err}
}
// TODO: trnasfer to the specific server
// How does it work? Just connect the new server, and re-start at handshake?
Expand All @@ -221,7 +220,39 @@ func (c *Client) joinConfiguration(conn *net.Conn) error {
c.ConfigHandler.EnableFeature(features)

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:
const ErrStage = "select known packs"
packs := []DataPack{}
Expand Down Expand Up @@ -329,3 +360,37 @@ func (d *DefaultConfigHandler) PopAllResourcePack() {
func (d *DefaultConfigHandler) SelectDataPacks(packs []DataPack) []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 changes: 33 additions & 0 deletions registry/README.md
Original file line number Diff line number Diff line change
@@ -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
}
}
11 changes: 9 additions & 2 deletions registry/codec.go
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
package registry

import (
"io"
"reflect"

"github.com/Tnze/go-mc/chat"
"github.com/Tnze/go-mc/nbt"
pk "github.com/Tnze/go-mc/net/packet"
)

type NetworkCodec struct {
Expand Down Expand Up @@ -72,7 +74,12 @@ type Dimension struct {
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()
codecTyp := codecVal.Type()
numField := codecVal.NumField()
Expand All @@ -82,7 +89,7 @@ func (c *NetworkCodec) Registry(id string) any {
continue
}
if registryID == id {
return codecVal.Field(i).Addr().Interface()
return codecVal.Field(i).Addr().Interface().(RegistryCodec)
}
}
return nil
Expand Down
51 changes: 49 additions & 2 deletions registry/network.go
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
package registry

import (
"errors"
"io"
"strconv"

pk "github.com/Tnze/go-mc/net/packet"
)

func (reg *Registry[E]) ReadFrom(r io.Reader) (int64, error) {
var length pk.VarInt

n, err := length.ReadFrom(r)
if err != nil {
return n, err
Expand All @@ -33,7 +34,7 @@ func (reg *Registry[E]) ReadFrom(r io.Reader) (int64, error) {
}

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 {
return n + n1 + n2 + n3, err
}
Expand All @@ -44,3 +45,49 @@ func (reg *Registry[E]) ReadFrom(r io.Reader) (int64, error) {
}
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] = &reg.values[id]
n += n3
}

reg.tags[string(tag)] = values
}
return n, nil
}
25 changes: 20 additions & 5 deletions registry/registry.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,25 @@ type Registry[E any] struct {
keys map[string]int32
values []E
indices map[*E]int32
tags map[string][]*E
}

func NewRegistry[E any]() Registry[E] {
return Registry[E]{
keys: make(map[string]int32),
values: make([]E, 0, 256),
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) {
id, ok := r.keys[key]
if !ok {
Expand All @@ -38,8 +47,14 @@ func (r *Registry[E]) Put(name string, data E) (id int32, val *E) {
return
}

func (r *Registry[E]) Clear() {
r.keys = make(map[string]int32)
r.values = r.values[:0]
r.indices = make(map[*E]int32)
}
// func (r *Registry[E]) BindTags(tag string, ids []int32) error {
// values := make([]*E, len(ids))
// for i, id := range ids {
// 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
// }

0 comments on commit 3137528

Please sign in to comment.