Files
bd2/go/internal/server/player/equipment_craft_test.go
T

219 lines
8.9 KiB
Go

package player
import (
"encoding/binary"
"os"
"path/filepath"
"testing"
"bd2server/internal/server/gamedata"
"bd2server/internal/server/wire"
)
func TestEquipMakingAgainstInstalledCurrentVersion(t *testing.T) {
testEquipMakingInstalled(t, 140, 14)
}
// Char10140 has Talent901: maximum level1, no experience in Skill901/1,
// and cumulative Growth901/1 threshold0 in current GameData.
func TestEquipMakingNonGrowingTalentAgainstInstalledCurrentVersion(t *testing.T) {
testEquipMakingInstalled(t, 10140, 0)
}
func testEquipMakingInstalled(t *testing.T, characterID, expectedExperience uint64) {
root := os.Getenv("BD2_REAL_GAMEDATA")
if root == "" {
t.Skip("set BD2_REAL_GAMEDATA for installed GameData integration test")
}
dir := t.TempDir()
inventory, err := OpenInventory(testStore(filepath.Join(dir, "items.json")), &Starter{Version: "2.35.10"})
if err != nil {
t.Fatal(err)
}
materials, err := inventory.GrantOnce("making-materials", []gamedata.BattleReward{{Type: 8, ID: 204, Count: 3}, {Type: 8, ID: 201, Count: 3}})
if err != nil || len(materials) != 2 {
t.Fatalf("materials=%+v err=%v", materials, err)
}
wallet, err := OpenWallet(testStore(filepath.Join(dir, "wallet.json")), Currency{Catalyst: 10})
if err != nil {
t.Fatal(err)
}
characters, err := OpenCharacterStore(testStore(filepath.Join(dir, "characters.json")), []Character{{InvenIndex: 77, ID: characterID, Level: 1, TalentLevel: 1}}, inventory, root, "20260923193640")
if err != nil {
t.Fatal(err)
}
equipment, err := OpenEquipmentInventory(testStore(filepath.Join(dir, "equipment.json")))
if err != nil {
t.Fatal(err)
}
craft, err := gamedata.LoadEquipmentCraftDesign(root, "20260923193640")
if err != nil {
t.Fatal(err)
}
upgrade, err := gamedata.LoadEquipmentUpgradeDesign(root, "20260923193640")
if err != nil {
t.Fatal(err)
}
if err := equipment.AttachUpgrade(upgrade, wallet, inventory); err != nil {
t.Fatal(err)
}
if err := equipment.AttachCraft(craft); err != nil {
t.Fatal(err)
}
if err := equipment.AttachCharacters(characters); err != nil {
t.Fatal(err)
}
equipment.BeginSession("making-test")
request := wire.AppendVarint(nil, 1, 5)
request = wire.AppendVarint(request, 2, 77)
request = wire.AppendVarint(request, 3, 1)
request = wire.AppendVarint(request, 4, 1)
for _, item := range materials {
request = wire.AppendBytes(request, 5, ItemWire(item))
}
code, response, handled, err := equipment.Handle("/EquipMaking", request)
if err != nil || !handled || code != 50 {
t.Fatalf("making code=%d handled=%t response=%x err=%v", code, handled, response, err)
}
if len(equipment.All()) != 1 || len(inventory.All()) != 0 {
t.Fatalf("making equipment=%+v inventory=%+v", equipment.All(), inventory.All())
}
if wallet.Snapshot().Catalyst != 7 {
t.Fatalf("making catalyst=%d", wallet.Snapshot().Catalyst)
}
if character, ok := characters.Find(77); !ok || character.TalentExp != expectedExperience {
t.Fatalf("making character=%+v found=%t", character, ok)
}
replayCode, replay, _, err := equipment.Handle("/EquipMaking", request)
if err != nil || replayCode != code || string(replay) != string(response) || len(equipment.All()) != 1 || wallet.Snapshot().Catalyst != 7 {
t.Fatalf("making replay code=%d response=%x equipment=%+v catalyst=%d err=%v", replayCode, replay, equipment.All(), wallet.Snapshot().Catalyst, err)
}
autoMaterials, err := inventory.GrantOnce("making-auto-materials", []gamedata.BattleReward{{Type: 8, ID: 204, Count: 3}, {Type: 8, ID: 201, Count: 3}})
if err != nil || len(autoMaterials) != 2 {
t.Fatalf("auto materials=%+v err=%v", autoMaterials, err)
}
autoRequest := wire.AppendVarint(nil, 1, 6)
autoRequest = wire.AppendVarint(autoRequest, 2, 77)
autoRequest = wire.AppendVarint(autoRequest, 3, 1)
autoRequest = wire.AppendVarint(autoRequest, 4, 1)
for _, item := range autoMaterials {
autoRequest = wire.AppendBytes(autoRequest, 5, ItemWire(item))
}
autoCode, autoResponse, autoHandled, err := equipment.Handle("/EquipMakingToBreakAuto", autoRequest)
if err != nil || !autoHandled || autoCode != 515 {
t.Fatalf("making auto code=%d handled=%t response=%x err=%v", autoCode, autoHandled, autoResponse, err)
}
if _, found, _ := wire.Bytes(autoResponse, 2); !found {
t.Fatalf("making auto omitted source equipment: %x", autoResponse)
}
if _, found, _ := wire.Bytes(autoResponse, 8); !found || len(equipment.All()) != 1 || len(inventory.All()) == 0 || wallet.Snapshot().Catalyst != 4 {
t.Fatalf("making auto response=%x equipment=%+v inventory=%+v catalyst=%d", autoResponse, equipment.All(), inventory.All(), wallet.Snapshot().Catalyst)
}
}
func TestEquipBreakUsesLevelRewardAndReplays(t *testing.T) {
dir := t.TempDir()
inventory, err := OpenInventory(testStore(filepath.Join(dir, "items.json")), &Starter{Version: "2.35.10"})
if err != nil {
t.Fatal(err)
}
wallet, err := OpenWallet(testStore(filepath.Join(dir, "wallet.json")), Currency{Gold: 100})
if err != nil {
t.Fatal(err)
}
equipment, err := OpenEquipmentInventory(testStore(filepath.Join(dir, "equipment.json")))
if err != nil {
t.Fatal(err)
}
design := equipmentBreakTestDesign()
if err := equipment.AttachUpgrade(design, wallet, inventory); err != nil {
t.Fatal(err)
}
equipment.BeginSession("break-test")
entry, err := equipment.GrantGeneratedOnce("break-source", Equipment{ID: 10, Level: 1, Rank: []uint64{0, 0, 0}})
if err != nil {
t.Fatal(err)
}
var packed [10]byte
n := binary.PutUvarint(packed[:], entry.InvenIndex)
request := wire.AppendBytes(wire.AppendVarint(nil, 1, 7), 2, packed[:n])
code, response, handled, err := equipment.Handle("/EquipBreak", request)
if err != nil || !handled || code != 56 || len(response) == 0 {
t.Fatalf("break code=%d handled=%t response=%x err=%v", code, handled, response, err)
}
if len(equipment.All()) != 0 {
t.Fatalf("broken equipment remained: %+v", equipment.All())
}
if got := inventory.All(); len(got) != 1 || got[0].ID != 201 || got[0].Type != 8 || got[0].Count != 2 {
t.Fatalf("break inventory=%+v", got)
}
replayCode, replay, _, err := equipment.Handle("/EquipBreak", request)
if err != nil || replayCode != code || string(replay) != string(response) || len(inventory.All()) != 1 {
t.Fatalf("break replay code=%d response=%x inventory=%+v err=%v", replayCode, replay, inventory.All(), err)
}
}
func TestEquipUpgradeToBreakAutoUpgradesThenRemoves(t *testing.T) {
dir := t.TempDir()
inventory, err := OpenInventory(testStore(filepath.Join(dir, "items.json")), &Starter{Version: "2.35.10"})
if err != nil {
t.Fatal(err)
}
wallet, err := OpenWallet(testStore(filepath.Join(dir, "wallet.json")), Currency{Gold: 100})
if err != nil {
t.Fatal(err)
}
equipment, err := OpenEquipmentInventory(testStore(filepath.Join(dir, "equipment.json")))
if err != nil {
t.Fatal(err)
}
design := equipmentBreakTestDesign()
if err := equipment.AttachUpgrade(design, wallet, inventory); err != nil {
t.Fatal(err)
}
equipment.BeginSession("upgrade-break-test")
entry, err := equipment.GrantOnce("upgrade-break-source", 10)
if err != nil {
t.Fatal(err)
}
request := wire.AppendVarint(nil, 1, 9)
request = wire.AppendVarint(request, 2, entry.InvenIndex)
request = wire.AppendVarint(request, 3, 2)
code, response, handled, err := equipment.Handle("/EquipUpgradeToBreakAuto", request)
if err != nil || !handled || code != 516 {
t.Fatalf("auto code=%d handled=%t response=%x err=%v", code, handled, response, err)
}
if attempts, _, _ := wire.Varint(response, 3); attempts != 2 {
t.Fatalf("auto attempts=%d response=%x", attempts, response)
}
if used, _, _ := wire.Varint(response, 6); used != 30 || wallet.Snapshot().Gold != 70 {
t.Fatalf("auto used=%d wallet=%+v", used, wallet.Snapshot())
}
if len(equipment.All()) != 0 {
t.Fatalf("auto-broken equipment remained: %+v", equipment.All())
}
if got := inventory.All(); len(got) != 1 || got[0].ID != 202 || got[0].Count != 3 {
t.Fatalf("auto break inventory=%+v", got)
}
replayCode, replay, _, err := equipment.Handle("/EquipUpgradeToBreakAuto", request)
if err != nil || replayCode != code || string(replay) != string(response) || wallet.Snapshot().Gold != 70 || len(inventory.All()) != 1 {
t.Fatalf("auto replay code=%d response=%x wallet=%+v inventory=%+v err=%v", replayCode, replay, wallet.Snapshot(), inventory.All(), err)
}
}
func equipmentBreakTestDesign() *gamedata.EquipmentUpgradeDesign {
return &gamedata.EquipmentUpgradeDesign{
MaxLevel: map[uint64]uint64{10: 2}, Group: map[uint64]uint64{10: 20}, RankGroup: map[uint64]uint64{10: 30},
Levels: map[[2]uint64]gamedata.EquipmentUpgradeLevel{
{20, 0}: {Level: 0, Costs: []gamedata.PromotionCost{{Type: 4, Count: 10}}, SuccessRatio: 1},
{20, 1}: {Level: 1, Costs: []gamedata.PromotionCost{{Type: 4, Count: 20}}, SuccessRatio: 1},
},
Break: map[[2]uint64][]gamedata.BattleReward{
{20, 0}: {{Type: 8, ID: 200, Count: 1}},
{20, 1}: {{Type: 8, ID: 201, Count: 2}},
{20, 2}: {{Type: 8, ID: 202, Count: 3}},
},
NotTrash: map[uint64]bool{10: true},
}
}