少年修仙传客户端代码仓库
hch
2025-06-12 204ef05a831c9484e2abc561d27ecbff7c797453
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
using LitJson;
using System;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
 
namespace vnxbqy.UI
{
    public class BlessedLandManageMouseModel : Model, IBeforePlayerDataInitialize, IPlayerLoginOk
    {
        readonly int FuncId = 227;
        public int isServerRunningLongEnough;  //开服天大于x天可用,不包含该天
        public int[] butlerLevelDurationArr;   //管家档位对应时长列表,单位天, [免费档时长, 付费档1时长, 付费档2时长, ...]
        public int[][] butlerCTGArr;           //管家档位购买对应充值ID列表 [[付费档1充值ID, ...], ...]
        public Dictionary<int, string> orgPriceDict = new Dictionary<int, string>();           //管家档位购买充值ID对应的折扣前金额,没配置的不显示
        public int timeS;                      //间隔x秒触发自动采集
        public int defaultLv;                   //默认勾选x级物品
        bool isLoginOk = false;
        bool isStart = false;
        public bool isTrigger = false;
        //<矿物ID,矿物LV>
        public Dictionary<int, int> nowChooseDict = new Dictionary<int, int>();
 
        public bool startState
        {
            get
            {
                return isStart;
            }
            set
            {
                isStart = value;
                StartStateChangeEvent?.Invoke();
            }
        }
        public event Action StartStateChangeEvent;
        public Action ChooseChangeEvent;
        BlessedLandModel blessedLandModel { get { return ModelCenter.Instance.GetModel<BlessedLandModel>(); } }
 
        public override void Init()
        {
            isServerRunningLongEnough = int.Parse(FuncConfigConfig.Get("MineAreaHousekeeper").Numerical1);
            butlerLevelDurationArr = JsonMapper.ToObject<int[]>(FuncConfigConfig.Get("MineAreaHousekeeper").Numerical2);
            butlerCTGArr = JsonMapper.ToObject<int[][]>(FuncConfigConfig.Get("MineAreaHousekeeper").Numerical3);
            timeS = int.Parse(FuncConfigConfig.Get("MineAreaHousekeeper").Numerical4);
            var jsonData = JsonMapper.ToObject(FuncConfigConfig.Get("MineAreaHousekeeper").Numerical5);
            List<string> keyList = jsonData.Keys.ToList();
            for (int i = 0; i < keyList.Count; i++)
            {
                orgPriceDict.Add(int.Parse(keyList[i]), jsonData[keyList[i]].ToJson());
            }
            defaultLv = int.Parse(FuncConfigConfig.Get("MineAreaHousekeeper1").Numerical1);
            GlobalTimeEvent.Instance.secondEvent += OnSecondEvent;
            TimeMgr.Instance.OnDayEvent += OnDayEvent;
            DTC0102_tagCDBPlayer.switchAccountEvent += OnSwitchAccount;
        }
 
        public override void UnInit()
        {
            GlobalTimeEvent.Instance.secondEvent -= OnSecondEvent;
            TimeMgr.Instance.OnDayEvent -= OnDayEvent;
            DTC0102_tagCDBPlayer.switchAccountEvent -= OnSwitchAccount;
        }
 
        private void OnSwitchAccount()
        {
            Stop();
        }
 
        private void OnDayEvent()
        {
            Stop();
        }
 
        private string GetLocalKey()
        {
            return StringUtility.Contact("BlessedLandManageMouse", "_", PlayerDatas.Instance.baseData.PlayerID);
        }
 
        public void LoadLocal()
        {
            string key = GetLocalKey();
            if (LocalSave.HasKey(key))
            {
                string res = LocalSave.GetString(key);
                if (res == null)
                {
                    DefaultMultiSelectCheck();
                    return;
                }
                Dictionary<int, int> tempDict = new Dictionary<int, int>();
 
                var jsonData = JsonMapper.ToObject(res);
                List<string> keyList = jsonData.Keys.ToList();
                for (int i = 0; i < keyList.Count; i++)
                {
                    tempDict.Add(int.Parse(keyList[i]), int.Parse(jsonData[keyList[i]].ToJson()));
                }
                if (tempDict.IsNullOrEmpty())
                {
                    DefaultMultiSelectCheck();
                    return;
                }
                bool isCheckLocalOk = CheckLocal(tempDict);
                if (isCheckLocalOk)
                {
                    List<int> tempList = tempDict.Keys.ToList();
                    for (int i = 0; i < tempList.Count; i++)
                    {
                        int itemId = tempList[i];
                        int itemLV = tempDict[itemId];
                        nowChooseDict[itemId] = itemLV;
                    }
                }
                else
                {
                    LocalSave.DeleteKey(key);
                    DefaultMultiSelectCheck();
                }
            }
            else
            {
                DefaultMultiSelectCheck();
            }
 
        }
 
