Files
bd2/go/internal/server/feature/recipes_test.go
T
Flechazo 5b5a219dc2 feat(server): add special loot and data-driven gameplay rules
Generate equipment loot atomically, grant random boxes and prevent repeat claims.
Read gacha pools, pity, products, tickets, missions, presets, chapter rewards
and inventory costs from GameData; extend both collaboration UR ticket pools.
Sync owned recipes, configure startup state and calendars in versioned seeds,
and validate unlock tickets and revival talents.
2026-10-04 19:15:59 +08:00

78 lines
2.4 KiB
Go

package feature
import (
"encoding/binary"
"reflect"
"testing"
"bd2server/internal/server/gamedata"
"bd2server/internal/server/player"
"bd2server/internal/server/stateio"
"bd2server/internal/server/versionconfig"
"bd2server/internal/server/wire"
)
func TestRecipesFollowOwnedGrantsAndRestart(t *testing.T) {
store := stateio.NewMemory()
starter := &player.Starter{Version: versionconfig.State()}
items, err := player.OpenInventory(store, starter)
if err != nil {
t.Fatal(err)
}
design := &gamedata.CookingRecipeDesign{IDs: map[uint64]bool{501: true, 701: true}}
service, err := NewRecipeService(design, []uint64{701}, items)
if err != nil {
t.Fatal(err)
}
check := func(service *RecipeService, want []uint64) {
t.Helper()
code, payload, handled, err := service.Handle("/RecipeInfo", wire.AppendVarint(nil, 1, 17))
if err != nil || !handled || code != 46 {
t.Fatalf("recipe response: %d %v %v", code, handled, err)
}
packed, _, err := wire.Bytes(payload, 2)
var ids []uint64
for len(packed) > 0 {
id, n := binary.Uvarint(packed)
if n <= 0 {
t.Fatal("malformed packed recipes")
}
ids = append(ids, id)
packed = packed[n:]
}
if err != nil || !reflect.DeepEqual(ids, want) {
t.Fatalf("recipes=%v want=%v err=%v", ids, want, err)
}
}
check(service, []uint64{701})
if _, err := items.GrantOnce("recipe-reward", []gamedata.BattleReward{{Type: 7, ID: 501, Count: 1}, {Type: 7, ID: 701, Count: 1}, {Type: 1, ID: 999, Count: 1}}); err != nil {
t.Fatal(err)
}
check(service, []uint64{501, 701})
reopened, err := player.OpenInventory(store, starter)
if err != nil {
t.Fatal(err)
}
service, err = NewRecipeService(design, []uint64{701}, reopened)
if err != nil {
t.Fatal(err)
}
check(service, []uint64{501, 701})
if _, err := reopened.GrantOnce("unknown-recipe", []gamedata.BattleReward{{Type: 7, ID: 800, Count: 1}}); err != nil {
t.Fatal(err)
}
if _, _, _, err := service.Handle("/RecipeInfo", wire.AppendVarint(nil, 1, 18)); err == nil {
t.Fatal("unknown owned recipe accepted")
}
}
func TestRecipeDesignRejectsUnknownInitialOwnership(t *testing.T) {
if _, err := NewRecipeService(&gamedata.CookingRecipeDesign{IDs: map[uint64]bool{501: true}}, []uint64{101}, statefulRecipeItems{}); err == nil {
t.Fatal("unknown initial recipe accepted")
}
}
type statefulRecipeItems struct{}
func (statefulRecipeItems) All() []player.Item { return nil }