Files
bd2/go/internal/server/world/pack_jam_test.go
T
Flechazo 5b5a219dc2 feat(server): add special loot and data-driven gameplay rules
Generate equipment loot atomically, grant random boxes and prevent repeat claims.
Read gacha pools, pity, products, tickets, missions, presets, chapter rewards
and inventory costs from GameData; extend both collaboration UR ticket pools.
Sync owned recipes, configure startup state and calendars in versioned seeds,
and validate unlock tickets and revival talents.
2026-10-04 19:15:59 +08:00

115 lines
4.1 KiB
Go

package world
import (
"bd2server/internal/server/gamedata"
"bd2server/internal/server/player"
"bd2server/internal/server/stateio"
"bd2server/internal/server/wire"
"errors"
"testing"
)
type jamFailStore struct {
*stateio.Memory
fail bool
}
func (s *jamFailStore) SaveWithEntries(domain string, core []byte, changes []stateio.EntryMutation) error {
if s.fail {
return errors.New("write failed")
}
return s.Memory.SaveWithEntries(domain, core, changes)
}
func TestPackJamClaimPersistsAndRepeatedDockingSucceeds(t *testing.T) {
storage := &jamFailStore{Memory: stateio.NewMemory()}
wallet, err := player.OpenWallet(storage, player.Currency{})
if err != nil {
t.Fatal(err)
}
s := testService()
s.wallet = wallet
s.packJamDesign = &gamedata.PackJamDesign{InsertMin: 5, InsertMax: 5, Reward: gamedata.Reward{Type: 3, Count: 150}}
s.fieldPacks = map[int]gamedata.FieldPack{3001: {ID: 3001, Type: 3, MapIDs: map[int]bool{30011: true}}}
request := wire.AppendVarint(wire.AppendVarint(nil, 1, 1), 2, 3001)
_, preview, _, err := s.Handle("/PackPreviewInfo", request)
if err != nil {
t.Fatal(err)
}
if _, found, _ := wire.Bytes(preview, 1); found {
t.Fatal("arena fabricated story quest")
}
if claimed, _, _ := wire.Varint(preview, 3); claimed != 0 {
t.Fatal("unclaimed reward marked claimed")
}
storage.fail = true
if _, body, _, err := s.Handle("/PackJamEvent", request); err == nil || body != nil {
t.Fatal("failed write returned success reward")
}
if wallet.WasGranted(packJamIdentity(3001)) || wallet.Snapshot().FreeJewelry != 0 {
t.Fatal("failed write changed wallet")
}
_, preview, _, err = s.Handle("/PackPreviewInfo", request)
if claimed, _, _ := wire.Varint(preview, 3); err != nil || claimed != 0 {
t.Fatal("failed grant preview marked claimed")
}
storage.fail = false
code, body, handled, err := s.Handle("/PackJamEvent", request)
if err != nil || !handled || code != 72 {
t.Fatalf("claim: %d %v %v", code, handled, err)
}
item, found, _ := wire.Bytes(body, 1)
typ, _, _ := wire.Varint(item, 3)
count, _, _ := wire.Varint(item, 4)
if !found || typ != 3 || count != 150 || wallet.Snapshot().FreeJewelry != 150 {
t.Fatal("wrong currency reward")
}
s.wallet, err = player.OpenWallet(storage, player.Currency{})
if err != nil {
t.Fatal(err)
}
_, preview, _, err = s.Handle("/PackPreviewInfo", request)
claimed, _, _ := wire.Varint(preview, 3)
if err != nil || claimed != 1 {
t.Fatal("reopened preview lost claim")
}
code, body, _, err = s.Handle("/PackJamEvent", request)
if err != nil || code != 72 || len(body) != 0 || s.wallet.Snapshot().FreeJewelry != 150 {
t.Fatal("repeated docking replayed reward")
}
story := wire.AppendVarint(wire.AppendVarint(nil, 1, 1), 2, 21)
_, preview, _, err = s.Handle("/PackPreviewInfo", story)
quest, found, _ := wire.Bytes(preview, 1)
id, _, _ := wire.Varint(quest, 1)
pack, _, _ := wire.Varint(quest, 6)
if err != nil || !found || id != 1 || pack != 21 {
t.Fatal("preview lost real active quest")
}
for _, invalid := range [][]byte{nil, wire.AppendVarint(nil, 2, 3001), wire.AppendVarint(wire.AppendVarint(nil, 1, 1), 2, 9999), wire.AppendVarint(wire.AppendVarint(nil, 1, 0), 2, 3001)} {
for _, path := range []string{"/PackPreviewInfo", "/PackJamEvent"} {
if _, _, handled, err := s.Handle(path, invalid); !handled || !errors.Is(err, ErrInvalidRequest) {
t.Fatalf("invalid %s: %v", path, err)
}
}
}
if s.wallet.Snapshot().FreeJewelry != 150 || s.wallet.WasGranted(packJamIdentity(9999)) {
t.Fatal("invalid pack changed wallet")
}
s.packJamDesign.Reward.Type = 8
if _, _, _, err := s.Handle("/PackJamEvent", story); err == nil {
t.Fatal("unsupported reward accepted")
}
if s.wallet.WasGranted(packJamIdentity(21)) {
t.Fatal("unsupported reward marked claimed")
}
s.packJamDesign.Reward.Type = 4
s.packJamDesign.Reward.Count = 73
code, body, _, err = s.Handle("/PackJamEvent", story)
item, _, _ = wire.Bytes(body, 1)
typ, _, _ = wire.Varint(item, 3)
count, _, _ = wire.Varint(item, 4)
if err != nil || code != 72 || typ != 4 || count != 73 || s.wallet.Snapshot().Gold != 73 {
t.Fatal("changed reward currency/count ignored")
}
}