yyl
5 天以前 51b0f6ed9f4e1d3bb6f8144470b46908c7699a96
Merge branch 'master' into h5version

# Conflicts:
# Main/Core/GameEngine/Launch/InitSettingTask.cs
# Main/SDK/SDKUtils.cs
20个文件已修改
2个文件已添加
911 ■■■■■ 已修改文件
Main/Component/UI/Core/ImageLanguageAdapter.cs 279 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/Component/UI/Core/ImageLanguageAdapter.cs.meta 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/Component/UI/Core/TextLanguageAdapter.cs 85 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/Core/GameEngine/Launch/InitSettingTask.cs 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/BeautyMM/BeautyMMShowWin.cs 18 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/CustomizedGift/CustomizedGiftModel.cs 4 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/FestivalActivity/FestivalActivityCheckInManager.cs 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/FestivalActivity/FestivalActivityManager.cs 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/FestivalActivity/FestivalActivityMissionManager.cs 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/FestivalActivity/FestivalActivityRechargeTotDayManager.cs 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/FestivalActivity/FestivalActivityRechargeTotalManager.cs 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/HeroDebut/HeroDebutManager.cs 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/HeroReturn/HeroReturnManager.cs 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/HeroUI/HeroBestWin.cs 34 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/HeroUI/HeroTrainWin.cs 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/HeroUI/HeroUIManager.Collect.cs 55 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/OpenServerActivity/OpenServerActivityCenter.cs 322 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/TimeRush/TimeRushManager.cs 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/TotDayRecharge/TotDayRechargeManager.cs 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/TotalRecharge/TotalRechargeManager.cs 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/Utility/EnumHelper.cs 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/Utility/UIHelper.cs 30 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/Component/UI/Core/ImageLanguageAdapter.cs
New file
@@ -0,0 +1,279 @@
using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
/// <summary>
/// 图片组件类型枚举
/// </summary>
public enum ImageComponentType
{
    None = 0,
    Image = 1,
    ImageEx = 2
}
/// <summary>
/// 单个语言的图片排版和适配数据节点
/// </summary>
[Serializable]
public class ImageLanguageConfigItem
{
    [Header("RectTransform 配置")]
    public Vector2 anchoredPosition = Vector2.zero;
    public Vector2 sizeDelta = new Vector2(100f, 100f);
    public Vector2 anchorMin = new Vector2(0.5f, 0.5f);
    public Vector2 anchorMax = new Vector2(0.5f, 0.5f);
    public Vector2 pivot = new Vector2(0.5f, 0.5f);
    public Vector3 localScale = Vector3.one;
    public Vector3 localRotation = Vector3.zero;
    [Header("Image 配置")]
    public bool enabled = true;
    public Color color = Color.white;
    public Image.Type type = Image.Type.Simple;
    public bool fillCenter = true;
    public Image.FillMethod fillMethod = Image.FillMethod.Horizontal;
    public float fillAmount = 1f;
    public int fillOrigin = 0;
    public bool preserveAspect = true;
    public float alphaHitTestMinimumThreshold = 0f;
    public bool useSpriteMesh = false;
    public float pixelsPerUnitMultiplier = 1f;
    public void ApplyToRectTransform(RectTransform rt)
    {
        if (rt == null) return;
        rt.anchorMin = anchorMin;
        rt.anchorMax = anchorMax;
        rt.pivot = pivot;
        rt.anchoredPosition = anchoredPosition;
        rt.sizeDelta = sizeDelta;
        rt.localScale = localScale;
        rt.localRotation = Quaternion.Euler(localRotation);
    }
    public void ReadFromRectTransform(RectTransform rt)
    {
        if (rt == null) return;
        anchorMin = rt.anchorMin;
        anchorMax = rt.anchorMax;
        pivot = rt.pivot;
        anchoredPosition = rt.anchoredPosition;
        sizeDelta = rt.sizeDelta;
        localScale = rt.localScale;
        localRotation = rt.localRotation.eulerAngles;
    }
    public void ApplyToImage(Image img)
    {
        if (img == null) return;
        img.color = color;
        img.type = type;
        img.fillCenter = fillCenter;
        img.fillMethod = fillMethod;
        img.fillAmount = fillAmount;
        img.fillOrigin = fillOrigin;
        img.preserveAspect = preserveAspect;
        img.alphaHitTestMinimumThreshold = alphaHitTestMinimumThreshold;
        img.useSpriteMesh = useSpriteMesh;
        img.pixelsPerUnitMultiplier = pixelsPerUnitMultiplier;
    }
    public void ReadFromImage(Image img)
    {
        if (img == null) return;
        color = img.color;
        type = img.type;
        fillCenter = img.fillCenter;
        fillMethod = img.fillMethod;
        fillAmount = img.fillAmount;
        fillOrigin = img.fillOrigin;
        preserveAspect = img.preserveAspect;
        alphaHitTestMinimumThreshold = img.alphaHitTestMinimumThreshold;
        useSpriteMesh = img.useSpriteMesh;
        pixelsPerUnitMultiplier = img.pixelsPerUnitMultiplier;
    }
    public ImageLanguageConfigItem Clone() => (ImageLanguageConfigItem)MemberwiseClone();
}
/// <summary>
/// 支持 Unity 序列化的字典
/// </summary>
[Serializable]
public class ImageLanguageConfigDictionary
{
    public List<string> keys = new List<string>();
    public List<ImageLanguageConfigItem> values = new List<ImageLanguageConfigItem>();
    public ImageLanguageConfigItem Get(string key)
    {
        if (string.IsNullOrEmpty(key)) return null;
        int index = keys.IndexOf(key);
        return index >= 0 ? values[index] : null;
    }
    public void Set(string key, ImageLanguageConfigItem value)
    {
        int index = keys.IndexOf(key);
        if (index >= 0) values[index] = value;
        else
        {
            keys.Add(key);
            values.Add(value);
        }
    }
    public bool ContainsKey(string key) => keys.Contains(key);
    public void Remove(string key)
    {
        int index = keys.IndexOf(key);
        if (index >= 0)
        {
            keys.RemoveAt(index);
            values.RemoveAt(index);
        }
    }
}
/// <summary>
/// 多语言图片排版适配器
/// </summary>
[RequireComponent(typeof(RectTransform))]
public class ImageLanguageAdapter : MonoBehaviour
{
    public const string DefaultLangId = "default";
    [SerializeField, Tooltip("语言配置字典")]
    private ImageLanguageConfigDictionary m_LanguageConfigs = new ImageLanguageConfigDictionary();
    [SerializeField, Tooltip("目标图片组件类型")]
    private ImageComponentType m_TargetImageType = ImageComponentType.None;
    [SerializeField, Tooltip("关联的图片组件引用")]
    private Component m_TargetImageComponent;
    private bool m_IsApplied = false;
    public ImageComponentType TargetImageType
    {
        get => m_TargetImageType;
        set => m_TargetImageType = value;
    }
    public Component TargetImageComponent
    {
        get => m_TargetImageComponent;
        set => m_TargetImageComponent = value;
    }
    public ImageLanguageConfigDictionary LanguageConfigs => m_LanguageConfigs;
    private void Awake() => DetectTargetComponent();
    private void OnEnable()
    {
        if (!Application.isPlaying || !m_IsApplied)
        {
            string langId = Application.isPlaying ? Language.Id : DefaultLangId;
            ApplyConfig(langId);
        }
    }
#if UNITY_EDITOR
    private void Reset()
    {
        DetectTargetComponent();
        if (!HasConfig(DefaultLangId)) ReadCurrentToConfig(DefaultLangId);
    }
#endif
    public ImageLanguageConfigItem GetConfig(string languageId) => m_LanguageConfigs.Get(languageId);
    public void SetConfig(string languageId, ImageLanguageConfigItem config) => m_LanguageConfigs.Set(languageId, config);
    public void RemoveConfig(string languageId) => m_LanguageConfigs.Remove(languageId);
    public bool HasConfig(string languageId) => m_LanguageConfigs.ContainsKey(languageId);
    public List<string> GetConfiguredLanguages() => new List<string>(m_LanguageConfigs.keys);
    public void ApplyConfig(string languageId)
    {
        var config = GetConfig(languageId);
        if (config == null) return;
        config.ApplyToRectTransform(GetComponent<RectTransform>());
        if (m_TargetImageComponent != null)
        {
            m_TargetImageComponent.gameObject.SetActive(config.enabled);
        }
        if (m_TargetImageComponent is Image img)
        {
            config.ApplyToImage(img);
        }
        m_IsApplied = true;
    }
    public void ReadCurrentToConfig(string languageId)
    {
        var config = new ImageLanguageConfigItem();
        config.ReadFromRectTransform(GetComponent<RectTransform>());
        if (m_TargetImageComponent is Image img)
        {
            config.ReadFromImage(img);
        }
        SetConfig(languageId, config);
    }
    public static string GetLanguageShowName(string languageId)
    {
        if (Language.languageShowDict != null && Language.languageShowDict.TryGetValue(languageId, out string showName))
            return showName;
        return languageId;
    }
    private void DetectTargetComponent()
    {
        if (m_TargetImageComponent != null)
        {
            DetermineImageType(m_TargetImageComponent);
            return;
        }
        m_TargetImageComponent = GetComponent<ImageEx>() ?? GetComponentInChildren<ImageEx>(true) as Component
                                ?? GetComponent<Image>() ?? GetComponentInChildren<Image>(true) as Component;
        DetermineImageType(m_TargetImageComponent);
    }
    private void DetermineImageType(Component component)
    {
        m_TargetImageType = component switch
        {
            ImageEx _ => ImageComponentType.ImageEx,
            Image _ => ImageComponentType.Image,
            _ => ImageComponentType.None
        };
    }
#if UNITY_EDITOR
    [ContextMenu("刷新组件检测")]
    public void Editor_ForceRefreshDetection()
    {
        DetectTargetComponent();
        UnityEditor.EditorUtility.SetDirty(this);
    }
    [ContextMenu("读取当前配置")]
    public void Editor_ReadCurrentConfig()
    {
        ReadCurrentToConfig(DefaultLangId);
        UnityEditor.EditorUtility.SetDirty(this);
    }
    [ContextMenu("应用默认配置")]
    public void Editor_ApplyDefaultConfig() => ApplyConfig(DefaultLangId);
#endif
}
Main/Component/UI/Core/ImageLanguageAdapter.cs.meta
New file
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 3ca83c0f98acaca459051c33bb4270dd
MonoImporter:
  externalObjects: {}
  serializedVersion: 2
  defaultReferences: []
  executionOrder: 0
  icon: {instanceID: 0}
  userData:
  assetBundleName:
  assetBundleVariant:
