少年修仙传客户端代码仓库
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
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
using LitJson;
using System;
using System.Collections.Generic;
using System.Linq;
using vnxbqy.UI;
 
 
public class CrossServerGodBattleFieldAssortModel : Model, IBeforePlayerDataInitialize, IPlayerLoginOk
{
    public readonly uint FuncMapID = 32060;                     //古神战场组队功能地图ID
    public readonly uint FuncMapEx = 0;
    public readonly byte QueryCount = 20;                       //查询条数
 
    //当前展示中的类型
    public uint HaveSpace = 1;                         // 是否只查看有空位置的队伍
    public uint IDLimitType = 0;                       // ID限制类型:1-同仙盟队长;2-同ServerGroupID队长;3-同ServerID队长
    //<索引,<队伍ID,队伍信息>> 所有队伍信息字典
    //索引 = FuncMapID * 1000 + FuncMapEx     分辨是哪个功能的 古神战场组队是32060000
    Dictionary<uint, Dictionary<uint, AssortTeamInfo>> assortTeamInfoDict = new Dictionary<uint, Dictionary<uint, AssortTeamInfo>>();
    //<索引,<类型,队伍ID列表>> 队伍信息的所属类型
    //类型 = HaveSpace * 1000 + IDLimitType   
    Dictionary<uint, Dictionary<uint, List<uint>>> assortFindTypeTeamIdDict = new Dictionary<uint, Dictionary<uint, List<uint>>>();
    Dictionary<uint, PlayerOnlineStateInfo> playerOnlineStateInfoDict = new Dictionary<uint, PlayerOnlineStateInfo>();
 
    public uint StartIndex;         // 查看的起始索引, 默认0
    public byte QueryCnt;           // 查看条数,默认20,最大不超过100
    public byte SearchLen;
    public string SearchMsg;        // 指定搜索时有用,可搜索指定队伍ID或模糊搜索队伍名称,搜索时返回最多QueryCnt个数的队伍
    public uint LoopIndex;          // 服务器检索到的索引,列表下拉时下一个查询包的StartIndex从这个LoopIndex开始
    public byte TeamCount;          // 如果返回的队伍数小于QueryCnt,代表服务器已经没有满足条件的队伍了,列表再下拉时不再发查询包
 
    public bool isOnlyServerGroupIDLeader = false;              //是否经查看自己服务器的队长    
    public bool isAutoJoin = false;                             //是否允许自动加入    
    public bool isSendB924Pack = false;
    public long nowPowerNum;                                    //玩家设定多少战力才能加入
    public int lastWorldChannelTime;                               //上次点击世界频道按钮的时间
    public int lastCrossServiceChannelTime;                       //上次点击跨服频道按钮的时间
    public int worldChannelTimeCD;                               //上次点击世界频道按钮的时间,秒
    public int crossServiceChannelTimeCD;                       //上次点击跨服频道按钮的时间,秒
 
    public bool isDisplayRedPoint = true;
 
    public event Action UpdateQueryPlayerFuncTeamRetInfoEvent;  //玩家没有队伍
    public event Action UpdateTeamInfoEvent;                    //队伍信息更新
    public event Action UpdateFindInfoEvent;                    //队伍查找信息更新
    public event Action UpdateTeamDissolveEvent;                //队伍销毁
    public event Action UpdatePlayerOnlineStateInfoEvent;       //玩家在线状态变化
 
    public event Action AddScrollerEvent;                    //增加项
 
    Redpoint entranceRedPoint = new Redpoint(21304, MainRedDot.CrossServerGodBattleFieldAssort);                        //队伍入口红点
    Redpoint manageRedPoint = new Redpoint(MainRedDot.CrossServerGodBattleFieldAssort, MainRedDot.CrossServerGodBattleFieldAssort * 10 + 1);     //申请审理按钮红点
    DailyQuestModel dailyQuestModel { get { return ModelCenter.Instance.GetModel<DailyQuestModel>(); } }
    RankModel rankModel { get { return ModelCenter.Instance.GetModel<RankModel>(); } }
 
    public override void Init()
    {
        rankModel.onRankRefresh += UpdatePlayerBillboardEvent;
        ILCrossServerModel.Instance.onSelectUpdate += OnSelectUpdate;
        dailyQuestModel.dailyQuestProgressUpdateEvent += DailyQuestProgressUpdateEvent;
        worldChannelTimeCD = int.Parse(FuncConfigConfig.Get("GodBattleFieldAssort").Numerical1);
        crossServiceChannelTimeCD = int.Parse(FuncConfigConfig.Get("GodBattleFieldAssort").Numerical2);
    }
 
    public override void UnInit()
    {
        rankModel.onRankRefresh -= UpdatePlayerBillboardEvent;
        ILCrossServerModel.Instance.onSelectUpdate -= OnSelectUpdate;
        dailyQuestModel.dailyQuestProgressUpdateEvent -= DailyQuestProgressUpdateEvent;
    }
 
