Skip to content

Commit

Permalink
[Feat] Support new map string format
Browse files Browse the repository at this point in the history
  • Loading branch information
CornWorld committed Jan 27, 2024
1 parent 644b073 commit 9a6da5b
Show file tree
Hide file tree
Showing 3 changed files with 192 additions and 0 deletions.
10 changes: 10 additions & 0 deletions packages/server/utils/pkg/map/blockManager/register.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
Expand Down
133 changes: 133 additions & 0 deletions packages/server/utils/pkg/map/map.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 }
Expand Down Expand Up @@ -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)
}
}
49 changes: 49 additions & 0 deletions packages/server/utils/pkg/map/map_test.go
Original file line number Diff line number Diff line change
@@ -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)
})
}

0 comments on commit 9a6da5b

Please sign in to comment.