From c8ac81c43cdf320f94515b97e14bfcb88f7bfceb Mon Sep 17 00:00:00 2001 From: hided62 Date: Wed, 19 Aug 2026 13:57:03 +0000 Subject: [PATCH] =?UTF-8?q?fix:=20=EC=9D=B4=EB=8F=99=20=EB=A1=9C=EA=B7=B8?= =?UTF-8?q?=EC=97=90=20=EC=8B=A4=EC=A0=9C=20=EB=8F=84=EC=8B=9C=EB=AA=85?= =?UTF-8?q?=EC=9D=84=20=ED=91=9C=EC=8B=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit NPC능동 실행 컨텍스트에 지도를 전달하고 이동·강행의 숫자 도시 코드 fallback을 제거한다. Ref/Core 차등 검사에서 세 명령의 목적 도시 로그와 코드 비노출을 확인한다. --- .../src/actions/turn/general/che_NPC능동.ts | 13 +++++++----- .../src/actions/turn/general/che_강행.ts | 7 ++----- .../src/actions/turn/general/che_이동.ts | 7 ++----- ...rnCommandGeneralMatrix.integration.test.ts | 21 +++++++++++++++++++ 4 files changed, 33 insertions(+), 15 deletions(-) diff --git a/packages/logic/src/actions/turn/general/che_NPC능동.ts b/packages/logic/src/actions/turn/general/che_NPC능동.ts index d033a289..085bc1e1 100644 --- a/packages/logic/src/actions/turn/general/che_NPC능동.ts +++ b/packages/logic/src/actions/turn/general/che_NPC능동.ts @@ -12,6 +12,7 @@ import { LogCategory, LogFormat } from '@sammo-ts/logic/logging/types.js'; import { JosaUtil } from '@sammo-ts/common'; import { z } from 'zod'; import type { TurnCommandEnv } from '@sammo-ts/logic/actions/turn/commandEnv.js'; +import type { ActionContextBuilder } from '@sammo-ts/logic/actions/turn/actionContext.js'; import type { GeneralTurnCommandSpec } from './index.js'; import type { MapDefinition } from '@sammo-ts/logic/world/types.js'; import { normalizeLegacyIntegerArg, parseArgsWithSchema } from '../parseArgs.js'; @@ -68,11 +69,8 @@ export class ActionResolver< const destCityId = args.destCityId; const storedDestCityId = args.storedDestCityId ?? destCityId; - let destCityName = `도시(${destCityId})`; - if (context.map) { - const c = context.map.cities.find((ct) => ct.id === destCityId); - if (c) destCityName = c.name; - } + const destCityName = + context.map?.cities.find((city) => city.id === destCityId)?.name ?? '알 수 없는 도시'; const josaRo = JosaUtil.pick(destCityName, '로'); @@ -132,6 +130,11 @@ export class ActionDefinition< } } +export const actionContextBuilder: ActionContextBuilder = (base, options) => ({ + ...base, + map: options.map, +}); + export const commandSpec: GeneralTurnCommandSpec = { key: 'che_NPC능동', category: '특수', // Valid category? Legacy didn't specify category in static prop usually, handled by mapping. Defaulting to '특수'. diff --git a/packages/logic/src/actions/turn/general/che_강행.ts b/packages/logic/src/actions/turn/general/che_강행.ts index d5a1010c..680d5ddb 100644 --- a/packages/logic/src/actions/turn/general/che_강행.ts +++ b/packages/logic/src/actions/turn/general/che_강행.ts @@ -68,11 +68,8 @@ export class ActionResolver< const goldCost = develCost * 5; // Log destination - let destCityName = `도시(${destCityId})`; - if (context.map) { - const c = context.map.cities.find((ct) => ct.id === destCityId); - if (c) destCityName = c.name; - } + const destCityName = + context.map?.cities.find((city) => city.id === destCityId)?.name ?? '알 수 없는 도시'; const josaRo = JosaUtil.pick(destCityName, '로'); diff --git a/packages/logic/src/actions/turn/general/che_이동.ts b/packages/logic/src/actions/turn/general/che_이동.ts index 3d99052f..8ffcde56 100644 --- a/packages/logic/src/actions/turn/general/che_이동.ts +++ b/packages/logic/src/actions/turn/general/che_이동.ts @@ -68,11 +68,8 @@ export class ActionResolver< const cost = context.develCost ?? 0; - let destCityName = `도시(${destCityId})`; - if (context.map) { - const c = context.map.cities.find((ct) => ct.id === destCityId); - if (c) destCityName = c.name; - } + const destCityName = + context.map?.cities.find((city) => city.id === destCityId)?.name ?? '알 수 없는 도시'; const josaRo = JosaUtil.pick(destCityName, '로'); diff --git a/tools/integration-tests/test/turnCommandGeneralMatrix.integration.test.ts b/tools/integration-tests/test/turnCommandGeneralMatrix.integration.test.ts index fcadabed..7ace0651 100644 --- a/tools/integration-tests/test/turnCommandGeneralMatrix.integration.test.ts +++ b/tools/integration-tests/test/turnCommandGeneralMatrix.integration.test.ts @@ -421,6 +421,21 @@ integration('general command success matrix', () => { ignoredPathPatterns: ignoredLifecyclePaths, }) ).toEqual([]); + if (action === 'che_이동' || action === 'che_강행') { + const actionLogSuffix = action === 'che_이동' ? '이동했습니다.' : '강행했습니다.'; + expect( + semanticLogSignatures( + core.after.logs.filter((entry) => String(entry.text).includes(actionLogSuffix)) + ) + ).toEqual( + semanticLogSignatures( + addedReferenceLogs(reference.before, reference.after.logs).filter((entry) => + String(entry.text).includes(actionLogSuffix) + ) + ) + ); + expect(core.after.logs.some((entry) => String(entry.text).includes('도시('))).toBe(false); + } }, 120_000 ); @@ -564,6 +579,12 @@ integration('NPC active command boundary parity', () => { ignoredPathPatterns: ignoredLifecyclePaths, }) ).toEqual([]); + if (completed) { + expect(semanticLogSignatures(core.after.logs)).toEqual( + semanticLogSignatures(addedReferenceLogs(reference.before, reference.after.logs)) + ); + expect(core.after.logs.some((entry) => String(entry.text).includes('도시('))).toBe(false); + } }, 120_000 );