少年修仙传客户端代码仓库
10296 子 【越南】【英语】【砍树】轮回殿 / 【越南】【英语】【砍树】轮回殿-客户端
8个文件已修改
25个文件已添加
1739 ■■■■■ 已修改文件
Core/GameEngine/DataToCtl/PackageRegedit.cs 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Core/GameEngine/Model/Config/CycleHallConfig.cs 221 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Core/GameEngine/Model/Config/CycleHallConfig.cs.meta 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Core/GameEngine/Model/TelPartialConfig/CycleHallConfig.cs 45 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Core/GameEngine/Model/TelPartialConfig/CycleHallConfig.cs.meta 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Core/NetworkPackage/DTCFile/ServerPack/HAA_SaleActivity/DTCAA88_tagMCActLunhuidianInfo.cs 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Core/NetworkPackage/DTCFile/ServerPack/HAA_SaleActivity/DTCAA88_tagMCActLunhuidianInfo.cs.meta 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Core/NetworkPackage/DTCFile/ServerPack/HAA_SaleActivity/DTCAA89_tagMCActLunhuidianPlayerInfo.cs 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Core/NetworkPackage/DTCFile/ServerPack/HAA_SaleActivity/DTCAA89_tagMCActLunhuidianPlayerInfo.cs.meta 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Core/NetworkPackage/ServerPack/HAA_SaleActivity/HAA88_tagMCActLunhuidianInfo.cs 88 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Core/NetworkPackage/ServerPack/HAA_SaleActivity/HAA88_tagMCActLunhuidianInfo.cs.meta 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Core/NetworkPackage/ServerPack/HAA_SaleActivity/HAA89_tagMCActLunhuidianPlayerInfo.cs 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Core/NetworkPackage/ServerPack/HAA_SaleActivity/HAA89_tagMCActLunhuidianPlayerInfo.cs.meta 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
System/LoopAct/CycleHall.meta 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
System/LoopAct/CycleHall/CycleHallActModel.cs 303 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
System/LoopAct/CycleHall/CycleHallActModel.cs.meta 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
System/LoopAct/CycleHall/CycleHallCell.cs 312 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
System/LoopAct/CycleHall/CycleHallCell.cs.meta 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
System/LoopAct/CycleHall/CycleHallCoolTime.cs 45 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
System/LoopAct/CycleHall/CycleHallCoolTime.cs.meta 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
System/LoopAct/CycleHall/CycleHallTabCell.cs 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
System/LoopAct/CycleHall/CycleHallTabCell.cs.meta 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
System/LoopAct/CycleHall/CycleHallWin.cs 374 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
System/LoopAct/CycleHall/CycleHallWin.cs.meta 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
System/LoopAct/CycleHall/OperationCycleHall.cs 83 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
System/LoopAct/CycleHall/OperationCycleHall.cs.meta 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
System/MainInterfacePanel/HighSettingTip.cs 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
System/MainInterfacePanel/MainRedDot.cs 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
System/RankAction/LoginActModel.cs 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
System/Welfare/OperationTimeHepler.cs 38 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
System/WindowBase/ModelCenter.cs 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Utility/ConfigInitiator.cs 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Utility/EnumHelper.cs 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Core/GameEngine/DataToCtl/PackageRegedit.cs
@@ -601,6 +601,8 @@
        Register(typeof(HA721_tagMCEmojiPackInfo), typeof(DTCA721_tagMCEmojiPackInfo));
        Register(typeof(HA512_tagMCFamilyZhenbaogeInfo), typeof(DTCA512_tagMCFamilyZhenbaogeInfo));
        Register(typeof(HA801_tagMCGiveAwardInfo), typeof(DTCA801_tagMCGiveAwardInfo));
        Register(typeof(HAA88_tagMCActLunhuidianInfo), typeof(DTCAA88_tagMCActLunhuidianInfo));
        Register(typeof(HAA89_tagMCActLunhuidianPlayerInfo), typeof(DTCAA89_tagMCActLunhuidianPlayerInfo));
    }
Core/GameEngine/Model/Config/CycleHallConfig.cs
New file
@@ -0,0 +1,221 @@
//--------------------------------------------------------
//    [Author]:           Fish
//    [  Date ]:           Wednesday, December 11, 2024
//--------------------------------------------------------
using System.Collections.Generic;
using System.IO;
using System.Threading;
using System;
using UnityEngine;
using LitJson;
public partial class CycleHallConfig
{
    public readonly int id;
    public readonly int RoundType;
    public readonly int TabType;
    public readonly int TabSort;
    public readonly string TabName;
    public readonly string StandImage;
    public readonly string TitleImage;
    public readonly string InfoImage;
    public CycleHallConfig()
    {
    }
    public CycleHallConfig(string input)
    {
        try
        {
            var tables = input.Split('\t');
            int.TryParse(tables[0],out id);
            int.TryParse(tables[1],out RoundType);
            int.TryParse(tables[2],out TabType);
            int.TryParse(tables[3],out TabSort);
            TabName = tables[4];
            StandImage = tables[5];
            TitleImage = tables[6];
            InfoImage = tables[7];
        }
        catch (Exception ex)
        {
            DebugEx.Log(ex);
        }
    }
    static Dictionary<string, CycleHallConfig> configs = new Dictionary<string, CycleHallConfig>();
    public static CycleHallConfig Get(string id)
    {
        if (!inited)
        {
            Debug.LogError("CycleHallConfig 还未完成初始化。");
            return null;
        }
        if (configs.ContainsKey(id))
        {
            return configs[id];
        }
        CycleHallConfig config = null;
        if (rawDatas.ContainsKey(id))
        {
            config = configs[id] = new CycleHallConfig(rawDatas[id]);
            rawDatas.Remove(id);
        }
        return config;
    }
    public static CycleHallConfig Get(int id)
    {
        return Get(id.ToString());
    }
    public static List<string> GetKeys()
    {
        var keys = new List<string>();
        keys.AddRange(configs.Keys);
        keys.AddRange(rawDatas.Keys);
        return keys;
    }
    public static List<CycleHallConfig> GetValues()
    {
        var values = new List<CycleHallConfig>();
        values.AddRange(configs.Values);
        var keys = new List<string>(rawDatas.Keys);
        for (int i = 0; i < keys.Count; i++)
        {
            values.Add(Get(keys[i]));
        }
        return values;
    }
    public static bool Has(string id)
    {
        return configs.ContainsKey(id) || rawDatas.ContainsKey(id);
    }
    public static bool Has(int id)
    {
        return Has(id.ToString());
    }
    public static bool inited { get; private set; }
    protected static Dictionary<string, string> rawDatas = new Dictionary<string, string>();
    public static void Init(bool sync=false)
    {
        inited = false;
        var path = string.Empty;
        if (AssetSource.refdataFromEditor)
        {
            path = ResourcesPath.CONFIG_FODLER +"/CycleHall.txt";
        }
        else
        {
            path = AssetVersionUtility.GetAssetFilePath("config/CycleHall.txt");
        }
        configs.Clear();
        var tempConfig = new CycleHallConfig();
        var preParse = tempConfig is IConfigPostProcess;
        if (sync)
        {
            var lines = File.ReadAllLines(path);
            if (!preParse)
            {
                rawDatas = new Dictionary<string, string>(lines.Length - 3);
            }
            for (int i = 3; i < lines.Length; i++)
            {
                try
                {
                    var line = lines[i];
                    var index = line.IndexOf("\t");
                    if (index == -1)
                    {
                        continue;
                    }
                    var id = line.Substring(0, index);
                    if (preParse)
                    {
                        var config = new CycleHallConfig(line);
                        configs[id] = config;
                        (config as IConfigPostProcess).OnConfigParseCompleted();
                    }
                    else
                    {
                        rawDatas[id] = line;
                    }
                }
                catch (System.Exception ex)
                {
                    Debug.LogError(ex);
                }
            }
            inited = true;
        }
        else
        {
            ThreadPool.QueueUserWorkItem((object _object) =>
            {
                var lines = File.ReadAllLines(path);
                if (!preParse)
                {
                    rawDatas = new Dictionary<string, string>(lines.Length - 3);
                }
                for (int i = 3; i < lines.Length; i++)
                {
                    try
                    {
                       var line = lines[i];
                        var index = line.IndexOf("\t");
                        if (index == -1)
                        {
                            continue;
                        }
                        var id = line.Substring(0, index);
                        if (preParse)
                        {
                            var config = new CycleHallConfig(line);
                            configs[id] = config;
                            (config as IConfigPostProcess).OnConfigParseCompleted();
                        }
                        else
                        {
                            rawDatas[id] = line;
                        }
                    }
                    catch (System.Exception ex)
                    {
                        Debug.LogError(ex);
                    }
                }
                inited = true;
            });
        }
    }
}
Core/GameEngine/Model/Config/CycleHallConfig.cs.meta
New file
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 46de5efda7e9da0458f6529432405a66
MonoImporter:
  externalObjects: {}
  serializedVersion: 2
  defaultReferences: []
  executionOrder: 0
  icon: {instanceID: 0}
  userData:
  assetBundleName:
  assetBundleVariant:
