feat(server): complete tracker flow and NPC shops, inns, commissions and reputation
This commit is contained in:
@@ -0,0 +1,128 @@
|
||||
package world
|
||||
|
||||
import (
|
||||
"bd2server/internal/server/gamedata"
|
||||
"bd2server/internal/server/player"
|
||||
"bd2server/internal/server/progress"
|
||||
"bd2server/internal/server/stateio"
|
||||
"bd2server/internal/server/wire"
|
||||
"testing"
|
||||
)
|
||||
|
||||
type eventPackSource struct {
|
||||
active bool
|
||||
pack gamedata.EventFieldPack
|
||||
}
|
||||
|
||||
func (p *eventPackSource) ResolveEventFieldPack(id int) (gamedata.EventFieldPack, bool, error) {
|
||||
return p.pack, p.active && p.pack.ID == id, nil
|
||||
}
|
||||
func (p *eventPackSource) ListEventFieldPacks() ([]gamedata.EventFieldPack, error) {
|
||||
if p.active {
|
||||
return []gamedata.EventFieldPack{p.pack}, nil
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// Exercise the actual purchase-to-field request chain rather than a single
|
||||
// permissive route. A hidden scene must not overwrite relogin's outside map.
|
||||
func TestHiddenPackPurchaseEntryMonstersAndOutsideRestore(t *testing.T) {
|
||||
s := testService()
|
||||
storage := stateio.NewMemory()
|
||||
var err error
|
||||
s.state, err = progress.OpenStore(storage)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
s.collection, err = player.OpenCollectionStore(storage, nil)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
s.inventory, err = player.OpenInventory(storage, s.starter)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
s.wallet, err = player.OpenWallet(storage, player.Currency{Gold: 100})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
source := &eventPackSource{active: true, pack: gamedata.EventFieldPack{ID: 912, MapIDs: []int{9121}, InitialPosition: "{}", BuyType: 4, BuyPrice: 20}}
|
||||
if err = s.AttachEventFieldPacks(source); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
s.monsterLoader = func(pack int) ([]gamedata.FieldMonsterDesign, error) {
|
||||
if pack != 912 {
|
||||
t.Fatalf("wrong pack for monsters %d", pack)
|
||||
}
|
||||
return []gamedata.FieldMonsterDesign{{ID: 3, GroupID: 7}}, nil
|
||||
}
|
||||
outside := wire.AppendString(wire.AppendVarint(nil, 2, 21), 3, `{"MapId":211,"PlayerPosition":{"x":4}}`)
|
||||
if err = s.state.SaveUserPosition(outside); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err = s.state.SetActivePackID(21); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
r := wire.AppendVarint(wire.AppendVarint(nil, 1, 1), 2, 912)
|
||||
if _, _, _, err = s.Handle("/PackInGameInfo", r); err == nil {
|
||||
t.Fatal("unbought hidden pack admitted")
|
||||
}
|
||||
for i := 0; i < 2; i++ {
|
||||
code, out, ok, err := s.Handle("/PackBuy", r)
|
||||
if err != nil || code != 6 || !ok {
|
||||
t.Fatalf("buy %d %v", code, err)
|
||||
}
|
||||
info, found, err := wire.Bytes(out, 1)
|
||||
if err != nil || !found {
|
||||
t.Fatal("missing PackInfo")
|
||||
}
|
||||
id, _, _ := wire.Varint(info, 1)
|
||||
owned, _, _ := wire.Varint(info, 8)
|
||||
if id != 912 || owned != 1 {
|
||||
t.Fatal("hidden buy response missing purchased identity")
|
||||
}
|
||||
}
|
||||
if s.wallet.Snapshot().Gold != 80 {
|
||||
t.Fatal("replayed purchase spent twice")
|
||||
}
|
||||
if _, _, _, err = s.Handle("/FieldObjectInfo", r); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
_, out, _, err := s.Handle("/PackInGameInfo", r)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
position, _, _ := wire.Bytes(out, 4)
|
||||
if string(position) != "{}" {
|
||||
t.Fatal("outside position leaked into hidden scene")
|
||||
}
|
||||
if _, found, _ := wire.Bytes(out, 12); !found {
|
||||
t.Fatal("client HuntingGroundInfo null")
|
||||
}
|
||||
if _, found, _ := wire.Bytes(out, 2); found {
|
||||
t.Fatal("hidden scene inherited story quests")
|
||||
}
|
||||
monster := wire.AppendVarint(wire.AppendVarint(nil, 1, 3), 2, 7)
|
||||
code, out, _, err := s.Handle("/MonsterInfo", monster)
|
||||
if err != nil || code != 51 {
|
||||
t.Fatalf("monster info %v", err)
|
||||
}
|
||||
m, _, _ := wire.Bytes(out, 1)
|
||||
id, _, _ := wire.Varint(m, 1)
|
||||
if id != 3 {
|
||||
t.Fatal("hidden monster not generated")
|
||||
}
|
||||
if pack, err := s.LastPlayedPackID(); err != nil || pack != 21 {
|
||||
t.Fatalf("hidden scene replaced persistent login %d %v", pack, err)
|
||||
}
|
||||
source.active = false
|
||||
if _, _, _, err = s.Handle("/PackBuy", r); err == nil {
|
||||
t.Fatal("expired pack repurchased")
|
||||
}
|
||||
if _, _, _, err = s.Handle("/PackInGameInfo", r); err == nil {
|
||||
t.Fatal("expired pack entered")
|
||||
}
|
||||
if pack, err := s.LastPlayedPackID(); err != nil || pack != 21 {
|
||||
t.Fatalf("expired hidden scene locked login %d %v", pack, err)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user