game.gno
1.34 Kb · 65 lines
1package game25
2
3import (
4 "strconv"
5 "strings"
6 "time"
7
8 "gno.land/p/nt/avl/v0"
9 "gno.land/p/nt/ufmt/v0"
10)
11
12var (
13 admin address
14 minterAddr address
15 balances avl.Tree
16 lastClaim avl.Tree
17 paused bool
18)
19
20func init(cur realm) {
21 admin = cur.Previous().Address()
22}
23
24func isAdmin(cur realm) bool {
25 return cur.Previous().Address() == admin
26}
27
28func requireNotPaused() {
29 if paused {
30 panic("game is paused")
31 }
32}
33
34func SetMinter(cur realm, newMinter string) {
35 if !isAdmin(cur) {
36 panic("unauthorized: only admin can set minter")
37 }
38 minterAddr = address(newMinter)
39}
40
41func ClaimAndMint(cur realm, coinsJson string) {
42 requireNotPaused()
43 caller := cur.Previous().Address().String()
44 now := time.Now().Unix()
45 if lastClaim.Has(caller) {
46 last, _ := strconv.ParseInt(lastClaim.Get(caller).(string), 10, 64)
47 if now-last < 60 {
48 remaining := 60 - (now - last)
49 panic("too fast — " + strconv.FormatInt(remaining, 10) + "s remaining (1 min cooldown)")
50 }
51 }
52 lastClaim.Set(caller, strconv.FormatInt(now, 10))
53 coinsJson = strings.TrimSpace(coinsJson)
54 balances.Set(caller, coinsJson)
55}
56
57func ClaimAchievement(cur realm, achievementId string) {
58 requireNotPaused()
59 caller := cur.Previous().Address().String()
60 balances.Set(caller+":"+achievementId, "1")
61}
62
63func Render(_ string) string {
64 return ufmt.Sprintf("# GnoMoji\n\nAdmin: %s\n", admin.String())
65}