    public void OnBeforePlayerDataInitialize()
    {
        //清除所有封包
        assortTeamInfoDict.Clear();
        assortFindTypeTeamIdDict.Clear();
        //选项赋初始值
        isOnlyServerGroupIDLeader = false;
        isSendB924Pack = false;
        isDisplayRedPoint = true;
    }
 
    public void OnPlayerLoginOk()
    {
        LoadAllTime();
        LoadPowerNum();
        isAutoJoin = LocalSave.GetBool(StringUtility.Contact("gszczd_toggle1_", PlayerDatas.Instance.baseData.PlayerID));
        TrySendQueryPlayerFuncTeam();
    }
 
    //保证只发一次B924包
    public void TrySendQueryPlayerFuncTeam()
    {
        if (isSendB924Pack)
            return;
        //没开古神战场
        if (!FuncOpen.Instance.IsFuncOpen(208))
            return;
        SendQueryPlayerFuncTeam(FuncMapID);
        isSendB924Pack = true;
    }
 
    //尝试获得指定索引的所有队伍字典
    public bool TryGetTeamInfoDict(out Dictionary<uint, AssortTeamInfo> teamInfoDict)
    {
        teamInfoDict = null; // 初始化输出参数为 null
        uint index = FuncMapID * 1000 + FuncMapEx;
        if (assortTeamInfoDict.IsNullOrEmpty())
            return false;
        if (!assortTeamInfoDict.TryGetValue(index, out teamInfoDict))
            return false;
        return true;
    }
 
    //尝试获得古神战场的所有队伍类型信息
    public bool TryGetTeamTypeDict(out Dictionary<uint, List<uint>> teamTypeDict)
    {
        teamTypeDict = null; // 初始化输出参数为 null
        uint index = FuncMapID * 1000 + FuncMapEx;
        if (assortFindTypeTeamIdDict.IsNullOrEmpty())
            return false;
        if (!assortFindTypeTeamIdDict.TryGetValue(index, out teamTypeDict))
            return false;
        return true;
    }
 
    //尝试获取指定类型的队伍id列表
    public bool TryGetTeamTypeList(uint haveSpace, uint iDLimitType, out List<uint> teamTypeList)
    {
        teamTypeList = null;
        if (!TryGetTeamTypeDict(out Dictionary<uint, List<uint>> teamTypeDict))
            return false;
        uint type = haveSpace * 1000 + iDLimitType;
        if (!teamTypeDict.TryGetValue(type, out teamTypeList))
            return false;
        return true;
    }
 
    //清除寻找队伍指定类型的列表
    public void ClearTeamTypeList()
    {
        if (!TryGetTeamTypeDict(out var teamTypeDict))
            return;
        teamTypeDict.Clear();
    }
 
    /// <summary>
    /// 获取玩家所在的队伍信息
    /// </summary>
    /// <param name="isCaptainID">玩家是不是所在的队伍的队长</param>
    /// <param name="teamID">玩家所在队伍的teamID</param>
    /// <param name="teamInfo">玩家所在队伍的详细信息</param>
    /// <returns>返回false说明玩家没有队伍</returns>
    public bool TryGetPlayerTeamInfo(out bool isCaptain, out uint teamID, out AssortTeamInfo teamInfo)
    {
        isCaptain = false;
        teamID = 0;
        teamInfo = null;
 
        if (!TryGetTeamInfoDict(out var teamInfoDict))
            return false;
 
        var keyArray = teamInfoDict.Keys.ToArray();
        for (int i = 0; i < keyArray.Length; i++)
        {
            uint nowTeamID = keyArray[i];
            var team = teamInfoDict[nowTeamID];
            uint captainID = team.CaptainID;
            var memberDict = team.MemberDict;
 
            if (memberDict.ContainsKey(PlayerDatas.Instance.baseData.PlayerID))
            {
                isCaptain = captainID == PlayerDatas.Instance.baseData.PlayerID;
                teamID = nowTeamID;
                teamInfo = team;
                return true;
            }
        }
 
        return false;
    }
 
    //尝试获得指定teamID的队伍信息
    public bool TryGetTeamInfo(uint teamID, out AssortTeamInfo teamInfo)
    {
        teamInfo = null;
        if (!TryGetTeamInfoDict(out var teamInfoDict))
            return false;
        if (!teamInfoDict.TryGetValue(teamID, out teamInfo))
            return false;
        return true;
    }
 
    //尝试获得队长信息
    public bool TryGetTeamCaptainMemberInfo(AssortTeamInfo teamInfo, out AssortMemberInfo memberInfo)
    {
        memberInfo = null;
        uint captainID = teamInfo.CaptainID;
        if (teamInfo.MemberDict.IsNullOrEmpty())
            return false;
        if (!teamInfo.MemberDict.TryGetValue(captainID, out memberInfo))
            return false;
        return true;
    }
 
