Implement hunting AP and progress, event tasks, exchanges, games, stories and actions; connect battle and reward handling. Add CashShop plugin and installation, server purchases and entitlements, recharge rules and plugin version metadata. Distribute binary calendars independently; cache GameData in memory and fix single-connection query deadlocks. Improve automatic login and recovery diagnostics; document configuration and release flows.
84 lines
2.7 KiB
Go
84 lines
2.7 KiB
Go
package world
|
|
|
|
import (
|
|
"bd2server/internal/server/gamedata"
|
|
"bd2server/internal/server/progress"
|
|
"bd2server/internal/server/stateio"
|
|
"bd2server/internal/server/wire"
|
|
"bytes"
|
|
"testing"
|
|
)
|
|
|
|
type researchEconomySpy struct {
|
|
calls int
|
|
rewards []gamedata.Reward
|
|
}
|
|
|
|
func (e *researchEconomySpy) Apply(_ string, _ []gamedata.Reward, rewards []gamedata.Reward) ([]byte, error) {
|
|
e.calls++
|
|
e.rewards = rewards
|
|
item := wire.AppendVarint(nil, 1, 17)
|
|
item = wire.AppendVarint(item, 2, 103)
|
|
item = wire.AppendVarint(item, 3, 1)
|
|
return wire.AppendBytes(nil, 1, item), nil
|
|
}
|
|
func TestResearchRequiresCurrentMapPersistsRewardAndCounts(t *testing.T) {
|
|
s := testService()
|
|
storage := stateio.NewMemory()
|
|
var err error
|
|
s.state, err = progress.OpenStore(storage)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if err = s.state.SetActivePackID(21); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
save := wire.AppendVarint(nil, 1, 1)
|
|
save = wire.AppendVarint(save, 2, 21)
|
|
save = wire.AppendString(save, 3, `{"MapId":211,"PlayerPosition":{"x":0,"y":0,"z":0},"ColleaguePositions":null}`)
|
|
if err = s.state.SaveUserPosition(save); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
s.researchDesigns = map[int]gamedata.FieldResearchDesign{21: {Objects: map[int]gamedata.FieldResearchObject{401: {ID: 401, Maps: []int{211}, CollectionID: 103}, 402: {ID: 402, Maps: []int{212}, CollectionID: 104}}}}
|
|
spy := &researchEconomySpy{}
|
|
s.researchEconomy = spy
|
|
req := wire.AppendVarint(nil, 1, 10)
|
|
req = wire.AppendVarint(req, 2, 21)
|
|
bad := wire.AppendVarint(append([]byte(nil), req...), 3, 402)
|
|
if _, _, _, err = s.Handle("/FieldObjectResearch", bad); err == nil {
|
|
t.Fatal("accepted different map")
|
|
}
|
|
req = wire.AppendVarint(req, 3, 401)
|
|
code, first, handled, err := s.Handle("/FieldObjectResearch", req)
|
|
if err != nil || !handled || code != 59 {
|
|
t.Fatalf("research: %d %v %v", code, handled, err)
|
|
}
|
|
if len(spy.rewards) != 1 || spy.rewards[0].Type != 17 || spy.rewards[0].ID != 103 {
|
|
t.Fatalf("collection reward must use type17: %+v", spy.rewards)
|
|
}
|
|
s.state, err = progress.OpenStore(storage)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
_, again, _, err := s.Handle("/FieldObjectResearch", req)
|
|
if err != nil || !bytes.Equal(first, again) || spy.calls != 1 {
|
|
t.Fatalf("replay duplicated reward or lost response: calls%d err%v", spy.calls, err)
|
|
}
|
|
counts := wire.AppendVarint(nil, 1, 11)
|
|
counts = wire.AppendVarint(counts, 2, 21)
|
|
counts = wire.AppendVarint(counts, 3, 1)
|
|
code, body, _, err := s.Handle("/PackRewardObjectCount", counts)
|
|
if err != nil || code != 226 {
|
|
t.Fatal(err)
|
|
}
|
|
info, _, err := wire.Bytes(body, 1)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
count, _, _ := wire.Varint(info, 3)
|
|
max, _, _ := wire.Varint(info, 4)
|
|
if count != 1 || max != 2 {
|
|
t.Fatalf("count%d max%d", count, max)
|
|
}
|
|
}
|