diff --git a/bot/configuration.go b/bot/configuration.go index 9fb345c..10dac57 100644 --- a/bot/configuration.go +++ b/bot/configuration.go @@ -2,6 +2,7 @@ package bot import ( "bytes" + "errors" "io" "github.com/Tnze/go-mc/chat" @@ -9,7 +10,6 @@ import ( "github.com/Tnze/go-mc/nbt" "github.com/Tnze/go-mc/net" pk "github.com/Tnze/go-mc/net/packet" - "github.com/Tnze/go-mc/registry" ) type ConfigHandler interface { @@ -159,6 +159,11 @@ func (c *Client) joinConfiguration(conn *net.Conn) error { return ConfigErr{ErrStage, err} } + registry := c.Registries.Registry(string(registryID)) + if registry == nil { + return ConfigErr{ErrStage, errors.New("unknown registry: " + string(registryID))} + } + for i := 0; i < int(length); i++ { var entryId pk.Identifier var hasData pk.Boolean @@ -178,7 +183,7 @@ func (c *Client) joinConfiguration(conn *net.Conn) error { if err != nil { return ConfigErr{ErrStage, err} } - err = registry.InsertNBTDataIntoRegistry(&c.Registries, string(registryID), string(entryId), data) + err = registry.InsertWithNBT(string(entryId), data) if err != nil { return ConfigErr{ErrStage, err} } diff --git a/registry/codec.go b/registry/codec.go index 30a1282..9491561 100644 --- a/registry/codec.go +++ b/registry/codec.go @@ -1,8 +1,6 @@ package registry import ( - "errors" - "fmt" "reflect" "github.com/Tnze/go-mc/chat" @@ -58,41 +56,22 @@ type Dimension struct { MonsterSpawnBlockLightLimit int32 `nbt:"monster_spawn_block_light_limit"` } -// InsertNBTDataIntoRegistry insert data (entry, data) into the registry. -// The codec should be a pointer of a struct. And the registry should be a field of the codec struct. -// -// This function is a temporary solution while the registry system isn't implemented well. -func InsertNBTDataIntoRegistry(codec any, registry, entry string, data nbt.RawMessage) error { - codecVal := reflect.ValueOf(codec) - if codecVal.Kind() != reflect.Pointer { - return errors.New("codec is not a pointer") - } - - codecVal = codecVal.Elem() - if codecVal.Kind() != reflect.Struct { - return errors.New("codec is not a pointer of struct") - } - +func (c *NetworkCodec) Registry(id string) RegistryHandler { + codecVal := reflect.ValueOf(c).Elem() codecTyp := codecVal.Type() - numField := codecVal.NumField() for i := 0; i < numField; i++ { registryID, ok := codecTyp.Field(i).Tag.Lookup("registry") if !ok { continue } - if registryID == registry { - fieldVal := codecVal.Field(i).Addr() - args := []reflect.Value{reflect.ValueOf(entry), reflect.ValueOf(data)} - err := fieldVal.MethodByName("InsertNBT").Call(args)[0] - if !err.IsNil() { - return err.Interface().(error) - } - if registry == "minecraft:chat_type" { - fmt.Println(fieldVal.Interface()) - } - return nil + if registryID == id { + return codecVal.Field(i).Addr().Interface().(RegistryHandler) } } - return errors.New("registry " + registry + " not found in the codec") + return nil +} + +type RegistryHandler interface { + InsertWithNBT(name string, data nbt.RawMessage) error } diff --git a/registry/registry.go b/registry/registry.go index 065d53e..78e4b7b 100644 --- a/registry/registry.go +++ b/registry/registry.go @@ -35,16 +35,21 @@ func (r *Registry[E]) FindByID(id int32) *E { } func (r *Registry[E]) Insert(name string, data E) { - r.Value = append(r.Value, Entry[E]{Name: name, Element: data}) + entry := Entry[E]{ + Name: name, + ID: int32(len(r.Value)), + Element: data, + } + r.Value = append(r.Value, entry) } -func (r *Registry[E]) InsertNBT(name string, data nbt.RawMessage) error { - entry := Entry[E]{Name: name, ID: int32(len(r.Value))} +func (r *Registry[E]) InsertWithNBT(name string, data nbt.RawMessage) error { + var elem E if data.Type != 0 { - if err := data.UnmarshalDisallowUnknownField(&entry.Element); err != nil { + if err := data.UnmarshalDisallowUnknownField(&elem); err != nil { return err } } - r.Value = append(r.Value, entry) + r.Insert(name, elem) return nil }