    //获得指定队伍成员的总战力
    public ulong GetTeamTotalPower(AssortTeamInfo teamInfo)
    {
        if (teamInfo.MemberDict.IsNullOrEmpty())
            return 0;
        ulong result = 0;
        var keyArray = teamInfo.MemberDict.Keys.ToArray();
        for (int i = 0; i < keyArray.Length; i++)
        {
            uint playerId = keyArray[i];
            var members = teamInfo.MemberDict[playerId];
            result += members.FightPower;
        }
        return result;
    }
 
    public List<uint> GetApplicantSortList(List<uint> list)
    {
        int sortType = FunctionTeamSetConfig.Get((int)FuncMapID).SortType;
        int sortReverse = FunctionTeamSetConfig.Get((int)FuncMapID).SortReverse;
        //按队员总战力排序 倒序
        if (sortType == 1 && sortReverse == 1)
        {
            list.Sort(CmpApplicantTeamByPower);
        }
        //按队员总战力排序 正序
        else if (sortType == 1 && sortReverse == 0)
        {
            list.Sort(CmpApplicantTeamByPower);
            list.Reverse();
        }
        //按队伍创建顺序排序 倒序
        else if (sortType == 0 && sortReverse == 1)
        {
            list.Sort(CmpApplicantTeamByCreateTime);
        }
        //按队伍创建顺序排序 正序
        else
        {
            list.Sort(CmpApplicantTeamByCreateTime);
            list.Reverse();
        }
        return list;
    }
 
    int CmpApplicantTeamByPower(uint a, uint b)
    {
        ulong fightPower1;
        ulong fightPower2;
        TryGetPlayerTeamInfo(out bool isCaptain, out uint teamID, out AssortTeamInfo teamInfo);
        fightPower1 = teamInfo.ApplicantDict[a].FightPower;
        fightPower2 = teamInfo.ApplicantDict[b].FightPower;
        if (fightPower1 > fightPower2)
        {
            return -1;
        }
        else if (fightPower1 < fightPower2)
        {
            return 1;
        }
        else
        {
            return 0;
        }
 
    }
 
    int CmpApplicantTeamByCreateTime(uint a, uint b)
    {
        uint createTime1;
        uint createTime2;
        TryGetPlayerTeamInfo(out bool isCaptain, out uint teamID, out AssortTeamInfo teamInfo);
        createTime1 = teamInfo.CreateTime;
        createTime2 = teamInfo.CreateTime;
        if (createTime1 > createTime2)
        {
            return -1;
        }
        else if (createTime1 < createTime2)
        {
            return 1;
        }
        else
        {
            return 0;
        }
 
    }
    public List<uint> GetShowList()
    {
        //获得当前的类型的队伍id
        List<uint> teamTypeList;
        if (!TryGetTeamTypeList(HaveSpace, IDLimitType, out teamTypeList))
            teamTypeList = new List<uint>();
        teamTypeList = GetTeamSortList(teamTypeList); // 排序:战力高的在前
 
        //获得玩家所有正在申请中的队伍
        var requestTeamList = GetPlayerRequestTeam();
        requestTeamList = GetTeamSortList(requestTeamList); // 排序:战力高的在前
 
        // 从 teamTypeList 中移除所有正在申请中的队伍,并添加到 containsList 中
        for (int i = 0; i < requestTeamList.Count; i++)
        {
            uint teamID = requestTeamList[i];
            if (teamTypeList.Contains(teamID))
            {
                teamTypeList.Remove(teamID);
            }
        }
 
        // 将正在申请的队伍插入到列表头部,保持排序顺序
        for (int i = requestTeamList.Count - 1; i >= 0; i--)
        {
            uint teamID = requestTeamList[i];
            teamTypeList.Insert(0, teamID);
        }
 
        return teamTypeList;
    }
    public List<uint> GetTeamSortList(List<uint> list)
    {
        int sortType = FunctionTeamSetConfig.Get((int)FuncMapID).SortType;
        int sortReverse = FunctionTeamSetConfig.Get((int)FuncMapID).SortReverse;
        //按队员总战力排序 倒序
        if (sortType == 1 && sortReverse == 1)
        {
            list.Sort(CmpTeamByPower);
        }
        //按队员总战力排序 正序
        else if (sortType == 1 && sortReverse == 0)
        {
            list.Sort(CmpTeamByPower);
            list.Reverse();
        }
        //按队伍创建顺序排序 倒序
        else if (sortType == 0 && sortReverse == 1)
        {
            list.Sort(CmpTeamByCreateTime);
        }
        //按队伍创建顺序排序 正序
        else
        {
            list.Sort(CmpTeamByCreateTime);
            list.Reverse();
        }
        return list;
    }
    int CmpTeamByPower(uint a, uint b)
    {
        ulong fightPower1;
        ulong fightPower2;
        TryGetTeamInfo(a, out AssortTeamInfo teamInfo1);
        TryGetTeamInfo(b, out AssortTeamInfo teamInfo2);
        fightPower1 = GetTeamTotalPower(teamInfo1);
        fightPower2 = GetTeamTotalPower(teamInfo2);
        if (fightPower1 > fightPower2)
        {
            return -1;
        }
        else if (fightPower1 < fightPower2)
        {
            return 1;
        }
        else
        {
            return 0;
        }
 
    }
 
