diff --git a/cmd/strom/data/main.go b/cmd/strom/data/main.go new file mode 100644 index 0000000..a2b6977 --- /dev/null +++ b/cmd/strom/data/main.go @@ -0,0 +1,118 @@ +package data + +import ( + "encoding/json" + "fmt" + "maps" + "os" + "slices" + + "github.com/admin-else/strom/data" + "github.com/admin-else/strom/proto_generated" + "github.com/admin-else/strom/util" +) + +// strom data 1.21.11 blocks id 0 name => air +// { +// "id": 0, +// "name": "air", +// "displayName": "Air", +// "hardness": 0.0, +// "resistance": 0.0, +// "stackSize": 64, +// "diggable": false, +// "material": "default", +// "transparent": true, +// "emitLight": 0, +// "filterLight": 0, +// "defaultState": 0, +// "minStateId": 0, +// "maxStateId": 0, +// "states": [], +// "drops": [], +// "boundingBox": "empty" +// }, + +func Run(args []string) (err error) { + var dataValues any + switch len(args) { + case 0: // print available versions + dataValues = proto_generated.SupportedVersions + case 1: // print available data for version + dataValues = slices.Collect(maps.Keys(data.Paths.Data[args[0]])) + case 2: + err = data.LoadVersionedJson(args[0], args[1], &dataValues) + case 3: + err = data.LoadVersionedJson(args[0], args[1], &dataValues) + if err != nil { + return + } + var dataSlices []any + dataSlices, err = util.AssertTypeError[[]any](dataValues) + if err != nil { + return + } + var result = make([]any, len(dataSlices)) + for _, v := range dataSlices { + var dataMap map[string]any + dataMap, err = util.AssertTypeError[map[string]any](v) + if err != nil { + return + } + var vToAppend any + vToAppend, err = util.MapGetError(dataMap, args[2]) + if err != nil { + return + } + result = append(result, vToAppend) + } + dataValues = result + case 4, 5: + err = data.LoadVersionedJson(args[0], args[1], &dataValues) + if err != nil { + return + } + var dataSlices []any + dataSlices, err = util.AssertTypeError[[]any](dataValues) + if err != nil { + return + } + found := false + for _, v := range dataSlices { + var dataMap map[string]any + dataMap, err = util.AssertTypeError[map[string]any](v) + if err != nil { + return + } + if v2, ok := dataMap[args[2]]; ok { + if args[3] != fmt.Sprint(v2) { + continue + } + + dataValues = dataMap + found = true + if len(args) == 5 { + dataValues, err = util.MapGetError(dataMap, args[4]) + if err != nil { + return + } + } + break + } + } + if !found { + err = fmt.Errorf("not found") + return + } + default: + err = fmt.Errorf("too many arguments") + } + + if err == nil { + e := json.NewEncoder(os.Stdout) + e.SetIndent("", " ") + err = e.Encode(dataValues) + return + } + return +} diff --git a/cmd/strom/main.go b/cmd/strom/main.go index 6f9ae38..bf447b8 100644 --- a/cmd/strom/main.go +++ b/cmd/strom/main.go @@ -10,6 +10,7 @@ import ( "slices" "github.com/admin-else/strom/cmd/strom/api" + "github.com/admin-else/strom/cmd/strom/data" "github.com/admin-else/strom/cmd/strom/extract_mca" "github.com/admin-else/strom/cmd/strom/offline_uuid" "github.com/admin-else/strom/cmd/strom/packet_inspector" @@ -41,6 +42,7 @@ var subcommands = map[string]func(args []string) error{ "api": api.Run, "version": Version, "extract-mca": extract_mca.Run, + "data": data.Run, } func Help(args []string) (err error) { diff --git a/util/must.go b/util/must.go index 6ecbe3b..a2332d6 100644 --- a/util/must.go +++ b/util/must.go @@ -1,5 +1,7 @@ package util +import "fmt" + func MustOk[T any](v T, ok bool) T { if !ok { panic("not ok") @@ -19,3 +21,20 @@ func Must(err error) { panic(err) } } + +func AssertTypeError[T any](v any) (T, error) { + var zero T + r, ok := v.(T) + if !ok { + return zero, fmt.Errorf("type assertion failed: %T cannot be asserted to %T", v, zero) + } + return r, nil +} + +func MapGetError[K comparable, V any, M map[K]V](m M, k K) (V, error) { + v, ok := m[k] + if !ok { + return v, fmt.Errorf("key %v not found", k) + } + return v, nil +}