using BrewMonster.Network; using BrewMonster.Scripts.Managers; using CSNetwork.C2SCommand; using CSNetwork.Protocols; using CSNetwork.S2CCommand; using System; using System.Collections.Generic; using UnityEngine; namespace BrewMonster.Common { using CounterTable = Dictionary; public class CECC2SCmdCache { public struct presentInfo { public int roleid; public int mailid; public int itemid; public int index; public int slot; }; int m_idLastPickUpItem; // ID of picked up item last time int m_idLastSelTarget; // ID of selected item last time bool m_bGetExpProps; bool m_bEnterSanctuary; CounterTable m_CounterMap = new CounterTable(); CounterTable m_CounterMap2 = new CounterTable(); List m_UseItemCmdList = new List(); List m_GetPlayerBriefInfoList = new List(); List m_PlayerBaseInfoList = new List(); List m_EnterSanctuaryList = new List(); List m_PresentInfoList = new List(); public CECC2SCmdCache() { m_idLastPickUpItem = 0; m_idLastSelTarget = 0; m_bGetExpProps = false; m_bEnterSanctuary = false; InitCounters(); } // Initialize counters bool InitCounters() { // 'Use item' command time counter CECCounter pCnt = new CECCounter(); pCnt.SetPeriod(200); pCnt.Reset(true); if (m_CounterMap.ContainsKey((int)CommandID.USE_ITEM)) { m_CounterMap[(int)CommandID.USE_ITEM] = pCnt; } else { m_CounterMap.Add((int)CommandID.USE_ITEM, pCnt); } // 'Pickup item' command time counter pCnt = new CECCounter(); pCnt.SetPeriod(500); if (m_CounterMap.ContainsKey((int)CommandID.PICKUP)) { m_CounterMap[(int)CommandID.PICKUP] = pCnt; } else { m_CounterMap.Add((int)CommandID.PICKUP, pCnt); } // 'Select target' command time counter pCnt = new CECCounter(); pCnt.SetPeriod(250); if (m_CounterMap.ContainsKey((int)CommandID.SELECT_TARGET)) { m_CounterMap[(int)CommandID.SELECT_TARGET] = pCnt; } else { m_CounterMap.Add((int)CommandID.SELECT_TARGET, pCnt); } // 'Get extend properties' command time counter pCnt = new CECCounter(); pCnt.SetPeriod(2000); pCnt.Reset(true); if (m_CounterMap.ContainsKey((int)CommandID.GET_EXT_PROP)) { m_CounterMap[(int)CommandID.GET_EXT_PROP] = pCnt; } else { m_CounterMap.Add((int)CommandID.GET_EXT_PROP, pCnt); } // 'Cast skill' command time counter pCnt = new CECCounter(); pCnt.SetPeriod(200); pCnt.Reset(true); if (m_CounterMap.ContainsKey((int)CommandID.CAST_SKILL)) { m_CounterMap[(int)CommandID.CAST_SKILL] = pCnt; } else { m_CounterMap.Add((int)CommandID.CAST_SKILL, pCnt); } // 'Revive ask' command time counter pCnt = new CECCounter(); pCnt.SetPeriod(500); pCnt.Reset(true); if (m_CounterMap.ContainsKey((int)CommandID.REVIVE_VILLAGE)) { m_CounterMap[(int)CommandID.REVIVE_VILLAGE] = pCnt; } else { m_CounterMap.Add((int)CommandID.REVIVE_VILLAGE, pCnt); } // 'Enter sanctuary' command time counter pCnt = new CECCounter(); pCnt.SetPeriod(2000); if (m_CounterMap.ContainsKey((int)CommandID.ENTER_SANCTUARY)) { m_CounterMap[(int)CommandID.ENTER_SANCTUARY] = pCnt; } else { m_CounterMap.Add((int)CommandID.ENTER_SANCTUARY, pCnt); } // 'Enter instance' command time counter pCnt = new CECCounter(); pCnt.SetPeriod(2000); pCnt.Reset(true); if (m_CounterMap.ContainsKey((int)CommandID.ENTER_INSTANCE)) { m_CounterMap[(int)CommandID.ENTER_INSTANCE] = pCnt; } else { m_CounterMap.Add((int)CommandID.ENTER_INSTANCE, pCnt); } // 'Rush fly' command time counter pCnt = new CECCounter(); pCnt.SetPeriod(500); pCnt.Reset(true); if (m_CounterMap.ContainsKey((int)CommandID.ACTIVE_RUSH_FLY)) { m_CounterMap[(int)CommandID.ACTIVE_RUSH_FLY] = pCnt; } else { m_CounterMap.Add((int)CommandID.ACTIVE_RUSH_FLY, pCnt); } // 'Cancel action' command time counter pCnt = new CECCounter(); pCnt.SetPeriod(200); pCnt.Reset(true); if (m_CounterMap.ContainsKey((int)CommandID.CANCEL_ACTION)) { m_CounterMap[(int)CommandID.CANCEL_ACTION] = pCnt; } else { m_CounterMap.Add((int)CommandID.CANCEL_ACTION, pCnt); } // 'Control pet' command time counter pCnt = new CECCounter(); pCnt.SetPeriod(400); pCnt.Reset(true); if (m_CounterMap.ContainsKey((int)CommandID.PET_CTRL)) { m_CounterMap[(int)CommandID.PET_CTRL] = pCnt; } else { m_CounterMap.Add((int)CommandID.PET_CTRL, pCnt); } // 'Hello' command time counter pCnt = new CECCounter(); pCnt.SetPeriod(2000); pCnt.Reset(true); if (m_CounterMap.ContainsKey((int)CommandID.SEVNPC_HELLO)) { m_CounterMap[(int)CommandID.SEVNPC_HELLO] = pCnt; } else { m_CounterMap.Add((int)CommandID.SEVNPC_HELLO, pCnt); } // 'Present' command time counter pCnt = new CECCounter(); pCnt.SetPeriod(1000); pCnt.Reset(true); if (m_CounterMap.ContainsKey((int)CommandID.PLAYER_GIVE_PRESENT)) { m_CounterMap[(int)CommandID.PLAYER_GIVE_PRESENT] = pCnt; } else { m_CounterMap.Add((int)CommandID.PLAYER_GIVE_PRESENT, pCnt); } // 'GetPlayerBriefInfo' time counter pCnt = new CECCounter(); pCnt.SetPeriod(2000); pCnt.Reset(true); if (m_CounterMap2.ContainsKey((int)ProtocolType.PROTOCOL_GETPLAYERBRIEFINFO)) { m_CounterMap2[(int)ProtocolType.PROTOCOL_GETPLAYERBRIEFINFO] = pCnt; } else { m_CounterMap2.Add((int)ProtocolType.PROTOCOL_GETPLAYERBRIEFINFO, pCnt); } // 'PlayerBaseInfo' time counter pCnt = new CECCounter(); pCnt.SetPeriod(2000); pCnt.Reset(true); if (m_CounterMap2.ContainsKey((int)ProtocolType.PROTOCOL_PLAYERBASEINFO)) { m_CounterMap2[(int)ProtocolType.PROTOCOL_PLAYERBASEINFO] = pCnt; } else { m_CounterMap2.Add((int)ProtocolType.PROTOCOL_PLAYERBASEINFO, pCnt); } pCnt = new CECCounter(); pCnt.SetPeriod(10 * 1000); pCnt.Reset(true); if (m_CounterMap2.ContainsKey((int)ProtocolType.PROTOCOL_FACTIONRESOURCEBATTLEGETMAP)) { m_CounterMap2[(int)ProtocolType.PROTOCOL_FACTIONRESOURCEBATTLEGETMAP] = pCnt; } else { m_CounterMap2.Add((int)ProtocolType.PROTOCOL_FACTIONRESOURCEBATTLEGETMAP, pCnt); } pCnt = new CECCounter(); pCnt.SetPeriod(10 * 1000); pCnt.Reset(true); if (m_CounterMap2.ContainsKey((int)ProtocolType.PROTOCOL_FACTIONRESOURCEBATTLEGETRECORD)) { m_CounterMap2[(int)ProtocolType.PROTOCOL_FACTIONRESOURCEBATTLEGETRECORD] = pCnt; } else { m_CounterMap2.Add((int)ProtocolType.PROTOCOL_FACTIONRESOURCEBATTLEGETRECORD, pCnt); } return true; } // Remove all un-sent commands in cache public void RemoveAllCmds() { m_UseItemCmdList.Clear(); // ���� C2S �����ʱ�� m_CounterMap[(int)CommandID.USE_ITEM].Reset(true); m_EnterSanctuaryList.Clear(); m_CounterMap[(int)CommandID.ENTER_SANCTUARY].Reset(true); m_bEnterSanctuary = false; m_PresentInfoList.Clear(); m_CounterMap[(int)CommandID.PLAYER_GIVE_PRESENT].Reset(true); // ����Э���ʱ�� m_GetPlayerBriefInfoList.Clear(); m_CounterMap2[(int)ProtocolType.PROTOCOL_GETPLAYERBRIEFINFO].Reset(true); m_PlayerBaseInfoList.Clear(); m_CounterMap2[(int)ProtocolType.PROTOCOL_PLAYERBASEINFO].Reset(true); m_CounterMap2[(int)ProtocolType.PROTOCOL_FACTIONRESOURCEBATTLEGETMAP].Reset(true); m_CounterMap2[(int)ProtocolType.PROTOCOL_FACTIONRESOURCEBATTLEGETRECORD].Reset(true); } // Tick routine public bool Tick(float dwDeltaTime) { float dwRealTime = Time.fixedUnscaledDeltaTime * 1000; foreach (var item in m_CounterMap) { item.Value.IncCounter(dwRealTime); } foreach (var item in m_CounterMap2) { item.Value.IncCounter(dwRealTime); } // Try to send 'use item' command in cache SendCachedCmdUseItem(); // Try to send 'get extend properties' command SendCachedCmdGetExtProp(); // Try to send 'GetPlayerBriefInfo' SendCachedGetPlayerBriefInfo(); // Try to send 'PlayerBaseInfo' SendCachedPlayerBaseInfo(); // Try to send 'PresentInfo' SendCachedPresentInfo(); if (m_bEnterSanctuary) { CECCounter pCnt = m_CounterMap[(int)CommandID.ENTER_SANCTUARY]; if (pCnt.IsFull()) { for (int i = 0; i < m_EnterSanctuaryList.Count; i++) { int id = m_EnterSanctuaryList[i]; UnityGameSession.Instance.GameSession.c2s_SendCmdEnterSanctuary(id); } m_EnterSanctuaryList.Clear(); m_bEnterSanctuary = false; } } return true; } // Send 'use item' command void SendCachedCmdUseItem() { CECCounter pCnt = m_CounterMap[(int)CommandID.USE_ITEM]; if (!pCnt.IsFull() || m_UseItemCmdList.Count == 0) return; pCnt.Reset(); // Send the first item cmd_use_item Cmd = m_UseItemCmdList[0]; UnityGameSession.Instance.GameSession.c2s_SendCmdUseItem(Cmd.where, (byte)Cmd.index, Cmd.item_id, Cmd.byCount); m_UseItemCmdList.Clear(); } // Send cached 'get extend properties' command void SendCachedCmdGetExtProp() { CECCounter pCnt = m_CounterMap[(int)CommandID.GET_EXT_PROP]; if (!m_bGetExpProps || !pCnt.IsFull()) return; pCnt.Reset(); m_bGetExpProps = false; UnityGameSession.Instance.GameSession.c2s_SendCmdGetExtProps(); } // Send cached 'GetPlayerBriefInfo' command void SendCachedGetPlayerBriefInfo() { CECCounter pCnt = m_CounterMap2[(int)ProtocolType.PROTOCOL_GETPLAYERBRIEFINFO]; if (!pCnt.IsFull() || m_GetPlayerBriefInfoList.Count == 0) return; pCnt.Reset(); getplayerbriefinfo p = m_GetPlayerBriefInfoList[0]; if (p.Playerlist.Count != 0) { // ��ȡ��һ�����id�������������Э�� getplayerbriefinfo temp = p; temp.Playerlist.Clear(); temp.Playerlist.Add(p.Playerlist[0]); UnityGameSession.Instance.GameSession.SendProtocol(temp); // ���б������ p.Playerlist.Remove(p.Playerlist[0]); } if (p.Playerlist.Count == 0) m_GetPlayerBriefInfoList.Remove(p); } // Remove the cached 'PlayerBaseInfo' request public void RemovePlayerBaseInfo(int iRoleID) { int pos = m_PlayerBaseInfoList.Find(x => x == iRoleID); if (pos != 0) { m_PlayerBaseInfoList.RemoveAt(pos); } } // Send cached 'PlayerBaseInfo' protocol void SendCachedPlayerBaseInfo() { CECCounter pCnt = m_CounterMap2[(int)ProtocolType.PROTOCOL_PLAYERBASEINFO]; if (!pCnt.IsFull() || m_PlayerBaseInfoList.Count == 0) return; pCnt.Reset(); List aRoles = new List(); for (int i = 0; i < m_PlayerBaseInfoList.Count; i++) { aRoles.Add(m_PlayerBaseInfoList[i]); } UnityGameSession.Instance.GameSession.GetRoleBaseInfo(aRoles.Count, aRoles); } void SendCachedPresentInfo() { CECCounter pCnt = m_CounterMap[(int)CommandID.PLAYER_GIVE_PRESENT]; if (!pCnt.IsFull() || m_PresentInfoList.Count == 0) return; pCnt.Reset(); presentInfo info = m_PresentInfoList[0]; UnityGameSession.Instance.GameSession.c2s_SendCmdGivePresent(info.roleid, info.mailid, info.itemid, info.index, info.slot); m_PresentInfoList.Remove(info); } // Send commands ... public void SendCmdUseItem(byte byPackage, byte bySlot, int tid, byte byCount) { CECCounter pCnt = m_CounterMap[(int)CommandID.USE_ITEM]; if (m_UseItemCmdList.Count == 0 && pCnt.IsFull()) { pCnt.Reset(); UnityGameSession.Instance.GameSession.c2s_SendCmdUseItem(byPackage, bySlot, tid, byCount); return; } cmd_use_item Cmd = new cmd_use_item(); if (m_UseItemCmdList.Count == 0) { Cmd.where = byPackage; Cmd.index = bySlot; Cmd.item_id = tid; Cmd.byCount = byCount; m_UseItemCmdList.Add(Cmd); return; } int idx = -1; for (int i = 0; i < m_UseItemCmdList.Count; i++) { Cmd = m_UseItemCmdList[i]; if (Cmd.where == byPackage && Cmd.index == bySlot) { CECHostPlayer pHost = EC_Game.GetGameRun().GetHostPlayer(); EC_Inventory pPack = pHost.GetPack(byPackage); if (pPack == null) return; EC_IvtrItem pItem = pPack.GetItem(bySlot); if (pItem == null || !pItem.CheckUseCondition()) return; int iTotal = Cmd.byCount + byCount; if (iTotal >= pItem.GetCount()) iTotal = pItem.GetCount(); AAssist.a_ClampRoof(ref iTotal, 255); Cmd.byCount = (byte)iTotal; break; } idx++; } if (idx < 0) { Cmd = new cmd_use_item(); Cmd.where = byPackage; Cmd.index = bySlot; Cmd.item_id = tid; Cmd.byCount = byCount; m_UseItemCmdList.Add(Cmd); } // Try to send command in cache SendCachedCmdUseItem(); } /* Send 'pick up item' command The strategy to send 'pick up item' command: 1. if the item is just the one which was to be picked up, check whether enough time has passed since last command was sent. If true, send command again, otherwise just throw command 2. if the item isn't the one which was to be picked up, send command directly. */ public void SendCmdPickUp(int idItem, int tid) { //StackChecker::ACTrace(5); CECCounter pCnt = m_CounterMap[(int)CommandID.PICKUP]; if (m_idLastPickUpItem != idItem || pCnt.IsFull()) { pCnt.Reset(); UnityGameSession.Instance.GameSession.RequestPickupItem(idItem, tid); m_idLastPickUpItem = idItem; } } // Send 'select target' command // The strategy to send 'select target' command is like as SendCmdPickUp() public void SendCmdSelectTarget(int id) { // Set selection first before server returns, so as to reduce the player waiting time. CECHostPlayer pHost = EC_Game.GetGameRun().GetHostPlayer(); pHost.SetSelectedTarget(id); CECCounter pCnt = m_CounterMap[(int)CommandID.SELECT_TARGET]; if (m_idLastSelTarget != id || pCnt.IsFull()) { pCnt.Reset(); UnityGameSession.Instance.GameSession.c2s_SendCmdSelectTarget(id); m_idLastSelTarget = id; } } // Send 'get extend properties' command public void SendCmdExtProps() { // If there is already a request waiting, return directly if (m_bGetExpProps) return; CECCounter pCnt = m_CounterMap[(int)CommandID.GET_EXT_PROP]; if (pCnt.IsFull()) { pCnt.Reset(); UnityGameSession.Instance.GameSession.c2s_SendCmdGetExtProps(); return; } m_bGetExpProps = true; } // Send 'revive ask' command public void SendCmdReviveVillage(int param = 0) { CECCounter pCnt = m_CounterMap[(int)CommandID.REVIVE_VILLAGE]; if (pCnt.IsFull()) { pCnt.Reset(); UnityGameSession.Instance.GameSession.c2s_SendCmdReviveVillage(param); } } // Send 'revive ask' command public void SendCmdReviveItem(int param = 0) { // This command merge time counter with REVIVE_VILLAGE CECCounter pCnt = m_CounterMap[(int)CommandID.REVIVE_VILLAGE]; if (pCnt.IsFull()) { pCnt.Reset(); UnityGameSession.Instance.GameSession.c2s_SendCmdReviveItem(param); } } // Send 'cast skill' command public void SendCmdCastSkill(int idSkill, byte byPVPMask, int iNumTarget, int[] aTargets) { CECCounter pCnt = m_CounterMap[(int)CommandID.CAST_SKILL]; if (pCnt.IsFull()) { pCnt.Reset(); UnityGameSession.Instance.GameSession.c2s_SendCmdCastSkill(idSkill, byPVPMask, iNumTarget, aTargets); } } // Send 'cast instant skill' command public void SendCmdCastInstantSkill(int idSkill, byte byPVPMask, int iNumTarget, int[] aTargets) { CECCounter pCnt = m_CounterMap[(int)CommandID.CAST_SKILL]; if (pCnt.IsFull()) { pCnt.Reset(); UnityGameSession.Instance.GameSession.c2s_SendCmdCastInstantSkill(idSkill, byPVPMask, iNumTarget, aTargets); } } // Send 'enter sanctuary' command void SendCmdEnterSanctuary(int id) { for (int i = 0; i < m_EnterSanctuaryList.Count; i++) { if (m_EnterSanctuaryList[i] == id) return; } // Delay this command some time m_bEnterSanctuary = true; CECCounter pCnt = m_CounterMap[(int)CommandID.ENTER_SANCTUARY]; pCnt.Reset(); m_EnterSanctuaryList.Add(id); } // Send 'enter instance' commnad void SendCmdEnterInstance(int iTransIdx, int idInst) { CECCounter pCnt = m_CounterMap[(int)CommandID.ENTER_INSTANCE]; if (pCnt.IsFull()) { pCnt.Reset(); UnityGameSession.Instance.GameSession.c2s_SendCmdEnterInstance(iTransIdx, idInst); } } void SendCmdActiveRushFly(bool bActive) { CECCounter pCnt = m_CounterMap[(int)CommandID.ACTIVE_RUSH_FLY]; if (pCnt.IsFull()) { pCnt.Reset(); UnityGameSession.Instance.GameSession.c2s_SendCmdActiveRushFly(bActive); } } public void SendCmdCancelAction() { CECCounter pCnt = m_CounterMap[(int)CommandID.CANCEL_ACTION]; if (pCnt.IsFull()) { pCnt.Reset(); UnityGameSession.Instance.GameSession.c2s_SendCmdCancelAction(); } } public void SendCmdPetCtrl(int idTarget, int cmd, byte[] pParamBuf, int iParamLen) { CECCounter pCnt = m_CounterMap[(int)CommandID.PET_CTRL]; if (pCnt.IsFull()) { pCnt.Reset(); UnityGameSession.Instance.GameSession.c2s_SendCmdPetCtrl(idTarget, cmd, pParamBuf, iParamLen); } } public void SendCmdNPCSevHello(int nid) { CECCounter pCnt = m_CounterMap[(int)CommandID.SEVNPC_HELLO]; if (pCnt.IsFull()) { pCnt.Reset(); UnityGameSession.Instance.GameSession.c2s_SendCmdNPCSevHello(nid); } } void SendCmdFactionPVPQueryInfo(int idFaction) { int piMax = -1; CECHostPlayer pHost = EC_Game.GetGameRun().GetHostPlayer(); if (pHost.GetCoolTime((int)CSNetwork.GPDataType.CoolTimeIndex.GP_CT_QUERY_MAFIA_PVP_INFO, out piMax) == 0) { UnityGameSession.Instance.GameSession.c2s_SendCmdQueryFactionPVPInfo(idFaction); } } // Send protocols ... public void SendGetPlayerBriefInfo(int iNumPlayer, int[] aIDs, int iReason) { if (iNumPlayer == 0 || aIDs == null || aIDs.Length == 0) return; // 1.�ϲ���ӵ��б� getplayerbriefinfo p = new getplayerbriefinfo(); p.Roleid = EC_Game.GetGameRun().GetHostPlayer().GetCharacterID(); p.Reason = (byte)iReason; for (int i = 0; i < iNumPlayer; ++i) { if (aIDs[i] != 0) p.Playerlist.Add(aIDs[i]); } if (p.Playerlist.Count > 0) m_GetPlayerBriefInfoList.Add(p); // 2.��鲢���� SendCachedGetPlayerBriefInfo(); } void SendGetPlayerBaseInfo(int iNumRole, int[] aRoleIDs) { if (iNumRole == 0 || aRoleIDs == null || aRoleIDs.Length == 0) return; for (int i = 0; i < iNumRole; i++) { if (aRoleIDs[i] != 0) m_PlayerBaseInfoList.Add(aRoleIDs[i]); } SendCachedPlayerBaseInfo(); } void SendGivePresentProtocol(int roleid, int mailid, int itemid, int index, int slot) { presentInfo info = new presentInfo(); info.roleid = roleid; info.mailid = mailid; info.itemid = itemid; info.index = index; info.slot = slot; m_PresentInfoList.Add(info); } void SendFactionPVPGetMap() { CECCounter pCnt = m_CounterMap2[(int)ProtocolType.PROTOCOL_FACTIONRESOURCEBATTLEGETMAP]; if (pCnt.IsFull()) { pCnt.Reset(); factionresourcebattlegetmap p = new factionresourcebattlegetmap(); p.Roleid = EC_Game.GetGameRun().GetHostPlayer().GetCharacterID(); UnityGameSession.Instance.GameSession.SendProtocol(p); } } void SendFactionPVPGetRank() { CECCounter pCnt = m_CounterMap2[(int)ProtocolType.PROTOCOL_FACTIONRESOURCEBATTLEGETRECORD]; if (pCnt.IsFull()) { pCnt.Reset(); factionresourcebattlegetrecord p = new factionresourcebattlegetrecord(); p.Roleid = EC_Game.GetGameRun().GetHostPlayer().GetCharacterID(); UnityGameSession.Instance.GameSession.SendProtocol(p); } } } }