    int CmpTeamByCreateTime(uint a, uint b)
    {
        uint createTime1;
        uint createTime2;
        TryGetTeamInfo(a, out AssortTeamInfo teamInfo1);
        TryGetTeamInfo(b, out AssortTeamInfo teamInfo2);
        createTime1 = teamInfo1.CreateTime;
        createTime2 = teamInfo2.CreateTime;
        if (createTime1 > createTime2)
        {
            return -1;
        }
        else if (createTime1 < createTime2)
        {
            return 1;
        }
        else
        {
            return 0;
        }
 
    }
    public bool TryGetPlayerRequestTeam(out List<uint> teamInfoList)
    {
        teamInfoList = new List<uint>();
        if (!TryGetTeamInfoDict(out var teamInfoDict))
            return false;
        var keyArray = teamInfoDict.Keys.ToArray();
        for (int i = 0; i < keyArray.Length; i++)
        {
            uint teamID = keyArray[i];
            var team = teamInfoDict[teamID];
            uint captainID = team.CaptainID;
            var applyIDList = team.ApplyIDList;
            if (!applyIDList.IsNullOrEmpty() && applyIDList.Contains(PlayerDatas.Instance.baseData.PlayerID))
            {
                teamInfoList.Add(teamID);
            }
        }
        return false;
    }
 
    //获取玩家所有正在申请中的队伍ID
    public List<uint> GetPlayerRequestTeam()
    {
        List<uint> result = new List<uint>();
        if (TryGetTeamInfoDict(out var teamInfoDict))
        {
            var keyArray = teamInfoDict.Keys.ToArray();
            for (int i = 0; i < keyArray.Length; i++)
            {
                uint teamID = keyArray[i];
                var team = teamInfoDict[teamID];
                var applyIDList = team.ApplyIDList;
                if (!applyIDList.IsNullOrEmpty() && applyIDList.Contains(PlayerDatas.Instance.baseData.PlayerID))
                {
                    result.Add(teamID);
                }
            }
        }
        return result;
    }
 
    //这个队伍是否在申请中
    public bool IsRequest(uint teamID)
    {
        if (TryGetTeamInfoDict(out var teamInfoDict))
        {
            var keyArray = teamInfoDict.Keys.ToArray();
            for (int i = 0; i < keyArray.Length; i++)
            {
                uint nowTeamID = keyArray[i];
                if (teamID == nowTeamID)
                {
                    var team = teamInfoDict[teamID];
                    var applyIDList = team.ApplyIDList;
                    if (!applyIDList.IsNullOrEmpty() && applyIDList.Contains(PlayerDatas.Instance.baseData.PlayerID))
                    {
                        return true;
                    }
                }
 
            }
        }
        return false;
    }
 
    // 发送B920 创建功能队伍包
    public void SendCreateFuncTeam(uint funcMapID, uint funcMapEx, string teamName, ushort minLV, uint minFightPower, uint minFightPowerEx, byte serverOnly, byte needCheck)
    {
        var pack = new CB920_tagCGCreateFuncTeam();
        pack.FuncMapID = funcMapID;
        pack.FuncMapEx = funcMapEx;
        pack.TeamName = teamName;
        pack.NameLen = (byte)teamName.Length;
        pack.MinLV = minLV;
        pack.MinFightPower = minFightPower;
        pack.MinFightPowerEx = minFightPowerEx;
        pack.ServerOnly = serverOnly;
        pack.NeedCheck = needCheck;
        GameNetSystem.Instance.SendInfo(pack);
    }
 
    // 发送B921 修改功能队伍包
    public void SendChangeFuncTeam(uint teamID, uint funcMapID, ushort minLV, uint minFightPower, uint minFightPowerEx, byte serverOnly, byte needCheck)
    {
        var pack = new CB921_tagCGChangeFuncTeam();
        pack.TeamID = teamID;
        pack.FuncMapID = funcMapID;
        pack.MinLV = minLV;
        pack.MinFightPower = minFightPower;
        pack.MinFightPowerEx = minFightPowerEx;
        pack.ServerOnly = serverOnly;
        pack.NeedCheck = needCheck;
        GameNetSystem.Instance.SendInfo(pack);
    }
 
