using Framework; using System; using System.Collections; using System.Collections.Generic; using System.Linq; using cfg; using cfg.StringCfg; using Cysharp.Threading.Tasks; using Newtonsoft.Json; using PhxhSDK; using SimpleJSON; using Sirenix.Utilities; using UnityEngine; using Constants = Framework.Constants; public class StringManager { private static StringManager m_instance; //public static LanguageType CurLanguage = LanguageType.Default; public static Dictionary MixKeyDic; public static string MixKeyConfigPath = "Assets/Config/MixKey/MixKeyConfig.json"; public static StringConfig StringConfig; public static StringManager Instance { get { if (m_instance == null) { m_instance = new StringManager(); } return m_instance; } } //public enum LanguageType //{ // Default, // CN, // TW, // EN, //} //登录时获取语言 public static LanguageManager.LanguageType GetLoginLanguageType() { #if UNITY_EDITOR var storeData = StorageMgr.Instance.GetStorage("LanguageStorage"); if (storeData != null) { if (!storeData.IsSetLanguage) { var systemLanguage = LanguageManager.Instance.GetDeviceLanguage(); switch (systemLanguage) { case SystemLanguage.Chinese: LanguageManager.Instance.SetCurrentLanguage(LanguageManager.LanguageType.CN); break; case SystemLanguage.ChineseSimplified: LanguageManager.Instance.SetCurrentLanguage(LanguageManager.LanguageType.CN); break; case SystemLanguage.English: LanguageManager.Instance.SetCurrentLanguage(LanguageManager.LanguageType.EN); break; default: LanguageManager.Instance.SetCurrentLanguage(LanguageManager.LanguageType.CN); break; } } else { LanguageManager.Instance.SetCurrentLanguage(storeData.LanguageType); } StoreCurLanguage(); } #else var type = LanguageManager.GetLanguageTypeByIndex(); DebugUtil.LogError($"--- OnLogin LanguageType:{type}"); var systemLanguage = LanguageManager.Instance.GetDeviceLanguage(); DebugUtil.LogError($"--- OnLogin systemLanguage:{systemLanguage}"); if (type == LanguageManager.LanguageType.Default) { switch (systemLanguage) { case SystemLanguage.Chinese: LanguageManager.Instance.SetCurrentLanguage(LanguageManager.LanguageType.CN); break; case SystemLanguage.ChineseSimplified: LanguageManager.Instance.SetCurrentLanguage(LanguageManager.LanguageType.CN); break; case SystemLanguage.English: DebugUtil.LogError($"--- OnLogin systemLanguage:English"); LanguageManager.Instance.SetCurrentLanguage(LanguageManager.LanguageType.EN); break; default: LanguageManager.Instance.SetCurrentLanguage(LanguageManager.LanguageType.CN); break; } } else { DebugUtil.LogError($"--- OnLogin SetCurrentLanguage:{type}"); LanguageManager.Instance.SetCurrentLanguage(type); } #endif return LanguageManager.CurLanguage; } public static string GetLocalizeJsonPath() { return Constants.DATA_LANGUAGE_PATH_DEFAULT; switch (LanguageManager.CurLanguage) { case LanguageManager.LanguageType.CN: return Constants.DATA_LANGUAGE_PATH_CN; case LanguageManager.LanguageType.EN: return Constants.DATA_LANGUAGE_PATH_EN; default: return Constants.DATA_LANGUAGE_PATH_CN; } } public static void StoreCurLanguage() { #if UNITY_EDITOR var storeData = StorageMgr.Instance.GetStorage("LanguageStorage"); if (storeData != null) { storeData.LanguageType = LanguageManager.CurLanguage; storeData.IsSetLanguage = true; StorageMgr.Instance.SyncForce = true; } #else LanguageManager.SetLanguageType(LanguageManager.CurLanguage); DebugUtil.LogError($"LanguageType:{LanguageManager.CurLanguage}"); #endif } #region 读对应文本值 private DataString GetStringConfigByKey(string key) { var dataString = StringConfig?.GetOrDefault(key); if (dataString == null || string.IsNullOrEmpty(dataString.Value)) { DebugUtil.LogWarning("{0}.GetStringConfigByKey: key = {1} is not exist, check table please!!", GetType(), key); } return dataString; } private string GetStringConfigValue(DataString data) { string value = ""; value = data.Value; //DebugUtil.LogG($"key:{data.Key}, name:{data.Name}"); value = _GetParamsReplacedStr(data, value); return value; } private bool _CheckIsOutCalculate(DataString data) { return data.OutCalculate.Count > 1; } private string GetStringConfigValue(DataString data, float outParam) { string value = ""; value = data.Value; //DebugUtil.LogG($"key:{data.Key}, name:{data.Name}"); if (_CheckIsOutCalculate(data)) { value = _GetInnerCalculateContent(data, value, outParam); } return value; } private string _GetParamsReplacedStr(DataString data, string content) { if (!content.Contains("[p")) { return content; } string retStr = content; if (content.Contains("[p0]")) { var param = _GetParam(data, 0); if (param == null || !MixKeyDic.ContainsKey(param)) { DebugUtil.LogError($"MixKey配置有误,StringConfigKey: {data.Key}"); return content; } var val = MixKeyDic[param]; retStr = retStr.Replace("[p0]", val); } if (content.Contains("[p1]")) { var param = _GetParam(data, 1); if (param == null || !MixKeyDic.ContainsKey(param)) { DebugUtil.LogError($"MixKey配置有误,StringConfigKey: {data.Key}"); return content; } var val = MixKeyDic[param]; retStr = retStr.Replace("[p1]", val); } if (content.Contains("[p2]")) { var param = _GetParam(data, 2); if (param == null || !MixKeyDic.ContainsKey(param)) { DebugUtil.LogError($"MixKey配置有误,StringConfigKey: {data.Key}"); return content; } var val = MixKeyDic[param]; retStr = retStr.Replace("[p2]", val); } return retStr; } #region MixKey计算 private string _GetInnerCalculateContent(DataString data, string content, float outParam) { if (data == null) { return content; } if (_CheckIsOutCalculate(data)) { if (!content.Contains("[p")) { DebugUtil.LogError($"文本内容缺少参数值,请检查StringLocalConfig表!!!,Key:{data.Key}"); return content; } var paramStrList = _GetParamStrList(data); if (paramStrList.Count < 0) { DebugUtil.LogError($"文本内容参数值数量不足,请检查StringLocalConfig表!!!,Key:{data.Key}"); return content; } var expression = _GetParamExpression(content, paramStrList, out List paramList); var result = _GetCalculateResult(data, expression, outParam, paramList); content = content.Replace(expression, result.ToString()); } content = _FilterOtherParam(data, content); return content; } /// /// 过滤掉非计算公式内的参数 /// private string _FilterOtherParam(DataString data, string content) { var retStr = content; if (content.Contains("[p0]")) { var param = _GetParam(data, 0); if (param == null || !MixKeyDic.ContainsKey(param)) { DebugUtil.LogError($"MixKey配置有误,StringConfigKey: {data.Key}"); return content; } var val = MixKeyDic[param]; retStr = retStr.Replace("[p0]", val); } if (content.Contains("[p1]")) { var param = _GetParam(data, 1); if (param == null || !MixKeyDic.ContainsKey(param)) { DebugUtil.LogError($"MixKey配置有误,StringConfigKey: {data.Key}"); return content; } var val = MixKeyDic[param]; retStr = retStr.Replace("[p1]", val); } if (content.Contains("[p2]")) { var param = _GetParam(data, 2); if (param == null || !MixKeyDic.ContainsKey(param)) { DebugUtil.LogError($"MixKey配置有误,StringConfigKey: {data.Key}"); return content; } var val = MixKeyDic[param]; retStr = retStr.Replace("[p2]", val); } return retStr; } /// /// 根据表达式获取到最终结果 /// /// /// /// /// /// private int _GetCalculateResult(DataString data, string expression, float outParam, List paramList) { var listOp = new string(expression); foreach (var param in paramList) { listOp = listOp.Replace(param, ""); } var vals = new List(); for (int i = 0; i < paramList.Count; i++) { var param = paramList[i]; var valStr = _GetParamsReplacedStr(data, param); float val = 0; if (valStr.Contains('%')) { valStr = valStr.Replace("%", ""); var f = float.Parse(valStr); val = f / 100 * outParam; } else { val = float.Parse(valStr); } vals.Add(val); } float result = 0; if (paramList.Count == 3) { if (listOp.Length < 2) { DebugUtil.LogError($"参数配置有误,请检查StringLocalConfig, key:{data.Key}"); return 0; } result = _Calculate(vals[0], vals[1], listOp[0]); result = _Calculate(result, vals[2], listOp[1]); } if (paramList.Count == 2) { if (listOp.Length < 1) { DebugUtil.LogError($"参数配置有误,请检查StringLocalConfig, key:{data.Key}"); return 0; } result = _Calculate(vals[0], vals[1], listOp[0]); } if (paramList.Count == 1) { result = vals[0]; } return (int)result; } /// /// 获取参数数量 /// /// /// private List _GetParamStrList(DataString data) { var strList = _GetParamStrList(data.OutCalculate); return strList; } private List _GetParamStrList(List paramList) { var strList = new List(); if (paramList.Count > 0) { for (int i = 0; i < paramList.Count; i++) { if (paramList[i] == 0) { strList.Add("[p0]"); } if (paramList[i] == 1) { strList.Add("[p1]"); } if (paramList[i] == 2) { strList.Add("[p2]"); } } } return strList; } /// /// 获取计算表达式,包含[p0]、[p1]、[p2] /// /// /// /// private string _GetParamExpression(string content, List paramStrList, out List paramList) { if (!string.IsNullOrEmpty(content)) { var paramCount = paramStrList.Count; if (paramCount == 3) { var idx0 = content.IndexOf("[p0]"); var idx1 = content.IndexOf("[p1]"); var idx2 = content.IndexOf("[p2]"); var sortList = new List>(); sortList.Add((idx0, "[p0]")); sortList.Add((idx1, "[p1]")); sortList.Add((idx2, "[p2]")); sortList.Sort((a, b) => a.Item1.CompareTo(b.Item1)); var startIdx = sortList[0].Item1; var endIdx = sortList[2].Item1 + 4; var calStr = content.Substring(startIdx, endIdx - startIdx); paramList = new List(sortList.Select(item => item.Item2).ToList()); return calStr; } if (paramCount == 2) { var idx0 = content.IndexOf(paramStrList[0]); var idx1 = content.IndexOf(paramStrList[1]); var startIdx = idx0 > idx1 ? idx1 : idx0; var endIdx = idx0 > idx1 ? idx0 : idx1; endIdx += 4; var calStr = content.Substring(startIdx, endIdx - startIdx); if (idx0 > idx1) { paramList = new List{paramStrList[0], paramStrList[1]}; } else { paramList = new List{paramStrList[1], paramStrList[0]}; } return calStr; } if (paramCount == 1) { var idx = content.IndexOf(paramStrList[0]); var startIdx = idx; var endIdx = idx + 4; var calStr = content.Substring(startIdx, endIdx - startIdx); paramList = new List{paramStrList[0]}; return calStr; } } paramList = new List(); return ""; } private float _Calculate(float p1, float p2, char op) { switch (op) { case '+': return p1 + p2; case '-': return p1 - p2; case '*': return p1 * p2; case 'x': return p1 * p2; case '/': { if (p2 == 0) { DebugUtil.LogError("传入出数为0!!!"); return 0; } return p1 / p2; } default: return 0; } } #endregion private string _GetParam(DataString data, int idx) { if (idx == 0) { return data.Param0; } if (idx == 1) { return data.Param1; } if (idx == 2) { return data.Param2; } return null; } public string GetTextByKey(string key) { DataString dataString = GetStringConfigByKey(key); if (dataString != null && !string.IsNullOrEmpty(dataString.Value)) { return GetStringConfigValue(dataString); } return key; } public string GetTextByKey(string key, float outParam) { DataString dataString = GetStringConfigByKey(key); if (dataString != null && !string.IsNullOrEmpty(dataString.Value)) { return GetStringConfigValue(dataString, outParam); } return key; } public string GetTextFirstParamByKey(string key) { DataString DataString = GetStringConfigByKey(key); if (DataString != null && !string.IsNullOrEmpty(DataString.Value)) { return GetFirstParamValue(DataString); } return key; } /// /// 获取string中第一个param的值 /// private string GetFirstParamValue(DataString data) { string value = data.Value; if (!value.Contains("[p")) { return null; } if (value.Contains("[p0]")) { var param = _GetParam(data, 0); if (param == null || !MixKeyDic.ContainsKey(param)) { DebugUtil.LogError($"MixKey配置有误,StringConfigKey: {data.Key}"); return null; } return MixKeyDic[param]; } return null; } public string GetTextByKeyAndParams(string key, T param) { DataString DataString = GetStringConfigByKey(key); string str = key; if (DataString != null) { str = GetStringConfigValue(DataString); try { str = string.Format(str, param); } catch (Exception e) { DebugUtil.LogError(e); } } return str; } public string GetTextByKeyAndParams(string key, T0 param0, T1 param1) { DataString DataString = GetStringConfigByKey(key); string str = key; if (DataString != null) { str = GetStringConfigValue(DataString); str = string.Format(str, param0, param1); } return str; } public string GetTextByKeyAndParams(string key, T0 param0, T1 param1, T2 param2) { DataString DataString = GetStringConfigByKey(key); string str = key; if (DataString != null) { str = GetStringConfigValue(DataString); str = string.Format(str, param0, param1, param2); } return str; } public string GetTextByKeyAndParams(string key, T0 param0, T1 param1, T2 param2, T3 param3) { DataString DataString = GetStringConfigByKey(key); string str = key; if (DataString != null) { str = GetStringConfigValue(DataString); str = string.Format(str, param0, param1, param2, param3); } return str; } public string GetTextByKeyAndParams(string key, T0 param0, T1 param1, T2 param2, T3 param3, T4 param4) { DataString DataString = GetStringConfigByKey(key); string str = key; if (DataString != null) { str = GetStringConfigValue(DataString); str = string.Format(str, param0, param1, param2, param3, param4); } return str; } //本地化,后续扩展 public string GetLocalizeTextByKey(string key) { return GetTextByKey(key); } /// /// 传入外部参数的含有Mixkey的文本 /// /// /// /// public string GetLocalizeTextByKey(string key, float outParam) { return GetTextByKey(key, outParam); } //可填入参数的文本,目前最多支持三个参数 public string GetLocalizeTextByKeyAndParams(string key, params object[] param) { if (param.Length <= 0) { return GetTextByKey(key); } else if (param.Length == 1) { return GetTextByKeyAndParams(key, param[0]); } else if (param.Length == 2) { return GetTextByKeyAndParams(key, param[0], param[1]); } else if (param.Length == 3) { return GetTextByKeyAndParams(key, param[0], param[1], param[2]); } else if (param.Length == 4) { return GetTextByKeyAndParams(key, param[0], param[1], param[2], param[3]); } DebugUtil.LogError(string.Format("==== 请检查文本内容参数个数!!! 文本Key为 {0} ! ====", key)); return ""; } /// /// 获取本地化文本,根据本地化key和参数列表 /// /// /// /// public string GetLocalizeTextByKeyAndList(string key, params string[] param) { if (param == null) return GetTextByKey(key); switch (param.Length) { case 0: return GetTextByKey(key); case 1: return GetTextByKeyAndParams(key, param[0]); case 2: return GetTextByKeyAndParams(key, param[0], param[1]); case 3: return GetTextByKeyAndParams(key, param[0], param[1], param[2]); default: { DebugUtil.LogError($"==== 请检查文本内容参数个数!!! 文本Key为 {key} ! ===="); } return string.Empty; } } //public static void ChangeLanguage(LanguageType language) //{ // CurLanguage = language; //} public static string GetStoryTalkText(string key, bool isFightStory = false) { if (isFightStory) { return Instance.GetLocalizeTextByKey(key); } return key; } #endregion #region MixKey加载 public static async UniTask LoadMixKeyDic() { var txtAsset = await AssetManager.Instance.LoadAssetAsync(MixKeyConfigPath); if (txtAsset == null) { DebugUtil.LogError("MixKeyConfig 资源无法加载,请检查路径!"); return; } var jsonTxt = txtAsset.text; var dic = JsonConvert.DeserializeObject>(jsonTxt); MixKeyDic = dic; } #endregion } public class LanguageStorage { public LanguageManager.LanguageType LanguageType; public bool IsSetLanguage; }