Main/Component/UI/Core/TextLanguageAdapter.cs
@@ -156,11 +156,22 @@
    private bool m_IsApplied = false;
    public TextComponentType TargetTextType => m_TargetTextType;
    public Component TargetTextComponent => m_TargetTextComponent;
    public LanguageConfigDictionary LanguageConfigs => m_LanguageConfigs;
    private void Awake() => DetectTargetComponent();
    // 开放 set 权限,允许外部或编辑器手动赋值
    public TextComponentType TargetTextType
    {
        get => m_TargetTextType;
        set => m_TargetTextType = value;
    }
    public Component TargetTextComponent
    {
        get => m_TargetTextComponent;
        set => m_TargetTextComponent = value;
    }
    public LanguageConfigDictionary LanguageConfigs => m_LanguageConfigs;
    private void OnEnable()
    {
@@ -171,19 +182,37 @@
        }
    }
#if UNITY_EDITOR
    private void Reset()
    {
        DetectTargetComponent();
        if (!HasConfig(DefaultLangId)) ReadCurrentToConfig(DefaultLangId);
    }
#endif
    public LanguageConfigItem GetConfig(string languageId) => m_LanguageConfigs.Get(languageId);
    public void SetConfig(string languageId, LanguageConfigItem config) => m_LanguageConfigs.Set(languageId, config);
    public void RemoveConfig(string languageId) => m_LanguageConfigs.Remove(languageId);
    public bool HasConfig(string languageId) => m_LanguageConfigs.ContainsKey(languageId);
    public List<string> GetConfiguredLanguages() => new List<string>(m_LanguageConfigs.keys);
    private void DetectTargetComponent()
    {
        if (m_TargetTextComponent != null)
        {
            DetermineTextType(m_TargetTextComponent);
            return;
        }
        m_TargetTextComponent = GetComponent<TextEx>() ?? GetComponentInChildren<TextEx>(true) as Component
                                ?? GetComponent<GradientText>() ?? GetComponentInChildren<GradientText>(true) as Component
                                ?? GetComponent<Text>() ?? GetComponentInChildren<Text>(true) as Component;
        DetermineTextType(m_TargetTextComponent);
    }
    private void DetermineTextType(Component component)
    {
        m_TargetTextType = component switch
        {
            TextEx _ => TextComponentType.TextEx,
            GradientText _ => TextComponentType.GradientText,
            Text _ => TextComponentType.Text,
            _ => TextComponentType.None
        };
    }
    public void ApplyConfig(string languageId)
    {
@@ -212,33 +241,13 @@
        return languageId;
    }
    private void DetectTargetComponent()
    {
        if (m_TargetTextComponent != null)
        {
            DetermineTextType(m_TargetTextComponent);
            return;
        }
        m_TargetTextComponent = GetComponent<GradientText>() ?? GetComponentInChildren<GradientText>(true) as Component
                                ?? GetComponent<TextEx>() ?? GetComponentInChildren<TextEx>(true) as Component
                                ?? GetComponent<Text>() ?? GetComponentInChildren<Text>(true) as Component;
        DetermineTextType(m_TargetTextComponent);
    }
    private void DetermineTextType(Component component)
    {
        m_TargetTextType = component switch
        {
            GradientText _ => TextComponentType.GradientText,
            TextEx _ => TextComponentType.TextEx,
            Text _ => TextComponentType.Text,
            _ => TextComponentType.None
        };
    }