    // 发送B922 功能队伍成员操作
    public void SendFuncTeamMemOP(uint teamID, uint funcMapID, byte oPType, uint oPData = 0)
    {
        var pack = new CB922_tagCGFuncTeamMemOP();
        pack.TeamID = teamID;
        pack.FuncMapID = funcMapID;
        pack.OPType = oPType;
        pack.OPData = oPData;
        GameNetSystem.Instance.SendInfo(pack);
    }
 
    // 发送B923 查找功能队伍列表
    public void SendQueryFuncTeam(uint funcMapID, uint funcMapEx, uint startIndex, byte queryCnt, byte haveSpace, byte iDLimitType, string searchMsg = "")
    {
 
        var pack = new CB923_tagCGQueryFuncTeam();
        pack.FuncMapID = funcMapID;
        pack.FuncMapEx = funcMapEx;
        pack.StartIndex = startIndex;
        pack.QueryCnt = queryCnt;
        pack.HaveSpace = haveSpace;
        pack.IDLimitType = iDLimitType;
        pack.SearchMsg = searchMsg;
        pack.SearchLen = (byte)searchMsg.Length;
        GameNetSystem.Instance.SendInfo(pack);
    }
 
    // 发送B924 查找玩家功能队伍
    public void SendQueryPlayerFuncTeam(uint funcMapID)
    {
        var pack = new CB924_tagCGQueryPlayerFuncTeam();
        pack.FuncMapID = funcMapID;
        GameNetSystem.Instance.SendInfo(pack);
    }
 
    public void UpdateFuncTeamRefreshInfo(HB920_tagGCFuncTeamRefresh pack)
    {
        uint index = pack.FuncMapID * 1000 + pack.FuncMapEx;
 
        if (!assortTeamInfoDict.TryGetValue(index, out var assortTeamInfo))
        {
            assortTeamInfo = new Dictionary<uint, AssortTeamInfo>();
            assortTeamInfoDict[index] = assortTeamInfo;
        }
 
        if (!assortTeamInfo.TryGetValue(pack.TeamID, out var teamInfo))
        {
            teamInfo = new AssortTeamInfo();
            assortTeamInfo[pack.TeamID] = teamInfo;
        }
 
        // 更新队伍基本信息
        teamInfo.TeamID = pack.TeamID;
        teamInfo.CreateTime = pack.CreateTime;
        teamInfo.FuncMapID = pack.FuncMapID;
        teamInfo.FuncMapEx = pack.FuncMapEx;
        teamInfo.TeamName = pack.TeamName;
        teamInfo.CaptainID = pack.CaptainID;
        teamInfo.MinLV = pack.MinLV;
        teamInfo.MinFightPower = ((ulong)pack.MinFightPowerEx * 100000000) + pack.MinFightPower;
        teamInfo.ServerOnly = pack.ServerOnly;
        teamInfo.NeedCheck = pack.NeedCheck;
        teamInfo.Value1 = pack.Value1;
        teamInfo.Value2 = pack.Value2;
 
        // 更新成员信息
        if (teamInfo.MemberDict == null)
        {
            teamInfo.MemberDict = new Dictionary<uint, AssortMemberInfo>();
        }
        else
        {
            teamInfo.MemberDict.Clear();
        }
 
        for (int i = 0; i < pack.MemberList.Length; i++)
        {
            var member = pack.MemberList[i];
            AssortMemberInfo memberInfo = new AssortMemberInfo
            {
                ServerID = member.ServerID,
                PlayerID = member.PlayerID,
                Name = member.Name,
                LV = member.LV,
                Job = member.Job,
                Face = member.Face,
                FacePic = member.FacePic,
                RealmLV = member.RealmLV,
                FightPower = ((ulong)member.FightPowerEx * 100000000) + member.FightPower,
                OfflineValue = member.OfflineValue,
                Value1 = member.Value1,
                Value2 = member.Value2,
            };
            teamInfo.MemberDict[member.PlayerID] = memberInfo;
            UpdateUpdatePlayerOnlineStateInfoDict(member.PlayerID, member.OfflineValue);
        }
 
        // 更新申请者信息
        if (teamInfo.ApplyIDList == null)
        {
            teamInfo.ApplyIDList = new List<uint>();
        }
        else
        {
            teamInfo.ApplyIDList.Clear();
        }
 
        for (int i = 0; i < pack.ApplyIDList.Length; i++)
        {
            teamInfo.ApplyIDList.Add(pack.ApplyIDList[i]);
        }
 
        if (teamInfo.ApplicantDict == null)
        {
            teamInfo.ApplicantDict = new Dictionary<uint, AssortMemberInfo>();
        }
        else
        {
            teamInfo.ApplicantDict.Clear();
        }
 
        for (int i = 0; i < pack.ApplyInfoList.Length; i++)
        {
            var apply = pack.ApplyInfoList[i];
            AssortMemberInfo applyInfo = new AssortMemberInfo
            {
                ServerID = apply.ServerID,
                PlayerID = apply.PlayerID,
                Name = apply.Name,
                LV = apply.LV,
                Job = apply.Job,
                Face = apply.Face,
                FacePic = apply.FacePic,
                RealmLV = apply.RealmLV,
                FightPower = ((ulong)apply.FightPowerEx * 100000000) + apply.FightPower,
            };
            teamInfo.ApplicantDict[apply.PlayerID] = applyInfo;
        }
        // 触发更新事件
        UpdateTeamInfoEvent?.Invoke();
        UpdateRedPoint();
    }
 
