少年修仙传客户端代码仓库
hch
2024-12-16 9377811d0ba27047e1e5ec2348a28eba1033d59d
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
using LitJson;
using System;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
 
namespace vnxbqy.UI
{
    public class CelestialPalaceModel : Model, IBeforePlayerDataInitialize, IPlayerLoginOk
    {
        public readonly int MoneyType = 47;         //天道币货币类型
        public readonly int StoreType = 310;        //天道币商店类型
        public readonly int FuncId = 235;           //仙宫功能Id
 
        public readonly int MaxHeaderCount = 3;     //树干天道果数量
        public readonly int MaxNormalCount = 3;     //树枝天道果数量
        public readonly int MaxTailCount = 2;       //树根天道果数量
 
        public readonly int HellLv1RowCount = 1;       //等级1宫殿总层数
        public readonly int HellLv2RowCount = 2;       //等级2宫殿总层数
        public readonly int HellLv3RowCount = 2;       //等级3宫殿总层数
        public readonly int HellLv4RowCount = 4;       //等级4宫殿总层数
        public readonly int HellLv5RowCount = 3;       //等级5宫殿总层数
 
        public int moneyItemId;     //天道币货币物品Id
        // 当前选中的页签按钮 0 仙宫 1 天道树 2 天道阁
        private int m_CurrentSelectedTabButtonType;
        public int currentSelectedTabButtonType
        {
            get { return m_CurrentSelectedTabButtonType; }
            set
            {
                m_CurrentSelectedTabButtonType = value;
                UpdateRedPoint();
                SelectedTabButtonClickedEvent?.Invoke(value);
            }
        }
 
        // 当前选中的宫殿Id
        private int m_CurrentSelectedXGId;
        public int currentSelectedXGId
        {
            get { return m_CurrentSelectedXGId; }
            set { m_CurrentSelectedXGId = value; }
        }
 
        // 当前选中的商品商店表ID
        private int m_CurrentSelectedShopGoodId;
        public int currentSelectedShopGoodId
        {
            get { return m_CurrentSelectedShopGoodId; }
            set
            {
                m_CurrentSelectedShopGoodId = value;
                SelectedShopCellClickedEvent?.Invoke();
            }
        }
 
        //每行展示的宫殿数组 int[所在行索引][排序后宫殿索引顺序]
        public int[][] hellShowArr;
        //<仙宫Id,所在行索引>  宫殿所在行索引字典
        public Dictionary<int, int> hellRowIndexDict = new Dictionary<int, int>();
        // 树冠所在行索引
        public int headerRowIndex;
        // int[树冠所在行索引,树枝方向] 树冠所在行索引
        public List<int[]> normalRowIndexList = new List<int[]>();
        // 树根所在行索引
        public int tailRowIndex;
        //<行索引,List<awardIndex>> 行索引对应奖励索引
        public Dictionary<int, List<int>> rowIndexCellDict = new Dictionary<int, List<int>>();
        //<奖励索引,行索引> 奖励索引对应行索引
        public Dictionary<int, int> awardIndexToRowIndexDict = new Dictionary<int, int>();
        // 当前气运值
        public uint nowQiYun;
        // 今日是否已点赞,指仙宫的外层点赞,非某个指定仙宫
        public bool likeStateToday;
        // <仙宫Id,今日是否点赞> 仙宫点赞状态字典
        public Dictionary<int, bool> xgLikeDict = new Dictionary<int, bool>();
        // <货币类型,总消耗数量> 货币总消耗数量字典
        public Dictionary<int, uint> xgUseTotalDict = new Dictionary<int, uint>();
        // <仙宫Id,玩家Id> 仙宫对应玩家字典
        public Dictionary<int, List<uint>> allPlayerDict = new Dictionary<int, List<uint>>();
        // <玩家Id,玩家详细信息> 所有玩家信息字典
        public Dictionary<int, Dictionary<uint, CelestialPalacePlayer>> allPlayerInfoDict = new Dictionary<int, Dictionary<uint, CelestialPalacePlayer>>();
        // <奖励索引,是否已领取> 奖励领取状态字典
        public Dictionary<int, bool> xgHaveDict = new Dictionary<int, bool>();
        // <仙宫Id,是否需要重新查询仙名录> 是否发查仙名录包字典
        public Dictionary<int, bool> xgNeedSendDict = new Dictionary<int, bool>();
 