        //如果没有配置,就勾上所有可勾选项,等级按默认配置
        void DefaultMultiSelectCheck()
        {
            if (nowChooseDict.Count == 0)
            {
                var itemIDToItemLVListDict = MineAreaItemConfig.GetItemIDToItemLVListDict();
                var itemIDToItemLVList = itemIDToItemLVListDict.Keys.ToList();
 
                for (int i = 0; i < itemIDToItemLVList.Count; i++)
                {
                    int itemId = itemIDToItemLVList[i];
                    if (!itemIDToItemLVListDict.TryGetValue(itemId, out var list) || list.IsNullOrEmpty())
                        continue;
                    int itemLv = list[list.Count - 1];
                    //福地物品表没这项
                    if (!MineAreaItemConfig.TryGetMineID(itemId, itemLv, out int mineId))
                        continue;
                    //这项现在是未解锁的
                    MineAreaItemConfig mineAreaItemConfig = MineAreaItemConfig.Get(mineId);
                    int limitLV = mineAreaItemConfig.LimitLV;
                    int lv = PlayerDatas.Instance.baseData.LV;
                    bool isLock = lv < limitLV;
                    if (isLock)
                        continue;
                    //福地物品表没这项
                    if (!MineAreaItemConfig.TryGetMineID(itemId, defaultLv, out int mineId1))
                        continue;
                    nowChooseDict[itemId] = defaultLv;
                }
 
            }
        }
 
        public void SaveLocal(bool isChoose, int itemId, int itemLV)
        {
            if (isChoose)
            {
                nowChooseDict[itemId] = itemLV;
            }
            else
            {
                if (nowChooseDict.ContainsKey(itemId))
                {
                    nowChooseDict.Remove(itemId);
                }
            }
 
            string res = JsonMapper.ToJson(nowChooseDict);
            string key = GetLocalKey();
            LocalSave.SetString(key, res);
        }
 
        public bool CheckLocal(Dictionary<int, int> dict)
        {
            List<int> list = dict.Keys.ToList();
            for (int i = 0; i < list.Count; i++)
            {
                int itemId = list[i];
                int itemLV = dict[itemId];
                //福地物品表没这项
                if (!MineAreaItemConfig.TryGetMineID(itemId, itemLV, out int mineId))
                    return false;
                //这项现在是未解锁的
                MineAreaItemConfig mineAreaItemConfig = MineAreaItemConfig.Get(mineId);
                int limitLV = mineAreaItemConfig.LimitLV;
                int lv = PlayerDatas.Instance.baseData.LV;
                bool isLock = lv < limitLV;
                if (isLock)
                    return false;
            }
            return true;
        }
 
        public void Start()
        {
            startState = true;
            timer = 0;
            StratAuto();
        }
 
        public void Stop()
        {
            startState = false;
        }
 
        public void StratAuto()
        {
            // 未登录,不执行
            if (!isLoginOk)
                return;
            // 福地功能没开
            if (!FuncOpen.Instance.IsFuncOpen(FuncId))
                return;
            //没雇佣总管
            //0 未雇佣-未使用免费次数 1 未雇佣-已使用免费次数 2 雇佣中-未开始自动采集 3 雇佣中-自动采集中
            int state = GetState();
            if (state == 0 || state == 1)
                return;
            // 未开启自动收集
            if (!isStart)
                return;
            // 没有空闲老鼠
            int allWorkerCount = blessedLandModel.WorkerCount;
            int freeWorkerCount = allWorkerCount - blessedLandModel.GetWorkingCount();
            if (freeWorkerCount < 0)
                return;
            // 工人体力耗尽
            int energyUsed = blessedLandModel.EnergyUsed;
            int totalEnergy = blessedLandModel.GetTotalEnergy();
            if (energyUsed >= totalEnergy)
            {
                Stop();
                return;
            }
            TrySend();
        }
 