#if UNITY_EDITOR
    private void Reset()
    {
        DetectTargetComponent();
        if (!HasConfig(DefaultLangId)) ReadCurrentToConfig(DefaultLangId);
    }
    [ContextMenu("刷新组件检测")]
    public void Editor_ForceRefreshDetection()
    {
Main/Core/GameEngine/Launch/InitSettingTask.cs
@@ -21,11 +21,14 @@
            SystemSetting.Instance.SetSoundVolume(SystemSetting.Instance.GetSoundVolume());
            SystemSetting.Instance.SetSoundEffect(SystemSetting.Instance.GetSoundEffect());
            SystemSetting.Instance.SetMuteMusic(SystemSetting.Instance.GetMuteMusic());
            SystemSetting.Instance.SetMuteSoundEffect(SystemSetting.Instance.GetMuteSoundEffect());
        }).Forget();
        
        // SoundPlayer.Instance.PlayBackGroundMusic(41);
        SystemSetting.Instance.SetGameFps(SystemSetting.Instance.GetGameFps());
        SystemSetting.Instance.LetFPSUnLimit();
Main/System/BeautyMM/BeautyMMShowWin.cs
@@ -11,6 +11,7 @@
    [SerializeField] Image qualityImg;
    [SerializeField] Text qualityText1; // 品质分两字显示,注意海外版本
    [SerializeField] Text qualityText2;
    [SerializeField] Text qualityText3;
    [SerializeField] Text nameText;
    [SerializeField] Button descBtn;
    [SerializeField] ImageEx roleImg;
@@ -158,8 +159,21 @@
        mmConfig = BeautyConfig.Get(mmID);
        qualityImg.SetSprite($"mmMark{mmConfig.BeautyQuality}");
        string qualityStr = Language.Get($"CommonQuality{mmConfig.BeautyQuality}");
        qualityText1.text = qualityStr[0].ToString();
        qualityText2.text = qualityStr.Substring(1);
        string langId = Language.Id;
        bool isChinese = langId == "zh" || langId == "ft";
        qualityText1.SetActive(isChinese);
        qualityText2.SetActive(isChinese);
        qualityText3.SetActive(!isChinese);
        if (isChinese)
        {
            qualityText1.text = qualityStr[0].ToString();
            qualityText2.text = qualityStr.Substring(1);
        }
        else
        {
            qualityText3.text = qualityStr;
        }
        nameText.text = mmConfig.Name;
        var skinID = BeautyMMManager.Instance.GetUsedSkinID(mmID);
        var skinConfig = BeautySkinConfig.Get(skinID);