        public event Action<int> SelectedTabButtonClickedEvent;             // 玩家点击不同页签按钮
        public event Action SelectedShopCellClickedEvent;                   // 玩家点击商店Cell
        public event Action UpdateXiangongInfoEvent;                        // 仙宫信息更新
        public event Action UpdateUseMoneyTotalInfoEvent;                   // 天道货币消耗信息更新
        public event Action UpdateXiangongNewPlayerInfoEvent;               // 仙宫新晋玩家信息更新
        public event Action UpdateXiangongRecPlayerInfoEvent;               // 仙宫仙名录玩家信息更新
        public event Action UpdateTiandaoTreeInfoEvent;                     // 天道树信息更新
        // 入口红点 458
        Redpoint mainRedPoint = new Redpoint(MainRedDot.CelestialPalaceRepoint);
        // 仙宫标签红点 4581
        Redpoint tabRedPoint1 = new Redpoint(MainRedDot.CelestialPalaceRepoint, MainRedDot.CelestialPalaceRepoint * 10 + 1);
        // 天道树标签红点 4582
        Redpoint tabRedPoint2 = new Redpoint(MainRedDot.CelestialPalaceRepoint, MainRedDot.CelestialPalaceRepoint * 10 + 2);
        // 【没使用,预留的】 天道阁标签红点 4583 
        // Redpoint tabRedPoint3 = new Redpoint(MainRedDot.CelestialPalaceRepoint, MainRedDot.CelestialPalaceRepoint * 10 + 3);
        // 每日点赞红点 4586
        Redpoint hellLikeRedPoint = new Redpoint(MainRedDot.CelestialPalaceRepoint * 10 + 1, MainRedDot.CelestialPalaceRepoint * 10 + 6);
        // 仙名录入口红点 4587
        Redpoint bookRedPoint = new Redpoint(MainRedDot.CelestialPalaceRepoint * 10 + 7);
        // 仙名录点赞红点 4588
        Redpoint bookLikeRedPoint = new Redpoint(MainRedDot.CelestialPalaceRepoint * 10 + 7, MainRedDot.CelestialPalaceRepoint * 10 + 8);
        //宫殿红点 4581001 ->4581019 <xgId,红点ID> (MainRedDot.CelestialPalaceRepoint * 10 + 1)*1000+xgid
        Dictionary<int, Redpoint> hellRedPointDict = new Dictionary<int, Redpoint>();
 
 
 
 
 
        public override void Init()
        {
            FuncOpen.Instance.OnFuncStateChangeEvent += OnFunctionStateChange;
            moneyItemId = int.Parse(FuncConfigConfig.Get("XiangongSet").Numerical3);
            hellShowArr = JsonMapper.ToObject<int[][]>(FuncConfigConfig.Get("XiangongSet").Numerical4);
            for (int i = 0; i < hellShowArr.Length; i++)
            {
                int[] rowInfo = hellShowArr[i];
                for (int j = 0; j < rowInfo.Length; j++)
                {
                    int xgId = rowInfo[j];
                    hellRowIndexDict[xgId] = i;
                }
            }
            GetRowIndex(out headerRowIndex, out normalRowIndexList, out tailRowIndex, out rowIndexCellDict, out awardIndexToRowIndexDict);
            InitHellRRedpoint();
 
        }
 
        void InitHellRRedpoint()
        {
            List<string> list = TiandaoTreeConfig.GetKeys();
            for (int i = 0; i < list.Count; i++)
            {
                int xgId = int.Parse(list[i]);
                hellRedPointDict[xgId] = new Redpoint(MainRedDot.CelestialPalaceRepoint * 10 + 1, (MainRedDot.CelestialPalaceRepoint * 10 + 1) * 1000 + xgId);
            }
 
        }
 
        public void OnBeforePlayerDataInitialize()
        {
            // 配置默认值
            currentSelectedTabButtonType = 0;
            currentSelectedXGId = 0;
            // 来自封包的数据
            likeStateToday = false;
            nowQiYun = 0;
            xgLikeDict.Clear();
            xgUseTotalDict.Clear();
            allPlayerInfoDict.Clear();
            allPlayerDict.Clear();
            xgHaveDict.Clear();
        }
 
        public void OnPlayerLoginOk()
        {
 
        }
 
