using System; using System.Collections.Generic; using System.Linq; using System.Text.RegularExpressions; using cfg; using PhxhSDK; using PhxhSDK.AOT.Encrypt; using static Framework.EventManager; namespace Framework.Condition { [ObfuzIgnoreExt] public interface ICondition { public EventName SignalName { get; } /// /// 检查条件是否满足 /// /// /// bool Check(List args); /// /// 获取条件参数对应的本地化文本数组 /// /// /// string[] GetArgLocalizations(List args); } public class ConditionException : Exception { public ConditionException(string message) : base(message) { } } public sealed class ConditionManager : Singlenton, IInitable { private const string CONDITION_PREFIX = "Condition"; private const string CONDITION_DESC_PREFIX = "condition_desc_"; //避免GC private List _tempConditionArgs = new(); private ICondition[] m_conditions; #region MainLife public void Init() { m_conditions = new ICondition[(int)ConditionType.Max]; foreach (ConditionType conditionType in Enum.GetValues(typeof(ConditionType))) { if (conditionType == ConditionType.None || conditionType == ConditionType.Max) continue; string typeName = $"{CONDITION_PREFIX}{conditionType}"; Type type = CommonUtilsFramework.GamePlayAssembly.GetType(typeName); if (type == null) { DebugUtil.LogError($"Cant find Type,name:{typeName}"); continue; } if (Activator.CreateInstance(type) is ICondition condition) m_conditions[(int)conditionType] = condition; else DebugUtil.LogError($"cant construct condition,type:{type},please check if your type is correctly implement ICondition"); } } public void Release() { m_conditions = null; _tempConditionArgs = null; } #endregion #region API public bool CheckCondition(int conditionID) { DataCondition conditionCfg = GetConditionCfg(conditionID); GetConditionCfgArgs(conditionCfg, ref _tempConditionArgs); return CheckCondition(conditionCfg.Type, _tempConditionArgs); } public bool CheckCondition(string condition) { string conditionName = Regex.Replace(condition, @"\(.*?\)", string.Empty); ConditionType conditionType = GetConditionType(conditionName); GetConditionStringArgs(condition, ref _tempConditionArgs); return CheckCondition(conditionType, _tempConditionArgs); } public bool CheckCondition(int[] conditionGroup, bool useAnd = true) { foreach (var conditionID in conditionGroup) { var isSuccess = CheckCondition(conditionID); if (useAnd) { if (!isSuccess) { return false; } } else { if (isSuccess) return true; } } return useAnd; } public bool CheckCondition(string[] conditionGroups, bool useAnd = true) { if (null == conditionGroups || 0 == conditionGroups.Length) return false; foreach (string condition in conditionGroups) { bool isSuccess = CheckCondition(condition); if (useAnd) { if (!isSuccess) return false; } else { if (isSuccess) return true; } } return useAnd; } /// /// 检查条件是否满足条件 /// /// /// /// /// public bool CheckCondition(ConditionType conditionType, List conditionArg) { if (m_conditions[(int)conditionType] == null) throw new Exception($"condition type is outside of range!condition type:{conditionType}"); return m_conditions[(int)conditionType].Check(conditionArg); } /// /// 获取条件参数的本地化文本数组 /// /// /// /// /// public string[] GetArgLocalizations(ConditionType conditionType, List listArg) { ICondition iCondition = m_conditions[(int)conditionType] ?? throw new Exception($"条件类型超出范围!类型:{conditionType}"); return iCondition.GetArgLocalizations(listArg); } public EventName GetConditionSignal(int conditionID) { var conditionCfg = GetConditionCfg(conditionID); if (conditionCfg != null) { return GetConditionSignal(conditionCfg.Type); } DebugUtil.LogError($"cant find condition!conditionID:{conditionID}"); return EventName.None; } public ConditionType GetConditionType(string conditionName) { conditionName = Regex.Replace(conditionName, @"\([^)]*\)", string.Empty); if (Enum.TryParse(conditionName, out ConditionType result)) return result; DebugUtil.LogError($"没有该条件类型:{conditionName}"); return ConditionType.None; } public EventName GetConditionSignal(string conditionName) { EventName eventName = GetConditionSignal(GetConditionType(conditionName)); if (EventName.None == eventName) DebugUtil.LogError($"cant find condition!conditionName:{conditionName}"); return eventName; } /// /// 获取条件参数 /// /// /// public void GetConditionStringArgs(string condition, ref List _args) { _args.Clear(); MatchCollection matches = Regex.Matches(condition, @"\((.*?)\)"); foreach (Match match in matches.Cast()) { string[] paramStrs = match.Groups[1].Value.Split(','); foreach (string paramStr in paramStrs) { if (!float.TryParse(paramStr, out float param)) continue; _args.Add(param); } } } public EventName GetConditionSignal(ConditionType conditionType) { var condition = GetConditionByType(conditionType); if (condition != null) { return condition.SignalName; } DebugUtil.LogError($"cant find condition!conditionType:{conditionType}"); return EventName.None; } public string GetConditionLocalization(int conditionID) { var conditionCfg = GetConditionCfg(conditionID); if (conditionCfg != null) { GetConditionCfgArgs(conditionCfg, ref _tempConditionArgs); return GetConditionLocalization(conditionCfg.Type, _tempConditionArgs); } DebugUtil.LogError($"cant find condition!conditionID:{conditionID}"); return null; } public string GetConditionLocalization(string condition) { string conditionName = Regex.Replace(condition, @"\(.*?\)", string.Empty); GetConditionStringArgs(condition, ref _tempConditionArgs); return GetConditionLocalization(GetConditionType(conditionName), _tempConditionArgs); } public string GetConditionLocalization(ConditionType conditionType, List args) { string key = $"{CONDITION_DESC_PREFIX}{conditionType}"; return StringManager.Instance.GetLocalizeTextByKeyAndList(key, GetArgLocalizations(conditionType, args)); } #endregion #region InnerFunction private DataCondition GetConditionCfg(int conditionID) { return TableManager.Instance.Tables.ConditionConfig.Get(conditionID); } private ICondition GetConditionByType(ConditionType conditionType) { var index = (int)conditionType; if (index < 0 || index >= m_conditions.Length) { DebugUtil.LogError("cant find condition!"); return null; } return m_conditions[index]; } private void GetConditionCfgArgs(DataCondition conditionCfg, ref List _args) { _args.Clear(); _args.Add(conditionCfg.Param1); _args.Add(conditionCfg.Param2); _args.Add(conditionCfg.Param3); } #endregion } }