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.
115 lines
4.1 KiB
Go
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")
|
|
}
|
|
}
|