        public override void UnInit()
        {
            FuncOpen.Instance.OnFuncStateChangeEvent -= OnFunctionStateChange;
        }
 
        private void OnFunctionStateChange(int obj)
        {
            if (FuncId == obj)
                UpdateRedPoint();
        }
 
        public void OpenCelestialPalaceWin()
        {
            currentSelectedTabButtonType = 0;
            currentSelectedXGId = 0;
            WindowCenter.Instance.Open<CelestialPalaceWin>();
            WindowCenter.Instance.Open<CelestialPalaceHellWin>();
            WindowCenter.Instance.Open<CelestialPalaceButtonGroupWin>();
        }
        public void JumpCelestialPalaceTreeWin()
        {
            currentSelectedTabButtonType = 1;
            currentSelectedXGId = 0;
            WindowCenter.Instance.Open<CelestialPalaceWin>();
            WindowCenter.Instance.Open<CelestialPalaceTreeWin>();
            WindowCenter.Instance.Open<CelestialPalaceButtonGroupWin>();
        }
        public void JumpCelestialPalaceShopWin()
        {
            currentSelectedTabButtonType = 2;
            currentSelectedXGId = 0;
            WindowCenter.Instance.Open<CelestialPalaceWin>();
            WindowCenter.Instance.Open<CelestialPalaceShopWin>();
            WindowCenter.Instance.Open<CelestialPalaceButtonGroupWin>();
        }
        // 点赞仙宫 发包
        public void SendA907LikePack(int xgID)
        {
            var pack = new CA907_tagCGLikeXiangong();
            pack.XiangongID = (ushort)xgID;
            GameNetSystem.Instance.SendInfo(pack);
        }
 
        // 查看仙宫仙名录 发包
        public void SendA906SeekPack(int xgID)
        {
            var pack = new CA906_tagCGQueryXiangongRecPlayers();
            pack.XiangongID = (ushort)xgID;
            GameNetSystem.Instance.SendInfo(pack);
        }
 
        // 领取天道果
        public void SendA504GetAwardPack(int awardIndex)
        {
            var pack = new CA504_tagCMPlayerGetReward();
            pack.RewardType = 75;
            pack.DataEx = (uint)awardIndex;
            GameNetSystem.Instance.SendInfo(pack);
        }
 
        // 仙宫新晋玩家信息
        public void UpdateXiangongNewPlayerInfo(HA927_tagGCXiangongNewPlayerInfo vNetData)
        {
            // 更新所有玩家信息字典
            int xgId = (int)vNetData.XiangongID;
            if (!allPlayerInfoDict.ContainsKey(xgId))
                allPlayerInfoDict[xgId] = new Dictionary<uint, CelestialPalacePlayer>();
 
            var newPlayerList = vNetData.NewPlayerList;
            for (int i = 0; i < newPlayerList.Length; i++)
            {
                uint playerId = newPlayerList[i].PlayerID;
                if (!allPlayerInfoDict[xgId].ContainsKey(playerId))
                    allPlayerInfoDict[xgId][playerId] = new CelestialPalacePlayer();
                allPlayerInfoDict[xgId][playerId].AddTime = newPlayerList[i].AddTime;
                allPlayerInfoDict[xgId][playerId].ServerID = newPlayerList[i].ServerID;
                allPlayerInfoDict[xgId][playerId].PlayerID = newPlayerList[i].PlayerID;
                allPlayerInfoDict[xgId][playerId].Name = newPlayerList[i].Name;
                allPlayerInfoDict[xgId][playerId].LV = newPlayerList[i].LV;
                allPlayerInfoDict[xgId][playerId].Job = newPlayerList[i].Job;
                allPlayerInfoDict[xgId][playerId].Face = newPlayerList[i].Face;
                allPlayerInfoDict[xgId][playerId].FacePic = newPlayerList[i].FacePic;
                allPlayerInfoDict[xgId][playerId].RealmLV = newPlayerList[i].RealmLV;
                allPlayerInfoDict[xgId][playerId].EquipShowSwitch = newPlayerList[i].EquipShowSwitch;
                allPlayerInfoDict[xgId][playerId].EquipShowID = newPlayerList[i].EquipShowID;
            }
 
            // 更新仙宫对应玩家字典
            if (!allPlayerDict.ContainsKey(xgId))
                allPlayerDict[xgId] = new List<uint>();
            for (int i = 0; i < newPlayerList.Length; i++)
            {
                uint playerId = newPlayerList[i].PlayerID;
                if (!allPlayerDict[xgId].Contains(playerId))
                    allPlayerDict[xgId].Add(playerId);
            }
 
            xgNeedSendDict[xgId] = true;
            UpdateRedPoint();
            UpdateXiangongNewPlayerInfoEvent?.Invoke();
        }
 