    public void UpdateQueryPlayerFuncTeamRetInfo(HB921_tagGCQueryPlayerFuncTeamRet pack)
    {
        //public uint FuncMapID;    // 功能地图ID或自定义的活动功能ID
        //public uint TeamID;       // 玩家所属队伍ID,目前只同步0的情况,如果玩家有队伍统一B920封包同步处理
        if (FuncMapID == pack.FuncMapID && pack.TeamID == 0)
        {
            UpdateQueryPlayerFuncTeamRetInfoEvent?.Invoke();
        }
        UpdateRedPoint();
    }
    public void UpdateFindFuncTeamListInfo(HB922_tagGCFuncTeamList pack)
    {
        this.StartIndex = pack.StartIndex;
        this.QueryCnt = pack.QueryCnt;
        this.SearchLen = pack.SearchLen;
        this.SearchMsg = pack.SearchMsg;
        this.LoopIndex = pack.LoopIndex;
        this.TeamCount = pack.TeamCount;
 
        uint index = pack.FuncMapID * 1000 + pack.FuncMapEx;
        uint type = (uint)pack.HaveSpace * 1000 + pack.IDLimitType;
 
        if (!assortTeamInfoDict.TryGetValue(index, out var assortTeamInfo))
        {
            assortTeamInfo = new Dictionary<uint, AssortTeamInfo>();
            assortTeamInfoDict[index] = assortTeamInfo;
        }
        if (!assortFindTypeTeamIdDict.TryGetValue(index, out var teamIdListDict))
        {
            teamIdListDict = new Dictionary<uint, List<uint>>();
            assortFindTypeTeamIdDict[index] = teamIdListDict;
        }
        if (!teamIdListDict.TryGetValue(type, out var teamIdList))
        {
            teamIdList = new List<uint>();
            teamIdListDict[type] = teamIdList;
        }
        if (pack.StartIndex == 0)
        {
            teamIdList.Clear();
        }
 
        for (int i = 0; i < pack.TeamList.Length; i++)
        {
            var key = pack.TeamList[i];
            uint teamID = key.TeamID;
 
            if (!assortTeamInfo.TryGetValue(teamID, out var teamInfo))
            {
                teamInfo = new AssortTeamInfo();
                assortTeamInfo[teamID] = teamInfo;
            }
 
            if (!teamIdList.Contains(teamID))
            {
                teamIdList.Add(teamID);
            }
 
            // 更新 teamInfo 的内容
            teamInfo.CreateTime = key.CreateTime;
            teamInfo.FuncMapEx = key.FuncMapEx;
            teamInfo.TeamName = key.TeamName;
            teamInfo.CaptainID = key.CaptainID;
            teamInfo.MinLV = key.MinLV;
            teamInfo.MinFightPower = ((ulong)key.MinFightPowerEx * 100000000) + key.MinFightPower;
            teamInfo.ServerOnly = key.ServerOnly;
            teamInfo.NeedCheck = key.NeedCheck;
            teamInfo.Value1 = key.Value1;
            teamInfo.Value2 = key.Value2;
 
            // 更新 ApplyIDList
            if (teamInfo.ApplyIDList == null)
            {
                teamInfo.ApplyIDList = new List<uint>();
            }
            else
            {
                teamInfo.ApplyIDList.Clear();
            }
            for (int j = 0; j < key.ApplyIDList.Length; j++)
            {
                var applyID = key.ApplyIDList[j];
                teamInfo.ApplyIDList.Add(applyID);
            }
 
            // 更新 MemberDict
            if (teamInfo.MemberDict == null)
            {
                teamInfo.MemberDict = new Dictionary<uint, AssortMemberInfo>();
            }
            else
            {
                teamInfo.MemberDict.Clear();
            }
 
            for (int j = 0; j < key.MemberList.Length; j++)
            {
                var member = key.MemberList[j];
                AssortMemberInfo memberInfo = new AssortMemberInfo();
                memberInfo.ServerID = member.ServerID;
                memberInfo.PlayerID = member.PlayerID;
                memberInfo.Name = member.Name;
                memberInfo.LV = member.LV;
                memberInfo.Job = member.Job;
                memberInfo.Face = member.Face;
                memberInfo.FacePic = member.FacePic;
                memberInfo.RealmLV = member.RealmLV;
                memberInfo.FightPower = ((ulong)member.FightPowerEx << 32) | member.FightPower;
                memberInfo.Value1 = member.Value1;
                memberInfo.Value2 = member.Value2;
                teamInfo.MemberDict[member.PlayerID] = memberInfo;
            }
        }
 
        // 触发更新事件
        if (StartIndex == 0)
        {
            UpdateFindInfoEvent?.Invoke();
        }
        else
        {
            AddScrollerEvent?.Invoke();
        }
    }
 