Main/System/CustomizedGift/CustomizedGiftModel.cs
@@ -12,9 +12,7 @@
    private int GiftAwardRecord; //领取状态
    public const int activityType = (int)OpenServerActivityCenter.ActivityType.AT_DateActivity;
    public const int activityID = 99999;
    //public const int activityID = (int)NewDayActivityID.CustomizedGiftWin;
    public static OperationType operaType = (OperationType)99999999;
    //public static OperationType operaType = OperationType.CustomizedGift;
@@ -27,7 +25,7 @@
        OperationTimeHepler.Instance.operationStartEvent += OperationStartEvent;
        OperationTimeHepler.Instance.operationEndEvent += OperationEndEvent;
        OperationTimeHepler.Instance.operationAdvanceEvent += OperationAdvanceEvent;
        OpenServerActivityCenter.Instance.Register(activityID, this, activityType);
        OpenServerActivityCenter.Instance.Register(activityID, this);
    }
Main/System/FestivalActivity/FestivalActivityCheckInManager.cs
@@ -49,8 +49,7 @@
        UpdateRedPoint();
    }
    public const int activityType = (int)OpenServerActivityCenter.ActivityType.AT_DateActivity;
    public const int activityID = (int)NewDayActivityID.FestivalActivityCheckInAct;
    public const int activityID = (int)OperationType.FestivalActivity_CheckIn;
    public static OperationType operaType = OperationType.FestivalActivity_CheckIn;
    public Redpoint redPoint = new Redpoint(MainRedDot.FestivalActivityRepoint,
Main/System/FestivalActivity/FestivalActivityManager.cs
@@ -81,8 +81,7 @@
        TryPopWin();
    }
    public const int activityType = (int)OpenServerActivityCenter.ActivityType.AT_DateActivity;
    public const int activityID = (int)NewDayActivityID.FestivalActivityAct;
    public const int activityID = (int)OperationType.FestivalActivity;
    public static OperationType operaType = OperationType.FestivalActivity;
    public Redpoint redPoint = new Redpoint(MainRedDot.FestivalActivityRepoint);
Main/System/FestivalActivity/FestivalActivityMissionManager.cs
@@ -65,8 +65,7 @@
        UpdateRedPoint();
    }
    public const int activityType = (int)OpenServerActivityCenter.ActivityType.AT_DateActivity;
    public const int activityID = (int)NewDayActivityID.FestivalActivityMissionAct;
    public const int activityID = (int)OperationType.FestivalActivity_Mission;
    public static OperationType operaType = OperationType.FestivalActivity_Mission;
    public Redpoint redPoint = new Redpoint(MainRedDot.FestivalActivityRepoint, FestivalActivityManager.Instance.GetRedPointId(FestivalActivityRepointType.Mission));
Main/System/FestivalActivity/FestivalActivityRechargeTotDayManager.cs
@@ -47,8 +47,7 @@
        awardRecord = 0;
    }
    public const int activityType = (int)OpenServerActivityCenter.ActivityType.AT_DateActivity;
    public const int activityID = (int)NewDayActivityID.FestivalActivityRechargeTotDayAct;
    public const int activityID = (int)OperationType.FestivalActivity_RechargeTotDay;
    public static OperationType operaType = OperationType.FestivalActivity_RechargeTotDay;
    // 总奖励
    public Redpoint redPoint = new Redpoint(
Main/System/FestivalActivity/FestivalActivityRechargeTotalManager.cs
@@ -48,8 +48,7 @@
        awardRecord = 0;
    }
    public const int activityType = (int)OpenServerActivityCenter.ActivityType.AT_DateActivity;
    public const int activityID = (int)NewDayActivityID.FestivalActivityRechargeTotalAct;
    public const int activityID = (int)OperationType.FestivalActivity_RechargeTotal;
    public static OperationType operaType = OperationType.FestivalActivity_RechargeTotal;
    // 总奖励
    public Redpoint redPoint = new Redpoint(
Main/System/HeroDebut/HeroDebutManager.cs
@@ -105,8 +105,7 @@
    }
    public readonly int sendRankType = 6;
    public int loadRankType => actNum * 1000 + sendRankType;
    public const int activityType = (int)OpenServerActivityCenter.ActivityType.AT_DateActivity;
    public const int activityID = (int)NewDayActivityID.HeroDebutAct;
    public const int activityID = (int)OperationType.HeroDebut;
    public static OperationType operaType = OperationType.HeroDebut;
    public Redpoint redPoint = new Redpoint(MainRedDot.HeroDebutRepoint);
Main/System/HeroReturn/HeroReturnManager.cs
@@ -105,8 +105,7 @@
    }
    public readonly int sendRankType = 6;
    public int loadRankType => actNum * 1000 + sendRankType;
    public const int activityType = (int)OpenServerActivityCenter.ActivityType.AT_DateActivity;
    public const int activityID = (int)NewDayActivityID.HeroReturnAct;
    public const int activityID = (int)OperationType.HeroReturn;
    public static OperationType operaType = OperationType.HeroReturn;
    public Redpoint redPoint = new Redpoint(MainRedDot.HeroReturnRepoint);