        // 仙宫仙名录玩家信息
        public void UpdateXiangongRecPlayerInfo(HA928_tagGCXiangongRecPlayerInfo vNetData)
        {
            int xgId = (int)vNetData.XiangongID;
            // 更新所有玩家信息字典
            if (!allPlayerInfoDict.ContainsKey(xgId))
                allPlayerInfoDict[xgId] = new Dictionary<uint, CelestialPalacePlayer>();
 
            var recPlayerList = vNetData.RecPlayerList;
            for (int i = 0; i < recPlayerList.Length; i++)
            {
                uint playerId = recPlayerList[i].PlayerID;
                if (!allPlayerInfoDict[xgId].ContainsKey(playerId))
                    allPlayerInfoDict[xgId][playerId] = new CelestialPalacePlayer();
                allPlayerInfoDict[xgId][playerId].AddTime = recPlayerList[i].AddTime;
                allPlayerInfoDict[xgId][playerId].ServerID = recPlayerList[i].ServerID;
                allPlayerInfoDict[xgId][playerId].PlayerID = recPlayerList[i].PlayerID;
                allPlayerInfoDict[xgId][playerId].Name = recPlayerList[i].Name;
                allPlayerInfoDict[xgId][playerId].LV = recPlayerList[i].LV;
                allPlayerInfoDict[xgId][playerId].Job = recPlayerList[i].Job;
                allPlayerInfoDict[xgId][playerId].Face = recPlayerList[i].Face;
                allPlayerInfoDict[xgId][playerId].FacePic = recPlayerList[i].FacePic;
                allPlayerInfoDict[xgId][playerId].RealmLV = recPlayerList[i].RealmLV;
            }
 
            // 更新仙宫对应玩家字典
 
            if (!allPlayerDict.ContainsKey(xgId))
                allPlayerDict[xgId] = new List<uint>();
            for (int i = 0; i < recPlayerList.Length; i++)
            {
                uint playerId = recPlayerList[i].PlayerID;
                if (!allPlayerDict[xgId].Contains(playerId))
                    allPlayerDict[xgId].Add(playerId);
            }
 
            xgNeedSendDict[xgId] = false;
            UpdateRedPoint();
            UpdateXiangongRecPlayerInfoEvent?.Invoke();
        }
 
        public void UpdateRedPoint()
        {
            // 重置所有红点
            mainRedPoint.state = RedPointState.None;
            tabRedPoint1.state = RedPointState.None;
            tabRedPoint2.state = RedPointState.None;
            hellLikeRedPoint.state = RedPointState.None;
            bookRedPoint.state = RedPointState.None;
            bookLikeRedPoint.state = RedPointState.None;
            var hellList = hellRedPointDict.Keys.ToList();
            for (int i = 0; i < hellList.Count; i++)
            {
                int nowxgId = hellList[i];
                hellRedPointDict[nowxgId].state = RedPointState.None;
            }
            // 有宫殿可点赞
            for (int i = 0; i < hellList.Count; i++)
            {
                int nowXGId = hellList[i];
                bool isLike = IsXGLike(nowXGId);
                bool isRoomHavePlayer = TryGetRoomNewPlayer(nowXGId, out var newPlayerList);
                if (!isLike && isRoomHavePlayer)
                {
                    hellRedPointDict[nowXGId].state = RedPointState.Simple;
                }
            }
            // 每日点赞
            if (!likeStateToday)
                hellLikeRedPoint.state = RedPointState.Simple;
 
            // 有可领取的天道果
            bool isHaveAwardbyAll = IsHaveAwardbyAll();
            if (isHaveAwardbyAll)
                tabRedPoint2.state = RedPointState.Simple;
 
            // 当前正在查看可点赞的仙宫和仙名录
            if (!XiangongConfig.Has(currentSelectedXGId))
                return;
            bool isLike1 = IsXGLike(currentSelectedXGId);
            bool isRoomHavePlayer1 = TryGetRoomNewPlayer(currentSelectedXGId, out var newPlayerList1);
            if (!isLike1 && isRoomHavePlayer1)
                bookLikeRedPoint.state = RedPointState.Simple;
        }
 
