chunk_key.gno
2.34 Kb · 91 lines
1package chunk
2
3import (
4 "strconv"
5 "strings"
6)
7
8// formatWorldID converts a world ID to a string key for storage lookups
9func formatWorldID(worldID uint32) string {
10 return strconv.FormatUint(uint64(worldID), 10)
11}
12
13// buildChunkKey constructs the on-chain chunk key: "worldID:x_y"
14func buildChunkKey(worldID uint32, x, y int) string {
15 return strconv.FormatUint(uint64(worldID), 10) + ":" + strconv.Itoa(x) + "_" + strconv.Itoa(y)
16}
17
18// parseChunkKey parses "worldID:x_y" into (worldID, x, y)
19func parseChunkKey(chunkKey string) (uint32, int, int) {
20 parts := strings.SplitN(chunkKey, ":", 2)
21 if len(parts) != 2 {
22 panic("invalid chunkKey format: " + chunkKey)
23 }
24
25 worldID, err := strconv.ParseUint(parts[0], 10, 32)
26 if err != nil {
27 panic("invalid worldID in chunkKey: " + chunkKey)
28 }
29
30 coords := strings.SplitN(parts[1], "_", 2)
31 if len(coords) != 2 {
32 panic("invalid coordinates in chunkKey: " + chunkKey)
33 }
34
35 x, errX := strconv.Atoi(coords[0])
36 if errX != nil {
37 panic("invalid x in chunkKey: " + chunkKey)
38 }
39
40 y, errY := strconv.Atoi(coords[1])
41 if errY != nil {
42 panic("invalid y in chunkKey: " + chunkKey)
43 }
44
45 return uint32(worldID), x, y
46}
47
48// buildCoordKey builds "x_y" coordinate string
49func buildCoordKey(x, y int) string {
50 return strconv.Itoa(x) + "_" + strconv.Itoa(y)
51}
52
53// normalizeChunkKey validates and canonicalizes the required world prefix.
54// Accepts only "worldID:x_y", returns canonical "worldID:x_y".
55func normalizeChunkKey(worldID uint32, chunkKey string) string {
56 if chunkKey == "" {
57 panic("empty chunkKey not allowed")
58 }
59
60 colon := strings.Index(chunkKey, ":")
61 if colon == -1 {
62 panic("chunkKey must include worldID prefix: worldID:x_y")
63 }
64
65 keyWorldID := chunkKey[:colon]
66 expected := formatWorldID(worldID)
67 if keyWorldID != expected {
68 panic("chunkKey worldID mismatch: expected " + expected + ", got " + keyWorldID)
69 }
70 coordKey := chunkKey[colon+1:]
71
72 x, y := parseCoordKey(coordKey)
73 return buildChunkKey(worldID, x, y)
74}
75
76// parseCoordKey parses "x_y" into (x, y)
77func parseCoordKey(coordKey string) (int, int) {
78 idx := strings.Index(coordKey, "_")
79 if idx == -1 {
80 panic("invalid coordKey: " + coordKey)
81 }
82 x, errX := strconv.Atoi(coordKey[:idx])
83 if errX != nil {
84 panic("invalid x in coordKey: " + coordKey)
85 }
86 y, errY := strconv.Atoi(coordKey[idx+1:])
87 if errY != nil {
88 panic("invalid y in coordKey: " + coordKey)
89 }
90 return x, y
91}