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 orgPriceDict = new Dictionary(); //管家档位购买充值ID对应的折扣前金额,没配置的不显示 public int timeS; //间隔x秒触发自动采集 public int defaultLv; //默认勾选x级物品 bool isLoginOk = false; bool isStart = false; public bool isTrigger = false; //<矿物ID,矿物LV> public Dictionary nowChooseDict = new Dictionary(); 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(); } } public override void Init() { isServerRunningLongEnough = int.Parse(FuncConfigConfig.Get("MineAreaHousekeeper").Numerical1); butlerLevelDurationArr = JsonMapper.ToObject(FuncConfigConfig.Get("MineAreaHousekeeper").Numerical2); butlerCTGArr = JsonMapper.ToObject(FuncConfigConfig.Get("MineAreaHousekeeper").Numerical3); timeS = int.Parse(FuncConfigConfig.Get("MineAreaHousekeeper").Numerical4); var jsonData = JsonMapper.ToObject(FuncConfigConfig.Get("MineAreaHousekeeper").Numerical5); List 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; } public override void UnInit() { GlobalTimeEvent.Instance.secondEvent -= OnSecondEvent; TimeMgr.Instance.OnDayEvent -= OnDayEvent; } 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 tempDict = new Dictionary(); var jsonData = JsonMapper.ToObject(res); List 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 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 dict) { List 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 GetChooseMineIDList() { if (nowChooseDict.IsNullOrEmpty()) return null; var resList = new List(); 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 sendPlayerIDList = new List(); //自己福地发过包的索引位置 List sendIndexList = new List(); 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 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; startState = 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()); } } }