diff --git a/backend/lib/db.js b/backend/lib/db.js index 9dbaa95..5c39101 100644 --- a/backend/lib/db.js +++ b/backend/lib/db.js @@ -12,7 +12,12 @@ const dbPool = mysql.createPool({ }); // 캐시 데이터 -let translationsCache = {}; +let translationsCache = { + blocks: {}, // 블록 번역 + items: {}, // 아이템 번역 + entities: {}, // 엔티티 번역 + itemsAndBlocks: {}, // 아이템 통계용 (items + blocks) +}; let iconsCache = {}; // { "type:name": iconUrl } - 타입별로 구분 let gamerulesCache = {}; @@ -35,23 +40,28 @@ async function loadTranslations() { ); // 캐시 초기화 - translationsCache = {}; + translationsCache = { blocks: {}, items: {}, entities: {}, all: {} }; iconsCache = {}; - // blocks, items, entities를 캐시에 저장 (type:name 형식으로 구분) + // 타입별로 분리하여 저장 blocks.forEach((row) => { - translationsCache[row.name] = row.name_ko; + translationsCache.blocks[row.name] = row.name_ko; if (row.icon) iconsCache[`block:${row.name}`] = row.icon; }); items.forEach((row) => { - translationsCache[row.name] = row.name_ko; + translationsCache.items[row.name] = row.name_ko; if (row.icon) iconsCache[`item:${row.name}`] = row.icon; }); entities.forEach((row) => { - translationsCache[row.name] = row.name_ko; + translationsCache.entities[row.name] = row.name_ko; if (row.icon) iconsCache[`entity:${row.name}`] = row.icon; }); + // 아이템 통계용 캐시 (items + blocks, 아이템 우선) + translationsCache.itemsAndBlocks = {}; + Object.assign(translationsCache.itemsAndBlocks, translationsCache.blocks); + Object.assign(translationsCache.itemsAndBlocks, translationsCache.items); + // gamerules 캐시 gamerulesCache = {}; gamerules.forEach((row) => { diff --git a/frontend/src/pages/PlayerStatsPage.jsx b/frontend/src/pages/PlayerStatsPage.jsx index 4bb6783..99a04c5 100644 --- a/frontend/src/pages/PlayerStatsPage.jsx +++ b/frontend/src/pages/PlayerStatsPage.jsx @@ -120,8 +120,10 @@ const PlayerStatsPage = ({ isMobile = false }) => { const firstPlayed = formatDate(playerDetail?.firstJoin); const lastPlayed = formatDate(playerDetail?.lastLeave > 0 ? playerDetail?.lastLeave : playerDetail?.lastJoin); - // 번역 함수 (DB에 없으면 영어 그대로) - const translate = (id) => translations[id] || id.replace(/_/g, ' '); + // 번역 함수 - 아이템 통계용 (items + blocks) + const translateItem = (id) => translations.itemsAndBlocks?.[id] || translations.items?.[id] || translations.blocks?.[id] || id.replace(/_/g, ' '); + // 번역 함수 - 몹 통계용 (entities) + const translateMob = (id) => translations.entities?.[id] || id.replace(/_/g, ' '); // 아이템 통계 정렬 (이름순) const sortedItems = stats?.items @@ -131,7 +133,7 @@ const PlayerStatsPage = ({ isMobile = false }) => { ...stat, total: (stat.mined || 0) + (stat.used || 0) + (stat.pickedUp || 0) + (stat.crafted || 0) })) - .sort((a, b) => translate(a.id).localeCompare(translate(b.id), 'ko')) + .sort((a, b) => translateItem(a.id).localeCompare(translateItem(b.id), 'ko')) : []; // 몹 통계 정렬 (이름순) @@ -142,7 +144,7 @@ const PlayerStatsPage = ({ isMobile = false }) => { ...stat, total: (stat.killed || 0) + (stat.killedBy || 0) })) - .sort((a, b) => translate(a.id).localeCompare(translate(b.id), 'ko')) + .sort((a, b) => translateMob(a.id).localeCompare(translateMob(b.id), 'ko')) : []; return ( @@ -307,7 +309,7 @@ const PlayerStatsPage = ({ isMobile = false }) => {