package personal_world import ( "chain/runtime" "gno.land/p/nt/avl" "gno.land/p/nt/ufmt" ) var ( verifierStore = avl.NewTree() // worldID -> map[chunkKey]verifier ) func SetChunkVerifier(cur realm, worldID uint32, chunkKey string, verifier string) { caller := runtime.PreviousRealm().Address() assertIsAdminOrOperator(caller) worldIDStr := ufmt.Sprintf("%d", worldID) var chunkMap map[string]string if value, exists := verifierStore.Get(worldIDStr); exists { chunkMap = value.(map[string]string) } else { chunkMap = make(map[string]string) verifierStore.Set(worldIDStr, chunkMap) } chunkMap[chunkKey] = verifier } // SetChunkVerifiers sets multiple chunk verifiers at once using direct string traversal. // chunkKeys and verifiers are comma-separated strings with matching item counts. // Example: chunkKeys="0_0,0_1,1_0", verifiers="hash1,hash2,hash3" func SetChunkVerifiers(cur realm, worldID uint32, chunkKeys string, verifiers string) { caller := runtime.PreviousRealm().Address() assertIsAdminOrOperator(caller) if chunkKeys == "" { panic("chunkKeys must not be empty") } if verifiers == "" { panic("verifiers must not be empty") } worldIDStr := ufmt.Sprintf("%d", worldID) var chunkMap map[string]string if value, exists := verifierStore.Get(worldIDStr); exists { chunkMap = value.(map[string]string) } else { chunkMap = make(map[string]string) verifierStore.Set(worldIDStr, chunkMap) } // Direct string traversal parsing (no strings.Split) keyStart, valStart := 0, 0 keyIdx, valIdx := 0, 0 count := 0 for { // Find next delimiter or end for keys for keyIdx < len(chunkKeys) && chunkKeys[keyIdx] != ',' { keyIdx++ } // Find next delimiter or end for values for valIdx < len(verifiers) && verifiers[valIdx] != ',' { valIdx++ } // Extract key and value key := chunkKeys[keyStart:keyIdx] val := verifiers[valStart:valIdx] // Validate: no empty keys or values allowed if key == "" { panic("empty chunkKey not allowed") } if val == "" { panic("empty verifier not allowed") } chunkMap[key] = val count++ // Check end conditions keyEnd := keyIdx >= len(chunkKeys) valEnd := valIdx >= len(verifiers) // Validate: both must end at the same time (same item count) if keyEnd != valEnd { panic("chunkKeys and verifiers count mismatch") } if keyEnd { break } // Move past the delimiter keyIdx++ valIdx++ keyStart = keyIdx valStart = valIdx } } func GetChunkVerifier(worldID uint32, chunkKey string) string { worldIDStr := ufmt.Sprintf("%d", worldID) if value, exists := verifierStore.Get(worldIDStr); exists { chunkMap := value.(map[string]string) return chunkMap[chunkKey] } return "" } func ListChunkVerifiers(worldID uint32, chunkKeys ...string) []map[string]string { if len(chunkKeys) > batchLimit { panic("chunkKeys exceeds batchLimit") } result := make([]map[string]string, 0, len(chunkKeys)) if len(chunkKeys) == 0 { return result } for _, chunkKey := range chunkKeys { verifier := GetChunkVerifier(worldID, chunkKey) if verifier != "" { result = append(result, map[string]string{"chunkKey": chunkKey, "status": "found", "verifier": verifier}) } else { result = append(result, map[string]string{"chunkKey": chunkKey, "status": "not_found"}) } } return result } func deleteWorldChunkVerifiers(worldID uint32) { worldIDStr := ufmt.Sprintf("%d", worldID) verifierStore.Remove(worldIDStr) }