game.gno
2.48 Kb · 80 lines
1package game
2
3import (
4 "strconv"
5
6 "gno.land/p/nt/bptree/v0"
7 "gno.land/p/nt/ownable/v0"
8)
9
10// The whole state of the realm. Everything is unexported and nothing below is
11// ever returned by reference: the trees and the ownable are /p/ types with
12// mutator methods, so handing one out would be handing out write access to
13// the realm.
14var (
15 owner *ownable.Ownable // the single owner, always an admin
16 admins bptree.BPTree // extra admins, managed by the owner: address -> nil
17 referees bptree.BPTree // game servers allowed to submit kills: address -> nil
18 treasury address // where the sales of the skins and planes realms go
19
20 version int64 // bumps on every admin write, see Version
21
22 params []*param // fixed registry, in display order
23 pilots bptree.BPTree // player address -> int64 kills, allocated at the first kill
24
25 killers ranking // the top players by kills recorded on-chain, see rankings.gno
26
27 webPath string // "/r/g1t2kg2vtr3fukg43eujkn6x53gfdyakhngt4sfd/gnofly/game/v0", used to build links in Render
28)
29
30// init runs once, when the package is added to the chain. This is the only
31// moment cur.Previous() is the deployer, so it is recorded here: the deployer
32// starts as owner, referee and treasury.
33//
34// Under `gno test` there is no deployer and the address is empty. The tests
35// call bootstrap themselves with a real address.
36func init(cur realm) {
37 bootstrap(cur.Previous().Address(), cur.PkgPath())
38}
39
40// bootstrap (re)creates the initial state: roles and params.
41func bootstrap(deployer address, pkgPath string) {
42 owner = ownable.NewWithAddress(deployer)
43 admins = bptree.BPTree{}
44 referees = bptree.BPTree{}
45 referees.Set(deployer.String(), nil)
46 treasury = deployer
47
48 params = defaultParams()
49 pilots = bptree.BPTree{}
50 killers = ranking{}
51 webPath = webPathOf(pkgPath)
52
53 version = 1
54}
55
56// Version returns a counter that bumps on every admin write: params,
57// treasury and roles. Referee actions (kills) do not bump it. A reader that cached StateJSON only has to read it
58// again when Version changed.
59func Version() int64 {
60 return version
61}
62
63// bump marks the admin-tunable state as changed.
64func bump() {
65 version++
66}
67
68// webPathOf turns "gno.land/r/g1t2kg2vtr3fukg43eujkn6x53gfdyakhngt4sfd/gnofly/game/v0" into "/r/g1t2kg2vtr3fukg43eujkn6x53gfdyakhngt4sfd/gnofly/game/v0".
69func webPathOf(pkgPath string) string {
70 for i := 0; i < len(pkgPath); i++ {
71 if pkgPath[i] == '/' {
72 return pkgPath[i:]
73 }
74 }
75 return ""
76}
77
78func itoa(n int64) string {
79 return strconv.FormatInt(n, 10)
80}