        private List<int> GetChooseMineIDList()
        {
            if (nowChooseDict.IsNullOrEmpty())
                return null;
            var resList = new List<int>();
            var itemList = nowChooseDict.Keys.ToList();
            for (int i = 0; i < itemList.Count; i++)
            {
                int itemId = itemList[i];
                int itemLV = nowChooseDict[itemId];
                //福地物品表没这项
                if (!MineAreaItemConfig.TryGetMineID(itemId, itemLV, out int mineId))
                    continue;
                resList.Add(mineId);
            }
            resList.Sort(SortSameItemLV);
            return resList;
        }
 
        private int SortSameItemLV(int mineIdA, int mineIdB)
        {
            MineAreaItemConfig mineAreaItemConfigA = MineAreaItemConfig.Get(mineIdA);
            MineAreaItemConfig mineAreaItemConfigB = MineAreaItemConfig.Get(mineIdB);
 
            int limitLV1 = mineAreaItemConfigA.LimitLV;
            int limitLV2 = mineAreaItemConfigB.LimitLV;
 
            int itemLV1 = mineAreaItemConfigA.ItemLV;
            int itemLV2 = mineAreaItemConfigB.ItemLV;
 
            int sortNum1 = mineAreaItemConfigA.SameItemLVSort;
            int sortNum2 = mineAreaItemConfigB.SameItemLVSort;
 
            //LimitLV 越小越靠前
            int limitLVCompare = limitLV1.CompareTo(limitLV2);
            if (limitLVCompare != 0)
                return limitLVCompare;
 
            //LimitLV 相同的情况下,itemLV 越大越靠前
            int itemLVCompare = itemLV2.CompareTo(itemLV1);
            if (itemLVCompare != 0)
                return itemLVCompare;
 
            //itemLV 相同的情况下,sortNum1 越小越靠前
            return sortNum1.CompareTo(sortNum2);
        }
 
        //将目标福地物品 按物品等级排序
        private int SortByItemLV(uint playerId, int indexA, int indexB)
        {
            if (blessedLandModel.newAreaDataDict.IsNullOrEmpty() || !blessedLandModel.newAreaDataDict.ContainsKey(playerId) ||
                blessedLandModel.newAreaDataDict[playerId].MineItems.IsNullOrEmpty() ||
                !blessedLandModel.newAreaDataDict[playerId].MineItems.ContainsKey(indexA) ||
                !blessedLandModel.newAreaDataDict[playerId].MineItems.ContainsKey(indexB))
                return 0;
 
            var mineItem1 = blessedLandModel.newAreaDataDict[playerId].MineItems[indexA];
            var mineItem2 = blessedLandModel.newAreaDataDict[playerId].MineItems[indexB];
 
            int mineID1 = mineItem1.MineID;
            int mineID2 = mineItem2.MineID;
            if (!MineAreaItemConfig.Has(mineID1) || !MineAreaItemConfig.Has(mineID2))
                return 0;
            MineAreaItemConfig mineAreaItemConfig1 = MineAreaItemConfig.Get(mineID1);
            MineAreaItemConfig mineAreaItemConfig2 = MineAreaItemConfig.Get(mineID2);
            int itemLV1 = mineAreaItemConfig1.ItemLV;
            int itemLV2 = mineAreaItemConfig2.ItemLV;
 
            return itemLV2.CompareTo(itemLV1);
        }
 
