Search Apps Documentation Source Content File Folder Download Copy Actions Download

data.gno

3.39 Kb ยท 142 lines
  1package personal_world
  2
  3import (
  4	"chain/runtime"
  5
  6	"gno.land/p/nt/avl"
  7	"gno.land/p/nt/ufmt"
  8)
  9
 10var (
 11	verifierStore = avl.NewTree() // worldID -> map[chunkKey]verifier
 12)
 13
 14func SetChunkVerifier(cur realm, worldID uint32, chunkKey string, verifier string) {
 15	caller := runtime.PreviousRealm().Address()
 16	assertIsAdminOrOperator(caller)
 17
 18	worldIDStr := ufmt.Sprintf("%d", worldID)
 19	var chunkMap map[string]string
 20
 21	if value, exists := verifierStore.Get(worldIDStr); exists {
 22		chunkMap = value.(map[string]string)
 23	} else {
 24		chunkMap = make(map[string]string)
 25		verifierStore.Set(worldIDStr, chunkMap)
 26	}
 27
 28	chunkMap[chunkKey] = verifier
 29}
 30
 31// SetChunkVerifiers sets multiple chunk verifiers at once using direct string traversal.
 32// chunkKeys and verifiers are comma-separated strings with matching item counts.
 33// Example: chunkKeys="0_0,0_1,1_0", verifiers="hash1,hash2,hash3"
 34func SetChunkVerifiers(cur realm, worldID uint32, chunkKeys string, verifiers string) {
 35	caller := runtime.PreviousRealm().Address()
 36	assertIsAdminOrOperator(caller)
 37
 38	if chunkKeys == "" {
 39		panic("chunkKeys must not be empty")
 40	}
 41	if verifiers == "" {
 42		panic("verifiers must not be empty")
 43	}
 44
 45	worldIDStr := ufmt.Sprintf("%d", worldID)
 46	var chunkMap map[string]string
 47
 48	if value, exists := verifierStore.Get(worldIDStr); exists {
 49		chunkMap = value.(map[string]string)
 50	} else {
 51		chunkMap = make(map[string]string)
 52		verifierStore.Set(worldIDStr, chunkMap)
 53	}
 54
 55	// Direct string traversal parsing (no strings.Split)
 56	keyStart, valStart := 0, 0
 57	keyIdx, valIdx := 0, 0
 58	count := 0
 59
 60	for {
 61		// Find next delimiter or end for keys
 62		for keyIdx < len(chunkKeys) && chunkKeys[keyIdx] != ',' {
 63			keyIdx++
 64		}
 65		// Find next delimiter or end for values
 66		for valIdx < len(verifiers) && verifiers[valIdx] != ',' {
 67			valIdx++
 68		}
 69
 70		// Extract key and value
 71		key := chunkKeys[keyStart:keyIdx]
 72		val := verifiers[valStart:valIdx]
 73
 74		// Validate: no empty keys or values allowed
 75		if key == "" {
 76			panic("empty chunkKey not allowed")
 77		}
 78		if val == "" {
 79			panic("empty verifier not allowed")
 80		}
 81
 82		chunkMap[key] = val
 83		count++
 84
 85		// Check end conditions
 86		keyEnd := keyIdx >= len(chunkKeys)
 87		valEnd := valIdx >= len(verifiers)
 88
 89		// Validate: both must end at the same time (same item count)
 90		if keyEnd != valEnd {
 91			panic("chunkKeys and verifiers count mismatch")
 92		}
 93		if keyEnd {
 94			break
 95		}
 96
 97		// Move past the delimiter
 98		keyIdx++
 99		valIdx++
100		keyStart = keyIdx
101		valStart = valIdx
102	}
103}
104
105func GetChunkVerifier(worldID uint32, chunkKey string) string {
106	worldIDStr := ufmt.Sprintf("%d", worldID)
107
108	if value, exists := verifierStore.Get(worldIDStr); exists {
109		chunkMap := value.(map[string]string)
110		return chunkMap[chunkKey]
111	}
112
113	return ""
114}
115
116func ListChunkVerifiers(worldID uint32, chunkKeys ...string) []map[string]string {
117	if len(chunkKeys) > batchLimit {
118		panic("chunkKeys exceeds batchLimit")
119	}
120
121	result := make([]map[string]string, 0, len(chunkKeys))
122	if len(chunkKeys) == 0 {
123		return result
124	}
125
126	for _, chunkKey := range chunkKeys {
127		verifier := GetChunkVerifier(worldID, chunkKey)
128
129		if verifier != "" {
130			result = append(result, map[string]string{"chunkKey": chunkKey, "status": "found", "verifier": verifier})
131		} else {
132			result = append(result, map[string]string{"chunkKey": chunkKey, "status": "not_found"})
133		}
134	}
135
136	return result
137}
138
139func deleteWorldChunkVerifiers(worldID uint32) {
140	worldIDStr := ufmt.Sprintf("%d", worldID)
141	verifierStore.Remove(worldIDStr)
142}