Main/System/HeroUI/HeroBestWin.cs
@@ -127,7 +127,7 @@
        allAttrScroll.verticalNormalizedPosition = 1;
        Display();
        HeroUIManager.Instance.skinRedpoint.state = HeroUIManager.Instance.HeroAllSkinStateForRedpoint(HeroUIManager.Instance.selectForPreviewHeroID, true) > 0 ? RedPointState.Simple : RedPointState.None;
    }
@@ -143,7 +143,7 @@
        jobPosNameText.text = HeroUIManager.Instance.GetJobName(heroConfig.Class);
        descText.text = heroConfig.Desc;
        HeroUIManager.Instance.PlayerLHSound(skinID);
        RefreshConn();
        normalSkillCell.Init(heroConfig.AtkSkillID, () =>
        {
@@ -195,8 +195,17 @@
    {
        if (heroConfig.FetterIDList.Length > 0)
        {
            connetionForm.SetActive(true);
            connetionForm.Display(heroConfig.FetterIDList[0], Language.Get("herocard38") + "\n", true);
            int fetterID = heroConfig.FetterIDList[0];
            HeroFetterConfig fetterConfig = HeroFetterConfig.Get(fetterID);
            if (fetterConfig != null && HeroUIManager.IsFetterAllHeroOpen(fetterConfig))
            {
                connetionForm.SetActive(true);
                connetionForm.Display(fetterID, Language.Get("herocard38") + "\n", true);
            }
            else
            {
                connetionForm.SetActive(false);
            }
        }
        else
        {
@@ -223,7 +232,7 @@
        }
        HeroUIManager.Instance.selectForPreviewHeroID = HeroUIManager.Instance.heroCollectList[resultIndex];
        Display();
        //控制一级功能界面的皮肤按钮
        var ui = UIManager.Instance.GetUI<HeroBestBaseWin>();
        if (ui != null)
@@ -332,7 +341,7 @@
    }
    void RefreshAllPotential()
    {
@@ -396,11 +405,21 @@
    //羁绊
    void RefreshFetter()
    {
        if (heroConfig.FetterIDList.Length == 0)
        if (heroConfig.FetterIDList.IsNullOrEmpty())
        {
            fetterGo.SetActive(false);
            return;
        }
        // 检查第一个羁绊组合是否满足开服天条件,不满足则隐藏整个羁绊区域
        int firstFetterID = heroConfig.FetterIDList[0];
        HeroFetterConfig firstFetterConfig = HeroFetterConfig.Get(firstFetterID);
        if (firstFetterConfig == null || !HeroUIManager.IsFetterAllHeroOpen(firstFetterConfig))
        {
            fetterGo.SetActive(false);
            return;
        }
        fetterGo.SetActive(true);
        for (int i = 0; i < fetterText.Length; i++)
@@ -528,6 +547,5 @@
            }
        }
    }
}
Main/System/HeroUI/HeroTrainWin.cs
@@ -373,8 +373,17 @@
    {
        if (hero.heroConfig.FetterIDList.Length > 0)
        {
            connetionForm.SetActive(true);
            connetionForm.Display(hero.heroConfig.FetterIDList[0], Language.Get("herocard38") + "\n", true, guid);
            int fetterID = hero.heroConfig.FetterIDList[0];
            HeroFetterConfig fetterConfig = HeroFetterConfig.Get(fetterID);
            if (fetterConfig != null && HeroUIManager.IsFetterAllHeroOpen(fetterConfig))
            {
                connetionForm.SetActive(true);
                connetionForm.Display(fetterID, Language.Get("herocard38") + "\n", true, guid);
            }
            else
            {
                connetionForm.SetActive(false);
            }
        }
        else
        {
@@ -696,6 +705,16 @@
            fetterGo.SetActive(false);
            return;
        }
        // 检查第一个羁绊组合是否满足开服天条件,不满足则隐藏整个羁绊区域
        int firstFetterID = hero.heroConfig.FetterIDList[0];
        HeroFetterConfig firstFetterConfig = HeroFetterConfig.Get(firstFetterID);
        if (firstFetterConfig == null || !HeroUIManager.IsFetterAllHeroOpen(firstFetterConfig))
        {
            fetterGo.SetActive(false);
            return;
        }
        fetterGo.SetActive(true);
        for (int i = 0; i < fetterText.Length; i++)
Main/System/HeroUI/HeroUIManager.Collect.cs
@@ -162,8 +162,8 @@
            HeroConfig heroConfig = HeroConfig.Get(heroID);
            if (heroConfig.PlayerCanUse == 0)
                continue;
            // 新增:开服第x天显示图鉴,0表示不限制开服天
            if (heroConfig.OpenCollectionDay > 0 && TimeUtility.OpenDay + 1 < heroConfig.OpenCollectionDay)
            // 开服第x天显示图鉴,0表示不限制开服天
            if (HasOpenCollectionDayLimit(heroID) && !IsOpenCollectionDayMet(heroID))
                continue;
            if (!heroCollectDict.ContainsKey(heroConfig.Quality))
            {
@@ -414,6 +414,57 @@
    }
    #region 开服天数相关方法
    /// <summary>
    /// 检查武将是否配置了开服展示天数限制
    /// </summary>
    /// <param name="heroID">武将ID</param>
    /// <returns>true: 有开服天限制; false: 无限制(OpenCollectionDay==0 或配置不存在)</returns>
    public static bool HasOpenCollectionDayLimit(int heroID)
    {
        HeroConfig heroConfig = HeroConfig.Get(heroID);
        if (heroConfig == null)
            return false;
        return heroConfig.OpenCollectionDay > 0;
    }
    /// <summary>
    /// 检查武将是否已满足开服展示天数要求(仅在有限制时调用有意义)
    /// </summary>
    /// <param name="heroID">武将ID</param>
    /// <returns>true: 已满足展示天数; false: 尚未满足</returns>
    public static bool IsOpenCollectionDayMet(int heroID)
    {
        HeroConfig heroConfig = HeroConfig.Get(heroID);
        if (heroConfig == null)
            return false;
        // OpenCollectionDay==0 无限制,视为已满足
        if (heroConfig.OpenCollectionDay <= 0)
            return true;
        return TimeUtility.OpenDay + 1 >= heroConfig.OpenCollectionDay;
    }
    /// <summary>
    /// 检查羁绊组合中所有武将是否都满足开服展示天数
    /// 只有配置了开服天限制的武将才需要检查,未配置限制的武将视为满足
    /// </summary>
    /// <param name="fetterConfig">羁绊配置</param>
    /// <returns>true: 所有武将都满足; false: 有武将不满足</returns>
    public static bool IsFetterAllHeroOpen(HeroFetterConfig fetterConfig)
    {
        for (int i = 0; i < fetterConfig.HeroIDList.Length; i++)
        {
            int heroID = fetterConfig.HeroIDList[i];
            // 有限制但未满足 -> 该羁绊不可显示
            if (HasOpenCollectionDayLimit(heroID) && !IsOpenCollectionDayMet(heroID))
                return false;
        }
        return true;
    }
    #endregion
    #endregion
}
Main/System/OpenServerActivity/OpenServerActivityCenter.cs
@@ -1,193 +1,129 @@
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
//修改成控制多个活动模块,如精彩活动模板1,精彩活动模板2
public class OpenServerActivityCenter : Singleton<OpenServerActivityCenter>
{
    public event Action openServerActivityStateChange;
    //{活动模板:{活动ID:活动接口}}
    Dictionary<int, Dictionary<int, IOpenServerActivity>> GameServerActivitys = new Dictionary<int, Dictionary<int, IOpenServerActivity>>();
    public int selectFuncOrder = -1;
    public enum ActivityType
    {
        AT_JCHD = 0,    //精彩活动
        AT_DateActivity,   //日期型活动- 按日期开放的排行榜系列活动相关 id从200开始(与其他活动区分,虽然id重复并没有关系), 类同节日活动
    }
    public OpenServerActivityCenter()
    {
        TimeUtility.OnServerOpenDayRefresh -= OnServerOpenDayRefresh;
        TimeUtility.OnServerOpenDayRefresh += OnServerOpenDayRefresh;
    }
    public void Register(int funcOrder, IOpenServerActivity activity, int activityType = (int)ActivityType.AT_JCHD)
    {
        if (!GameServerActivitys.ContainsKey(activityType))
        {
            GameServerActivitys.Add(activityType, new Dictionary<int, IOpenServerActivity>());
        }
        var openServerActivitys = GameServerActivitys[activityType];
        if (!openServerActivitys.ContainsKey(funcOrder))
        {
            openServerActivitys.Add(funcOrder, activity);
            activity.onStateUpdate -= OnStateUpdate;
            activity.onStateUpdate += OnStateUpdate;
        }
    }
    private void OnStateUpdate(int _order)
    {
        if (openServerActivityStateChange != null)
        {
            openServerActivityStateChange();
        }
    }
    private void OnServerOpenDayRefresh()
    {
        if (openServerActivityStateChange != null)
        {
            openServerActivityStateChange();
        }
    }
    public bool IsAnyActivityOpen(out int _functionOrder, int activityType = (int)ActivityType.AT_JCHD)
    {
        if (!GameServerActivitys.ContainsKey(activityType))
        {
            GameServerActivitys.Add(activityType, new Dictionary<int, IOpenServerActivity>());
        }
        var openServerActivitys = GameServerActivitys[activityType];
        _functionOrder = 0;
        foreach (var _order in openServerActivitys.Keys)
        {
            if (openServerActivitys[_order].IsOpen || openServerActivitys[_order].IsAdvance)
            {
                _functionOrder = _order;
                return true;
            }
        }
        return false;
    }
    public bool IsActivityOpen(int _funcOrder, int activityType = (int)ActivityType.AT_JCHD)
    {
        if (!GameServerActivitys.ContainsKey(activityType))
        {
            GameServerActivitys.Add(activityType, new Dictionary<int, IOpenServerActivity>());
        }
        bool isOpen = false;
        var openServerActivitys = GameServerActivitys[activityType];
        if (openServerActivitys.ContainsKey(_funcOrder))
        {
            isOpen = openServerActivitys[_funcOrder].IsOpen || openServerActivitys[_funcOrder].IsAdvance;
        }
        return isOpen;
    }
    public bool IsPriorityOpenOpen(int _funcOrder, int activityType = (int)ActivityType.AT_JCHD)
    {
        if (!GameServerActivitys.ContainsKey(activityType))
        {
            GameServerActivitys.Add(activityType, new Dictionary<int, IOpenServerActivity>());
        }
        var openServerActivitys = GameServerActivitys[activityType];
        if (openServerActivitys.ContainsKey(_funcOrder))
        {
            return openServerActivitys[_funcOrder].priorityOpen;
        }
        return false;
    }
    public void ProcessErrorTip()
    {
        SysNotifyMgr.Instance.ShowTip("ActiveOutTime");
    }
    //AT_Activity2 日期型活动-默认设计都是同一个入口,根据活动替换图标和名称,打开不同界面
    public NewDayActivityInfo GetNewDayActionEnterInfo()
    {
        // if (IsActivityOpen((int)NewDayActivityID.BossTrial, (int)ActivityType.AT_Activity2))
        // {
        //     return new NewDayActivityInfo() { activityID = (int)NewDayActivityID.BossTrial, redpointID = MainRedDot.BossTrialRepoint, winName = "BossTrialActWin" };
        // }
        // else if (IsActivityOpen((int)NewDayActivityID.SecretPlaceXB, (int)ActivityType.AT_Activity2))
        // {
        //     return new NewDayActivityInfo() { activityID = (int)NewDayActivityID.SecretPlaceXB, redpointID = MainRedDot.MjxbRedpoint, winName = "SecretPlaceActWin" };
        // }
        // else if (IsActivityOpen((int)NewDayActivityID.PetHorseAct, (int)ActivityType.AT_Activity2))
        // {
        //     return new NewDayActivityInfo() { activityID = (int)NewDayActivityID.PetHorseAct, redpointID = MainRedDot.QCTrainActRedpoint, winName = "PetHorseActWin" };
        // }
        // else if (IsActivityOpen((int)NewDayActivityID.TreasurePavilionAct, (int)ActivityType.AT_Activity2))
        // {
        //     return new NewDayActivityInfo() { activityID = (int)NewDayActivityID.TreasurePavilionAct, redpointID = MainRedDot.TreasurePavilionRankActRepoint, winName = "TreasurePavilionRankActWin" };
        // }
        return new NewDayActivityInfo() { activityID = 0 };
    }
    //AT_Activity2 入口信息
    public struct NewDayActivityInfo
    {
        public int activityID;
        public int redpointID;
        public string winName;
    }
}
public interface IOpenServerActivity
{
    bool IsOpen { get; }
    bool IsAdvance { get; }
    bool priorityOpen { get; }
    event Action<int> onStateUpdate;
}
public class ILOpenServerActivityProxy : IOpenServerActivity
{
    public bool IsOpen => funcIsOpen();
    public bool IsAdvance => funcIsAdvance();
    public bool priorityOpen => funcPriorityOpen();
    public event Action<int> onStateUpdate;
    private Func<bool> funcIsOpen;
    private Func<bool> funcIsAdvance;
    private Func<bool> funcPriorityOpen;
    public ILOpenServerActivityProxy(Func<bool> isOpen, Func<bool> isAdvance, Func<bool> priorityOpen)
    {
        funcIsOpen = isOpen;
        funcIsAdvance = isAdvance;
        funcPriorityOpen = priorityOpen;
    }
    public void StateUpdate(int id)
    {
        if (onStateUpdate != null)
        {
            onStateUpdate(id);
        }
    }
}
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
//修改成控制多个活动模块,如精彩活动模板1,精彩活动模板2
public class OpenServerActivityCenter : Singleton<OpenServerActivityCenter>
{
    public event Action openServerActivityStateChange;
    //{活动ID:活动接口}
    Dictionary<int, IOpenServerActivity> GameServerActivitys = new Dictionary<int, IOpenServerActivity>();
    public int selectFuncOrder = -1;
    public OpenServerActivityCenter()
    {
        TimeUtility.OnServerOpenDayRefresh -= OnServerOpenDayRefresh;
        TimeUtility.OnServerOpenDayRefresh += OnServerOpenDayRefresh;
    }
    public void Register(int funcOrder, IOpenServerActivity activity)
    {
        if (!GameServerActivitys.ContainsKey(funcOrder))
        {
            GameServerActivitys.Add(funcOrder, activity);
            activity.onStateUpdate -= OnStateUpdate;
            activity.onStateUpdate += OnStateUpdate;
        }
    }
    private void OnStateUpdate(int _order)
    {
        if (openServerActivityStateChange != null)
        {
            openServerActivityStateChange();
        }
    }
    private void OnServerOpenDayRefresh()
    {
        if (openServerActivityStateChange != null)
        {
            openServerActivityStateChange();
        }
    }
    public bool IsAnyActivityOpen(out int _functionOrder)
    {
        _functionOrder = 0;
        foreach (var _order in GameServerActivitys.Keys)
        {
            if (GameServerActivitys[_order].IsOpen || GameServerActivitys[_order].IsAdvance)
            {
                _functionOrder = _order;
                return true;
            }
        }
        return false;
    }
    public bool IsActivityOpen(int _funcOrder)
    {
        bool isOpen = false;
        if (GameServerActivitys.ContainsKey(_funcOrder))
        {
            isOpen = GameServerActivitys[_funcOrder].IsOpen || GameServerActivitys[_funcOrder].IsAdvance;
        }
        return isOpen;
    }
    public bool IsPriorityOpenOpen(int _funcOrder)
    {
        if (GameServerActivitys.ContainsKey(_funcOrder))
        {
            return GameServerActivitys[_funcOrder].priorityOpen;
        }
        return false;
    }
    public void ProcessErrorTip()
    {
        SysNotifyMgr.Instance.ShowTip("ActiveOutTime");
    }
}
public interface IOpenServerActivity
{
    bool IsOpen { get; }
    bool IsAdvance { get; }
    bool priorityOpen { get; }
    event Action<int> onStateUpdate;
}
public class ILOpenServerActivityProxy : IOpenServerActivity
{
    public bool IsOpen => funcIsOpen();
    public bool IsAdvance => funcIsAdvance();
    public bool priorityOpen => funcPriorityOpen();
    public event Action<int> onStateUpdate;
    private Func<bool> funcIsOpen;
    private Func<bool> funcIsAdvance;
    private Func<bool> funcPriorityOpen;
    public ILOpenServerActivityProxy(Func<bool> isOpen, Func<bool> isAdvance, Func<bool> priorityOpen)
    {
        funcIsOpen = isOpen;
        funcIsAdvance = isAdvance;
        funcPriorityOpen = priorityOpen;
    }
    public void StateUpdate(int id)
    {
        if (onStateUpdate != null)
        {
            onStateUpdate(id);
        }
    }
}
Main/System/TimeRush/TimeRushManager.cs
@@ -26,8 +26,7 @@
        }
    }
    public const int activityType = (int)OpenServerActivityCenter.ActivityType.AT_DateActivity;
    public const int activityID = (int)NewDayActivityID.TimeRushAct;
    public const int activityID = (int)OperationType.TimeRush;
    public int actNum = 10;
    public static OperationType operaType = OperationType.TimeRush;
    public Redpoint redPoint = new Redpoint(MainRedDot.TimeRushRepoint);