        // 仙宫信息
        public void UpdateXiangongInfo(HB114_tagMCXiangongInfo vNetData)
        {
            likeStateToday = vNetData.LikeStateToday == 1;
            for (int i = 0; i < vNetData.XiangongList.Length; i++)
            {
                int xgID = vNetData.XiangongList[i].XiangongID;
                bool isLikeStateToday = vNetData.XiangongList[i].LikeStateToday == 1;
                xgLikeDict[xgID] = isLikeStateToday;
            }
            UpdateRedPoint();
            UpdateXiangongInfoEvent?.Invoke();
        }
 
        // 天道树信息
        public void UpdateTiandaoTreeInfo(HB115_tagMCTiandaoTreeInfo vNetData)
        {
            nowQiYun = vNetData.Qiyun;
            xgHaveDict = ParseAwardStateList(vNetData.AwardStateList);
            UpdateRedPoint();
            UpdateTiandaoTreeInfoEvent?.Invoke();
        }
 
        // 累计消耗货币信息
        public void UpdateUseMoneyTotalInfo(HB116_tagMCUseMoneyTotalInfo vNetData)
        {
            for (int i = 0; i < vNetData.InfoList.Length; i++)
            {
                int moneyType = vNetData.InfoList[i].MoneyType;
                uint useTotal = vNetData.InfoList[i].UseTotal;
                xgUseTotalDict[moneyType] = useTotal;
                if (moneyType == MoneyType)
                {
                    UpdateRedPoint();
                    UpdateUseMoneyTotalInfoEvent?.Invoke();
                }
 
            }
        }
 
        // 解析奖励索引对应的领取状态
        Dictionary<int, bool> ParseAwardStateList(uint[] AwardStateList)
        {
            Dictionary<int, bool> xgHaveDict = new Dictionary<int, bool>();
            for (int i = 0; i < AwardStateList.Length; i++)
            {
                uint currentState = AwardStateList[i];
                for (int j = 0; j < 31; j++)
                {
                    int awardIndex = i * 31 + j;
                    bool isReceived = (currentState & (1U << j)) != 0;
                    xgHaveDict[awardIndex] = isReceived;
                }
            }
            return xgHaveDict;
        }
 
        // 判断当前仙宫是否需要重新发包获取数据
        public bool IsNeedSendA906Pack(int xgId)
        {
            if (!xgNeedSendDict.TryGetValue(xgId, out bool isNeed))
                return true;
            return isNeed;
        }
 
        // 获取当前这档天道果的显示状态 0 不可领取(未达成) 1 可领取 2 已领取
        public int GetGainState(int awardIndex)
        {
            // 已达成
            if (IsAwardArrive(awardIndex))
            {
                //可领取?
                return IsHaveAward(awardIndex) ? 2 : 1;
            }
            else
            {
                return 0;
            }
        }
 
        // 当前天道果的所需值是否达成
        public bool IsAwardArrive(int awardIndex)
        {
            return TiandaoTreeConfig.Has(awardIndex) ? nowQiYun >= TiandaoTreeConfig.Get(awardIndex).NeedQiyun : false;
        }
 
        // 当前天道果的奖励是否领取
        public bool IsHaveAward(int awardIndex)
        {
            return xgHaveDict != null && xgHaveDict.TryGetValue(awardIndex, out bool isHave) ? isHave : false;
        }
 
        //当前是否有可领取的天道果
        public bool IsHaveAwardbyAll()
        {
            if (xgHaveDict == null) return false;
            var list = TiandaoTreeConfig.GetKeys();
            for (int i = 0; i < list.Count; i++)
            {
                int awardIndex = int.Parse(list[i]);
                if (GetGainState(awardIndex) == 1)
                    return true;
            }
            return false;
        }
 
        // 当前这档奖励多少个天道果
        public int GetAwardCount(int awardIndex)
        {
            if (!TiandaoTreeConfig.Has(awardIndex))
                return 0;
            TiandaoTreeConfig config = TiandaoTreeConfig.Get(awardIndex);
            int count = 0;
            int[][] awardArr = config.AwardItemList;
            for (int i = 0; i < awardArr.Length; i++)
            {
                if (awardArr[i][0] == moneyItemId)
                {
                    count += awardArr[i][1];
                }
            }
            return count;
        }
 
