Files
core2026/packages/logic/src/auction/alias.ts
T

215 lines
3.7 KiB
TypeScript

import { LiteHashDRBG, RandUtil } from '@sammo-ts/common';
import { simpleSerialize } from '../war/utils.js';
export const LEGACY_RANDOM_GENERAL_FIRST_NAMES = [
'가',
'간',
'감',
'강',
'고',
'공',
'공손',
'곽',
'관',
'괴',
'교',
'금',
'노',
'뇌',
'능',
'도',
'동',
'두',
'등',
'마',
'맹',
'문',
'미',
'반',
'방',
'부',
'비',
'사',
'사마',
'서',
'설',
'성',
'소',
'손',
'송',
'순',
'신',
'심',
'악',
'안',
'양',
'엄',
'여',
'염',
'오',
'왕',
'요',
'우',
'원',
'위',
'유',
'육',
'윤',
'이',
'장',
'저',
'전',
'정',
'제갈',
'조',
'종',
'주',
'진',
'채',
'태사',
'하',
'하후',
'학',
'한',
'향',
'허',
'호',
'화',
'황',
'공손',
'손',
'왕',
'유',
'장',
'조',
] as const;
export const LEGACY_RANDOM_GENERAL_LAST_NAMES = [
'가',
'간',
'강',
'거',
'건',
'검',
'견',
'경',
'공',
'광',
'권',
'규',
'녕',
'단',
'대',
'도',
'등',
'람',
'량',
'례',
'로',
'료',
'모',
'민',
'박',
'범',
'보',
'비',
'사',
'상',
'색',
'서',
'소',
'속',
'송',
'수',
'순',
'습',
'승',
'양',
'연',
'영',
'온',
'옹',
'완',
'우',
'웅',
'월',
'위',
'유',
'윤',
'융',
'이',
'익',
'임',
'정',
'제',
'조',
'주',
'준',
'지',
'찬',
'책',
'충',
'탁',
'택',
'통',
'패',
'평',
'포',
'합',
'해',
'혁',
'현',
'화',
'환',
'회',
'횡',
'후',
'훈',
'휴',
'흠',
'흥',
] as const;
const readNameParts = (value: unknown, fallback: readonly string[]): string[] => {
if (!Array.isArray(value)) {
return [...fallback];
}
const result = value.filter((entry): entry is string => typeof entry === 'string');
return result.length > 0 ? result : [...fallback];
};
export const buildAuctionAliasPool = (
hiddenSeed: string | number,
configConst: Record<string, unknown> = {}
): string[] => {
const persistedPool = readNameParts(configConst.obfuscatedNamePool, []);
if (persistedPool.length > 0) {
return persistedPool;
}
const firstNames = readNameParts(configConst.randGenFirstName, LEGACY_RANDOM_GENERAL_FIRST_NAMES);
const middleNames = readNameParts(configConst.randGenMiddleName, ['']);
const lastNames = readNameParts(configConst.randGenLastName, LEGACY_RANDOM_GENERAL_LAST_NAMES);
const pool: string[] = [];
for (const first of firstNames) {
for (const middle of middleNames) {
for (const last of lastNames) {
pool.push(`${first}${middle}${last}`);
}
}
}
return new RandUtil(new LiteHashDRBG(simpleSerialize(hiddenSeed, 'obfuscatedNamePool'))).shuffle(pool);
};
export const buildAuctionAlias = (
generalId: number,
hiddenSeed: string | number,
configConst: Record<string, unknown> = {}
): string => {
const shuffled = buildAuctionAliasPool(hiddenSeed, configConst);
const normalizedId = Math.max(0, Math.floor(generalId));
const duplicateIndex = Math.floor(normalizedId / shuffled.length);
const name = shuffled[normalizedId % shuffled.length] ?? `익명${normalizedId}`;
return duplicateIndex === 0 ? name : `${name}${duplicateIndex}`;
};