package mapping import ( "github.com/akmalfairuz/legacy-version/internal" "github.com/df-mc/worldupgrader/blockupgrader" "github.com/sandertv/gophertunnel/minecraft/protocol" "golang.org/x/exp/maps" ) func convert(entries []protocol.BlockEntry) (states []blockupgrader.BlockState) { for _, entry := range entries { propertiesMap := map[string][]any{} if props := jsonCheck[[]any](entry.Properties, "properties"); props != nil { for _, prop := range *props { prop := prop.(map[string]any) name := jsonCheck[string](prop, "name") enum := jsonCheck[[]any](prop, "enum") if enum == nil { int32Enum := jsonCheck[[]int32](prop, "enum") if int32Enum != nil { enum = &[]any{} for _, i := range *int32Enum { *enum = append(*enum, i) } } } if name == nil || enum == nil { panic("could not find field `name` and `enum`") } propertiesMap[*name] = *enum } } combinations := make([]map[string]any, 0) generateCombinationsRecursively(propertiesMap, internal.NewIterator(maps.Keys(propertiesMap)), map[string]any{}, &combinations) if len(combinations) == 0 { combinations = append(combinations, map[string]any{}) } for _, combination := range combinations { blockState := blockupgrader.BlockState{ Name: entry.Name, Properties: combination, } states = append(states, blockState) } } return } func generateCombinationsRecursively[K comparable, V any](all map[K][]V, iterator *internal.Iterator[K], current map[K]V, output *[]map[K]V) { if !iterator.HasNext() { entry := map[K]V{} for k, v := range current { entry[k] = v } out := append(*output, entry) *output = out } else { key := iterator.Next() set := all[key] for _, value := range set { current[key] = value generateCombinationsRecursively[K, V](all, iterator, current, output) delete(current, key) } iterator.Previous() } } func jsonCheck[T any](json map[string]any, field string) *T { fieldValue, found := json[field] if !found { return nil } castedValue, ok := fieldValue.(T) if !ok { return nil } return &castedValue }