        // 尝试自动领取天道果 并返回排序的奖励列表  true 有天道果能被自动领取 false 没有天道果能被自动领取
        public bool TryAutoHaveAward(out List<Item> awardList)
        {
            awardList = new List<Item>();
            bool isHave = false;
            // <物品id,物品数量> 奖励物品信息字典
            Dictionary<int, int> tempDict = new Dictionary<int, int>();
            //发包索引列表
            List<int> allAwardItemList = new List<int>();
            List<int> xgHaveList = xgHaveDict.Keys.ToList();
 
            for (int i = 0; i < xgHaveList.Count; i++)
            {
                int index = xgHaveList[i];
                if (!TiandaoTreeConfig.Has(index)) continue;
                int state = GetGainState(index);
                if (state == 1)
                {
                    isHave = true;
                    if (!allAwardItemList.Contains(index))
                        allAwardItemList.Add(index);
                    var awardItemList = TiandaoTreeConfig.Get(index).AwardItemList;
                    for (int j = 0; j < awardItemList.Length; j++)
                    {
                        int itemId = awardItemList[j][0];
                        int count = awardItemList[j][1];
                        if (!tempDict.ContainsKey(itemId))
                        {
                            tempDict[itemId] = count;
                        }
                        else
                        {
                            tempDict[itemId] += count;
                        }
                    }
                }
            }
 
            if (isHave)
            {
                for (int i = 0; i < allAwardItemList.Count; i++)
                    SendA504GetAwardPack(allAwardItemList[i]);
 
                var list = tempDict.Keys.ToList();
                list.Sort((a, b) => SortByItemColor(a, b, tempDict));
                for (int i = 0; i < list.Count; i++)
                {
                    int itemId = list[i];
                    int allCount = tempDict[itemId];
                    awardList.Add(new Item() { id = itemId, count = allCount });
                }
            }
 
            return isHave;
        }
 
 
        int SortByItemColor(int a, int b, Dictionary<int, int> tempDict)
        {
            int count1 = tempDict[a];
            int count2 = tempDict[b];
            int quality1 = ItemConfig.Get(a).ItemColor;
            int quality2 = ItemConfig.Get(b).ItemColor;
 
            //品质高的排在前面
            if (quality1 != quality2)
            {
                return quality2.CompareTo(quality1);
            }
 
            // 品质相同时,数量多的排在前面
            if (count1 != count2)
            {
                return count2.CompareTo(count1);
            }
 
            // 如果品质和数量都相同,保持原有顺序
            return 0;
        }
 
        // 获得树冠,树枝,树根的行数和方向
        public void GetRowIndex(out int headerRowIndex, out List<int[]> normalRowIndexList, out int tailRowIndex, out Dictionary<int, List<int>> rowIndexCellDict, out Dictionary<int, int> awardIndexToRowIndexDict)
        {
            headerRowIndex = 0;
            normalRowIndexList = new List<int[]>();
            tailRowIndex = 0;
            awardIndexToRowIndexDict = new Dictionary<int, int>();
            rowIndexCellDict = new Dictionary<int, List<int>>();
            List<string> list = TiandaoTreeConfig.GetKeys();
            //树冠在第0行 有3个果实
            int rowIndex = 0;
            int count = list.Count;
            rowIndexCellDict[rowIndex] = new List<int>();
            for (int i = 0; i < MaxHeaderCount; i++)
            {
                int awardIndex = count - i;
                rowIndexCellDict[rowIndex].Add(awardIndex);
                awardIndexToRowIndexDict[awardIndex] = rowIndex;
            }
            rowIndexCellDict[rowIndex].Sort();
            rowIndexCellDict[rowIndex].Reverse();
            count -= MaxHeaderCount;
            headerRowIndex = rowIndex;
 
            //一节树干有3个果实 由两节树干组成
            count -= MaxTailCount;
            count /= MaxNormalCount;
            for (int i = 0; i < count; i++)
            {
                rowIndex += 1;
                normalRowIndexList.Add(new int[2] { rowIndex, i % 2 == 1 ? 0 : 1 });
                rowIndexCellDict[rowIndex] = new List<int>();
                for (int j = MaxNormalCount - 1; j >= 0; j--)
                {
                    int awardIndex = (j + list.Count - MaxTailCount) - rowIndex * MaxNormalCount;
                    rowIndexCellDict[rowIndex].Add(awardIndex);
                    awardIndexToRowIndexDict[awardIndex] = rowIndex;
                }
                rowIndexCellDict[rowIndex].Sort();
                rowIndexCellDict[rowIndex].Reverse();
            }
            //树根在最后一行 有2个果实
            rowIndex += 1;
            tailRowIndex = rowIndex;
            rowIndexCellDict[rowIndex] = new List<int>();
            for (int i = MaxTailCount - 1; i >= 0; i--)
            {
                int awardIndex = i + 1;
                rowIndexCellDict[rowIndex].Add(awardIndex);
                awardIndexToRowIndexDict[awardIndex] = rowIndex;
            }
            rowIndexCellDict[rowIndex].Sort();
            rowIndexCellDict[rowIndex].Reverse();
        }
 
