2025-08-12 19:49:50 +08:00
|
|
|
import { _decorator, sys } from "cc";
|
|
|
|
|
import { Language } from "../../schema/schema";
|
2025-09-01 16:26:37 +08:00
|
|
|
import { ConfigManager } from "../../chat18x/manager/ConfigManager";
|
2025-08-12 19:49:50 +08:00
|
|
|
import { CommonConfig } from "../Config/CommonConfig";
|
|
|
|
|
import li_EventManager from "./li_EventManager";
|
|
|
|
|
import Utils from "./Utils";
|
|
|
|
|
import { InnerMsgCode } from "../Config/InnerMsgCode";
|
2025-09-21 19:49:08 +08:00
|
|
|
import { logger } from "db://assets/Scripts/Main/Common/Logger";
|
2025-08-12 19:49:50 +08:00
|
|
|
|
|
|
|
|
const { ccclass } = _decorator;
|
|
|
|
|
|
|
|
|
|
export enum LanguageType {
|
|
|
|
|
EN = "en", // 英文
|
|
|
|
|
CN = "cn", // 中文
|
|
|
|
|
HI = "hi", // 印地语
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export enum LanguageEvent {
|
|
|
|
|
LANGUAGE_CHANGED = "LANGUAGE_CHANGED",
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@ccclass("LanguageUtils")
|
|
|
|
|
export default class LanguageUtils {
|
|
|
|
|
private static currentLanguage: LanguageType = LanguageType.EN;
|
|
|
|
|
private static languageCache: Map<string, string> = new Map();
|
|
|
|
|
private static isInitialized: boolean = false;
|
|
|
|
|
|
|
|
|
|
public static get CurrentLanguage(): LanguageType {
|
|
|
|
|
if (!this.isInitialized) {
|
|
|
|
|
this.init();
|
|
|
|
|
}
|
|
|
|
|
return this.currentLanguage;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private static init() {
|
|
|
|
|
if (this.isInitialized) return;
|
|
|
|
|
this.isInitialized = true;
|
|
|
|
|
this.loadLanguageSetting();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private static loadLanguageSetting() {
|
|
|
|
|
const savedLanguage = sys.localStorage.getItem(
|
|
|
|
|
CommonConfig.StorageConfig.LANGUAGE_SETTING
|
|
|
|
|
);
|
|
|
|
|
if (
|
|
|
|
|
savedLanguage &&
|
|
|
|
|
Object.values(LanguageType).includes(savedLanguage as LanguageType)
|
|
|
|
|
) {
|
|
|
|
|
this.currentLanguage = savedLanguage as LanguageType;
|
|
|
|
|
} else {
|
|
|
|
|
this.detectSystemLanguage();
|
|
|
|
|
}
|
2025-09-21 19:49:08 +08:00
|
|
|
logger.log(
|
2025-08-12 19:49:50 +08:00
|
|
|
"LanguageUtils initialized with language:",
|
|
|
|
|
this.currentLanguage
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private static detectSystemLanguage() {
|
|
|
|
|
const systemLanguage = sys.language;
|
|
|
|
|
if (systemLanguage.startsWith("zh")) {
|
2025-09-10 14:24:52 +08:00
|
|
|
this.currentLanguage = LanguageType.EN;
|
2025-08-12 19:49:50 +08:00
|
|
|
} else if (systemLanguage.startsWith("hi")) {
|
|
|
|
|
this.currentLanguage = LanguageType.HI;
|
|
|
|
|
} else {
|
|
|
|
|
this.currentLanguage = LanguageType.EN;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static setLanguage(language: LanguageType): void {
|
|
|
|
|
if (!this.isInitialized) {
|
|
|
|
|
this.init();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (this.currentLanguage === language) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
this.currentLanguage = language;
|
|
|
|
|
this.languageCache.clear();
|
|
|
|
|
sys.localStorage.setItem(
|
|
|
|
|
CommonConfig.StorageConfig.LANGUAGE_SETTING,
|
|
|
|
|
language
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
Utils.sendInnerMsg(InnerMsgCode.LanguageChange, language);
|
2025-09-21 19:49:08 +08:00
|
|
|
logger.log("Language changed to:", language);
|
2025-08-12 19:49:50 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static getText(key: string, defaultText: string = ""): string {
|
|
|
|
|
if (!this.isInitialized) {
|
|
|
|
|
this.init();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!key) {
|
|
|
|
|
return defaultText;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (this.languageCache.has(key)) {
|
|
|
|
|
return this.languageCache.get(key);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!ConfigManager.tables || !ConfigManager.tables.TbLanguage) {
|
2025-09-21 19:49:08 +08:00
|
|
|
logger.warn("Language table not loaded yet");
|
2025-08-12 19:49:50 +08:00
|
|
|
return defaultText || key;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const languageData = ConfigManager.tables.TbLanguage.get(key);
|
|
|
|
|
if (!languageData) {
|
2025-09-21 19:49:08 +08:00
|
|
|
logger.warn(`Language key not found: ${key}`);
|
2025-08-12 19:49:50 +08:00
|
|
|
return defaultText || key;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
let text: string = "";
|
|
|
|
|
switch (this.currentLanguage) {
|
|
|
|
|
case LanguageType.EN:
|
|
|
|
|
text = languageData.languageEn;
|
|
|
|
|
break;
|
|
|
|
|
case LanguageType.CN:
|
|
|
|
|
text = languageData.languageCn;
|
|
|
|
|
break;
|
|
|
|
|
case LanguageType.HI:
|
|
|
|
|
text = languageData.languageHi;
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
text = languageData.languageEn;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!text || text.length === 0) {
|
|
|
|
|
text = languageData.languageEn || defaultText || key;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
this.languageCache.set(key, text);
|
|
|
|
|
return text;
|
|
|
|
|
}
|
|
|
|
|
|
2025-08-26 19:41:13 +08:00
|
|
|
public static getTextByLanguage(
|
2025-08-12 19:49:50 +08:00
|
|
|
key: string,
|
2025-08-26 19:41:13 +08:00
|
|
|
language: LanguageType = LanguageType.EN,
|
2025-08-12 19:49:50 +08:00
|
|
|
defaultText: string = ""
|
|
|
|
|
): string {
|
2025-08-26 19:41:13 +08:00
|
|
|
if (!this.isInitialized) {
|
|
|
|
|
this.init();
|
2025-08-12 19:49:50 +08:00
|
|
|
}
|
|
|
|
|
|
2025-08-26 19:41:13 +08:00
|
|
|
if (!key) {
|
|
|
|
|
return defaultText;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!ConfigManager.tables || !ConfigManager.tables.TbLanguage) {
|
2025-09-21 19:49:08 +08:00
|
|
|
logger.warn("Language table not loaded yet");
|
2025-08-26 19:41:13 +08:00
|
|
|
return defaultText || key;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const languageData = ConfigManager.tables.TbLanguage.get(key);
|
|
|
|
|
if (!languageData) {
|
2025-09-21 19:49:08 +08:00
|
|
|
logger.warn(`Language key not found: ${key}`);
|
2025-08-26 19:41:13 +08:00
|
|
|
return defaultText || key;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
let text: string = "";
|
|
|
|
|
switch (language) {
|
|
|
|
|
case LanguageType.EN:
|
|
|
|
|
text = languageData.languageEn;
|
|
|
|
|
break;
|
|
|
|
|
case LanguageType.CN:
|
|
|
|
|
text = languageData.languageCn;
|
|
|
|
|
break;
|
|
|
|
|
case LanguageType.HI:
|
|
|
|
|
text = languageData.languageHi;
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
text = languageData.languageEn;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!text || text.length === 0) {
|
|
|
|
|
text = languageData.languageEn || defaultText || key;
|
|
|
|
|
}
|
|
|
|
|
|
2025-08-12 19:49:50 +08:00
|
|
|
return text;
|
|
|
|
|
}
|
|
|
|
|
|
2025-09-10 14:24:52 +08:00
|
|
|
public static getTextWithParams(
|
|
|
|
|
key: string,
|
|
|
|
|
params: { [key: string]: any },
|
|
|
|
|
defaultText: string = ""
|
|
|
|
|
): string {
|
|
|
|
|
let text = this.getText(key, defaultText);
|
|
|
|
|
|
|
|
|
|
if (!params || Object.keys(params).length === 0) {
|
|
|
|
|
return text;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Replace placeholders in the format {paramName} with actual values
|
|
|
|
|
for (const [paramKey, paramValue] of Object.entries(params)) {
|
|
|
|
|
const placeholder = `{${paramKey}}`;
|
|
|
|
|
text = text.replace(new RegExp(placeholder, 'g'), String(paramValue));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return text;
|
|
|
|
|
}
|
|
|
|
|
|
2025-08-12 19:49:50 +08:00
|
|
|
public static getAvailableLanguages(): LanguageType[] {
|
|
|
|
|
return Object.values(LanguageType);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static getLanguageDisplayName(language: LanguageType): string {
|
|
|
|
|
switch (language) {
|
|
|
|
|
case LanguageType.EN:
|
|
|
|
|
return "English";
|
|
|
|
|
case LanguageType.CN:
|
|
|
|
|
return "中文";
|
|
|
|
|
case LanguageType.HI:
|
|
|
|
|
return "हिंदी";
|
|
|
|
|
default:
|
|
|
|
|
return language;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static clearCache(): void {
|
|
|
|
|
this.languageCache.clear();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static onLanguageChanged(
|
|
|
|
|
callback: (language: LanguageType) => void,
|
|
|
|
|
target: any
|
|
|
|
|
): void {
|
|
|
|
|
Utils.addInnerEL(InnerMsgCode.LanguageChange, target, callback);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static offLanguageChanged(
|
|
|
|
|
callback: (language: LanguageType) => void,
|
|
|
|
|
target: any
|
|
|
|
|
): void {
|
|
|
|
|
Utils.removeInnerEL(InnerMsgCode.LanguageChange, target, callback);
|
|
|
|
|
}
|
|
|
|
|
}
|