fix: Ref 게임 로직과 시나리오 풀 호환을 보정
월 경계, 전투 기술 상한, 연감과 베팅·설문·경매 정산 순서를 Ref 계약에 맞춘다.\n\n시나리오 일반 풀을 ENGINE mutation과 logical tick 기반으로 직렬화하고 914·915 catalog 및 조건부 100기 pool 실행 경계를 추가한다.\n\n경매 worker는 세대별 durable event만 만들고 ENGINE이 row lock 후 상태 전이와 정산을 단일 transaction으로 소유한다.
This commit is contained in:
@@ -129,6 +129,7 @@ const buildContext = (options: {
|
||||
userId: string;
|
||||
roles?: string[];
|
||||
develCost?: number;
|
||||
currentDevelCost?: number;
|
||||
rankRows?: Array<{ generalId: number; type: string; value: number }>;
|
||||
}): GameApiContext => {
|
||||
const db = {
|
||||
@@ -142,7 +143,10 @@ const buildContext = (options: {
|
||||
findMany: async () => options.rankRows ?? [],
|
||||
},
|
||||
worldState: {
|
||||
findFirst: async () => ({ config: { const: { develCost: options.develCost ?? 200 } } }),
|
||||
findFirst: async () => ({
|
||||
config: { const: { develCost: options.develCost ?? 200 } },
|
||||
...(options.currentDevelCost === undefined ? {} : { meta: { develcost: options.currentDevelCost } }),
|
||||
}),
|
||||
},
|
||||
} as unknown as DatabaseClient;
|
||||
return {
|
||||
@@ -267,6 +271,42 @@ describe('tournament router permissions and mutations', () => {
|
||||
expect(snapshot.participants[0]!.groupId).toBeLessThan(8);
|
||||
});
|
||||
|
||||
it('charges the current game_env develcost instead of the scenario snapshot', async () => {
|
||||
const redis = new MemoryRedis();
|
||||
const transport = new TournamentTransport();
|
||||
const general = buildGeneral(1, 'user-1');
|
||||
transport.gold.set(general.id, general.gold);
|
||||
await setTournamentFixture(redis, {
|
||||
stage: 1,
|
||||
phase: 0,
|
||||
type: 0,
|
||||
auto: true,
|
||||
openYear: 193,
|
||||
openMonth: 1,
|
||||
termSeconds: 60,
|
||||
nextAt: '2026-07-26T01:00:00.000Z',
|
||||
});
|
||||
await redis.set('sammo:che:default:tournament:participants', '[]');
|
||||
const caller = appRouter.createCaller(
|
||||
buildContext({
|
||||
redis,
|
||||
transport,
|
||||
generals: [general],
|
||||
userId: 'user-1',
|
||||
develCost: 200,
|
||||
currentDevelCost: 64,
|
||||
})
|
||||
);
|
||||
|
||||
await expect(caller.tournament.join()).resolves.toEqual({ ok: true, count: 1 });
|
||||
expect(transport.gold.get(general.id)).toBe(1_936);
|
||||
expect(transport.commands).toContainEqual({
|
||||
type: 'adjustGeneralResources',
|
||||
reason: 'tournamentJoin',
|
||||
adjustments: [{ generalId: general.id, goldDelta: -64, minGoldAfter: 0 }],
|
||||
});
|
||||
});
|
||||
|
||||
it('serializes concurrent bets and enforces the legacy per-user 1000 limit', async () => {
|
||||
const redis = new MemoryRedis();
|
||||
const transport = new TournamentTransport();
|
||||
|
||||
Reference in New Issue
Block a user