131 lines
4.9 KiB
Go
131 lines
4.9 KiB
Go
package player
|
|
|
|
import (
|
|
"os"
|
|
"path/filepath"
|
|
"testing"
|
|
|
|
"bd2server/internal/server/gamedata"
|
|
"bd2server/internal/server/stateio"
|
|
"bd2server/internal/server/wire"
|
|
)
|
|
|
|
func inventorySlotTestDesign() *gamedata.InventorySlotDesign {
|
|
return &gamedata.InventorySlotDesign{
|
|
Items: gamedata.InventorySlotRule{Default: 100, Maximum: 500, PriceType: 4, BasePrice: 300, MaxPrice: 10000},
|
|
Storage: gamedata.InventorySlotRule{Default: 100, Maximum: 400, PriceType: 4, BasePrice: 300, MaxPrice: 10000},
|
|
Equipment: gamedata.InventorySlotRule{Default: 500, Maximum: 2000, PriceType: 4, BasePrice: 300, MaxPrice: 10000},
|
|
EquipmentStorage: gamedata.InventorySlotRule{Default: 100, Maximum: 400, PriceType: 4, BasePrice: 300, MaxPrice: 10000},
|
|
}
|
|
}
|
|
|
|
func inventorySlotTestCounts() InventorySlotCounts {
|
|
return InventorySlotCounts{Items: 100, Storage: 100, Equipment: 500, EquipmentStorage: 100}
|
|
}
|
|
|
|
func TestInventorySlotExpansionChargesPersistsAndReplays(t *testing.T) {
|
|
store := stateio.NewMemory()
|
|
wallet, err := OpenWallet(store, Currency{Gold: 100000})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
slots, err := OpenInventorySlots(store, inventorySlotTestDesign(), inventorySlotTestCounts(), wallet)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
slots.BeginSession("test")
|
|
request := wire.AppendVarint(wire.AppendVarint(nil, 1, 7), 2, 2)
|
|
code, response, ok, err := slots.Handle("/InvenAddSlot", request)
|
|
if err != nil || !ok || code != 24 || len(response) != 0 {
|
|
t.Fatalf("code=%d response=%x ok=%t err=%v", code, response, ok, err)
|
|
}
|
|
if wallet.Snapshot().Gold != 99100 { // first two slots cost 400 + 500
|
|
t.Fatalf("gold=%d", wallet.Snapshot().Gold)
|
|
}
|
|
if _, _, _, err := slots.Handle("/InvenAddSlot", request); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if wallet.Snapshot().Gold != 99100 {
|
|
t.Fatalf("replay charged twice: %d", wallet.Snapshot().Gold)
|
|
}
|
|
reopened, err := OpenInventorySlots(store, inventorySlotTestDesign(), inventorySlotTestCounts(), wallet)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
counts, err := reopened.InventorySlotCounts()
|
|
if err != nil || counts.Items != 102 {
|
|
t.Fatalf("counts=%+v err=%v", counts, err)
|
|
}
|
|
}
|
|
|
|
func TestInventorySlotEndpointsUseTheirProtocolCodes(t *testing.T) {
|
|
for path, code := range map[string]int{
|
|
"/InvenAddSlot": 24, "/StorageAddSlot": 25, "/EquipAddSlot": 39, "/EquipStorageAddSlot": 82,
|
|
} {
|
|
t.Run(path, func(t *testing.T) {
|
|
store := stateio.NewMemory()
|
|
wallet, _ := OpenWallet(store, Currency{Gold: 1000})
|
|
slots, _ := OpenInventorySlots(store, inventorySlotTestDesign(), inventorySlotTestCounts(), wallet)
|
|
slots.BeginSession("test")
|
|
request := wire.AppendVarint(wire.AppendVarint(nil, 1, 1), 2, 1)
|
|
got, body, ok, err := slots.Handle(path, request)
|
|
if err != nil || !ok || got != code || len(body) != 0 || wallet.Snapshot().Gold != 600 {
|
|
t.Fatalf("code=%d body=%x ok=%t gold=%d err=%v", got, body, ok, wallet.Snapshot().Gold, err)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestUnlimitedInventoryUsesGameDataMaximumAtLoginOnly(t *testing.T) {
|
|
store := stateio.NewMemory()
|
|
wallet, _ := OpenWallet(store, Currency{})
|
|
slots, _ := OpenInventorySlots(store, inventorySlotTestDesign(), inventorySlotTestCounts(), wallet)
|
|
path := filepath.Join(t.TempDir(), "dev-tools.json")
|
|
slots.AttachDevelopmentSettings(path)
|
|
if err := os.WriteFile(path, []byte(`{"version":1,"inventory":{"unlimited":true}}`), 0o600); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
counts, err := slots.InventorySlotCounts()
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if counts.Items != 500 || counts.Equipment != 2000 || counts.Storage != 100 || counts.EquipmentStorage != 100 {
|
|
t.Fatalf("counts=%+v", counts)
|
|
}
|
|
if err := os.WriteFile(path, []byte(`{"version":1,"inventory":{"unlimited":false}}`), 0o600); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
counts, err = slots.InventorySlotCounts()
|
|
if err != nil || counts != inventorySlotTestCounts() {
|
|
t.Fatalf("restored counts=%+v err=%v", counts, err)
|
|
}
|
|
}
|
|
|
|
func TestUnlimitedInventoryRejectsMalformedDevelopmentSettings(t *testing.T) {
|
|
store := stateio.NewMemory()
|
|
wallet, _ := OpenWallet(store, Currency{})
|
|
slots, _ := OpenInventorySlots(store, inventorySlotTestDesign(), inventorySlotTestCounts(), wallet)
|
|
path := filepath.Join(t.TempDir(), "dev-tools.json")
|
|
slots.AttachDevelopmentSettings(path)
|
|
if err := os.WriteFile(path, []byte(`{"version":1,"inventory":{"unlimited":true},"extra":1}`), 0o600); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if _, err := slots.InventorySlotCounts(); err == nil {
|
|
t.Fatal("malformed settings accepted")
|
|
}
|
|
if err := os.WriteFile(path, []byte(`{"version":1}`), 0o600); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if _, err := slots.InventorySlotCounts(); err == nil {
|
|
t.Fatal("settings without inventory accepted")
|
|
}
|
|
}
|
|
|
|
func TestInventorySlotPriceCapsEachAddedSlot(t *testing.T) {
|
|
rule := gamedata.InventorySlotRule{Default: 100, Maximum: 500, PriceType: 4, BasePrice: 300, MaxPrice: 10000}
|
|
price, err := inventorySlotPrice(rule, 196, 2)
|
|
if err != nil || price != 20000 {
|
|
t.Fatalf("price=%d err=%v", price, err)
|
|
}
|
|
}
|