Kind Realm (renderable)
Name game_world
Namespace akkadia / beta
Exported functions 18
Module gno.land/r/akkadia/beta/game_world
gno 0.9 policy.gno gno
⧉
1 package game_world 2 3 import ( 4 "chain" 5 "strconv" 6 7 "gno.land/p/akkadia/beta/accesscontrol" 8 AddApprovedCreator (cur interface {.seal func(); Address func() .uverse.address; IsCode func() bool; IsCurrent func() bool; IsEphemeral func() bool; IsUser func() bool; IsUserCall func() bool; IsUserRun func() bool; PkgPath func() string; Previous func() .uverse.realm; String func() string; Sub func(string) .uverse.realm; Subpath func() string}, gameType string, creator string)
CreateGameWorld (cur interface {.seal func(); Address func() .uverse.address; IsCode func() bool; IsCurrent func() bool; IsEphemeral func() bool; IsUser func() bool; IsUserCall func() bool; IsUserRun func() bool; PkgPath func() string; Previous func() .uverse.realm; String func() string; Sub func(string) .uverse.realm; Subpath func() string}, gameType string) uint64
GetApprovedCreatorCount (gameType string) int
GetGameTypePolicy (gameType string) struct{CreationCost int64; CreationMode gno.land/r/akkadia/beta/game_world.CreationMode}
GetGameWorld (gameWorldID uint64) struct{ID uint64; Owner .uverse.address; GameType string; Status gno.land/r/akkadia/beta/game_world.GameWorldStatus; CreatedHeight int64; RestrictedHeight int64}
GetLatestGameWorldID () uint64
GetListLimit () int
GetRestrictedGameWorldCount () int
HasGameTypePolicy (gameType string) bool
HasGameWorld (gameWorldID uint64) bool
IsApprovedCreator (gameType string, creator string) bool
ListApprovedCreators (gameType string, offset int, count int) [].uverse.address
ListLatestGameWorldsByOwner (owner string) []gno.land/r/akkadia/beta/game_world.GameWorld
ListRestrictedGameWorldIDs (page int, count int) []uint64
RemoveApprovedCreator (cur interface {.seal func(); Address func() .uverse.address; IsCode func() bool; IsCurrent func() bool; IsEphemeral func() bool; IsUser func() bool; IsUserCall func() bool; IsUserRun func() bool; PkgPath func() string; Previous func() .uverse.realm; String func() string; Sub func(string) .uverse.realm; Subpath func() string}, gameType string, creator string)
RestrictGameWorld (cur interface {.seal func(); Address func() .uverse.address; IsCode func() bool; IsCurrent func() bool; IsEphemeral func() bool; IsUser func() bool; IsUserCall func() bool; IsUserRun func() bool; PkgPath func() string; Previous func() .uverse.realm; String func() string; Sub func(string) .uverse.realm; Subpath func() string}, gameWorldID uint64)
SetApprovedCreators (cur interface {.seal func(); Address func() .uverse.address; IsCode func() bool; IsCurrent func() bool; IsEphemeral func() bool; IsUser func() bool; IsUserCall func() bool; IsUserRun func() bool; PkgPath func() string; Previous func() .uverse.realm; String func() string; Sub func(string) .uverse.realm; Subpath func() string}, gameType string, creatorsCSV string, approved bool)
SetGameTypePolicy (cur interface {.seal func(); Address func() .uverse.address; IsCode func() bool; IsCurrent func() bool; IsEphemeral func() bool; IsUser func() bool; IsUserCall func() bool; IsUserRun func() bool; PkgPath func() string; Previous func() .uverse.realm; String func() string; Sub func(string) .uverse.realm; Subpath func() string}, gameType string, creationCost int64, mode int)
Signatures reconstructed verbatim from vm/qfuncs — interface params keep their inline definitions.
Render unavailable
rate limit exceeded — the render query is served by the Gnoland archive RPC.
vm/qrender output, sanitized (docs/render-security.md) and displayed in an empty-sandbox iframe — scripts, forms and popups cannot run. Links stay inert in-preview; right-click to open.
"gno.land/p/nt/bptree/v0"
9 "gno.land/r/akkadia/beta/admin"
10 )
11
12 const (
13 SetGameTypePolicyEvent = "SetGameTypePolicy"
14 AddApprovedCreatorEvent = "AddApprovedCreator"
15 RemoveApprovedCreatorEvent = "RemoveApprovedCreator"
16 SetApprovedCreatorsEvent = "SetApprovedCreators"
17 approvedCreatorListMax = 100
18 approvedCreatorBatchMax = 100
19 gameTypeMaxLen = 64
20 )
21
22 var (
23 gameTypePolicies *bptree.BPTree
24 approvedCreators *bptree.BPTree
25 )
26
27 func init() {
28 initializePolicyState()
29 }
30
31 func SetGameTypePolicy(cur realm, gameType string , creationCost int64 , mode CreationMode) {
32 executor := accesscontrol.MustGetAdminOrOperatorCaller( 0 , cur, admin.IsAdmin, admin.IsOperator)
33 assertValidGameType(gameType)
34 if creationCost < 0 {
35 panic( "creation cost must not be negative" )
36 }
37 assertValidCreationMode(mode)
38
39 oldValue := gameTypePolicies.Get(gameType)
40 old := GameTypePolicy{}
41 found := oldValue != nil
42 if found {
43 old = oldValue.(GameTypePolicy)
44 }
45 if found && old.CreationCost == creationCost && old.CreationMode == mode {
46 return
47 }
48 gameTypePolicies.Set(gameType, GameTypePolicy{CreationCost: creationCost, CreationMode: mode})
49 chain.Emit(
50 SetGameTypePolicyEvent,
51 "executor" , executor.String(),
52 "gameType" , gameType,
53 "oldCreationCost" , strconv.FormatInt(old.CreationCost, 10 ),
54 "newCreationCost" , strconv.FormatInt(creationCost, 10 ),
55 "oldCreationMode" , strconv.Itoa( int (old.CreationMode)),
56 "newCreationMode" , strconv.Itoa( int (mode)),
57 )
58 }
59
60 func AddApprovedCreator(cur realm, gameType string , creator address) {
61 executor := accesscontrol.MustGetAdminOrOperatorCaller( 0 , cur, admin.IsAdmin, admin.IsOperator)
62 mustGetGameTypePolicy(gameType)
63 assertValidCreator(creator)
64 if !setApprovedCreator(gameType, creator, true ) {
65 return
66 }
67 chain.Emit(
68 AddApprovedCreatorEvent,
69 "executor" , executor.String(),
70 "gameType" , gameType,
71 "creator" , creator.String(),
72 )
73 }
74
75 func RemoveApprovedCreator(cur realm, gameType string , creator address) {
76 executor := accesscontrol.MustGetAdminOrOperatorCaller( 0 , cur, admin.IsAdmin, admin.IsOperator)
77 mustGetGameTypePolicy(gameType)
78 assertValidCreator(creator)
79 if !setApprovedCreator(gameType, creator, false ) {
80 return
81 }
82 chain.Emit(
83 RemoveApprovedCreatorEvent,
84 "executor" , executor.String(),
85 "gameType" , gameType,
86 "creator" , creator.String(),
87 )
88 }
89
90 func SetApprovedCreators(cur realm, gameType, creatorsCSV string , approved bool ) {
91 executor := accesscontrol.MustGetAdminOrOperatorCaller( 0 , cur, admin.IsAdmin, admin.IsOperator)
92 mustGetGameTypePolicy(gameType)
93 if creatorsCSV == "" {
94 panic( "creator list must not be empty" )
95 }
96
97 requestedCount := 0
98 changedCount := 0
99 start := 0
100 for {
101 end := start
102 for end < len(creatorsCSV) && creatorsCSV[end] != ',' {
103 end++
104 }
105 requestedCount++
106 if requestedCount > approvedCreatorBatchMax {
107 panic( "creator list exceeds limit" )
108 }
109 creator := address(creatorsCSV[start:end])
110 assertValidCreator(creator)
111 if setApprovedCreator(gameType, creator, approved) {
112 changedCount++
113 }
114 if end == len(creatorsCSV) {
115 break
116 }
117 start = end + 1
118 }
119 if changedCount == 0 {
120 return
121 }
122 chain.Emit(
123 SetApprovedCreatorsEvent,
124 "executor" , executor.String(),
125 "gameType" , gameType,
126 "creatorsCSV" , creatorsCSV,
127 "approved" , strconv.FormatBool(approved),
128 "requestedCount" , strconv.Itoa(requestedCount),
129 "changedCount" , strconv.Itoa(changedCount),
130 )
131 }
132
133 func setApprovedCreator(gameType string , creator address, approved bool ) bool {
134 set, found := getApprovedCreators(gameType)
135 old := found && set.Has(creator.String())
136 if old == approved {
137 return false
138 }
139 if approved {
140 if !found {
141 set = createApprovedCreators(gameType)
142 }
143 set.Set(creator.String(), true )
144 } else {
145 set.Remove(creator.String())
146 }
147 return true
148 }
149
150 func IsApprovedCreator(gameType string , creator address) bool {
151 mustGetGameTypePolicy(gameType)
152 assertValidCreator(creator)
153 return isApprovedCreator(gameType, creator)
154 }
155
156 func GetApprovedCreatorCount(gameType string ) int {
157 mustGetGameTypePolicy(gameType)
158 set, found := getApprovedCreators(gameType)
159 if !found {
160 return 0
161 }
162 return set.Size()
163 }
164
165 func ListApprovedCreators(gameType string , offset, count int ) []address {
166 mustGetGameTypePolicy(gameType)
167 if offset < 0 {
168 panic( "offset must not be negative" )
169 }
170 if count < 1 || count > approvedCreatorListMax {
171 panic( "count must be between 1 and 100" )
172 }
173 result := []address{}
174 set, found := getApprovedCreators(gameType)
175 if !found {
176 return result
177 }
178 set.IterateByOffset(offset, count, func (value string , _ any ) bool {
179 result = append(result, address(value))
180 return false
181 })
182 return result
183 }
184
185 func HasGameTypePolicy(gameType string ) bool {
186 assertValidGameType(gameType)
187 return gameTypePolicies.Has(gameType)
188 }
189
190 func GetGameTypePolicy(gameType string ) GameTypePolicy {
191 return mustGetGameTypePolicy(gameType)
192 }
193
194 func initializePolicyState() {
195 gameTypePolicies = bptree.NewBPTree32()
196 approvedCreators = bptree.NewBPTree32()
197 }
198
199 func assertValidGameType(gameType string ) {
200 if len(gameType) < 1 || len(gameType) > gameTypeMaxLen {
201 panic( "game type key length must be between 1 and 64" )
202 }
203 for _, ch := range gameType {
204 if (ch < 'a' || ch > 'z' ) && (ch < '0' || ch > '9' ) && ch != '_' && ch != '-' {
205 panic( "invalid game type key" )
206 }
207 }
208 }
209
210 func mustGetGameTypePolicy(gameType string ) GameTypePolicy {
211 assertValidGameType(gameType)
212 value := gameTypePolicies.Get(gameType)
213 if value == nil {
214 panic( "game type policy not found: " + gameType)
215 }
216 return value.(GameTypePolicy)
217 }
218
219 func getApprovedCreators(gameType string ) (*bptree.BPTree, bool ) {
220 value := approvedCreators.Get(gameType)
221 if value == nil {
222 return nil , false
223 }
224 return value.(*bptree.BPTree), true
225 }
226
227 func createApprovedCreators(gameType string ) *bptree.BPTree {
228 set := bptree.NewBPTree32()
229 approvedCreators.Set(gameType, set)
230 return set
231 }
232
233 func isApprovedCreator(gameType string , creator address) bool {
234 set, found := getApprovedCreators(gameType)
235 return found && set.Has(creator.String())
236 }
237
238 func assertValidCreationMode(mode CreationMode) {
239 if mode < CreationModeOperatorOnly || mode > CreationModePublicCreator {
240 panic( "invalid creation mode" )
241 }
242 }
243
244 func assertValidCreator(creator address) {
245 if !creator.IsValid() {
246 panic( "invalid creator address" )
247 }
248 }
249
250 func resetGameWorldState() {
251 initializePolicyState()
252 resetGameWorldStore()
253 }
254