Search Apps Documentation Source Content File Folder Download Copy Actions Download State String Boolean Number Struct Map Slice Pointer Function Closure Reference Nil Package Type Interface Unknown

api.gno

5.48 Kb · 194 lines
  1package gnodice
  2
  3import (
  4	"strconv"
  5	"strings"
  6)
  7
  8// Lectures : ces fonctions ne modifient rien. Le site et le croupier les
  9// appellent gratuitement (sans transaction) pour lire l'état du jeu en JSON.
 10// Les seules chaînes écrites sont des adresses, des empreintes/graines
 11// hexadécimales (vérifiées) et des statuts fixes : rien à échapper.
 12
 13// GetInfoJSON renvoie l'état global du jeu et les dernières parties terminées.
 14func GetInfoJSON() string {
 15	t := now()
 16	var b strings.Builder
 17	b.WriteString("{")
 18	str(&b, "owner", owner.String())
 19	str(&b, "pendingOwner", pendingOwner.String())
 20	str(&b, "croupier", croupier.String())
 21	str(&b, "realm", realmAddr.String())
 22	boolean(&b, "paused", paused)
 23	num(&b, "bankroll", Bankroll())
 24	num(&b, "reserved", reserved)
 25	num(&b, "available", available())
 26	num(&b, "maxCoverableBet", MaxCoverableBet())
 27	num(&b, "minBet", MinBet)
 28	num(&b, "maxBet", MaxBet)
 29	num(&b, "multiplier", PayoutMultiplier)
 30	num(&b, "cooldown", CooldownSeconds)
 31	num(&b, "historySize", HistorySize)
 32	num(&b, "resolveTimeout", ResolveTimeout)
 33	num(&b, "revealWindow", RevealWindow)
 34	num(&b, "totalGames", totalGames)
 35	num(&b, "totalWins", int64(totalWins))
 36	num(&b, "totalLosses", int64(totalLosses))
 37	num(&b, "totalRefunded", int64(totalRefunded))
 38	num(&b, "totalExpired", int64(totalExpired))
 39	num(&b, "totalWagered", totalWagered)
 40	num(&b, "totalPaid", totalPaid)
 41	num(&b, "totalFunded", totalFunded)
 42	num(&b, "totalWithdrawn", totalWithdrawn)
 43	num(&b, "openGames", int64(openGames.Size()))
 44	num(&b, "dailyPayoutLimit", dailyPayoutLimit)
 45	todayPaid := int64(0)
 46	if t/86400 == payoutDay {
 47		todayPaid = payoutToday
 48	}
 49	num(&b, "payoutToday", todayPaid)
 50	num(&b, "lowBankroll", lowBankroll)
 51	num(&b, "now", t)
 52	b.WriteString(`"recent":`)
 53	writeGameIDs(&b, recent)
 54	b.WriteString("}")
 55	return b.String()
 56}
 57
 58// GetPlayerJSON renvoie les statistiques d'un joueur, son temps d'attente,
 59// ses parties en cours et ses 10 dernières parties terminées.
 60func GetPlayerJSON(addr string) string {
 61	player := address(addr)
 62	if !player.IsValid() {
 63		return `{"error":"adresse invalide"}`
 64	}
 65	p := getPlayer(player)
 66	if p == nil {
 67		p = &playerData{}
 68	}
 69	t := now()
 70	nextPlayAt := int64(0)
 71	if p.LastPlay > 0 {
 72		nextPlayAt = p.LastPlay + CooldownSeconds
 73	}
 74
 75	var b strings.Builder
 76	b.WriteString("{")
 77	str(&b, "address", player.String())
 78	num(&b, "played", int64(p.Played))
 79	num(&b, "wins", int64(p.Wins))
 80	num(&b, "wagered", p.Wagered)
 81	num(&b, "paid", p.Paid)
 82	num(&b, "lastPlay", p.LastPlay)
 83	num(&b, "nextPlayAt", nextPlayAt)
 84	num(&b, "cooldownRemaining", cooldownRemaining(p, t))
 85	boolean(&b, "blocked", isBlocked(player))
 86	num(&b, "now", t)
 87	b.WriteString(`"open":`)
 88	writePlayerOpenGames(&b, player, p.Open)
 89	b.WriteString(`,"history":`)
 90	writeGameIDs(&b, p.History)
 91	b.WriteString("}")
 92	return b.String()
 93}
 94
 95// GetGameJSON renvoie une partie, ou {"error":...} si elle n'existe pas.
 96func GetGameJSON(id int64) string {
 97	g := getGame(id)
 98	if g == nil {
 99		return `{"error":"partie introuvable"}`
100	}
101	var b strings.Builder
102	writeGame(&b, g)
103	return b.String()
104}
105
106// GetOpenGamesJSON renvoie les parties en cours (en attente de tirage ou de
107// révélation), de la plus ancienne à la plus récente, à partir du numéro
108// `after` exclu (pagination ; 0 pour commencer). Utilisé par le croupier.
109func GetOpenGamesJSON(after int64) string {
110	var b strings.Builder
111	b.WriteString("[")
112	count := 0
113	openGames.Iterate(gameKey(after+1), "", func(key string, _ any) bool {
114		v := games.Get(key)
115		if count > 0 {
116			b.WriteString(",")
117		}
118		writeGame(&b, v.(*Game))
119		count++
120		return count >= maxPageSize
121	})
122	b.WriteString("]")
123	return b.String()
124}
125
126// --- écriture JSON ---
127
128func writePlayerOpenGames(b *strings.Builder, player address, open int) {
129	b.WriteString("[")
130	if open > 0 {
131		count := 0
132		// Les parties en cours sont peu nombreuses (cooldown de 10 min) :
133		// on parcourt la liste des parties ouvertes en partant de la plus récente.
134		openGames.ReverseIterate("", "", func(key string, _ any) bool {
135			v := games.Get(key)
136			g := v.(*Game)
137			if g.Player == player {
138				if count > 0 {
139					b.WriteString(",")
140				}
141				writeGame(b, g)
142				count++
143			}
144			return count >= open || count >= maxPageSize
145		})
146	}
147	b.WriteString("]")
148}
149
150// writeGameIDs écrit les parties de la plus récente à la plus ancienne.
151func writeGameIDs(b *strings.Builder, ids []int64) {
152	b.WriteString("[")
153	for i := len(ids) - 1; i >= 0; i-- {
154		if i != len(ids)-1 {
155			b.WriteString(",")
156		}
157		writeGame(b, mustGetGame(ids[i]))
158	}
159	b.WriteString("]")
160}
161
162func writeGame(b *strings.Builder, g *Game) {
163	b.WriteString("{")
164	num(b, "id", g.ID)
165	str(b, "player", g.Player.String())
166	str(b, "status", g.Status.String())
167	str(b, "commitment", g.Commitment)
168	str(b, "seed", g.Seed)
169	num(b, "guess", int64(g.Guess))
170	num(b, "roll", int64(g.Roll))
171	num(b, "bet", g.Bet)
172	num(b, "payout", g.Payout)
173	boolean(b, "won", g.Won())
174	num(b, "time", g.PlacedAt)
175	num(b, "height", g.PlacedHeight)
176	num(b, "rolledAt", g.RolledAt)
177	num(b, "settledAt", g.SettledAt)
178	b.WriteString(`"resolveDeadline":` + itoa64(g.PlacedAt+ResolveTimeout))
179	b.WriteString("}")
180}
181
182// Chaque champ est suivi d'une virgule ; le dernier champ d'un objet est
183// écrit à la main, sans virgule.
184func str(b *strings.Builder, key, value string) {
185	b.WriteString(`"` + key + `":"` + value + `",`)
186}
187
188func num(b *strings.Builder, key string, value int64) {
189	b.WriteString(`"` + key + `":` + strconv.FormatInt(value, 10) + `,`)
190}
191
192func boolean(b *strings.Builder, key string, value bool) {
193	b.WriteString(`"` + key + `":` + strconv.FormatBool(value) + `,`)
194}