Search Apps Documentation Source Content File Folder Download Copy Actions Download

verifier.gno

2.85 Kb · 105 lines
  1package personal_world
  2
  3import (
  4	"gno.land/p/akkadia/v0/accesscontrol"
  5	"gno.land/r/akkadia/v0/admin"
  6)
  7
  8// SetChunkVerifier stores verifier for a specific chunk key of a world.
  9func SetChunkVerifier(cur realm, worldID uint32, chunkKey string, verifier string) {
 10	assertNotFrozen()
 11	accesscontrol.AssertIsAdminOrOperator(0, cur, admin.IsAdmin, admin.IsOperator)
 12
 13	canonicalChunkKey := normalizeChunkKey(worldID, chunkKey)
 14	verifierStore.Set(worldID, canonicalChunkKey, verifier)
 15}
 16
 17// SetChunkVerifiers sets multiple chunk verifiers at once using direct string traversal.
 18// chunkKeys and verifiers are comma-separated strings with matching item counts.
 19// Example: chunkKeys="1:0_0,1:0_1", verifiers="a1b2c3d4,e5f6a7b8"
 20func SetChunkVerifiers(cur realm, worldID uint32, chunkKeys string, verifiers string) {
 21	assertNotFrozen()
 22	accesscontrol.AssertIsAdminOrOperator(0, cur, admin.IsAdmin, admin.IsOperator)
 23
 24	if chunkKeys == "" {
 25		panic("chunkKeys must not be empty")
 26	}
 27	if verifiers == "" {
 28		panic("verifiers must not be empty")
 29	}
 30
 31	// Direct string traversal parsing (no strings.Split)
 32	keyStart, valStart := 0, 0
 33	keyIdx, valIdx := 0, 0
 34	count := 0
 35
 36	for {
 37		// Find next delimiter or end for keys
 38		for keyIdx < len(chunkKeys) && chunkKeys[keyIdx] != ',' {
 39			keyIdx++
 40		}
 41		// Find next delimiter or end for values
 42		for valIdx < len(verifiers) && verifiers[valIdx] != ',' {
 43			valIdx++
 44		}
 45
 46		// Extract key and value
 47		key := chunkKeys[keyStart:keyIdx]
 48		val := verifiers[valStart:valIdx]
 49
 50		// Validate: no empty keys or values allowed
 51		if val == "" {
 52			panic("empty verifier not allowed")
 53		}
 54
 55		count++
 56		assertBatchLimit("chunkKeys", count)
 57		canonicalChunkKey := normalizeChunkKey(worldID, key)
 58		verifierStore.Set(worldID, canonicalChunkKey, val)
 59
 60		// Check end conditions
 61		keyEnd := keyIdx >= len(chunkKeys)
 62		valEnd := valIdx >= len(verifiers)
 63
 64		// Validate: both must end at the same time (same item count)
 65		if keyEnd != valEnd {
 66			panic("chunkKeys and verifiers count mismatch")
 67		}
 68		if keyEnd {
 69			break
 70		}
 71
 72		// Move past the delimiter
 73		keyIdx++
 74		valIdx++
 75		keyStart = keyIdx
 76		valStart = valIdx
 77	}
 78}
 79
 80func GetChunkVerifier(worldID uint32, chunkKey string) string {
 81	assertMigrationStateAvailable()
 82	canonicalChunkKey := normalizeChunkKey(worldID, chunkKey)
 83	verifier, found := verifierStore.Get(worldID, canonicalChunkKey)
 84	if !found {
 85		return ""
 86	}
 87	return verifier
 88}
 89
 90func ListChunkVerifiers(worldID uint32, chunkKeys ...string) []map[string]string {
 91	assertMigrationStateAvailable()
 92	assertListLimit("chunkKeys", len(chunkKeys))
 93	result := []map[string]string{}
 94	for _, chunkKey := range chunkKeys {
 95		canonicalChunkKey := normalizeChunkKey(worldID, chunkKey)
 96		verifier, found := verifierStore.Get(worldID, canonicalChunkKey)
 97		if found {
 98			result = append(result, map[string]string{
 99				"chunkKey": canonicalChunkKey,
100				"verifier": verifier,
101			})
102		}
103	}
104	return result
105}