feat: 국가 메타 업데이트 기능 추가 및 관련 로직 구현
This commit is contained in:
@@ -429,26 +429,35 @@ const assertNationEditable = (
|
||||
};
|
||||
|
||||
const updateNationMeta = async (
|
||||
ctx: Pick<GameApiContext, 'db'>,
|
||||
ctx: Pick<GameApiContext, 'turnDaemon'>,
|
||||
nationId: number,
|
||||
updates: Record<string, unknown>
|
||||
updates: Record<string, unknown>,
|
||||
currentMeta: Record<string, unknown>
|
||||
): Promise<InputJsonValue> => {
|
||||
const nation = await ctx.db.nation.findUnique({
|
||||
where: { id: nationId },
|
||||
select: { meta: true },
|
||||
const expectedUpdatedAt = typeof currentMeta._updatedAt === 'string' ? currentMeta._updatedAt : undefined;
|
||||
const result = await ctx.turnDaemon.requestCommand({
|
||||
type: 'setNationMeta',
|
||||
nationId,
|
||||
updates,
|
||||
expectedUpdatedAt,
|
||||
});
|
||||
if (!nation) {
|
||||
throw new TRPCError({ code: 'NOT_FOUND', message: 'Nation not found' });
|
||||
if (!result || result.type !== 'setNationMeta') {
|
||||
throw new TRPCError({ code: 'INTERNAL_SERVER_ERROR', message: 'Unexpected response' });
|
||||
}
|
||||
const meta = asRecord(nation.meta);
|
||||
const nextMeta = { ...meta, ...updates } as InputJsonValue;
|
||||
await ctx.db.nation.update({
|
||||
where: { id: nationId },
|
||||
data: {
|
||||
meta: nextMeta,
|
||||
},
|
||||
});
|
||||
return nextMeta;
|
||||
if (!result.ok) {
|
||||
if (result.reason === 'CONFLICT') {
|
||||
throw new TRPCError({
|
||||
code: 'CONFLICT',
|
||||
message: '다른 사용자가 정책을 변경했습니다. 재시도하거나 현재 상태로 갱신해주세요.',
|
||||
});
|
||||
}
|
||||
throw new TRPCError({ code: 'BAD_REQUEST', message: result.reason });
|
||||
}
|
||||
return {
|
||||
...currentMeta,
|
||||
...updates,
|
||||
_updatedAt: result.updatedAt,
|
||||
} as InputJsonValue;
|
||||
};
|
||||
|
||||
const mapGeneralList = async (
|
||||
@@ -1239,9 +1248,10 @@ export const nationRouter = router({
|
||||
throw new TRPCError({ code: 'NOT_FOUND', message: 'Nation not found' });
|
||||
}
|
||||
assertNationEditable(me, nation.meta);
|
||||
const nationMeta = asRecord(nation.meta);
|
||||
await updateNationMeta(ctx, me.nationId, {
|
||||
notice: input.msg,
|
||||
});
|
||||
}, nationMeta);
|
||||
return { ok: true };
|
||||
}),
|
||||
setScoutMsg: authedProcedure
|
||||
@@ -1261,9 +1271,10 @@ export const nationRouter = router({
|
||||
throw new TRPCError({ code: 'NOT_FOUND', message: 'Nation not found' });
|
||||
}
|
||||
assertNationEditable(me, nation.meta);
|
||||
const nationMeta = asRecord(nation.meta);
|
||||
await updateNationMeta(ctx, me.nationId, {
|
||||
infoText: input.msg,
|
||||
});
|
||||
}, nationMeta);
|
||||
return { ok: true };
|
||||
}),
|
||||
setRate: authedProcedure
|
||||
@@ -1283,9 +1294,10 @@ export const nationRouter = router({
|
||||
throw new TRPCError({ code: 'NOT_FOUND', message: 'Nation not found' });
|
||||
}
|
||||
assertNationEditable(me, nation.meta);
|
||||
const nationMeta = asRecord(nation.meta);
|
||||
await updateNationMeta(ctx, me.nationId, {
|
||||
rate: input.amount,
|
||||
});
|
||||
}, nationMeta);
|
||||
return { ok: true };
|
||||
}),
|
||||
setBill: authedProcedure
|
||||
@@ -1305,9 +1317,10 @@ export const nationRouter = router({
|
||||
throw new TRPCError({ code: 'NOT_FOUND', message: 'Nation not found' });
|
||||
}
|
||||
assertNationEditable(me, nation.meta);
|
||||
const nationMeta = asRecord(nation.meta);
|
||||
await updateNationMeta(ctx, me.nationId, {
|
||||
bill: input.amount,
|
||||
});
|
||||
}, nationMeta);
|
||||
return { ok: true };
|
||||
}),
|
||||
setSecretLimit: authedProcedure
|
||||
@@ -1327,9 +1340,10 @@ export const nationRouter = router({
|
||||
throw new TRPCError({ code: 'NOT_FOUND', message: 'Nation not found' });
|
||||
}
|
||||
assertNationEditable(me, nation.meta);
|
||||
const nationMeta = asRecord(nation.meta);
|
||||
await updateNationMeta(ctx, me.nationId, {
|
||||
secretlimit: input.amount,
|
||||
});
|
||||
}, nationMeta);
|
||||
return { ok: true };
|
||||
}),
|
||||
setBlockWar: authedProcedure
|
||||
@@ -1359,7 +1373,7 @@ export const nationRouter = router({
|
||||
await updateNationMeta(ctx, me.nationId, {
|
||||
war: input.value ? 1 : 0,
|
||||
available_war_setting_cnt: nextRemain,
|
||||
});
|
||||
}, meta);
|
||||
return { availableCnt: nextRemain };
|
||||
}),
|
||||
setBlockScout: authedProcedure
|
||||
@@ -1379,9 +1393,10 @@ export const nationRouter = router({
|
||||
throw new TRPCError({ code: 'NOT_FOUND', message: 'Nation not found' });
|
||||
}
|
||||
assertNationEditable(me, nation.meta);
|
||||
const nationMeta = asRecord(nation.meta);
|
||||
await updateNationMeta(ctx, me.nationId, {
|
||||
scout: input.value ? 1 : 0,
|
||||
});
|
||||
}, nationMeta);
|
||||
return { ok: true };
|
||||
}),
|
||||
getBattleCenter: authedProcedure.query(async ({ ctx }) => {
|
||||
|
||||
@@ -8,6 +8,7 @@ import { findCrewTypeById, getTechCost } from '@sammo-ts/logic/world/unitSet.js'
|
||||
|
||||
import { authedProcedure, router } from '../../trpc.js';
|
||||
import { loadUnitSetDefinitionByName } from '../../battleSim/unitSetLoader.js';
|
||||
import type { GameApiContext } from '../../context.js';
|
||||
import { getMyGeneral } from '../shared/general.js';
|
||||
import { resolveSecretPermission } from '../shared/secretPermission.js';
|
||||
|
||||
@@ -42,6 +43,33 @@ type SetterInfo = {
|
||||
date: string | null;
|
||||
};
|
||||
|
||||
const updateNationMeta = async (
|
||||
ctx: Pick<GameApiContext, 'turnDaemon'>,
|
||||
nationId: number,
|
||||
updates: Record<string, unknown>,
|
||||
currentMeta: Record<string, unknown>
|
||||
): Promise<void> => {
|
||||
const expectedUpdatedAt = typeof currentMeta._updatedAt === 'string' ? currentMeta._updatedAt : undefined;
|
||||
const result = await ctx.turnDaemon.requestCommand({
|
||||
type: 'setNationMeta',
|
||||
nationId,
|
||||
updates,
|
||||
expectedUpdatedAt,
|
||||
});
|
||||
if (!result || result.type !== 'setNationMeta') {
|
||||
throw new TRPCError({ code: 'INTERNAL_SERVER_ERROR', message: 'Unexpected response' });
|
||||
}
|
||||
if (!result.ok) {
|
||||
if (result.reason === 'CONFLICT') {
|
||||
throw new TRPCError({
|
||||
code: 'CONFLICT',
|
||||
message: '다른 사용자가 정책을 변경했습니다. 재시도하거나 현재 상태로 갱신해주세요.',
|
||||
});
|
||||
}
|
||||
throw new TRPCError({ code: 'BAD_REQUEST', message: result.reason });
|
||||
}
|
||||
};
|
||||
|
||||
const DEFAULT_NATION_PRIORITY = [
|
||||
'불가침제의',
|
||||
'선전포고',
|
||||
@@ -665,15 +693,14 @@ export const npcRouter = router({
|
||||
valueSetTime: new Date().toISOString(),
|
||||
};
|
||||
|
||||
await ctx.db.nation.update({
|
||||
where: { id: nation.id },
|
||||
data: {
|
||||
meta: {
|
||||
...nationMeta,
|
||||
npc_nation_policy: nextPolicyRoot,
|
||||
},
|
||||
await updateNationMeta(
|
||||
ctx,
|
||||
nation.id,
|
||||
{
|
||||
npc_nation_policy: nextPolicyRoot,
|
||||
},
|
||||
});
|
||||
nationMeta
|
||||
);
|
||||
|
||||
return { ok: true };
|
||||
}),
|
||||
@@ -722,15 +749,14 @@ export const npcRouter = router({
|
||||
prioritySetTime: new Date().toISOString(),
|
||||
};
|
||||
|
||||
await ctx.db.nation.update({
|
||||
where: { id: nation.id },
|
||||
data: {
|
||||
meta: {
|
||||
...nationMeta,
|
||||
npc_nation_policy: nextPolicyRoot,
|
||||
},
|
||||
await updateNationMeta(
|
||||
ctx,
|
||||
nation.id,
|
||||
{
|
||||
npc_nation_policy: nextPolicyRoot,
|
||||
},
|
||||
});
|
||||
nationMeta
|
||||
);
|
||||
|
||||
return { ok: true };
|
||||
}),
|
||||
@@ -778,15 +804,14 @@ export const npcRouter = router({
|
||||
prioritySetTime: new Date().toISOString(),
|
||||
};
|
||||
|
||||
await ctx.db.nation.update({
|
||||
where: { id: nation.id },
|
||||
data: {
|
||||
meta: {
|
||||
...nationMeta,
|
||||
npc_general_policy: nextPolicyRoot,
|
||||
},
|
||||
await updateNationMeta(
|
||||
ctx,
|
||||
nation.id,
|
||||
{
|
||||
npc_general_policy: nextPolicyRoot,
|
||||
},
|
||||
});
|
||||
nationMeta
|
||||
);
|
||||
|
||||
return { ok: true };
|
||||
}),
|
||||
|
||||
Reference in New Issue
Block a user