        // 获取领取到了哪一层
        public int GetJumpRowIndex()
        {
            int lastRowIndex = tailRowIndex;//玩家最后可领取所在层,默认是最后一层
            List<int> xgHaveList = xgHaveDict.Keys.ToList();
            for (int i = 0; i < xgHaveList.Count; i++)
            {
                int awardIndex = xgHaveList[i];
                if (!TiandaoTreeConfig.Has(awardIndex)) continue;
                int state = GetGainState(awardIndex);
                if (state == 1 || state == 2)
                {
                    if (awardIndexToRowIndexDict != null && awardIndexToRowIndexDict.TryGetValue(awardIndex, out int rowIndex))
                    {
                        lastRowIndex = rowIndex;
                    }
                }
            }
            return Mathf.Max(lastRowIndex, 0);
        }
 
        // 获取总共消耗了多少天道果
        public uint GetAllCostCount()
        {
            return xgUseTotalDict != null && xgUseTotalDict.TryGetValue(MoneyType, out uint count) ? count : 0;
        }
 
        // 当前仙宫今日是否点赞
        public bool IsXGLike(int xgId)
        {
            return xgLikeDict != null && xgLikeDict.TryGetValue(xgId, out bool isLike) ? isLike : false;
        }
 
        // 当前玩家是指定仙宫的新晋仙官吗
        public bool IsNewPlayer(int xgId, uint nowPlayerId)
        {
            if (!TryGetRoomNewPlayer(xgId, out var newPlayerList) || newPlayerList == null)
                return false;
            return newPlayerList.Contains(nowPlayerId);
        }
 
        // 当前宫殿是否有新晋仙官 并返回新晋仙官playerId列表
        public bool TryGetRoomNewPlayer(int xgId, out List<uint> newPlayerList)
        {
            newPlayerList = new List<uint>();
            var serverNow = TimeUtility.GetTodayStartTime(); // 获取服务器当前时间的当天0点
            if (!XiangongConfig.Has(xgId) || allPlayerDict == null || !allPlayerDict.TryGetValue(xgId, out var list) || list == null || allPlayerInfoDict == null || !allPlayerInfoDict.TryGetValue(xgId, out var xgInfo) || xgInfo == null)
                return false;
            for (int i = 0; i < list.Count; i++)
            {
                if (!xgInfo.TryGetValue(list[i], out var celestialPalacePlayer) || celestialPalacePlayer == null)
                    continue;
                uint showTimes = (uint)XiangongConfig.Get(xgId).ShowDays;
                // 获取玩家晋升的时间点,并取该天的开始时间(0点)
                var addTime = TimeUtility.GetTime((uint)(celestialPalacePlayer.AddTime));
                var overTime = TimeUtility.GetDayStartTime(addTime.Year, addTime.Month, addTime.Day);
                // 计算展示期的结束时间
                overTime = overTime.AddDays(showTimes);
                // 比较展示期结束时间是否还在当前时间之后
                if (overTime > serverNow)
                    newPlayerList.Add(list[i]);
            }
 
            return newPlayerList.Count > 0;
        }
 
        // 获得排序后的指定仙宫的所有玩家详细信息(仙名录)
        public List<CelestialPalacePlayer> GetSortXGPlayInfo(int xgId)
        {
            List<CelestialPalacePlayer> xgPlayerList = GetXGPlayInfo(xgId);
            xgPlayerList.Sort(SortPlayInfoByAddTime);
            return xgPlayerList;
        }
 