Core/GameEngine/Model/TelPartialConfig/CycleHallConfig.cs
New file
@@ -0,0 +1,45 @@
using System;
using System.Collections.Generic;
using System.Linq;
public partial class CycleHallConfig : IConfigPostProcess
{
    static List<int> tabIndexList = new List<int>();
    static Dictionary<int, int> sortDict = new Dictionary<int, int>();
    //<轮回类型,<界面类型,配置ID>>
    static Dictionary<int, Dictionary<int, int>> infoDict = new Dictionary<int, Dictionary<int, int>>();
    public void OnConfigParseCompleted()
    {
        sortDict[TabSort] = id;
        if (!infoDict.ContainsKey(RoundType))
            infoDict[RoundType] = new Dictionary<int, int>();
        infoDict[RoundType][TabType] = id;
    }
    public static List<int> GetTabList()
    {
        if (sortDict.IsNullOrEmpty())
            return null;
        if (tabIndexList.IsNullOrEmpty())
        {
            var list = sortDict.Keys.ToList();
            list.Sort();
            for (int i = 0; i < list.Count; i++)
            {
                int id = sortDict[list[i]];
                if (!tabIndexList.Contains(id))
                    tabIndexList.Add(id);
            }
        }
        return tabIndexList;
    }
    public static int GetIndex(int roundType, int tabType)
    {
        return infoDict.TryGetValue(roundType, out var info) && info.TryGetValue(tabType, out var index) ? index : 0;
    }
}
Core/GameEngine/Model/TelPartialConfig/CycleHallConfig.cs.meta
New file
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 45773961a64b0b849bf2fb89b6b1e1b4
MonoImporter:
  externalObjects: {}
  serializedVersion: 2
  defaultReferences: []
  executionOrder: 0
  icon: {instanceID: 0}
  userData:
  assetBundleName:
  assetBundleVariant:
Core/NetworkPackage/DTCFile/ServerPack/HAA_SaleActivity/DTCAA88_tagMCActLunhuidianInfo.cs
New file
@@ -0,0 +1,12 @@
using UnityEngine;
using System.Collections;
using vnxbqy.UI;
public class DTCAA88_tagMCActLunhuidianInfo : DtcBasic {
    public override void Done(GameNetPackBasic vNetPack) {
        base.Done(vNetPack);
        HAA88_tagMCActLunhuidianInfo vNetData = vNetPack as HAA88_tagMCActLunhuidianInfo;
        OperationTimeHepler.Instance.UpdateActLunhuidianInfo(vNetData);
    }
}
Core/NetworkPackage/DTCFile/ServerPack/HAA_SaleActivity/DTCAA88_tagMCActLunhuidianInfo.cs.meta
New file
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: b463d1cc3e1fc57428bda82df21ac883
MonoImporter:
  externalObjects: {}
  serializedVersion: 2
  defaultReferences: []
  executionOrder: 0
  icon: {instanceID: 0}
  userData:
  assetBundleName:
  assetBundleVariant:
Core/NetworkPackage/DTCFile/ServerPack/HAA_SaleActivity/DTCAA89_tagMCActLunhuidianPlayerInfo.cs
New file
@@ -0,0 +1,13 @@
using UnityEngine;
using System.Collections;
using vnxbqy.UI;
// AA 89 轮回殿活动玩家信息 #tagMCActLunhuidianPlayerInfo
public class DTCAA89_tagMCActLunhuidianPlayerInfo : DtcBasic {
    public override void Done(GameNetPackBasic vNetPack) {
        base.Done(vNetPack);
        HAA89_tagMCActLunhuidianPlayerInfo vNetData = vNetPack as HAA89_tagMCActLunhuidianPlayerInfo;
        ModelCenter.Instance.GetModel<CycleHallActModel>().UpdatePlayerInfo(vNetData);
    }
}
Core/NetworkPackage/DTCFile/ServerPack/HAA_SaleActivity/DTCAA89_tagMCActLunhuidianPlayerInfo.cs.meta
New file
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 90193da3d53a59d45943fe6183aa06ef
MonoImporter:
  externalObjects: {}
  serializedVersion: 2
  defaultReferences: []
  executionOrder: 0
  icon: {instanceID: 0}
  userData:
  assetBundleName:
  assetBundleVariant:
Core/NetworkPackage/ServerPack/HAA_SaleActivity/HAA88_tagMCActLunhuidianInfo.cs
New file
@@ -0,0 +1,88 @@
using UnityEngine;
using System.Collections;
// AA 88 轮回殿活动信息 #tagMCActLunhuidianInfo
public class HAA88_tagMCActLunhuidianInfo : GameNetPackBasic
{
    public byte ActNum;    // 活动编号
    public string StartDate;    // 开始日期 y-m-d
    public string EndtDate;    // 结束日期 y-m-d
    public byte ResetType;    // 重置类型,0-0点重置;1-5点重置
    public ushort LimitLV;    // 限制等级
    public byte RoundCount;
    public tagMCActLunhuidianRound[] RoundList;    // 轮回列表,支持多个不同类型轮回同时开启
    public HAA88_tagMCActLunhuidianInfo()
    {
        _cmd = (ushort)0xAA88;
    }
    public override void ReadFromBytes(byte[] vBytes)
    {
        TransBytes(out ActNum, vBytes, NetDataType.BYTE);
        TransBytes(out StartDate, vBytes, NetDataType.Chars, 10);
        TransBytes(out EndtDate, vBytes, NetDataType.Chars, 10);
        TransBytes(out ResetType, vBytes, NetDataType.BYTE);
        TransBytes(out LimitLV, vBytes, NetDataType.WORD);
        TransBytes(out RoundCount, vBytes, NetDataType.BYTE);
        RoundList = new tagMCActLunhuidianRound[RoundCount];
        for (int i = 0; i < RoundCount; i++)
        {
            RoundList[i] = new tagMCActLunhuidianRound();
            TransBytes(out RoundList[i].RoundType, vBytes, NetDataType.BYTE);
            TransBytes(out RoundList[i].AwardType, vBytes, NetDataType.BYTE);
            TransBytes(out RoundList[i].AwardTypeValue, vBytes, NetDataType.DWORD);
            TransBytes(out RoundList[i].RoundMax, vBytes, NetDataType.BYTE);
            TransBytes(out RoundList[i].AwardCount, vBytes, NetDataType.BYTE);
            RoundList[i].AwardList = new tagMCActLunhuidianAward[RoundList[i].AwardCount];
            for (int j = 0; j < RoundList[i].AwardCount; j++)
            {
                RoundList[i].AwardList[j] = new tagMCActLunhuidianAward();
                TransBytes(out RoundList[i].AwardList[j].AwardIndex, vBytes, NetDataType.BYTE);
                TransBytes(out RoundList[i].AwardList[j].NeedValue, vBytes, NetDataType.DWORD);
                TransBytes(out RoundList[i].AwardList[j].Count, vBytes, NetDataType.BYTE);
                RoundList[i].AwardList[j].AwardItemList = new tagMCActLunhuidianItem[RoundList[i].AwardList[j].Count];
                for (int k = 0; k < RoundList[i].AwardList[j].Count; k++)
                {
                    RoundList[i].AwardList[j].AwardItemList[k] = new tagMCActLunhuidianItem();
                    TransBytes(out RoundList[i].AwardList[j].AwardItemList[k].ItemID, vBytes, NetDataType.DWORD);
                    TransBytes(out RoundList[i].AwardList[j].AwardItemList[k].ItemCount, vBytes, NetDataType.WORD);
                    TransBytes(out RoundList[i].AwardList[j].AwardItemList[k].IsBind, vBytes, NetDataType.BYTE);
                }
            }
            TransBytes(out RoundList[i].CTGIDCount, vBytes, NetDataType.BYTE);
            TransBytes(out RoundList[i].CTGIDList, vBytes, NetDataType.WORD, RoundList[i].CTGIDCount);
            TransBytes(out RoundList[i].ShopType, vBytes, NetDataType.WORD);
        }
    }
    public struct tagMCActLunhuidianItem
    {
        public uint ItemID;
        public ushort ItemCount;
        public byte IsBind;
    }
    public struct tagMCActLunhuidianRound
    {
        public byte RoundType;        // 轮回类型
        public byte AwardType;        // 奖励类型 1-消耗货币;2-寻宝次数
        public uint AwardTypeValue;        // 奖励类型对应值,消耗货币时为对应的货币类型,寻宝时为对应的寻宝类型
        public byte RoundMax;        // 最大可循环轮次
        public byte AwardCount;
        public tagMCActLunhuidianAward[] AwardList;        // 每轮奖励列表
        public byte CTGIDCount;
        public ushort[] CTGIDList;        // CTGID列表
        public ushort ShopType;        // 开放商店类型,可能为0不开放
    }
    public struct tagMCActLunhuidianAward
    {
        public byte AwardIndex;        // 奖励记录索引 0~30
        public uint NeedValue;        // 奖励所需值
        public byte Count;        // 奖励物品数
        public tagMCActLunhuidianItem[] AwardItemList;        // 奖励物品列表
    }
}
Core/NetworkPackage/ServerPack/HAA_SaleActivity/HAA88_tagMCActLunhuidianInfo.cs.meta
New file
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 8d1f68d3a34b985459720eb7308f9ded
MonoImporter:
  externalObjects: {}
  serializedVersion: 2
  defaultReferences: []
  executionOrder: 0
  icon: {instanceID: 0}
  userData:
  assetBundleName:
  assetBundleVariant:
Core/NetworkPackage/ServerPack/HAA_SaleActivity/HAA89_tagMCActLunhuidianPlayerInfo.cs
New file
@@ -0,0 +1,25 @@
using UnityEngine;
using System.Collections;
// AA 89 轮回殿活动玩家信息 #tagMCActLunhuidianPlayerInfo
public class HAA89_tagMCActLunhuidianPlayerInfo : GameNetPackBasic {
    public byte ActNum;    // 活动编号
    public byte RoundType;    // 轮回类型
    public byte CurRound;    // 当前轮次
    public uint CurValue;    // 累计值
    public uint AwardRecord;    // 当前轮次奖励领奖记录,按奖励索引二进制位存储是否已领取,所有奖励已领取后自动进入下一轮,且重置该奖励状态
    public HAA89_tagMCActLunhuidianPlayerInfo () {
        _cmd = (ushort)0xAA89;
    }
    public override void ReadFromBytes (byte[] vBytes) {
        TransBytes (out ActNum, vBytes, NetDataType.BYTE);
        TransBytes (out RoundType, vBytes, NetDataType.BYTE);
        TransBytes (out CurRound, vBytes, NetDataType.BYTE);
        TransBytes (out CurValue, vBytes, NetDataType.DWORD);
        TransBytes (out AwardRecord, vBytes, NetDataType.DWORD);
    }
}
Core/NetworkPackage/ServerPack/HAA_SaleActivity/HAA89_tagMCActLunhuidianPlayerInfo.cs.meta
New file
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 09be82f59b1c9ab45bb4db8e93b2bca9
MonoImporter:
  externalObjects: {}
  serializedVersion: 2
  defaultReferences: []
  executionOrder: 0
  icon: {instanceID: 0}
  userData:
  assetBundleName:
  assetBundleVariant:
System/LoopAct/CycleHall.meta
New file
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 0aad5025ad382ef46a2a7aca96fffddb
folderAsset: yes
DefaultImporter:
  externalObjects: {}
  userData:
  assetBundleName:
  assetBundleVariant:
System/LoopAct/CycleHall/CycleHallActModel.cs
New file
@@ -0,0 +1,303 @@
using LitJson;
using System;
using System.Collections.Generic;
using System.Linq;
namespace vnxbqy.UI
{
    public class CycleHallActModel : Model, IBeforePlayerDataInitialize, IPlayerLoginOk, IOpenServerActivity
    {
        private int m_NowTabId;
        public int nowTabId
        {
            get { return m_NowTabId; }
            set
            {
                m_NowTabId = value;
                UpdateRedpoint();
                onNowTabIdUpdate?.Invoke();
            }
        }
        //同步播放摆动动画
        public Action PlayAnimationSync;
        private bool isPlayAnimation = false;
        public bool IsPlayAnimation
        {
            get
            {
                return isPlayAnimation;
            }
            set
            {
                isPlayAnimation = value;
                if (isPlayAnimation)
                {
                    PlayAnimationSync?.Invoke();
                }
                isPlayAnimation = false;
            }
        }
        public Dictionary<int, HAA89_tagMCActLunhuidianPlayerInfo> playerInfoDict = new Dictionary<int, HAA89_tagMCActLunhuidianPlayerInfo>();
        public event Action<int> onStateUpdate;
        public event Action onNowTabIdUpdate;
        public Redpoint redPoint = new Redpoint(MainRedDot.CycleHallRepoint);
        //<索引,红点>
        public Dictionary<int, Redpoint> redPointDict = new Dictionary<int, Redpoint>();
        //<轮回类型,界面ID>
        public Dictionary<int, int> windowIDDict = new Dictionary<int, int>();
        public const int activityType = (int)OpenServerActivityCenter.ActivityType.AT_Activity2;
        public const int activityID = (int)NewDayActivityID.CycleHallAct;
        public static Operation operaType = Operation.default47;
        public int actNum = 10; //对应界面
        public event Action UpdatePlayerInfoAction;
        StoreModel storeModel { get { return ModelCenter.Instance.GetModel<StoreModel>(); } }
        public override void Init()
        {
            OperationTimeHepler.Instance.operationStartEvent += OperationStartEvent;
            OperationTimeHepler.Instance.operationEndEvent += OperationEndEvent;
            OperationTimeHepler.Instance.operationAdvanceEvent += OperationAdvanceEvent;
            storeModel.RefreshBuyShopLimitEvent += RefreshBuyShopLimitEvent;
            OpenServerActivityCenter.Instance.Register(activityID, this, activityType);
            LoadTable();
        }
        private void LoadTable()
        {
            var jsonData = JsonMapper.ToObject(FuncConfigConfig.Get("CycleHall").Numerical1);
            List<string> keyList = jsonData.Keys.ToList();
            for (int i = 0; i < keyList.Count; i++)
            {
                windowIDDict.Add(int.Parse(keyList[i]), int.Parse(jsonData[keyList[i]].ToJson()));
            }
        }
        public OperationCycleHall GetOperationInfo()
        {
            OperationTimeHepler.Instance.TryGetOperation(operaType, out OperationCycleHall cycleHallAct);
            return cycleHallAct;
        }
        public List<int> GetTabIDList()
        {
            OperationCycleHall act;
            OperationTimeHepler.Instance.TryGetOperation(operaType, out act);
            if (act == null)
                return new List<int>();
            var list = CycleHallConfig.GetTabList();
            if (list.IsNullOrEmpty())
                return new List<int>();
            List<int> resList = new List<int>();
            for (int i = 0; i < list.Count; i++)
            {
                int id = list[i];
                if (!CycleHallConfig.Has(id))
                    continue;
                CycleHallConfig config = CycleHallConfig.Get(id);
                if (act.TryGetRound(config.RoundType, out var info))
                {
                    if (!resList.Contains(id))
                    {
                        resList.Add(id);
                    }
                }
            }
            return resList;
        }
        public void OnBeforePlayerDataInitialize()
        {
            playerInfoDict.Clear();
        }
        public void OnPlayerLoginOk()
        {
        }
        public override void UnInit()
        {
            storeModel.RefreshBuyShopLimitEvent -= RefreshBuyShopLimitEvent;
        }
        private void RefreshBuyShopLimitEvent()
        {
            UpdateRedpoint();
        }
        public bool IsOpen
        {
            get
            {
                return OperationTimeHepler.Instance.SatisfyOpenCondition(operaType);
            }
        }
        public bool priorityOpen
        {
            get
            {
                return redPoint.state == RedPointState.Simple;
            }
        }
        public bool IsAdvance
        {
            get
            {
                return OperationTimeHepler.Instance.SatisfyAdvanceCondition(operaType);
            }
        }
        private void OperationEndEvent(Operation type, int state)
        {
            if (type == operaType)
            {
                if (onStateUpdate != null)
                {
                    onStateUpdate(activityID);
                }
                WindowCenter.Instance.Close<CycleHallWin>();
                UpdateRedpoint();
            }
        }
        private void OperationAdvanceEvent(Operation type)
        {
            if (type == operaType)
            {
                if (onStateUpdate != null)
                {
                    onStateUpdate(activityID);
                }
            }
        }
        private void OperationStartEvent(Operation type, int state)
        {
            if (type == operaType && state == 0)
            {
                if (onStateUpdate != null)
                {
                    onStateUpdate(activityID);
                }
            }
        }
        //0 不可领取 1 可领取  2 已领取
        public int GetAwardState(int roundType, int index)
        {
            if (playerInfoDict == null || !playerInfoDict.TryGetValue((byte)roundType, out var playerInfo) || playerInfo == null)
                return 0;
            OperationCycleHall act;
            OperationTimeHepler.Instance.TryGetOperation(operaType, out act);
            if (act == null || !act.TryGetRoundInfoByIndex(roundType, index, out var awardInfo))
                return 0;
            if (playerInfo.CurValue >= awardInfo.NeedValue)
            {
                return (playerInfo.AwardRecord & (1 << index)) != 0 ? 2 : 1;
            }
            else
            {
                return 0;
            }
        }
        public void UpdateRedpoint()
        {
            redPoint.state = RedPointState.None;
            if (redPointDict != null)
            {
                var redPointList = redPointDict.Keys.ToList();
                for (int i = 0; i < redPointList.Count; i++)
                {
                    int redPointId = redPointList[i];
                    redPointDict[redPointId].state = RedPointState.None;
                }
            }
            if (!IsOpen) return;
            var act = GetOperationInfo();
            if (act == null || act.roundInfoDict == null)
                return;
            var roundTypeList = act.roundInfoDict.Keys.ToList();
            for (int i = 0; i < roundTypeList.Count; i++)
            {
                int roundType = roundTypeList[i];
                if (!act.roundInfoDict.ContainsKey(roundType))
                    continue;
                int id = CycleHallConfig.GetIndex(roundType, 1);
                if (id <= 0)
                    continue;
                if (!redPointDict.ContainsKey(id))
                    redPointDict[id] = new Redpoint(MainRedDot.CycleHallRepoint, MainRedDot.CycleHallRepoint * 1000 + id);
                //有可领取的任务奖励
                if (!act.TryGetRound(roundType, out var round) || round.AwardList == null)
                    return;
                for (int j = 0; j < round.AwardList.Length; j++)
                {
                    var award = round.AwardList[j];
                    int index = award.AwardIndex;
                    int state = GetAwardState(roundType, index);//0 不可领取 1 可领取  2 已领取
                    if (state == 1)
                        redPointDict[id].state = RedPointState.Simple;
                }
                //商店免费
                id = CycleHallConfig.GetIndex(roundType, 2);
                if (id <= 0)
                    continue;
                if (!redPointDict.ContainsKey(id))
                    redPointDict[id] = new Redpoint(MainRedDot.CycleHallRepoint, MainRedDot.CycleHallRepoint * 1000 + id);
                List<StoreConfig> _list = null;
                StoreConfig.TryGetStoreConfigs(round.ShopType, out _list);
                int storeCnt = _list == null ? 0 : _list.Count;
                for (int k = 0; k < storeCnt; k++)
                {
                    if (_list[k].MoneyNumber == 0)
                    {
                        int remainNum;
                        storeModel.TryGetIsSellOut(_list[k], out remainNum);
                        if (remainNum > 0)
                            redPointDict[id].state = RedPointState.Simple;
                    }
                }
            }
        }
        public void UpdatePlayerInfo(HAA89_tagMCActLunhuidianPlayerInfo netPack)
        {
            if (actNum != netPack.ActNum)
                return;
            if (!playerInfoDict.ContainsKey(netPack.RoundType))
                playerInfoDict[netPack.RoundType] = new HAA89_tagMCActLunhuidianPlayerInfo();
            playerInfoDict[netPack.RoundType].RoundType = netPack.RoundType;
            playerInfoDict[netPack.RoundType].CurRound = netPack.CurRound;
            playerInfoDict[netPack.RoundType].CurValue = netPack.CurValue;
            playerInfoDict[netPack.RoundType].AwardRecord = netPack.AwardRecord;
            UpdatePlayerInfoAction?.Invoke();
            UpdateRedpoint();
        }
        public void SendGetAward(int roundType, int needValue)
        {
            CA504_tagCMPlayerGetReward getReward = new CA504_tagCMPlayerGetReward();
            getReward.RewardType = 78;
            getReward.DataEx = (uint)actNum;
            getReward.DataExStr = StringUtility.Contact(roundType, "|", needValue);
            getReward.DataExStrLen = (byte)getReward.DataExStr.Length;
            GameNetSystem.Instance.SendInfo(getReward);
        }
    }
}
System/LoopAct/CycleHall/CycleHallActModel.cs.meta
New file
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 6ed45a4569cca334e8a223caa1ef69f3
MonoImporter:
  externalObjects: {}
  serializedVersion: 2
  defaultReferences: []
  executionOrder: 0
  icon: {instanceID: 0}
  userData:
  assetBundleName:
  assetBundleVariant:
System/LoopAct/CycleHall/CycleHallCell.cs
New file
@@ -0,0 +1,312 @@
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
namespace vnxbqy.UI
{
    public class CycleHallCell : CellView
    {
        [SerializeField] Transform mission;
        [SerializeField] Transform gift;
        [SerializeField] ImageEx imgFinish;
        [SerializeField] TextEx txtTitle;
        [SerializeField] ButtonEx btnMissionHave;
        [SerializeField] List<ItemCell> missionItemCells = new List<ItemCell>();
        [SerializeField] List<ImageEx> missionHaves = new List<ImageEx>();
        [SerializeField] List<ImageEx> missionGreys = new List<ImageEx>();
        [SerializeField] List<RotationTween> missionTweens = new List<RotationTween>();
        [SerializeField] Slider buyCountGiftSlider;
        [SerializeField] Text buyCountGiftSliderText;
        [SerializeField] List<ItemCell> giftItemCells = new List<ItemCell>();
        [SerializeField] ButtonEx btnBuy;
        [SerializeField] ImageEx imgRed;
        [SerializeField] TextEx txtBuy;
        [SerializeField] ImageEx imgBuy;
        [SerializeField] TextEx txtLimitCount;
        [SerializeField] TextEx orgPrice;
        int roundType;
        int tabType;
        int index;
        CycleHallActModel model { get { return ModelCenter.Instance.GetModel<CycleHallActModel>(); } }
        VipModel vipModel { get { return ModelCenter.Instance.GetModel<VipModel>(); } }
        BossTrialModel bossTrialModel { get { return ModelCenter.Instance.GetModel<BossTrialModel>(); } }
        StoreModel storeModel { get { return ModelCenter.Instance.GetModel<StoreModel>(); } }
        private void OnEnable()
        {
            model.PlayAnimationSync += OnPlaySyncAnimation;
            for (int i = 0; i < missionTweens.Count; i++)
            {
                missionTweens[i].Stop();
                missionTweens[i].SetStartState();
            }
            if (tabType == 1)
            {
                int state = model.GetAwardState(roundType, index);//0 不可领取 1 可领取  2 已领取
                for (int i = 0; i < missionTweens.Count; i++)
                {
                    var act = model.GetOperationInfo();
                    if (act == null || !act.TryGetRound(roundType, out var round) || round.AwardList == null || round.AwardList.Length <= index || index < 0)
                        return;
                    var award = round.AwardList[index];
                    if (award.AwardItemList == null)
                        return;
                    if (i < award.AwardItemList.Length)
                    {
                        if (state == 1)
                        {
                            missionTweens[i].Play();
                        }
                    }
                }
            }
        }
        private void OnDisable()
        {
            model.PlayAnimationSync -= OnPlaySyncAnimation;
        }
        public void Display(int index, CellView cellView)
        {
            this.index = index;
            roundType = cellView.info.Value.infoInt1;
            tabType = cellView.info.Value.infoInt2;
            mission.SetActive(tabType == 1);
            gift.SetActive(tabType == 2);
            btnMissionHave.enabled = false;
            imgRed.SetActive(false);
            if (model.playerInfoDict == null || !model.playerInfoDict.TryGetValue((byte)roundType, out var playerInfo) || playerInfo == null)
                return;
            if (tabType == 1)
            {
                var act = model.GetOperationInfo();
                if (act == null || !act.TryGetRound(roundType, out var round) || round.AwardList == null || round.AwardList.Length <= index || index < 0)
                    return;
                var award = round.AwardList[index];
                int state = model.GetAwardState(roundType, index);//0 不可领取 1 可领取  2 已领取
                imgFinish.SetActive(state == 2);
                orgPrice.SetActive(false);
                txtTitle.text = Language.Get(StringUtility.Contact("CycleHallMissionTitle", "_", roundType), award.NeedValue);
                buyCountGiftSlider.value = playerInfo.CurValue / (float)award.NeedValue;
                buyCountGiftSliderText.text = string.Format("{0}/{1}", playerInfo.CurValue, award.NeedValue);
                btnMissionHave.enabled = true;
                btnMissionHave.SetListener(() =>
                {
                    HaveMissionAward();
                });
                for (int i = 0; i < missionItemCells.Count; i++)
                {
                    var itemBaisc = missionItemCells[i];
                    if (i < award.AwardItemList.Length)
                    {
                        var itemInfo = award.AwardItemList[i];
                        itemBaisc.SetActive(true);
                        missionHaves[i].SetActive(state == 2);
                        missionGreys[i].SetActive(state == 2);
                        ItemCellModel cellModel = new ItemCellModel((int)itemInfo.ItemID, false, (ulong)itemInfo.ItemCount);
                        itemBaisc.Init(cellModel);
                        itemBaisc.button.AddListener(() =>
                        {
                            if (state == 1)
                            {
                                HaveMissionAward();
                            }
                            else
                            {
                                ItemTipUtility.Show((int)itemInfo.ItemID);
                            }
                        });
                    }
                    else
                    {
                        itemBaisc.SetActive(false);
                        missionHaves[i].SetActive(false);
                        missionGreys[i].SetActive(false);
                    }
                }
                OnPlaySyncAnimation();
            }
            else if (tabType == 2)
            {
                var act = model.GetOperationInfo();
                if (act == null || !act.TryGetRound(roundType, out var round) || round.CTGIDList == null)
                    return;
                List<StoreConfig> _list = null;
                StoreConfig.TryGetStoreConfigs(round.ShopType, out _list);
                if (_list != null && index < _list.Count)
                {
                    DisplayStore(_list[index]);
                    return;
                }
                index = index - (_list != null ? _list.Count : 0);
                if (round.CTGIDList.Length <= index || index < 0)
                    return;
                int ctgId = round.CTGIDList[index];
                if (!CTGConfig.Has(ctgId))
                    return;
                CTGConfig config = CTGConfig.Get(ctgId);
                var countInfo = GetBuyCntInfo(ctgId);
                int buyCnt = countInfo.x;
                int totalCnt = countInfo.y;
                btnBuy.SetActive(buyCnt < totalCnt);
                imgBuy.SetActive(buyCnt >= totalCnt);
                OrderInfoConfig orderConfig;
                vipModel.TryGetOrderInfo(ctgId, out orderConfig);
                txtBuy.text = Language.Get("PayMoneyNum", UIHelper.GetMoneyFormat(orderConfig.PayRMBNum));
                txtLimitCount.SetActive(true);
                txtLimitCount.text = Language.Get("CycleHall05", UIHelper.AppendColor(buyCnt >= totalCnt ? TextColType.Red : TextColType.Green, Mathf.Max(0, totalCnt - buyCnt).ToString(), true));
                if (orgPrice != null)
                {
                    orgPrice.SetActive(PlayerDatas.Instance.baseData.IsActive90Off);
                    orgPrice.text = Language.Get("PayMoneyNum", UIHelper.GetMoneyFormat(orderConfig.m_PayRMBNum));
                }
                btnBuy.SetListener(() =>
                {
                    if (PlayerDatas.Instance.baseData.VIPLv < config.VipLevel)
                    {
                        SysNotifyMgr.Instance.ShowTip("VIPNotEnough", config.VipLevel);
                        return;
                    }
                    if (bossTrialModel.IsOpen)
                    {
                        //参与时间结束前直接购买,时间结束后再购买需要弹窗提示
                        if (bossTrialModel.IsPrepareTime || bossTrialModel.IsJoin)
                            vipModel.CTG(ctgId);
                        else
                        {
                            ConfirmCancel.ShowPopConfirm(Language.Get("Mail101"), Language.Get("BossTrial14"), (bool isOk) =>
                            {
                                if (isOk)
                                {
                                    vipModel.CTG(ctgId);
                                }
                            });
                        }
                    }
                    else
                    {
                        vipModel.CTG(ctgId);
                    }
                });
                txtTitle.text = config.Title;
                if (vipModel.TryGetRechargeItem(ctgId, out var list) && list != null)
                {
                    for (int i = 0; i < giftItemCells.Count; i++)
                    {
                        var itemBaisc = giftItemCells[i];
                        if (i < list.Count)
                        {
                            var itemInfo = list[i];
                            itemBaisc.SetActive(true);
                            ItemCellModel cellModel = new ItemCellModel((int)itemInfo.id, false, (ulong)itemInfo.count);
                            itemBaisc.Init(cellModel);
                            itemBaisc.button.AddListener(() =>
                            {
                                ItemTipUtility.Show((int)itemInfo.id);
                            });
                        }
                        else
                        {
                            itemBaisc.SetActive(false);
                        }
                    }
                }
            }
        }
        public void HaveMissionAward()
        {
            var act = model.GetOperationInfo();
            if (act == null || !act.TryGetRound(roundType, out var round) || round.AwardList == null || round.AwardList.Length <= index || index < 0)
                return;
            int state = model.GetAwardState(roundType, index);//0 不可领取 1 可领取  2 已领取
            if (state != 1)
                return;
            model.SendGetAward(roundType, (int)round.AwardList[index].NeedValue);
        }
        public Int2 GetBuyCntInfo(int ctgID)
        {
            VipModel.RechargeCount rechargeCount;
            vipModel.TryGetRechargeCount(ctgID, out rechargeCount);
            var ctgConfig = CTGConfig.Get(ctgID);
            int buyCnt = 0;
            int totalCnt = 0;
            buyCnt = rechargeCount.totalCount;
            totalCnt = ctgConfig.TotalBuyCount;
            return new Int2(buyCnt, totalCnt);
        }
        private void DisplayStore(StoreConfig storeConfig)
        {
            bool isFree = storeConfig.MoneyNumber == 0;
            txtTitle.text = isFree ? Language.Get("StoreName_free") : Language.Get("StoreName_money");
            //saleObj.SetActive(false);
            int remainNum;
            storeModel.TryGetIsSellOut(storeConfig, out remainNum);
            orgPrice.SetActive(false);
            txtLimitCount.SetActive(!isFree);
            txtLimitCount.text = Language.Get("CycleHall06", UIHelper.AppendColor(remainNum == 0 ? TextColType.Red : TextColType.Green, Mathf.Max(0, remainNum).ToString(), true));
            imgRed.SetActive(isFree);
            btnBuy.SetActive(remainNum > 0);
            btnBuy.SetListener(() =>
            {
                storeModel.SendBuyShopItemWithPopCheck(storeConfig, 1, (int)BuyStoreItemCheckType.ActGift);
            });
            imgBuy.SetActive(remainNum <= 0);
            txtBuy.text = isFree ? Language.Get("AloneFree") : Language.Get("ItemOverdue105", UIHelper.GetMoneyFormat(storeConfig.MoneyNumber));
            var items = storeModel.GetShopItemlistByIndex(storeConfig);
            for (int i = 0; i < giftItemCells.Count; i++)
            {
                var itemBaisc = giftItemCells[i];
                if (i < items.Count)
                {
                    var itemInfo = items[i];
                    itemBaisc.SetActive(true);
                    ItemCellModel cellModel = new ItemCellModel(itemInfo.itemId, false, (ulong)itemInfo.count);
                    itemBaisc.Init(cellModel);
                    itemBaisc.button.AddListener(() =>
                    {
                        ItemTipUtility.Show(itemInfo.itemId);
                    });
                }
                else
                {
                    itemBaisc.SetActive(false);
                }
            }
        }
        private void OnPlaySyncAnimation()
        {
            if (tabType != 1)
                return;
            for (int i = 0; i < missionTweens.Count; i++)
            {
                missionTweens[i].Stop();
                missionTweens[i].SetStartState();
            }
            int state = model.GetAwardState(roundType, index);//0 不可领取 1 可领取  2 已领取
            for (int i = 0; i < missionTweens.Count; i++)
            {
                if (missionTweens[i].isActiveAndEnabled && state == 1)
                {
                    missionTweens[i].Play();
                }
            }
        }
    }
}
System/LoopAct/CycleHall/CycleHallCell.cs.meta
New file
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: b094794b25bc1d843881da5367b1e683
MonoImporter:
  externalObjects: {}
  serializedVersion: 2
  defaultReferences: []
  executionOrder: 0
  icon: {instanceID: 0}
  userData:
  assetBundleName:
  assetBundleVariant:
System/LoopAct/CycleHall/CycleHallCoolTime.cs
New file
@@ -0,0 +1,45 @@
using UnityEngine;
using UnityEngine.UI;
namespace vnxbqy.UI
{
    public class CycleHallCoolTime : MonoBehaviour
    {
        [SerializeField] Text m_Time;
        [SerializeField] Image m_bg;
        private void OnEnable()
        {
            GlobalTimeEvent.Instance.secondEvent += RefreshSecond;
            RefreshSecond();
        }
        private void OnDisable()
        {
            GlobalTimeEvent.Instance.secondEvent -= RefreshSecond;
        }
        private void RefreshSecond()
        {
            m_bg.SetActive(true);
            m_Time.SetActive(true);
            int seconds = OperationTimeHepler.Instance.GetOperationSurplusTime(Operation.default47);
            if (seconds > 0)
            {
                if (seconds < 86400)
                {
                    m_Time.text = StringUtility.Contact("<color=#8DDC11FF>", TimeUtility.SecondsToHMS(seconds), "</color>");
                }
                else
                {
                    m_bg.SetActive(false);
                    m_Time.SetActive(false);
                }
            }
            else
            {
                m_Time.text = UIHelper.AppendColor(TextColType.Red, Language.Get("XMZZ110"));
            }
        }
    }
}
System/LoopAct/CycleHall/CycleHallCoolTime.cs.meta
New file
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: d43151b3e2d5155439acfd393a6a8fc0
MonoImporter:
  externalObjects: {}
  serializedVersion: 2
  defaultReferences: []
  executionOrder: 0
  icon: {instanceID: 0}
  userData:
  assetBundleName:
  assetBundleVariant:
System/LoopAct/CycleHall/CycleHallTabCell.cs
New file
@@ -0,0 +1,28 @@
using UnityEngine;
namespace vnxbqy.UI
{
    public class CycleHallTabCell : CellView
    {
        CycleHallActModel model { get { return ModelCenter.Instance.GetModel<CycleHallActModel>(); } }
        [SerializeField] TextEx txtName;
        [SerializeField] ImageEx imgBg;
        [SerializeField] ButtonEx btnTab;
        [SerializeField] RedpointBehaviour redPoint;
        public void Display(int id)
        {
            if (!CycleHallConfig.Has(id))
                return;
            CycleHallConfig config = CycleHallConfig.Get(id);
            redPoint.redpointId = MainRedDot.CycleHallRepoint * 1000 + id;
            imgBg.SetSprite(model.nowTabId == id ? "CycleHallTabBG_1" : "CycleHallTabBG_2");
            imgBg.SetNativeSize();
            txtName.text = config.TabName;
            btnTab.SetListener(() =>
            {
                model.nowTabId = id;
            });
        }
    }
}
System/LoopAct/CycleHall/CycleHallTabCell.cs.meta
New file
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: b1c189692a14b054ba1829a4a8170e2e
MonoImporter:
  externalObjects: {}
  serializedVersion: 2
  defaultReferences: []
  executionOrder: 0
  icon: {instanceID: 0}
  userData:
  assetBundleName:
  assetBundleVariant:
System/LoopAct/CycleHall/CycleHallWin.cs
New file
@@ -0,0 +1,374 @@
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
namespace vnxbqy.UI
{
    // 轮回殿
    public class CycleHallWin : Window
    {
        [SerializeField] ScrollerController tabScroller;
        [SerializeField] ImageEx imgTitle;
        [SerializeField] ImageEx imgInfo;
        [SerializeField] ImageEx imgLH;
        [SerializeField] TextEx actTime;
        [SerializeField] TextEx txtRewardRound;
        [SerializeField] ButtonEx btnGo;
        [SerializeField] ButtonEx btnClose;
        [SerializeField] ScrollerController scroller;
        RechargeGiftActModel rechargeGiftActModel { get { return ModelCenter.Instance.GetModel<RechargeGiftActModel>(); } }
        CycleHallActModel model { get { return ModelCenter.Instance.GetModel<CycleHallActModel>(); } }
        StoreModel storeModel { get { return ModelCenter.Instance.GetModel<StoreModel>(); } }
        VipModel vipModel { get { return ModelCenter.Instance.GetModel<VipModel>(); } }
        protected override void AddListeners()
        {
            btnGo.SetListener(OnClickGo);
            btnClose.SetListener(CloseClick);
        }
        protected override void BindController()
        {
        }
        protected override void OnPreOpen()
        {
            GlobalTimeEvent.Instance.secondEvent += SecondEvent;
            tabScroller.OnRefreshCell += OnScrollerRefreshTabCell;
            scroller.OnRefreshCell += OnScrollerRefreshCell;
            model.onNowTabIdUpdate += OnNowTabIdUpdate;
            vipModel.rechargeCountEvent += VipModel_rechargeCountEvent;
            storeModel.RefreshBuyShopLimitEvent += RefreshBuyShopLimitEvent;
            model.UpdatePlayerInfoAction += OnUpdatePlayerInfoAction;
            OperationTimeHepler.Instance.operationTimeUpdateEvent += OperationTimeUpdateEvent;
            var list = model.GetTabIDList();
            if (!list.IsNullOrEmpty())
            {
                model.nowTabId = list.First();
            }
            else
            {
                model.nowTabId = int.Parse(CycleHallConfig.GetKeys()[0]);
            }
            Display();
        }
        protected override void OnPreClose()
        {
            GlobalTimeEvent.Instance.secondEvent -= SecondEvent;
            tabScroller.OnRefreshCell -= OnScrollerRefreshTabCell;
            scroller.OnRefreshCell -= OnScrollerRefreshCell;
            model.onNowTabIdUpdate -= OnNowTabIdUpdate;
            vipModel.rechargeCountEvent -= VipModel_rechargeCountEvent;
            storeModel.RefreshBuyShopLimitEvent -= RefreshBuyShopLimitEvent;
            model.UpdatePlayerInfoAction -= OnUpdatePlayerInfoAction;
            OperationTimeHepler.Instance.operationTimeUpdateEvent -= OperationTimeUpdateEvent;
        }
        private void OperationTimeUpdateEvent(Operation operation)
        {
            if (operation == Operation.default47)
            {
                tabScroller.m_Scorller.RefreshActiveCellViews();
                scroller.m_Scorller.RefreshActiveCellViews();
                Display();
            }
        }
        private void OnUpdatePlayerInfoAction()
        {
            tabScroller.m_Scorller.RefreshActiveCellViews();
            scroller.m_Scorller.RefreshActiveCellViews();
            Display();
        }
        private void RefreshBuyShopLimitEvent()
        {
            scroller.m_Scorller.RefreshActiveCellViews();
            model.IsPlayAnimation = true;
        }
        private void VipModel_rechargeCountEvent(int obj)
        {
            scroller.m_Scorller.RefreshActiveCellViews();
            model.IsPlayAnimation = true;
        }
        private void OnNowTabIdUpdate()
        {
            tabScroller.m_Scorller.RefreshActiveCellViews();
            CreateScroller();
            scroller.JumpIndex(JumpIndex());
            Display();
        }
        private void OnScrollerRefreshTabCell(ScrollerDataType type, CellView cell)
        {
            var _cell = cell as CycleHallTabCell;
            _cell.Display(_cell.index);
        }
        private void OnScrollerRefreshCell(ScrollerDataType type, CellView cell)
        {
            var _cell = cell as CycleHallCell;
            _cell.Display(_cell.index, cell);
            model.IsPlayAnimation = true;
        }
        protected override void OnAfterOpen()
        {
            CreateTabScroller();
            tabScroller.JumpIndex(JumpTabIndex());
            CreateScroller();
            scroller.JumpIndex(JumpIndex());
        }
        protected override void OnAfterClose()
        {
        }
        private void SecondEvent()
        {
            GetActTime(functionOrder);
        }
        private void Display()
        {
            int id = model.nowTabId;
            if (!CycleHallConfig.Has(id))
                return;
            CycleHallConfig config = CycleHallConfig.Get(id);
            int roundType = config.RoundType;
            int tabType = config.TabType;
            var act = model.GetOperationInfo();
            if (act == null || !act.TryGetRound(roundType, out var round) || !model.playerInfoDict.TryGetValue(roundType, out var playerInfo))
                return;
            btnGo.SetActive(tabType == 1);
            imgLH.SetSprite(config.StandImage);
            imgLH.SetNativeSize();
            imgTitle.SetSprite(config.TitleImage);
            imgTitle.SetNativeSize();
            imgInfo.SetSprite(config.InfoImage);
            imgInfo.SetNativeSize();
            txtRewardRound.text = Language.Get("CycleHall01", playerInfo.CurRound, round.RoundMax);
            GetActTime(functionOrder);
        }
        private void GetActTime(int functionOrder)
        {
            var act = model.GetOperationInfo();
            actTime.text = act == null ? string.Empty : Language.Get("CycleHall07", TimeUtility.SecondsToDHMSCHS(act.GetResetSurplusTime()));
        }
        private void CreateTabScroller()
        {
            tabScroller.Refresh();
            var list = model.GetTabIDList();
            if (!list.IsNullOrEmpty())
            {
                for (int i = 0; i < list.Count; i++)
                {
                    tabScroller.AddCell(ScrollerDataType.Header, list[i]);
                }
            }
            tabScroller.Restart();
        }
        private void CreateScroller()
        {
            int id = model.nowTabId;
            if (!CycleHallConfig.Has(id))
                return;
            CycleHallConfig config = CycleHallConfig.Get(id);
            CellInfo cellInfo = new CellInfo();
            cellInfo.infoInt1 = config.RoundType;
            cellInfo.infoInt2 = config.TabType;
            if (config.TabType == 1)
            {
                scroller.Refresh();
                var act = model.GetOperationInfo();
                if (act != null && act.TryGetRound(config.RoundType, out var round) && round.AwardList != null)
                {
                    for (int i = 0; i < round.AwardList.Length; i++)
                    {
                        scroller.AddCell(ScrollerDataType.Header, i, cellInfo);
                    }
                }
                scroller.Restart();
            }
            else if (config.TabType == 2)
            {
                scroller.Refresh();
                var act = model.GetOperationInfo();
                if (act != null && act.TryGetRound(config.RoundType, out var round) && round.CTGIDList != null)
                {
                    List<StoreConfig> _list = null;
                    StoreConfig.TryGetStoreConfigs(round.ShopType, out _list);
                    int totaleCnt = (_list == null ? 0 : _list.Count) + round.CTGIDList.Length;
                    for (int i = 0; i < totaleCnt; i++)
                    {
                        scroller.AddCell(ScrollerDataType.Header, i, cellInfo);
                    }
                }
                scroller.Restart();
            }
        }
        private int JumpTabIndex()
        {
            var act = model.GetOperationInfo();
            if (act == null || act.roundInfoDict == null)
                return 0;
            var roundTypeList = act.roundInfoDict.Keys.ToList();
            for (int i = 0; i < roundTypeList.Count; i++)
            {
                int roundType = roundTypeList[i];
                if (!act.roundInfoDict.ContainsKey(roundType))
                    continue;
                int id = CycleHallConfig.GetIndex(roundType, 1);
                if (id <= 0)
                    continue;
                var tabIDList = model.GetTabIDList();
                if (tabIDList == null)
                    return 0;
                //有可领取的任务奖励
                if (!act.TryGetRound(roundType, out var round) || round.AwardList == null)
                    return 0;
                for (int j = 0; j < round.AwardList.Length; j++)
                {
                    var award = round.AwardList[j];
                    int index = award.AwardIndex;
                    int state = model.GetAwardState(roundType, index);//0 不可领取 1 可领取  2 已领取
                    if (state == 1)
                    {
                        int num = tabIDList.IndexOf(id);
                        model.nowTabId = id;
                        return num >= 0 ? num : 0;
                    }
                }
            }
            for (int i = 0; i < roundTypeList.Count; i++)
            {
                //商店免费
                int roundType = roundTypeList[i];
                if (!act.roundInfoDict.ContainsKey(roundType))
                    continue;
                int id = CycleHallConfig.GetIndex(roundType, 2);
                if (id <= 0)
                    continue;
                var tabIDList = model.GetTabIDList();
                if (tabIDList == null)
                    return 0;
                //有可领取的任务奖励
                if (!act.TryGetRound(roundType, out var round) || round.AwardList == null)
                    return 0;
                List<StoreConfig> _list = null;
                StoreConfig.TryGetStoreConfigs(round.ShopType, out _list);
                int storeCnt = _list == null ? 0 : _list.Count;
                for (int k = 0; k < storeCnt; k++)
                {
                    if (_list[k].MoneyNumber == 0)
                    {
                        int remainNum;
                        storeModel.TryGetIsSellOut(_list[k], out remainNum);
                        if (remainNum > 0)
                        {
                            int num = tabIDList.IndexOf(id);
                            model.nowTabId = id;
                            return num >= 0 ? num : 0;
                        }
                    }
                }
            }
            return 0;
        }
        private int JumpIndex()
        {
            int id = model.nowTabId;
            if (!CycleHallConfig.Has(id))
                return 0;
            CycleHallConfig config = CycleHallConfig.Get(id);
            if (config.TabType == 1)
            {
                return JumpMissionIndex();
            }
            else if (config.TabType == 2)
            {
                return JumpGiftIndex();
            }
            return 0;
        }
        private int JumpMissionIndex()
        {
            int id = model.nowTabId;
            if (!CycleHallConfig.Has(id))
                return 0;
            CycleHallConfig config = CycleHallConfig.Get(id);
            var act = model.GetOperationInfo();
            if (act == null || !act.TryGetRound(config.RoundType, out var round) || round.AwardList == null)
                return 0;
            for (int i = 0; i < round.AwardList.Length; i++)
            {
                var award = round.AwardList[i];
                int state = model.GetAwardState(config.RoundType, award.AwardIndex);
                if (state == 1)
                    return i;
            }
            return 0;
        }
        private int JumpGiftIndex()
        {
            int id = model.nowTabId;
            if (!CycleHallConfig.Has(id))
                return 0;
            CycleHallConfig config = CycleHallConfig.Get(id);
            var act = model.GetOperationInfo();
            if (act == null || !act.TryGetRound(config.RoundType, out var round) || round.CTGIDList == null)
                return 0;
            List<StoreConfig> _list = null;
            StoreConfig.TryGetStoreConfigs(round.ShopType, out _list);
            int storeCnt = _list == null ? 0 : _list.Count;
            for (int i = 0; i < storeCnt; i++)
            {
                int remainNum;
                storeModel.TryGetIsSellOut(_list[i], out remainNum);
                if (remainNum > 0)
                    return i;
            }
            //跳过已购买
            for (int i = 0; i < round.CTGIDList.Length; i++)
            {
                int ctgID = round.CTGIDList[i];
                var countInfo = rechargeGiftActModel.GetBuyCntInfo(ctgID);
                if (countInfo.x < countInfo.y)
                    return i + storeCnt;
            }
            return 0;
        }
        public void OnClickGo()
        {
            int id = model.nowTabId;
            if (!CycleHallConfig.Has(id))
                return;
            CycleHallConfig config = CycleHallConfig.Get(id);
            int winID;
            if (model.windowIDDict == null || !model.windowIDDict.TryGetValue(config.RoundType, out winID))
                return;
            WindowJumpMgr.Instance.WindowJumpTo((JumpUIType)winID);
        }
    }
}
System/LoopAct/CycleHall/CycleHallWin.cs.meta
New file
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 03e60155dbab8a543b9748d90b64cf2f
MonoImporter:
  externalObjects: {}
  serializedVersion: 2
  defaultReferences: []
  executionOrder: 0
  icon: {instanceID: 0}
  userData:
  assetBundleName:
  assetBundleVariant:
System/LoopAct/CycleHall/OperationCycleHall.cs
New file
@@ -0,0 +1,83 @@
using System.Collections.Generic;
namespace vnxbqy.UI
{
    //轮回殿活动
    public class OperationCycleHall : OperationBase
    {
        // <轮回类型, HAA88_tagMCActLunhuidianInfo.tagMCActLunhuidianRound>
        public Dictionary<int, HAA88_tagMCActLunhuidianInfo.tagMCActLunhuidianRound> roundInfoDict = new Dictionary<int, HAA88_tagMCActLunhuidianInfo.tagMCActLunhuidianRound>();
        public bool TryGetRound(int roundType, out HAA88_tagMCActLunhuidianInfo.tagMCActLunhuidianRound round)
        {
            round = new HAA88_tagMCActLunhuidianInfo.tagMCActLunhuidianRound { };
            if (roundInfoDict == null || !roundInfoDict.TryGetValue(roundType, out round))
                return false;
            return true;
        }
        public bool TryGetRoundInfoByIndex(int roundType, int index, out HAA88_tagMCActLunhuidianInfo.tagMCActLunhuidianAward awardInfo)
        {
            awardInfo = new HAA88_tagMCActLunhuidianInfo.tagMCActLunhuidianAward { };
            if (!TryGetRound(roundType, out var round) || round.AwardList == null)
                return false;
            for (int i = 0; i < round.AwardList.Length; i++)
            {
                if (round.AwardList[i].AwardIndex == index)
                {
                    awardInfo = round.AwardList[i];
                    return true;
                }
            }
            return true;
        }
        public bool TryGetRoundInfoByNeedValue(int roundType, int needValue, out HAA88_tagMCActLunhuidianInfo.tagMCActLunhuidianAward awardInfo)
        {
            awardInfo = new HAA88_tagMCActLunhuidianInfo.tagMCActLunhuidianAward { };
            if (!TryGetRound(roundType, out var round) || round.AwardList == null)
                return false;
            for (int i = 0; i < round.AwardList.Length; i++)
            {
                if (round.AwardList[i].NeedValue == needValue)
                {
                    awardInfo = round.AwardList[i];
                    return true;
                }
            }
            return true;
        }
        public override bool SatisfyOpenCondition()
        {
            return PlayerDatas.Instance.baseData.LV >= limitLv;
        }
        public override string ToDisplayTime()
        {
            var textBuilder = OperationTimeHepler.textBuilder;
            textBuilder.Length = 0;
            textBuilder.Append(startDate.ToDisplay());
            if (startDate != endDate)
            {
                textBuilder.Append("—");
                textBuilder.Append(endDate.ToDisplay());
            }
            return textBuilder.ToString();
        }
        public override void Reset()
        {
            base.Reset();
        }
        public void ParseCycleHallInfo(HAA88_tagMCActLunhuidianInfo package)
        {
            roundInfoDict.Clear();
            for (int i = 0; i < package.RoundList.Length; i++)
            {
                roundInfoDict[package.RoundList[i].RoundType] = package.RoundList[i];
            }
        }
    }
}
System/LoopAct/CycleHall/OperationCycleHall.cs.meta
New file
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 0808e48a7e494424ab338530cfbc9c41
MonoImporter:
  externalObjects: {}
  serializedVersion: 2
  defaultReferences: []
  executionOrder: 0
  icon: {instanceID: 0}
  userData:
  assetBundleName:
  assetBundleVariant:
System/MainInterfacePanel/HighSettingTip.cs
@@ -50,6 +50,7 @@
        [SerializeField] Button m_xg;
        [SerializeField] Button m_XY;
        [SerializeField] Button m_LHD;
        private bool isNeedTip = true;
@@ -103,6 +104,7 @@
            });
            m_xg.SetListener(() => { ModelCenter.Instance.GetModel<CelestialPalaceModel>().OpenCelestialPalaceWin(); });
            m_XY.SetListener(() => { WindowCenter.Instance.Open<FairyAffinityWin>(); });
            m_LHD.SetListener(() => { WindowCenter.Instance.Open<CycleHallWin>(); });
        }
        public void Init()
@@ -116,6 +118,7 @@
            OpenServerActivityCenter.Instance.openServerActivityStateChange += OpenServerActivityStateChange;
            m_JPBN.SetActive(NeedForWhiteModel.Instance.IsOpen());
            m_XY.SetActive(ModelCenter.Instance.GetModel<FairyAffinityLoginActModel>().IsOpen);
            m_LHD.SetActive(ModelCenter.Instance.GetModel<CycleHallActModel>().IsOpen);
            ShowNewActionButton();
        }
System/MainInterfacePanel/MainRedDot.cs
@@ -139,6 +139,8 @@
        public const int PhantasmPavilionZhanLingRepoint = 460; //幻境战令
        public const int FairyAffinityRepoint = 461; //仙缘
        public const int FairyEmbleManageRepoint = 462;//仙盟徽章管理入口红点
        public const int CycleHallRepoint = 463; //轮回殿
        public const int RedPoint_MR648 = 900; // BT功能红点 - 每日648
System/RankAction/LoginActModel.cs
@@ -18,7 +18,7 @@
        public const int activityID = (int)NewDayActivityID.LoginAct;
        public static Operation operaType = Operation.default29;
        public int actNum = 30; //对应界面
        public int actNum = 10; //对应界面
        public event Action UpdateyLoginEvent; 
        public override void Init()
System/Welfare/OperationTimeHepler.cs
@@ -1095,6 +1095,35 @@
            }
        }
        public void UpdateActLunhuidianInfo(HAA88_tagMCActLunhuidianInfo package)
        {
            OperationBase operationBase = null;
            operationDict.TryGetValue(Operation.default47, out operationBase);
            if (string.IsNullOrEmpty(package.StartDate) || string.IsNullOrEmpty(package.EndtDate))
            {
                ForceStopOperation(Operation.default47);
            }
            else
            {
                if (operationBase == null)
                {
                    operationBase = new OperationCycleHall();
                    operationDict.Add(Operation.default47, operationBase);
                }
                OperationCycleHall operation = operationBase as OperationCycleHall;
                operation.Reset();
                operation.startDate = ParseOperationDate(package.StartDate);
                operation.endDate = ParseOperationDate(package.EndtDate);
                operation.resetType = package.ResetType;
                operation.limitLv = package.LimitLV;
                operation.ParseCycleHallInfo(package);
                if (operationTimeUpdateEvent != null)
                {
                    operationTimeUpdateEvent(Operation.default47);
                }
            }
        }
        public void UpdateActGubaoInfo(HAA81_tagMCActGubaoInfo package)
        {
            OperationBase operationBase = null;
@@ -1791,11 +1820,10 @@
        default44,  //日期型活动 - 仙缘登陆,可补签
        default45,  //日期型活动 - 仙缘任务
        default46,  //日期型活动 - 仙缘礼包
        default47,
        default48,
        default49,
        default50,
        default47,  //日期型活动 - 轮回殿
        default48,
        default49,
        default50,
        max,
    }
}
System/WindowBase/ModelCenter.cs
@@ -286,6 +286,7 @@
            RegisterModel<FairyAffinityLoginActModel>();
            RegisterModel<FairyAffinityMissionActModel>();
            RegisterModel<FairyAffinityRechargeGiftActModel>();
            RegisterModel<CycleHallActModel>();
            inited = true;
        }
Utility/ConfigInitiator.cs
@@ -377,6 +377,7 @@
        normalTasks.Add(new ConfigInitTask("PlayerFacePicStar", () => { PlayerFacePicStarConfig.Init(); }, () => { return PlayerFacePicStarConfig.inited; }));
        normalTasks.Add(new ConfigInitTask("ChatBubbleBoxStar", () => { ChatBubbleBoxStarConfig.Init(); }, () => { return ChatBubbleBoxStarConfig.inited; }));
        normalTasks.Add(new ConfigInitTask("EmojiPack", () => { EmojiPackConfig.Init(); }, () => { return EmojiPackConfig.inited; }));
        normalTasks.Add(new ConfigInitTask("CycleHall", () => { CycleHallConfig.Init(); }, () => { return CycleHallConfig.inited; }));
    }
    static List<ConfigInitTask> doingTasks = new List<ConfigInitTask>();
Utility/EnumHelper.cs
@@ -1884,6 +1884,7 @@
    FairyAffinityLoginAct = 214,  //仙缘登陆活动
    FairyAffinityMissionAct = 215,  //仙缘任务活动
    FairyAffinityRechargeGiftAct = 216,  //仙缘礼包活动
    CycleHallAct = 217,  //轮回殿活动
}