From 9a6da5b3bf94369f7a56d61d2041ca9ac9e09116 Mon Sep 17 00:00:00 2001 From: CornWorld Date: Sat, 27 Jan 2024 16:30:09 +0800 Subject: [PATCH] [Feat] Support new map string format --- .../utils/pkg/map/blockManager/register.go | 10 ++ packages/server/utils/pkg/map/map.go | 133 ++++++++++++++++++ packages/server/utils/pkg/map/map_test.go | 49 +++++++ 3 files changed, 192 insertions(+) create mode 100644 packages/server/utils/pkg/map/map_test.go diff --git a/packages/server/utils/pkg/map/blockManager/register.go b/packages/server/utils/pkg/map/blockManager/register.go index 980d9e9..4c800a8 100644 --- a/packages/server/utils/pkg/map/blockManager/register.go +++ b/packages/server/utils/pkg/map/blockManager/register.go @@ -8,12 +8,22 @@ import ( type tranFunc func(_type.Block) _type.Block var transBlockTypeFunc map[uint8]tranFunc +var GetBlockIdByName map[string]uint8 +var GetMetaById map[uint8]_type.Meta func Register(meta _type.Meta, transFunc tranFunc) { if transBlockTypeFunc == nil { transBlockTypeFunc = make(map[uint8]tranFunc) } + if GetBlockIdByName == nil { + GetBlockIdByName = make(map[string]uint8) + } + if GetMetaById == nil { + GetMetaById = make(map[uint8]_type.Meta) + } + GetBlockIdByName[meta.Name] = meta.BlockId + GetMetaById[meta.BlockId] = meta transBlockTypeFunc[meta.BlockId] = transFunc logrus.Println("Registered a block type", "id:", meta.BlockId, " name:", meta.Name, " description:", meta.Description) } diff --git a/packages/server/utils/pkg/map/map.go b/packages/server/utils/pkg/map/map.go index 05698b0..f3904f1 100644 --- a/packages/server/utils/pkg/map/map.go +++ b/packages/server/utils/pkg/map/map.go @@ -2,11 +2,13 @@ package _map import ( "encoding/json" + "fmt" "github.com/sirupsen/logrus" "server/utils/pkg/instruction" "server/utils/pkg/map/blockManager" "server/utils/pkg/map/type" "strconv" + "strings" ) type MapSize struct{ W, H uint8 } @@ -213,3 +215,134 @@ func FullStr2GameMap(mapId uint32, originalMapStr string) *Map { mapInfo{size, mapId}, } } + +// To marshal uint8 array to json as number array +type uint8Array []uint8 + +func (a uint8Array) MarshalJSON() ([]byte, error) { + var res string + if a == nil { + res = "null" + } else { + res = strings.Join(strings.Fields(fmt.Sprintf("%d", a)), ",") + } + return []byte(res), nil +} + +type mapJsonStruct struct { + Mappings struct { + Block []string `json:"block"` + Owner []uint16 `json:"owner,omitempty"` + } `json:"mappings"` + Type []uint8Array `json:"type"` + Owner []uint8Array `json:"owner,omitempty"` + Number [][]uint16 `json:"number,omitempty"` +} + +func JsonStrToMap(jsonStr string) *Map { + var res mapJsonStruct + if err := json.Unmarshal([]byte(jsonStr), &res); err != nil { + logrus.Panic(err) + return nil + } + + // process original mapping + blockMapping := make(map[uint8]uint8) + for i, v := range res.Mappings.Block { + blockMapping[uint8(i)] = blockManager.GetBlockIdByName[v] + } + + if res.Mappings.Owner == nil || res.Owner == nil { + res.Mappings.Owner = nil + res.Owner = nil + } else { + // add blank at 0 owner id + res.Mappings.Owner = append([]uint16{0}, res.Mappings.Owner...) + } + + var blocks [][]_type.Block + if (res.Number != nil && len(res.Type) != len(res.Number)) || (res.Owner != nil && len(res.Type) != len(res.Owner)) { + logrus.Panic("original block type, number, owner id must have the same size") + } + blocks = make([][]_type.Block, len(res.Type)) + + for i, v := range res.Type { + if (res.Number != nil && len(v) != len(res.Number[i])) || (res.Owner != nil && len(v) != len(res.Owner[i])) { + logrus.Panic("original block type, number, owner id must have the same size") + } + blocks[i] = make([]_type.Block, len(v)) + + for j, typeId := range v { + n := uint16(0) + o := uint16(0) + if res.Owner != nil { + if res.Owner[i][j] >= uint8(len(res.Mappings.Owner)) { + logrus.Panic("original owner id must be less than owner id mapping size") + } + + o = res.Mappings.Owner[res.Owner[i][j]] + } + if res.Number != nil { + n = res.Number[i][j] + } + + if typeId >= uint8(len(blockMapping)) { + logrus.Panic("original block type must be less than block type mapping size") + } + + blocks[i][j] = blockManager.NewBlock(blockMapping[typeId], n, o) + } + } + return &Map{ + blocks, + mapInfo{MapSize{uint8(len(blocks[0])), uint8(len(blocks))}, 0}, + } +} + +func MapToJsonStr(m *Map) string { + var ret = mapJsonStruct{} + typeMapping := make(map[uint8]uint8) + ownerMapping := make(map[uint16]uint8) + ownerMapping[0] = 0 // blank owner id + + ret.Type = make([]uint8Array, m.size.H) + ret.Owner = make([]uint8Array, m.size.H) + ret.Number = make([][]uint16, m.size.H) + + for i, row := range m.blocks { + ret.Type[i] = make(uint8Array, m.size.W) + ret.Owner[i] = make(uint8Array, m.size.W) + ret.Number[i] = make([]uint16, m.size.W) + + for j, b := range row { + if _, ok := typeMapping[b.Meta().BlockId]; !ok { + typeMapping[b.Meta().BlockId] = uint8(len(typeMapping)) + } + if _, ok := ownerMapping[b.OwnerId()]; !ok { + ownerMapping[b.OwnerId()] = uint8(len(ownerMapping)) + } + + ret.Type[i][j] = typeMapping[b.Meta().BlockId] + ret.Owner[i][j] = ownerMapping[b.OwnerId()] + ret.Number[i][j] = b.Number() + } + } + + for k := range typeMapping { + ret.Mappings.Block = append(ret.Mappings.Block, blockManager.GetMetaById[k].Name) + } + for k := range ownerMapping { + ret.Mappings.Owner = append(ret.Mappings.Owner, k) + } + + ret.Mappings.Owner = ret.Mappings.Owner[1:] // remove blank owner id + + logrus.Info(ret) + + if retJson, err := json.Marshal(ret); err != nil { + logrus.Panic(err) + return "" + } else { + return string(retJson) + } +} diff --git a/packages/server/utils/pkg/map/map_test.go b/packages/server/utils/pkg/map/map_test.go new file mode 100644 index 0000000..1644c2c --- /dev/null +++ b/packages/server/utils/pkg/map/map_test.go @@ -0,0 +1,49 @@ +package _map + +import ( + _ "server/utils/pkg/map/blockManager/block" + "testing" +) + +func TestMapToJsonStr(t *testing.T) { + t.Run("t1", func(t *testing.T) { + str := ` + { + "mappings": { + "block":[ + "blank", + "castle", + "king", + "mountain", + "soldier" + ], + "owner": [ + 1, + 2 + ] + }, + "type": [ + [1, 0, 0, 0], + [0, 2, 3, 0], + [0, 3, 2, 0], + [0, 0, 0, 1] + ], + "owner": [ + [0, 0, 0, 0], + [0, 1, 0, 0], + [0, 0, 2, 0], + [0, 0, 0, 0] + ], + "number": [ + [43, 0, 0, 0], + [0, 1, 0, 0], + [0, 0, 1, 0], + [0, 0, 0, 43] + ] + } +` + m := JsonStrToMap(str) + got := MapToJsonStr(m) + t.Log(got) + }) +}