PathrockNetwork Gno Explorer
HomeBlocksTransactionsTokensRealmsPackagesValidatorsAnalytics

PathrockNetwork Gno Explorer — an independent explorer for Gno.land Mainnet (gnoland-1), operated by PathrockNetwork. Not an official Gno.land service.

gnowebarchive RPC

gno.land/r/akkadia/beta/game_world

Realm
Open in gnoweb ↗

Overview

Kind
Realm (renderable)
Name
game_world
Namespace
akkadia / beta
Files
9 (gnomod.toml)
Exported functions
18
Module
gno.land/r/akkadia/beta/game_world
gno
0.9

Files (9)

  • gnomod.tomltoml
  • config.gnogno
  • game_world.gnogno
  • policy.gnogno
  • store.gnogno
  • game_world_test.gnogno
  • policy_test.gnogno
  • security_test.gnogno
  • setup_test.gnogno
  • game_world.gnogno
    1package game_world23import (4	"chain"5	"chain/banker"6	"chain/runtime"7	"chain/runtime/unsafe"8

    Functions

    • 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.

    Rendered

    RenderedRawgnoweb ↗

    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.

    "strconv"
    9
    10 "gno.land/p/akkadia/beta/accesscontrol"
    11 "gno.land/r/akkadia/beta/admin"
    12)
    13
    14const (
    15 CreateGameWorldEvent = "CreateGameWorld"
    16 RestrictGameWorldEvent = "RestrictGameWorld"
    17)
    18
    19type CreationMode int
    20
    21const (
    22 CreationModeInvalid CreationMode = iota
    23 CreationModeOperatorOnly
    24 CreationModeApprovedCreator
    25 CreationModePublicCreator
    26)
    27
    28type GameWorldStatus int
    29
    30const (
    31 GameWorldStatusInvalid GameWorldStatus = iota
    32 GameWorldStatusExists
    33 GameWorldStatusRestricted
    34)
    35
    36type GameWorld struct {
    37 ID uint64
    38 Owner address
    39 GameType string
    40 Status GameWorldStatus
    41 CreatedHeight int64
    42 RestrictedHeight int64
    43}
    44
    45type GameTypePolicy struct {
    46 CreationCost int64
    47 CreationMode CreationMode
    48}
    49
    50func CreateGameWorld(cur realm, gameType string) uint64 {
    51 owner := accesscontrol.MustGetUserCaller(0, cur)
    52 policy := mustGetGameTypePolicy(gameType)
    53 assertCreationAllowed(gameType, owner, policy.CreationMode)
    54 assertExactUgnotPayment(policy.CreationCost)
    55
    56 id := createGameWorld(owner, gameType)
    57 if policy.CreationCost > 0 {
    58 bnk := banker.NewBanker(banker.BankerTypeRealmSend, cur)
    59 bnk.SendCoins(cur.Address(), admin.GetFeeCollector(), chain.Coins{{"ugnot", policy.CreationCost}})
    60 }
    61 emitCreateGameWorld(owner, id, gameType, policy.CreationCost)
    62 return id
    63}
    64
    65func RestrictGameWorld(cur realm, gameWorldID uint64) {
    66 executor := accesscontrol.MustGetAdminOrOperatorCaller(0, cur, admin.IsAdmin, admin.IsOperator)
    67 world := GetGameWorld(gameWorldID)
    68 if world.Status == GameWorldStatusRestricted {
    69 return
    70 }
    71 world.Status = GameWorldStatusRestricted
    72 world.RestrictedHeight = runtime.ChainHeight()
    73 gameWorlds.Set(uint64Key(gameWorldID), world)
    74 removeOwnerGameWorldID(world.Owner, gameWorldID)
    75 restrictedGameWorldIDs.Set(uint64Key(gameWorldID), true)
    76 chain.Emit(
    77 RestrictGameWorldEvent,
    78 "executor", executor.String(),
    79 "id", strconv.FormatUint(gameWorldID, 10),
    80 "oldStatus", strconv.Itoa(int(GameWorldStatusExists)),
    81 "newStatus", strconv.Itoa(int(GameWorldStatusRestricted)),
    82 "restrictedHeight", strconv.FormatInt(world.RestrictedHeight, 10),
    83 )
    84}
    85
    86func HasGameWorld(gameWorldID uint64) bool { return gameWorlds.Has(uint64Key(gameWorldID)) }
    87
    88func GetGameWorld(gameWorldID uint64) GameWorld {
    89 value := gameWorlds.Get(uint64Key(gameWorldID))
    90 if value == nil {
    91 panic("game world not found: " + strconv.FormatUint(gameWorldID, 10))
    92 }
    93 return value.(GameWorld)
    94}
    95
    96func GetLatestGameWorldID() uint64 { return latestGameWorldID }
    97
    98func GetListLimit() int { return gameWorldListLimit }
    99
    100func GetRestrictedGameWorldCount() int { return restrictedGameWorldIDs.Size() }
    101
    102func ListRestrictedGameWorldIDs(page, count int) []uint64 {
    103 if page < 1 {
    104 panic("page must be at least 1")
    105 }
    106 if count < 1 || count > gameWorldListLimit {
    107 panic("count must be between 1 and 100")
    108 }
    109 result := []uint64{}
    110 restrictedGameWorldIDs.IterateByOffset((page-1)*count, count, func(key string, _ any) bool {
    111 result = append(result, parseUint64Key(key))
    112 return false
    113 })
    114 return result
    115}
    116
    117func ListLatestGameWorldsByOwner(owner address) []GameWorld {
    118 ids, found := getOwnerGameWorldIDs(owner)
    119 if !found {
    120 return []GameWorld{}
    121 }
    122 offset := ids.Size() - gameWorldListLimit
    123 if offset < 0 {
    124 offset = 0
    125 }
    126 result := []GameWorld{}
    127 ids.IterateByOffset(offset, gameWorldListLimit, func(key string, _ any) bool {
    128 result = append(result, GetGameWorld(parseUint64Key(key)))
    129 return false
    130 })
    131 return result
    132}
    133
    134func createGameWorld(owner address, gameType string) uint64 {
    135 if latestGameWorldID == uint64(18446744073709551615) {
    136 panic("game world id exhausted")
    137 }
    138 latestGameWorldID++
    139 id := latestGameWorldID
    140 gameWorlds.Set(uint64Key(id), GameWorld{
    141 ID: id,
    142 Owner: owner,
    143 GameType: gameType,
    144 Status: GameWorldStatusExists,
    145 CreatedHeight: runtime.ChainHeight(),
    146 })
    147 addOwnerGameWorldID(owner, id)
    148 return id
    149}
    150
    151func assertCreationAllowed(gameType string, creator address, mode CreationMode) {
    152 switch mode {
    153 case CreationModeOperatorOnly:
    154 if !admin.IsAdmin(creator) && !admin.IsOperator(creator) {
    155 panic("game type creation is operator only")
    156 }
    157 case CreationModeApprovedCreator:
    158 if !isApprovedCreator(gameType, creator) {
    159 panic("creator is not approved for game type")
    160 }
    161 case CreationModePublicCreator:
    162 return
    163 default:
    164 panic("invalid creation mode")
    165 }
    166}
    167
    168func assertExactUgnotPayment(expected int64) {
    169 coins := unsafe.OriginSend()
    170 if expected == 0 {
    171 if len(coins) != 0 {
    172 panic("exact payment required: expected no coins, got " + coins.String())
    173 }
    174 return
    175 }
    176 if len(coins) != 1 || coins[0].Denom != "ugnot" || coins[0].Amount != expected {
    177 panic("exact payment required: expected " + strconv.FormatInt(expected, 10) + "ugnot, got " + coins.String())
    178 }
    179}
    180
    181func emitCreateGameWorld(owner address, id uint64, gameType string, creationCost int64) {
    182 chain.Emit(
    183 CreateGameWorldEvent,
    184 "executor", owner.String(),
    185 "id", strconv.FormatUint(id, 10),
    186 "owner", owner.String(),
    187 "gameType", gameType,
    188 "creationCost", strconv.FormatInt(creationCost, 10),
    189 "createdHeight", strconv.FormatInt(runtime.ChainHeight(), 10),
    190 )
    191}
    192