155 lines
4.9 KiB
Go
155 lines
4.9 KiB
Go
package world
|
|
|
|
import (
|
|
"testing"
|
|
|
|
"bd2server/internal/server/gamedata"
|
|
"bd2server/internal/server/player"
|
|
"bd2server/internal/server/progress"
|
|
"bd2server/internal/server/stateio"
|
|
"bd2server/internal/server/wire"
|
|
)
|
|
|
|
func TestArenaPositionRestoresAcrossRestartWithoutStoryQuestOrRepurchase(t *testing.T) {
|
|
storage := stateio.NewMemory()
|
|
state, err := progress.OpenStore(storage)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
const raw = `{"MapId":30011,"PlayerPosition":{"x":-2.1,"y":0,"z":6.4}}`
|
|
request := wire.AppendVarint(nil, 2, 3001)
|
|
request = wire.AppendString(request, 3, raw)
|
|
if err := state.SaveUserPosition(request); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
state, err = progress.OpenStore(storage)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
s := testService()
|
|
s.state = state
|
|
s.fieldPacks = map[int]gamedata.FieldPack{3001: {ID: 3001, Type: 3, BuyPrice: 99, UseSchedule: 1, HasOpenRule: true, TicketID: 13001, SquadLevel: 50, MapIDs: map[int]bool{30011: true}}}
|
|
if pack, err := s.LastPlayedPackID(); err != nil || pack != 3001 {
|
|
t.Fatalf("restored login pack=%d err=%v", pack, err)
|
|
}
|
|
s.fieldPacks[3002] = gamedata.FieldPack{ID: 3002, Type: 3, MapIDs: map[int]bool{30021: true}}
|
|
accountInfo := s.accountPackInfo()
|
|
arenaRows := 0
|
|
if err := wire.Walk(accountInfo, func(field wire.Field) error {
|
|
if field.Number == 1 {
|
|
id, _, _ := wire.Varint(field.Value, 1)
|
|
if id == 3002 {
|
|
t.Fatal("unvisited arena was exposed as purchased")
|
|
}
|
|
if id == 3001 {
|
|
arenaRows++
|
|
buy, _, _ := wire.Varint(field.Value, 8)
|
|
if buy != 1 {
|
|
t.Fatal("saved arena missing purchased marker")
|
|
}
|
|
if err := wire.Walk(field.Value, func(inner wire.Field) error {
|
|
if inner.Number != 1 && inner.Number != 8 {
|
|
t.Fatalf("saved arena fabricated field %d", inner.Number)
|
|
}
|
|
return nil
|
|
}); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
}
|
|
return nil
|
|
}); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if arenaRows != 1 {
|
|
t.Fatalf("saved arena rows=%d", arenaRows)
|
|
}
|
|
request = wire.AppendVarint(wire.AppendVarint(nil, 1, 1), 2, 3001)
|
|
code, body, handled, err := s.Handle("/PackInGameInfo", request)
|
|
if err != nil || !handled || code != 5 {
|
|
t.Fatalf("arena info code=%d handled=%v err=%v", code, handled, err)
|
|
}
|
|
position, _, err := wire.Bytes(body, 4)
|
|
if err != nil || string(position) != raw {
|
|
t.Fatalf("restored arena position=%s err=%v", position, err)
|
|
}
|
|
if _, found, _ := wire.Bytes(body, 2); found {
|
|
t.Fatal("arena inherited a story quest")
|
|
}
|
|
if pack, err := s.CurrentPackID(); err != nil || pack != 3001 {
|
|
t.Fatalf("current arena pack=%d err=%v", pack, err)
|
|
}
|
|
request = wire.AppendVarint(wire.AppendVarint(nil, 1, 2), 2, 21)
|
|
_, body, _, err = s.Handle("/PackInGameInfo", request)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
position, _, _ = wire.Bytes(body, 4)
|
|
if string(position) != "{}" {
|
|
t.Fatal("arena position leaked into story pack")
|
|
}
|
|
}
|
|
|
|
func TestArenaEntryPreservesTicketPurchaseAndMapRestrictions(t *testing.T) {
|
|
s := testService()
|
|
s.fieldPacks = map[int]gamedata.FieldPack{9001: {ID: 9001, Type: 3, HasOpenRule: true, TicketID: 555, MapIDs: map[int]bool{90011: true}}}
|
|
inventory, err := player.OpenInventory(stateio.NewMemory(), &player.Starter{Version: "2.35.10"})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
s.inventory = inventory
|
|
if s.packUnlocked(9001) {
|
|
t.Fatal("missing content ticket accepted")
|
|
}
|
|
if _, err := inventory.GrantOnce("arena-ticket", []gamedata.BattleReward{{Type: 19, ID: 555, Count: 1}}); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if !s.packUnlocked(9001) {
|
|
t.Fatal("free arena with owned ticket refused")
|
|
}
|
|
pack := s.fieldPacks[9001]
|
|
pack.BuyPrice = 10
|
|
s.fieldPacks[9001] = pack
|
|
if s.packUnlocked(9001) {
|
|
t.Fatal("paid arena was purchased implicitly")
|
|
}
|
|
request := wire.AppendVarint(nil, 2, 9001)
|
|
request = wire.AppendString(request, 3, `{"MapId":211,"PlayerPosition":{"x":1}}`)
|
|
if err := s.state.SaveUserPosition(request); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if _, err := s.LastPlayedPackID(); err == nil {
|
|
t.Fatal("foreign map restored as arena")
|
|
}
|
|
}
|
|
|
|
func TestLastPlayedStoryPackRestoresItsExactPosition(t *testing.T) {
|
|
s := testService()
|
|
s.packs = map[int]map[int]gamedata.QuestDesign{21: s.quests, 22: {1: {ID: 1}}}
|
|
s.transitions = map[int]gamedata.PackTransition{21: {PackID: 21, NextPackID: 22}}
|
|
attachTestStoryCatalog(s)
|
|
for quest := range s.quests {
|
|
if err := s.state.ClearQuest(quest, 21); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
}
|
|
const raw = `{"MapId":221,"PlayerPosition":{"x":7.5,"y":0,"z":-2.2},"ColleaguePositions":null}`
|
|
request := wire.AppendVarint(nil, 2, 22)
|
|
request = wire.AppendString(request, 3, raw)
|
|
if err := s.state.SaveUserPosition(request); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if pack, err := s.LastPlayedPackID(); err != nil || pack != 22 {
|
|
t.Fatalf("last story pack=%d err=%v", pack, err)
|
|
}
|
|
request = wire.AppendVarint(wire.AppendVarint(nil, 1, 1), 2, 22)
|
|
_, body, _, err := s.Handle("/PackInGameInfo", request)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
position, _, _ := wire.Bytes(body, 4)
|
|
if string(position) != raw {
|
|
t.Fatalf("story position=%s", position)
|
|
}
|
|
}
|