@@ -68,7 +67,7 @@
        OperationTimeHepler.Instance.operationAdvanceEvent += OperationAdvanceEvent;
        StoreModel.Instance.RefreshBuyShopLimitEvent += RefreshBuyShopLimitEvent;
        //storeModel.RefreshBuyShopLimitEvent += RefreshBuyShopLimitEvent;
        OpenServerActivityCenter.Instance.Register(activityID, this, activityType);
        OpenServerActivityCenter.Instance.Register(activityID, this);
        var config = FuncConfigConfig.Get("TimeRush");
        windowIDDict = ConfigParse.ParseIntDict(config.Numerical1);
Main/System/TotDayRecharge/TotDayRechargeManager.cs
@@ -47,8 +47,7 @@
        awardRecord = 0;
    }
    public const int activityType = (int)OpenServerActivityCenter.ActivityType.AT_DateActivity;
    public const int activityID = (int)NewDayActivityID.TotDayRechargeAct;
    public const int activityID = (int)OperationType.TotDayRecharge;
    public static OperationType operaType = OperationType.TotDayRecharge;
    // 总奖励
    public Redpoint redPoint = new Redpoint(MainRedDot.RedPoint_OSGala, MainRedDot.RedPoint_OSGala * 10 + 6);
Main/System/TotalRecharge/TotalRechargeManager.cs
@@ -48,8 +48,7 @@
        awardRecord = 0;
    }
    public const int activityType = (int)OpenServerActivityCenter.ActivityType.AT_DateActivity;
    public const int activityID = (int)NewDayActivityID.TotalRechargeAct;
    public const int activityID = (int)OperationType.TotalRecharge;
    public static OperationType operaType = OperationType.TotalRecharge;
    // 总奖励
    public Redpoint redPoint = new Redpoint(MainRedDot.RedPoint_OSGala, MainRedDot.RedPoint_OSGala * 10 + 5);
