feat: grant paid currency and draw tickets by mail

This commit is contained in:
2026-10-03 01:25:36 +08:00
parent 0adac4c6bb
commit f7146adc3a
9 changed files with 277 additions and 14 deletions
+5
View File
@@ -313,6 +313,11 @@ func (s *Wallet) GrantQuestOnce(identity string, rewards []gamedata.Reward) (Cur
next := cloneWallet(s.state)
for _, reward := range rewards {
switch reward.Type {
case 2:
if math.MaxUint64-next.Jewelry < reward.Count {
return Currency{}, errors.New("player: paid jewelry overflow")
}
next.Jewelry += reward.Count
case 3:
if math.MaxUint64-next.FreeJewelry < reward.Count {
return Currency{}, errors.New("player: free jewelry overflow")
+16 -2
View File
@@ -1,6 +1,7 @@
package player
import (
"math"
"path/filepath"
"testing"
@@ -13,7 +14,7 @@ func TestWalletGrantPersistsAndIsIdempotent(t *testing.T) {
if err != nil {
t.Fatal(err)
}
rewards := []gamedata.Reward{{Type: 4, Count: 1500}, {Type: 3, Count: 70}, {Type: 12, Count: 45}, {Type: 25, ID: 210, Count: 1}}
rewards := []gamedata.Reward{{Type: 2, Count: 100000000}, {Type: 4, Count: 1500}, {Type: 3, Count: 70}, {Type: 12, Count: 45}, {Type: 25, ID: 210, Count: 1}}
if _, err := wallet.GrantQuestOnce("quest:1", rewards); err != nil {
t.Fatal(err)
}
@@ -25,7 +26,20 @@ func TestWalletGrantPersistsAndIsIdempotent(t *testing.T) {
t.Fatal(err)
}
got := wallet.Snapshot()
if got.Gold != 1600 || got.FreeJewelry != 70 || got.Catalyst != 45 {
if got.Jewelry != 100000000 || got.Gold != 1600 || got.FreeJewelry != 70 || got.Catalyst != 45 {
t.Fatalf("wallet=%+v", got)
}
}
func TestWalletPaidJewelryOverflowDoesNotCommitGrant(t *testing.T) {
wallet, err := OpenWallet(testStore(filepath.Join(t.TempDir(), "wallet.json")), Currency{Jewelry: math.MaxUint64})
if err != nil {
t.Fatal(err)
}
if _, err := wallet.GrantQuestOnce("paid-overflow", []gamedata.Reward{{Type: 4, Count: 10}, {Type: 2, Count: 1}}); err == nil {
t.Fatal("paid jewelry overflow accepted")
}
if got := wallet.Snapshot(); got.Jewelry != math.MaxUint64 || got.Gold != 0 || wallet.WasGranted("paid-overflow") {
t.Fatalf("failed grant changed wallet: %+v", got)
}
}