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/g1t2kg2vtr3fukg43eujkn6x53gfdyakhngt4sfd/gnofly/arena/v0

Realm
Open in gnoweb ↗

Overview

Kind
Realm (renderable)
Name
v0
Namespace
g1t2kg2vtr3fukg43eujkn6x53gfdyakhngt4sfd / gnofly / arena
Files
15 (gnomod.toml)
Exported functions
21
Module
gno.land/r/g1t2kg2vtr3fukg43eujkn6x53gfdyakhngt4sfd/gnofly/arena/v0
gno
0.9

Files (15)

  • gnomod.tomltoml
  • arena.gnogno
  • claims.gnogno
  • doc.gnogno
  • earnings.gnogno
  • errors.gnogno
  • escrow.gnogno
  • json.gnogno
  • lobby.gnogno
  • render.gnogno
  • results.gnogno
  • roles.gnogno
  • rounds.gnogno
  • spec.gnogno
  • validate.gnogno
  • json.gnogno
    1package arena23import "strings"45// The JSON documents are built by hand. That is safe because every string6// that reaches them was validated against a JSON-safe charset when it was7// written: ids are hex, modes and nonces [a-z0-9-], tickets hex, addresses

    Functions

    • ArenaJSON(id string) string

    • ArenasJSON() string

    • CancelRound(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}, id string)

    • Claim(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}) int64

    • Claimable(addr string) int64

    • ClaimsJSON(addr string) string

    • EarningsJSON() string

    • Enter(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}, spec string, ticket string) string

    • Escrowed() int64

    • ExpireLobby(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}, id string)

    • Leave(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}, id string)

    • PlayerJSON(addr string) string

    • RefundDelay() int64

    • RefundRound(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}, id string)

    • Render(path string) string

    • ResultJSON(id string) string

    • ResultsJSON() string

    • SetRefundDelay(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}, seconds int64)

    • SettleRound(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}, id string, deaths string)

    • StartRound(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}, id string) int64

    • Version() int64

    Signatures reconstructed verbatim from vm/qfuncs — interface params keep their inline definitions.

    Rendered

    RenderedRawgnoweb ↗
    8
    // bech32. The one string that is not under the realm's control, an address
    9// typed into a query, goes through quote.
    10//
    11// Ordering is deterministic everywhere: arenas follow their id (the tree
    12// iterates in key order), a lobby and a round the order of entry, results
    13// are newest first and earnings best first.
    14
    15// ArenasJSON returns every arena someone paid into and whose game is not
    16// over, as a JSON array sorted by id:
    17//
    18// [
    19// { "id": "3f2a...", "mode": "deathmatch", "stake": 10000000,
    20// "minSeats": 2, "maxSeats": 8, "lives": 3, "seconds": 900, "killTarget": 5,
    21// "creator": "g1...", "created": 1790950000, "nonce": "k3x9",
    22// "lobby": [ { "address": "g1...", "ticket": "9f86d0...00a08" } ],
    23// "round": { "startedAt": 1790950300, "players": [ "g1...", "g1..." ] } }
    24// ]
    25//
    26// The output has no whitespace. "round" is null until the game starts.
    27// The fields from "mode" to "nonce" are the arena's spec: the game server
    28// rebuilds the spec string, and so the id, from them.
    29func ArenasJSON() string {
    30 var b strings.Builder
    31 b.WriteByte('[')
    32 first := true
    33 arenas.Iterate("", "", func(id string, v any) bool {
    34 if !first {
    35 b.WriteByte(',')
    36 }
    37 first = false
    38 writeArena(&b, id, v.(*arena))
    39 return false
    40 })
    41 b.WriteByte(']')
    42 return b.String()
    43}
    44
    45// ArenaJSON returns one arena in the shape of ArenasJSON, or null.
    46func ArenaJSON(id string) string {
    47 a := getArena(id)
    48 if a == nil {
    49 return "null"
    50 }
    51 var b strings.Builder
    52 writeArena(&b, id, a)
    53 return b.String()
    54}
    55
    56func writeArena(b *strings.Builder, id string, a *arena) {
    57 b.WriteString(`{"id":"` + id + `","mode":"` + a.mode + `"`)
    58 for _, f := range []struct {
    59 k string
    60 v int64
    61 }{{"stake", a.stake}, {"minSeats", a.minSeats}, {"maxSeats", a.maxSeats}, {"lives", a.lives},
    62 {"seconds", a.seconds}, {"killTarget", a.killTarget}} {
    63 b.WriteString(`,"` + f.k + `":` + itoa(f.v))
    64 }
    65 b.WriteString(`,"creator":"` + a.creator.String() + `","created":` + itoa(a.created) + `,"nonce":"` + a.nonce + `"`)
    66 b.WriteString(`,"lobby":[`)
    67 for i, p := range a.lobby {
    68 if i > 0 {
    69 b.WriteByte(',')
    70 }
    71 b.WriteString(`{"address":"` + p.String() + `","ticket":"` + a.tickets[i] + `"}`)
    72 }
    73 b.WriteString(`],"round":`)
    74 if a.round == nil {
    75 b.WriteString("null}")
    76 return
    77 }
    78 b.WriteString(`{"startedAt":` + itoa(a.round.startedAt) + `,"players":[`)
    79 for i, p := range a.round.players {
    80 if i > 0 {
    81 b.WriteByte(',')
    82 }
    83 b.WriteString(`"` + p.String() + `"`)
    84 }
    85 b.WriteString("]}}")
    86}
    87
    88// ResultsJSON returns the last closed games, newest first, at most 50:
    89//
    90// [ { "id": "3f2a...", "mode": "deathmatch", "stake": 10000000,
    91// "outcome": "settled", "players": 2, "pot": 20000000, "fee": 500000,
    92// "closedAt": 1790951000,
    93// "payouts": [ { "address": "g1...", "amount": 19500000 } ] } ]
    94func ResultsJSON() string {
    95 var b strings.Builder
    96 b.WriteByte('[')
    97 for i := len(closed) - 1; i >= 0; i-- {
    98 if i < len(closed)-1 {
    99 b.WriteByte(',')
    100 }
    101 r, _ := resultOf(closed[i])
    102 writeResult(&b, closed[i], r)
    103 }
    104 b.WriteByte(']')
    105 return b.String()
    106}
    107
    108// ResultJSON returns the result of one closed game in the shape of
    109// ResultsJSON, or null when the realm does not have it (still running, or
    110// too old).
    111func ResultJSON(id string) string {
    112 r, ok := resultOf(id)
    113 if !ok {
    114 return "null"
    115 }
    116 var b strings.Builder
    117 writeResult(&b, id, r)
    118 return b.String()
    119}
    120
    121func writeResult(b *strings.Builder, id string, r result) {
    122 b.WriteString(`{"id":"` + id + `","mode":"` + r.mode + `","stake":` + itoa(r.stake) +
    123 `,"outcome":"` + r.outcome + `","players":` + itoa(r.players) + `,"pot":` + itoa(r.pot) +
    124 `,"fee":` + itoa(r.fee) + `,"closedAt":` + itoa(r.closedAt) + `,"payouts":[`)
    125 for i, p := range r.payouts {
    126 if i > 0 {
    127 b.WriteByte(',')
    128 }
    129 b.WriteString(`{"address":"` + p.Address.String() + `","amount":` + itoa(p.Amount) + `}`)
    130 }
    131 b.WriteString("]}")
    132}
    133
    134// EarningsJSON returns the top winners as a JSON array, best first, at most
    135// 10 entries:
    136//
    137// [ { "address": "g1...", "won": 19000000, "rounds": 3 } ]
    138//
    139// The output has no whitespace. "won" adds up, round after round, what the
    140// player was paid above their own stake, never less than zero for a round.
    141// "rounds" is how many settled rounds they played. With equal winnings, the
    142// player who got there first stays ahead.
    143func EarningsJSON() string {
    144 var b strings.Builder
    145 b.WriteByte('[')
    146 for i, addr := range winners.addrs {
    147 if i > 0 {
    148 b.WriteByte(',')
    149 }
    150 writeTotals(&b, `"`+addr.String()+`"`, totalsOf(addr))
    151 }
    152 b.WriteByte(']')
    153 return b.String()
    154}
    155
    156// PlayerJSON returns one player's totals as a JSON object:
    157//
    158// { "address": "g1...", "won": 19000000, "rounds": 3 }
    159//
    160// The output has no whitespace. An unknown address returns the same shape
    161// with zero won and zero rounds.
    162func PlayerJSON(addr address) string {
    163 var b strings.Builder
    164 writeTotals(&b, quote(addr.String()), totalsOf(addr))
    165 return b.String()
    166}
    167
    168// writeTotals writes the totals of a player. quoted is the player's address
    169// as a JSON string literal, quotes included.
    170func writeTotals(b *strings.Builder, quoted string, t totals) {
    171 b.WriteString(`{"address":`)
    172 b.WriteString(quoted)
    173 b.WriteString(`,"won":`)
    174 b.WriteString(itoa(t.won))
    175 b.WriteString(`,"rounds":`)
    176 b.WriteString(itoa(t.rounds))
    177 b.WriteByte('}')
    178}
    179
    180// quote returns s as a JSON string literal, quotes included. It is for the
    181// strings the realm did not validate. Quotes and backslashes are escaped and
    182// anything outside printable ASCII is replaced by "?", so the result is
    183// valid JSON whatever s holds.
    184func quote(s string) string {
    185 var b strings.Builder
    186 b.WriteByte('"')
    187 for i := 0; i < len(s); i++ {
    188 c := s[i]
    189 switch {
    190 case c == '"' || c == '\\':
    191 b.WriteByte('\\')
    192 b.WriteByte(c)
    193 case c < 0x20 || c > 0x7e:
    194 b.WriteByte('?')
    195 default:
    196 b.WriteByte(c)
    197 }
    198 }
    199 b.WriteByte('"')
    200 return b.String()
    201}
    202

    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.