    public void UpdateFuncTeamDissolveInfo(HB923_tagGCFuncTeamDissolve pack)
    {
        bool isHaveTeam = TryGetPlayerTeamInfo(out bool isCaptain, out uint nowTeamID, out AssortTeamInfo teamInfo);
        if (isHaveTeam && isCaptain)
        {
            isAutoJoin = false;
            nowPowerNum = 0;
            SavePowerNum();
            LocalSave.SetBool(StringUtility.Contact("gszczd_toggle1_", PlayerDatas.Instance.baseData.PlayerID), isAutoJoin);
        }
 
        uint teamID = pack.TeamID;
        if (TryGetTeamTypeDict(out Dictionary<uint, List<uint>> teamTypeDict))
        {
            var list = teamTypeDict.Keys.ToList();
            for (int i = 0; i < list.Count; i++)
            {
                uint type = list[i];
                var typeList = teamTypeDict[type];
                if (typeList.Contains(teamID))
                {
                    typeList.Remove(teamID);
                }
            }
        }
        if (TryGetTeamInfoDict(out var teamInfoDict) && teamInfoDict.ContainsKey(teamID))
        {
            teamInfoDict.Remove(teamID);
        }
        UpdateTeamDissolveEvent?.Invoke();
        UpdateRedPoint();
    }
 
    void DailyQuestProgressUpdateEvent(int obj)
    {
        UpdateRedPoint();
    }
 
    void OnSelectUpdate()
    {
        UpdateRedPoint();
    }
 
    void UpdatePlayerBillboardEvent(int obj)
    {
        UpdateRedPoint();
    }
 
    public void UpdateRedPoint()
    {
        entranceRedPoint.state = RedPointState.None;
        manageRedPoint.state = RedPointState.None;
 
        if (TimeUtility.OpenDay < GeneralDefine.crossServerBattleFieldOpenDay)
        {
            return;
        }
 
        bool isHaveTeam = TryGetPlayerTeamInfo(out bool isCaptain, out uint teamID, out AssortTeamInfo teamInfo);
        //活动处于开启状况
        if (IsOpenAction())
            return;
        //玩家有队伍 
        if (isHaveTeam)
        {
            //玩家是队长 且 申请列表中有成员
            if (isCaptain && teamInfo.ApplicantDict.Count > 0)
            {
                manageRedPoint.state = RedPointState.Simple;
            }
        }
        //玩家没队伍
        else
        {
            if (isDisplayRedPoint)
            {
                entranceRedPoint.state = RedPointState.Simple;
            }
        }
    }
 
    public int GetWorldChannelCoolDownEndTime()
    {
        if (lastWorldChannelTime == 0)
            return 0;
        var overTime = TimeUtility.GetTime((uint)(lastWorldChannelTime + worldChannelTimeCD));
        if (TimeUtility.ServerNow > overTime)
            return 0;
        return (int)(overTime - TimeUtility.ServerNow).TotalSeconds;
    }
 
    public int GetCrossServiceChannelCoolDownEndTime()
    {
        if (lastCrossServiceChannelTime == 0)
            return 0;
        var overTime = TimeUtility.GetTime((uint)(lastCrossServiceChannelTime + crossServiceChannelTimeCD));
        if (TimeUtility.ServerNow > overTime)
            return 0;
        return (int)(overTime - TimeUtility.ServerNow).TotalSeconds;
    }
 
    public void SetWorldChannelTime()
    {
        lastWorldChannelTime = TimeUtility.AllSeconds;
    }
 
    public void SetCrossServiceChannelTime()
    {
        lastCrossServiceChannelTime = TimeUtility.AllSeconds;
    }
 
    public void SaveAllTime()
    {
        int[] arr = new int[2];
        arr[0] = lastWorldChannelTime;
        arr[1] = lastCrossServiceChannelTime;
        LocalSave.SetIntArray(StringUtility.Contact("gszczd_", PlayerDatas.Instance.baseData.PlayerID), arr);
    }
 