        //是否有合适的物品
        private bool TrySend()
        {
            var chooseMineIDList = GetChooseMineIDList();
            //没有用户勾选的物品列表
            if (chooseMineIDList.IsNullOrEmpty())
                return false;
            //一个福地信息也没有
            var newAreaDataDict = blessedLandModel.newAreaDataDict;
            if (newAreaDataDict.IsNullOrEmpty())
                return false;
 
            uint myPlayerId = blessedLandModel.myPlayerId;
 
            bool isHas = false;
            //当前空闲工人数量
            int nowFreeWorkerCount = blessedLandModel.GetNowFreeWorkerCount();
            //当前可用工人体力
            int nowCanUseEnergy = blessedLandModel.GetNowCanUseEnergy();
            //最大可发包数量 = 当前空闲工人数、剩余疲劳数, 两者取最小值
            int sandCntMax = Mathf.Min(nowCanUseEnergy, nowFreeWorkerCount);
            //当前发了多少包
            int nowSendCnt = 0;
            //敌对福地和周围福地已经发过包的玩家ID
            List<uint> sendPlayerIDList = new List<uint>();
            //自己福地发过包的索引位置
            List<int> sendIndexList = new List<int>();
 
            for (int i = 0; i < sandCntMax; i++)
            {
                if (!isStart || nowSendCnt >= sandCntMax)
                    return isHas;
                for (int j = 0; j < chooseMineIDList.Count; j++)
                {
                    if (!isStart || nowSendCnt >= sandCntMax)
                        return isHas;
                    int mineID = chooseMineIDList[j];
                    if (!MineAreaItemConfig.Has(mineID))
                        continue;
                    MineAreaItemConfig mineAreaItemConfig = MineAreaItemConfig.Get(mineID);
                    int itemId = mineAreaItemConfig.ItemID;
                    int itemLv = mineAreaItemConfig.ItemLV;
 
                    MineAreaInfo mineAreaInfo;
                    List<uint> playerIDList;
                    //先找个人福地
                    if (newAreaDataDict.TryGetValue(myPlayerId, out mineAreaInfo) && !mineAreaInfo.MineItems.IsNullOrEmpty())
                    {
                        var mineItemsList = mineAreaInfo.MineItems.Keys.ToList();
                        mineItemsList.Sort((int a, int b) => SortByItemLV(myPlayerId, a, b));
                        for (int k = 0; k < mineItemsList.Count; k++)
                        {
                            if (!isStart || nowSendCnt >= sandCntMax)
                                return isHas;
                            int index = mineItemsList[k];
                            var mineItem = mineAreaInfo.MineItems[index];
                            if (sendIndexList.Contains(index))
                                continue;
                            if (!MineAreaItemConfig.Has(mineItem.MineID))
                                continue;
                            MineAreaItemConfig config = MineAreaItemConfig.Get(mineItem.MineID);
                            //当前项已在拉取
                            if (mineItem.WorkerCount > 0)
                                continue;
                            //不是指定的矿物
                            if (itemId != config.ItemID || config.ItemLV < itemLv)
                                continue;
                            isHas = true;
                            nowSendCnt += 1;
                            sendIndexList.Add(index);
                            blessedLandModel.SendCB030Pack(myPlayerId, (byte)index, (byte)1, 0);
                        }
                    }
 
 
                    //找周围福地
                    if (!blessedLandModel.typeToPlayerIDs.IsNullOrEmpty() && blessedLandModel.typeToPlayerIDs.TryGetValue(3, out playerIDList))
                    {
                        for (int k = 0; k < playerIDList.Count; k++)
                        {
                            uint playerId = playerIDList[k];
                            if (!isStart || nowSendCnt >= sandCntMax)
                                return isHas;
                            if (!newAreaDataDict.TryGetValue(playerId, out mineAreaInfo))
                                continue;
                            if (sendPlayerIDList.Contains(playerId))
                                continue;
                            //是否采集了这个人的其他资源
                            bool isSnatchItem = blessedLandModel.IsSnatchItem(playerId);
                            if (isSnatchItem)
                                continue;
 
                            var mineItems = mineAreaInfo.MineItems;
                            var mineItemsList = mineItems.Keys.ToList();
                            mineItemsList.Sort((int a, int b) => SortByItemLV(playerId, a, b));
                            for (int l = 0; l < mineItemsList.Count; l++)
                            {
                                int index = mineItemsList[l];
                                var mineItem = mineItems[index];
                                if (sendPlayerIDList.Contains(playerId))
                                    continue;
                                if (!MineAreaItemConfig.Has(mineItem.MineID))
                                    continue;
                                MineAreaItemConfig config = MineAreaItemConfig.Get(mineItem.MineID);
                                //不是指定的矿物
                                if (itemId != config.ItemID || config.ItemLV < itemLv)
                                    continue;
                                //当前资源正在被自己或别人采集
                                if (mineItem.RobWorkerCount > 0)
                                    continue;
                                isHas = true;
                                nowSendCnt += 1;
                                sendPlayerIDList.Add(playerId);
                                blessedLandModel.SendCB030Pack(playerId, (byte)index, (byte)1, 0);
                                break;
                            }
                        }
                    }
 
 
                    //找敌对福地
                    if (!blessedLandModel.typeToPlayerIDs.IsNullOrEmpty() && blessedLandModel.typeToPlayerIDs.TryGetValue(2, out playerIDList))
                    {
                        for (int k = 0; k < playerIDList.Count; k++)
                        {
                            uint playerId = playerIDList[k];
                            if (!isStart || nowSendCnt >= sandCntMax)
                                return isHas;
                            if (!newAreaDataDict.TryGetValue(playerId, out mineAreaInfo))
                                continue;
                            if (sendPlayerIDList.Contains(playerId))
                                continue;
                            //是否采集了这个人的其他资源
                            bool isSnatchItem = blessedLandModel.IsSnatchItem(playerId);
                            if (isSnatchItem)
                                continue;
                            var mineItems = mineAreaInfo.MineItems;
                            var mineItemsList = mineItems.Keys.ToList();
                            mineItemsList.Sort((int a, int b) => SortByItemLV(playerId, a, b));
                            for (int l = 0; l < mineItemsList.Count; l++)
                            {
                                int index = mineItemsList[l];
                                var mineItem = mineItems[index];
                                if (sendPlayerIDList.Contains(playerId))
                                    continue;
                                if (!MineAreaItemConfig.Has(mineItem.MineID))
                                    continue;
                                MineAreaItemConfig config = MineAreaItemConfig.Get(mineItem.MineID);
                                //不是指定的矿物
                                if (itemId != config.ItemID || config.ItemLV < itemLv)
                                    continue;
                                //当前资源正在被自己或别人采集
                                if (mineItem.RobWorkerCount > 0)
                                    continue;
                                isHas = true;
                                nowSendCnt += 1;
                                sendPlayerIDList.Add(playerId);
                                blessedLandModel.SendCB030Pack(playerId, (byte)index, (byte)1, 0);
                                break;
                            }
                        }
                    }
                }
            }
 
            //循环结束还有可发包的次数 刷新周围福地
            if (isStart && nowSendCnt < sandCntMax)
            {
                //超出今日周围福地刷新次数上限
                bool isLimit = blessedLandModel.TryGetRefreshTypeDailyLimitValue(2, out int maxLimit);
                if (isLimit && blessedLandModel.RefreshCountRob >= maxLimit)
                    return isHas;
                //在冷却时间中
                if (blessedLandModel.GetCoolDownEndTime(0) > 0)
                    return isHas;
                //能刷新周围福地就刷新周围福地
                blessedLandModel.SendCB031Pack(2);
                blessedLandModel.lastSurroundRefreshTime = TimeUtility.AllSeconds;
                blessedLandModel.SetTime(0);
                blessedLandModel.SaveAllTime();
                isTrigger = true;
            }
            return isHas;
        }
 