Main/Utility/EnumHelper.cs
@@ -1810,21 +1810,6 @@
    Mount,
}
//OpenServerActivityCenter.ActivityType.AT_Activity2的活动  历史原因不要用100
public enum NewDayActivityID
{
    TimeRushAct = 200,  //轮回殿(武将冲刺)
    HeroDebutAct = 201,  //英雄登场活动
    HeroReturnAct = 202,  //英雄返场活动
    TotalRechargeAct = 203,   //累充活动
    TotDayRechargeAct = 204,  //累充天活动
    FestivalActivityAct = 205,  //节日活动
    FestivalActivityRechargeTotalAct = 206,
    FestivalActivityRechargeTotDayAct = 207,
    FestivalActivityCheckInAct = 208,
    FestivalActivityMissionAct = 209,   //节日活动-任务
}
//仙玉购买的二次确认框类型
public enum BuyStoreItemCheckType
{
Main/Utility/UIHelper.cs
@@ -237,10 +237,17 @@
    /// </summary>
    public static string ReplaceLargeNum(double num, int decimalPlaces = 1)
    {
        const long K = 10000;    //国内为万,海外为千
        const long M = K * 10000;
        const long B = M * 10000;
        const long T = B * 10000;
        // 获取当前语言状态
        string langId = Language.Id;
        bool isChinese = langId == "zh" || langId == "ft";
        // 简繁中文万进制 (10000),其他千进制 (1000)
        long baseUnit = isChinese ? 10000 : 1000;
        long K = baseUnit;
        long M = K * baseUnit;
        long B = M * baseUnit;
        long T = B * baseUnit;
        if (num >= T)
        {
@@ -267,10 +274,17 @@
    //用于美术字 统一用字母KMBT代表使用,小数点用.
    public static string ReplaceLargeArtNum(double num)
    {
        const long K = 10000;    //国内为万,海外为千
        const long M = K * 10000;
        const long B = M * 10000;
        const long T = B * 10000;
        // 获取当前语言状态
        string langId = Language.Id;
        bool isChinese = langId == "zh" || langId == "ft";
        // 简繁中文万进制 (10000),其他千进制 (1000)
        long baseUnit = isChinese ? 10000 : 1000;
        long K = baseUnit;
        long M = K * baseUnit;
        long B = M * baseUnit;
        long T = B * baseUnit;
        if (num >= T)
        {