    public void LoadAllTime()
    {
        int[] arr = LocalSave.GetIntArray(StringUtility.Contact("gszczd_", PlayerDatas.Instance.baseData.PlayerID));
        if (arr != null && arr.Length == 2)
        {
            lastWorldChannelTime = arr[0];
            lastCrossServiceChannelTime = arr[1];
        }
        else
        {
            lastWorldChannelTime = 0;
            lastCrossServiceChannelTime = 0;
        }
    }
 
    public void SavePowerNum()
    {
        int[] arr = new int[2];
        arr[0] = (int)(nowPowerNum / 100000000);
        arr[1] = (int)(nowPowerNum % 100000000);
        LocalSave.SetIntArray(StringUtility.Contact("gszczd_powernum", PlayerDatas.Instance.baseData.PlayerID), arr);
    }
 
    public void LoadPowerNum()
    {
        int[] arr = LocalSave.GetIntArray(StringUtility.Contact("gszczd_powernum", PlayerDatas.Instance.baseData.PlayerID));
        if (arr != null && arr.Length == 2)
        {
            nowPowerNum = (long)arr[0] * 100000000 + (long)arr[1];
        }
        else
        {
            nowPowerNum = 0;
        }
    }
 
    public bool IsNoTeamName()
    {
        return FunctionTeamSetConfig.Get((int)FuncMapID).NeedName == 0;
    }
 
    public bool IsOpenAction()
    {
        if (FunctionTeamSetConfig.Get((int)FuncMapID).OPLimitInAct == 0)
        {
            return false;
        }
        int index = Math.Max(ILCrossServerModel.Instance.selectIndex, 0);
        var int3Config = ILCrossServerModel.Instance.crossBattleFieldOpenTimes[index];
        var state = ILCrossServerModel.Instance.GetActionState(index);
        if (state == 1)
            return true;
        return false;
    }
 
    public void UpdatePlayerOnlineStateInfo(HB315_tagGCRelatedPlayerOnlineState vNetData)
    {
        UpdateUpdatePlayerOnlineStateInfoDict(vNetData.PlayerID, vNetData.OfflineValue, vNetData.IsCross);
    }
 
    void UpdateUpdatePlayerOnlineStateInfoDict(uint playerId, uint offlineValue = 1, byte isCross = 0)
    {
        if (!playerOnlineStateInfoDict.TryGetValue(playerId, out var playerOnlineStateInfo))
        {
            playerOnlineStateInfo = new PlayerOnlineStateInfo();
            playerOnlineStateInfoDict[playerId] = playerOnlineStateInfo;
        }
        playerOnlineStateInfo.IsOnline = offlineValue == 0;
        playerOnlineStateInfo.IsCross = isCross == 1;
        playerOnlineStateInfo.OfflineValue = offlineValue >= 1 ? offlineValue : 0;
        UpdatePlayerOnlineStateInfoEvent?.Invoke();
    }
    public bool IsPlayerOnline(uint playerId)
    {
        //没有这个玩家的信息默认视为离线
        if (!playerOnlineStateInfoDict.TryGetValue(playerId, out var playerOnlineStateInfo))
            return false;
        return playerOnlineStateInfo.IsOnline;
    }
}
 
 
public class AssortTeamInfo
{
    public uint TeamID;
    public uint CreateTime;         //创建队伍时间戳
    public uint FuncMapID;          // 功能地图ID或自定义的活动功能ID
    public uint FuncMapEx;          // 功能地图扩展,如不同的层级
    public string TeamName;         // 队伍名称
    public uint CaptainID;          //队长ID,队伍ServerID直接取队长的ServerID
    public ushort MinLV;            //最低等级限制
    public ulong MinFightPower;     //最低战力限制
    public byte ServerOnly;         //是否仅本服玩家可加入,0-否,1-是
    public byte NeedCheck;          //是否需要审核
    public uint Value1;             //值1
    public uint Value2;             //值2
    public Dictionary<uint, AssortMemberInfo> MemberDict = new Dictionary<uint, AssortMemberInfo>();       //成员详细信息
    public List<uint> ApplyIDList = new List<uint>();                                                           //申请者PlayerID
    public Dictionary<uint, AssortMemberInfo> ApplicantDict = new Dictionary<uint, AssortMemberInfo>();   //申请者详细信息
}
 
public class AssortMemberInfo
{
    public uint ServerID;
    public uint PlayerID;
    public string Name;
    public ushort LV;
    public byte Job;
    public uint Face;        //基本脸型
    public uint FacePic;        //头像框
    public ushort RealmLV;
    public ulong FightPower;
    public uint OfflineValue;
    public uint Value1;
    public uint Value2;
}
public class PlayerOnlineStateInfo
{
    public bool IsOnline;           // 是否在线
    public bool IsCross;            // 是否跨服同步的,如果是跨服则离线时间计算时要取跨服服务器时间
    public uint OfflineValue;       // 上次离线时间戳
}