        // 获得指定仙宫的所有玩家详细信息(仙名录)
        public List<CelestialPalacePlayer> GetXGPlayInfo(int xgId)
        {
            List<CelestialPalacePlayer> xgPlayerList = new List<CelestialPalacePlayer>();
            if (allPlayerDict == null || !allPlayerDict.TryGetValue(xgId, out var playerIdList) || !allPlayerInfoDict.TryGetValue(xgId, out var xgInfo) || xgInfo == null)
                return xgPlayerList;
            for (int i = 0; i < playerIdList.Count; i++)
            {
                uint playerId = playerIdList[i];
                if (!xgInfo.TryGetValue(playerId, out var celestialPalacePlayerInfo))
                    continue;
                xgPlayerList.Add(celestialPalacePlayerInfo);
            }
            return xgPlayerList;
        }
 
        // 根据新晋时间戳排序仙名录
        public int SortPlayInfoByAddTime(CelestialPalacePlayer a, CelestialPalacePlayer b)
        {
            return TimeUtility.GetTime(b.AddTime).CompareTo(TimeUtility.GetTime(a.AddTime));
        }
 
        //展示称号
        public void ShowTitle(int titleId, ImageEx imgTitle)
        {
            DienstgradConfig config = DienstgradConfig.Get(titleId);
            UIFrame frame = imgTitle.GetComponent<UIFrame>();
            if (UIFrameMgr.Inst.ContainsDynamicImage(config.Image))
            {
                if (frame == null) frame = imgTitle.gameObject.AddComponent<UIFrame>();
                imgTitle.raycastTarget = false;
                frame.ResetFrame(config.Image);
                frame.enabled = true;
            }
            else
            {
                if (frame != null) frame.enabled = false;
                imgTitle.SetSprite(config.Image);
            }
        }
 
        // 获取当前时间戳的年/月/日字符串
        public string GetAddTimeToYearMonthDay(uint AddTime)
        {
            var time = TimeUtility.GetTime(AddTime);
            return Language.Get("CelestialPalace10", time.Year, time.Month, time.Day);
        }
 
        public int GetItemId(RoleEquipType type, uint[] equipShowID)
        {
            if (equipShowID != null)
            {
                foreach (var id in equipShowID)
                {
                    var itemConfig = ItemConfig.Get((int)id);
                    if (itemConfig != null && itemConfig.EquipPlace == (int)type)
                    {
                        return (int)id;
                    }
                }
            }
            return 0;
        }
 
        //获得当前层索引的宫殿等级  返回0说明错误,否则返回1-5
        public int GetRowIndexLV(int rowIndex)
        {
            int[] rowCounts = new int[] { HellLv1RowCount, HellLv2RowCount, HellLv3RowCount, HellLv4RowCount, HellLv5RowCount };
            int cumulativeRows = 0;
            for (int i = 0; i < rowCounts.Length; i++)
            {
                cumulativeRows += rowCounts[i];
                if (rowIndex < cumulativeRows)
                {
                    return i + 1; // 等级是从1开始的
                }
            }
            return 0; // 如果索引不在范围内,返回0表示错误
        }
 
        //跳转到最近宫殿红点索引
        public int JumpToCanLikeHellRowIndex()
        {
            // 有宫殿可点赞
            var hellList = hellRedPointDict.Keys.ToList();
            for (int i = 0; i < hellList.Count; i++)
            {
                int nowXGId = hellList[i];
                bool isLike = IsXGLike(nowXGId);
                bool isRoomHavePlayer = TryGetRoomNewPlayer(nowXGId, out var newPlayerList);
                if (!isLike && isRoomHavePlayer)
                {
                    if (hellRowIndexDict.ContainsKey(nowXGId))
                    {
                        return hellRowIndexDict[nowXGId];
                    }
                }
            }
            return 0;
        }
    }
 
 
}
public class CelestialPalacePlayer
{
    public uint AddTime;             // 新晋时间戳
    public uint ServerID;
    public uint PlayerID;
    public string Name;             // 玩家名,size = NameLen
    public ushort LV;               // 玩家等级
    public byte Job;                // 玩家职业
    public ushort RealmLV;          // 玩家境界
    public uint EquipShowSwitch;
    public uint[] EquipShowID;
    public uint Face;        //基本脸型
    public uint FacePic;        //头像框
}