        public int timer = 0;
 
        private void OnSecondEvent()
        {
            // 工人体力耗尽 立刻停掉自动采集
            int energyUsed = blessedLandModel.EnergyUsed;
            int totalEnergy = blessedLandModel.GetTotalEnergy();
            if (energyUsed >= totalEnergy)
            {
                Stop();
                return;
            }
 
            timer += 1;
            if (timer >= timeS)
            {
                StratAuto();
                timer = 0;
            }
        }
 
        public void OnBeforePlayerDataInitialize()
        {
            isLoginOk = false;
            isTrigger = false;
            timer = 0;
        }
 
        public void OnPlayerLoginOk()
        {
            isLoginOk = true;
            LoadLocal();
        }
 
        //0 未雇佣-未使用免费次数 1 未雇佣-已使用免费次数 2 雇佣中-未开始自动采集 3 雇佣中-自动采集中
        public int GetState()
        {
            uint housekeeperEndTime = blessedLandModel.HousekeeperEndTime;
            // 管家档位对应时长列表中,免费档时长如果配0代表没有免费试用
            if (butlerLevelDurationArr[0] > 0)
            {
                //未使用免费次数
                if (housekeeperEndTime == 0)
                {
                    return 0;
                }
                else
                {
                    //雇佣时间过期
                    if (housekeeperEndTime < TimeUtility.AllSeconds)
                    {
                        return 1;
                    }
                    else
                    {
                        return startState ? 3 : 2;
                    }
                }
            }
            else
            {
                if (housekeeperEndTime == 0)
                {
                    return 1;
                }
                else
                {
                    //雇佣时间过期
                    if (housekeeperEndTime < TimeUtility.AllSeconds)
                    {
                        return 1;
                    }
                    else
                    {
                        return startState ? 3 : 2;
                    }
                }
            }
        }
 
        //发送福地管家免费试用包
        public void SendFreeUse()
        {
            GameNetSystem.Instance.SendInfo(new CB035_tagCMMineHouseKeeperFreeUse());
        }
    }
}