From 53da747d569aaa321da2781f89fde241124d3412 Mon Sep 17 00:00:00 2001 From: HungDK <> Date: Tue, 4 Nov 2025 14:36:40 +0700 Subject: [PATCH] Request and play anim revive --- .../Scripts/Managers/EC_ManPlayer.cs | 1011 +++++++++-------- .../Scripts/Network/CSNetwork/GameSession.cs | 32 + .../Scripts/Network/UnityGameSession.cs | 12 + 3 files changed, 566 insertions(+), 489 deletions(-) diff --git a/Assets/PerfectWorld/Scripts/Managers/EC_ManPlayer.cs b/Assets/PerfectWorld/Scripts/Managers/EC_ManPlayer.cs index 4a4609027c..feba3a85f3 100644 --- a/Assets/PerfectWorld/Scripts/Managers/EC_ManPlayer.cs +++ b/Assets/PerfectWorld/Scripts/Managers/EC_ManPlayer.cs @@ -1,490 +1,523 @@ -using BrewMonster; -using BrewMonster.Network; -using CSNetwork; -using CSNetwork.GPDataType; -using CSNetwork.Protocols; -using CSNetwork.Protocols.RPCData; -using PerfectWorld.Scripts.Player; -using System; -using System.Collections; -using System.Collections.Generic; -using System.Runtime.InteropServices; -using TMPro; -using UnityEngine; -using UnityEngine.SceneManagement; - -namespace PerfectWorld.Scripts.Managers -{ - namespace BrewMonster.Managers - { - [Serializable] - public class EC_ManPlayer : IMsgHandler - { - Dictionary m_UkPlayerTab = new Dictionary(); - Dictionary m_PlayerTab = new Dictionary(); - private readonly object m_csPlayerTab = new object(); - CECHostPlayer m_pHostPlayer; - public int HandlerId => (int)MANAGER_INDEX.MAN_PLAYER; - public bool ProcessMessage(ECMSG Msg) - { - if (Msg.iSubID == 0) - { - if (GameController.Instance == null) return true; - if (GameController.Instance.GetHostPlayer() == null) return true; - GameController.Instance.GetHostPlayer().ProcessMessage(Msg); - } - else if (Msg.iSubID < 0) - { - switch ((int)Msg.dwMsg) - { - case int value when value == EC_MsgDef.MSG_PM_PLAYERINFO: - { - OnMsgPlayerInfo(Msg); - break; - } - case int value when value == EC_MsgDef.MSG_PM_PLAYERMOVE: - { - OnMsgPlayerMove(Msg); - break; - } - case int value when value == EC_MsgDef.MSG_PM_PLAYERSTOPMOVE: - { - OnMsgPlayerStopMove(Msg); - break; - } - case int value when value == EC_MsgDef.MSG_PM_FACTION_PVP_MASK_MODIFY: - case int value1 when value1 == EC_MsgDef.MSG_PM_PLAYERATKRESULT: - Debug.Log("EC_MsgDef.MSG_PM_FACTION_PVP_MASK_MODIFY"); - TransmitMessage(Msg); - break; - } - } - else - { - - } - return true; - } - - public void OnMsgPlayerInfo(ECMSG Msg) - { - int iHostID = Convert.ToInt32(Msg.dwParam3); - int lenghtByte = Marshal.SizeOf(); - byte[] byteArray = new byte[lenghtByte]; - byte[] data = (byte[])Msg.dwParam1; - for (int i = 0; i < lenghtByte; i++) - { - byteArray[i] = data[i]; - } - int cid = BitConverter.ToInt32(byteArray); - int commandID = Convert.ToInt32(Msg.dwParam2); - switch (commandID) - { - case CommandID.PLAYER_INFO_1: - case CommandID.PLAYER_ENTER_WORLD: - case CommandID.PLAYER_ENTER_SLICE: - { - if (cid != iHostID) - { - info_player_1 info_Player_1 = GPDataTypeHelper.FromBytes((byte[])Msg.dwParam1); - RoleInfo roleInfo = (RoleInfo)Msg.dwParam4; - ElsePlayerEnter(info_Player_1, commandID, roleInfo); - GameController.Instance.Log("ElsePlayer has join"); - } - break; - } - case CommandID.SELF_INFO_1: - cmd_self_info_1 info = GPDataTypeHelper.FromBytes((byte[])Msg.dwParam1); - HostPlayerInfo1(info); - break; - case CommandID.PLAYER_INFO_2: break; - case CommandID.PLAYER_INFO_3: break; - case CommandID.PLAYER_INFO_4: break; - - case CommandID.PLAYER_INFO_1_LIST: - { - byte[] bytes = (byte[])Msg.dwParam1; - cmd_player_info_1_list pCmd = GPDataTypeHelper.FromBytes(bytes); - if (pCmd.count == 0) - { - break; - } - int lenght = Marshal.SizeOf(); - int preSize = 0; - byte[] pDataBuf = null; - preSize += Marshal.SizeOf(); - RoleInfo roleInfo = (RoleInfo)Msg.dwParam4; - for (int i = 0; i < pCmd.count; i++) - { - pDataBuf = new byte[lenght]; - for (int j = 0; j < pDataBuf.Length; j++) - { - pDataBuf[j] = bytes[preSize + j]; - } - info_player_1 Info = GPDataTypeHelper.FromBytes(pDataBuf); - if (Info.cid != iHostID) - { - EC_ElsePlayer pPlayer = ElsePlayerEnter(Info, commandID, roleInfo); - } - - // Calculate player info data size and skip it - int iSize = Marshal.SizeOf(); - if ((Info.state & PlayerNPCState.GP_STATE_ADV_MODE) != 0) - iSize += Marshal.SizeOf() * 2; - - if ((Info.state & PlayerNPCState.GP_STATE_SHAPE) != 0) - iSize += Marshal.SizeOf(); - - if ((Info.state & PlayerNPCState.GP_STATE_EMOTE) != 0) - iSize += Marshal.SizeOf(); - - if ((Info.state & PlayerNPCState.GP_STATE_EXTEND_PROPERTY) != 0) - iSize += Marshal.SizeOf() * NumberDWORDsPlayerNPC.OBJECT_EXT_STATE_COUNT; - - if ((Info.state & PlayerNPCState.GP_STATE_FACTION) != 0) - iSize += (Marshal.SizeOf() + Marshal.SizeOf()); - - if ((Info.state & PlayerNPCState.GP_STATE_BOOTH) != 0) - iSize += Marshal.SizeOf(); - - //// Parse effect data - if ((Info.state & PlayerNPCState.GP_STATE_EFFECT) != 0) - { - iSize += Marshal.SizeOf(); - byte byNum = bytes[preSize + iSize]; - - if (byNum > 0) - iSize += byNum * Marshal.SizeOf(); - } - - if ((Info.state & PlayerNPCState.GP_STATE_PARIAH) != 0) - iSize += Marshal.SizeOf(); - - if ((Info.state & PlayerNPCState.GP_STATE_IN_MOUNT) != 0) - iSize += Marshal.SizeOf() + Marshal.SizeOf(); - - // Parse bind data - if ((Info.state & PlayerNPCState.GP_STATE_IN_BIND) != 0) - iSize += Marshal.SizeOf() + Marshal.SizeOf(); - - // Parse spouse data - if ((Info.state & PlayerNPCState.GP_STATE_SPOUSE) != 0) - iSize += Marshal.SizeOf(); - - if ((Info.state & PlayerNPCState.GP_STATE_EQUIPDISABLED) != 0) - iSize += Marshal.SizeOf(); - - if ((Info.state & PlayerNPCState.GP_STATE_PLAYERFORCE) != 0) - iSize += Marshal.SizeOf(); - - if ((Info.state & PlayerNPCState.GP_STATE_MULTIOBJ_EFFECT) != 0) - { - int effectNum = Marshal.ReadInt32(bytes, iSize);//*(int*)(pDataBuf + iSize); - iSize += Marshal.SizeOf(); - - if (effectNum > 0) - iSize += effectNum * (Marshal.SizeOf() + Marshal.SizeOf()); - } - - if ((Info.state & PlayerNPCState.GP_STATE_COUNTRY) != 0) - iSize += Marshal.SizeOf(); - if ((Info.state2 & PlayerNPCState2.GP_STATE2_TITLE) != 0) - iSize += Marshal.SizeOf(); - if ((Info.state2 & PlayerNPCState2.GP_STATE2_REINCARNATION) != 0) - iSize += Marshal.SizeOf(); - if ((Info.state2 & PlayerNPCState2.GP_STATE2_REALM) != 0) - iSize += Marshal.SizeOf(); - if ((Info.state2 & PlayerNPCState2.GP_STATE2_FACTION_PVP_MASK) != 0) - iSize += Marshal.SizeOf(); - - // Goblin refine data - if ((Info.state & PlayerNPCState.GP_STATE_GOBLINREFINE) != 0) - iSize += Marshal.SizeOf(); - - //pDataBuf += iSize; - - preSize += iSize; - } - break; - } - } - } - - public void OnMsgPlayerMove(ECMSG Msg) - { - int iHostID = Convert.ToInt32(Msg.dwParam3); - cmd_object_move pCmd = GPDataTypeHelper.FromBytes((byte[])Msg.dwParam1); - if (pCmd.use_time == 0) - return; - if (pCmd.id != iHostID) - { - EC_ElsePlayer pPlayer = SeekOutElsePlayer(pCmd.id); - if (pPlayer) - { - pPlayer.MoveTo(pCmd); - } - } - } - - public bool HostPlayerInfo1(cmd_self_info_1 info) - { - //bool isDoneWorldRender = false; - //bool isDoneNPCRender = false; - //Action actLoadChar = () => - //{ - // if (!isDoneNPCRender || !isDoneWorldRender) - // { - // return; - // } - // GameController.Instance.InitCharacter(info); - //}; - //string nameScene = "NPCRender"; - //UnityGameSession.Instance.LoadScene(nameScene, LoadSceneMode.Single, (value) => - //{ - // isDoneNPCRender = value; - // actLoadChar?.Invoke(); - //}); - //nameScene = "WorldRender"; - //UnityGameSession.Instance.LoadScene(nameScene, LoadSceneMode.Additive, (value) => - //{ - // isDoneWorldRender = value; - // actLoadChar?.Invoke(); - //}); - //UnityGameSession.Instance.LoadScene("HoangTest", LoadSceneMode.Single, (value) => - //{ - // isDoneWorldRender = value; - // actLoadChar?.Invoke(); - //}); - GameController.Instance.InitCharacter(info); - return true; - } - - public EC_ElsePlayer ElsePlayerEnter(info_player_1 info, int iCmd, RoleInfo roleInfo) - { - // If this player's id is in unknown table, remove it because this player - // won't be unknown anymore - if (m_UkPlayerTab.TryGetValue(info.cid, out int value)) - { - if (value != 0) // Pair.second != 0 - { - m_UkPlayerTab.Remove(info.cid); - } - } - - int iAppearFlag = (iCmd == (int)CommandID.PLAYER_ENTER_WORLD) ? - (int)PlayerAppearFlag.APPEAR_ENTERWORLD : (int)PlayerAppearFlag.APPEAR_RUNINTOVIEW; - - // Has player been in active player table ? - EC_ElsePlayer pPlayer = GetElsePlayer(info.cid); - if (pPlayer) - { - // This player has existed in player table, call special initial function - // TODO: fix after pPlayer init - pPlayer.Init(roleInfo, info); - return pPlayer; - } - - // Create a new player - if (!(pPlayer = CreateElsePlayer(roleInfo, info, iAppearFlag))) - { - return null; - } - lock (m_csPlayerTab) - { - if (m_PlayerTab.ContainsKey(info.cid)) - { - m_PlayerTab[info.cid] = pPlayer; - } - else - { - m_PlayerTab.Add(info.cid, pPlayer); - } - } - return pPlayer; - } - - private EC_ElsePlayer CreateElsePlayer(RoleInfo roleInfo, info_player_1 info, int iAppearFlag) - { - GameObject ob = GameController.Instance.InitCharacter(info); - EC_ElsePlayer elsePlayer = ob.AddComponent(); - elsePlayer.GetComponent().enabled = false; - //init - elsePlayer.Init(roleInfo, info); - return elsePlayer; - } - - public EC_ElsePlayer GetElsePlayer(int cid, long dwBornStamp = 0) - { - lock (m_csPlayerTab) - { - if (!m_PlayerTab.TryGetValue(cid, out var player)) - return null; - if (dwBornStamp != 0) - { - //TO DO: fix after GetBornStamp() is create in code - //if (player.GetBornStamp() != dwBornStamp) - return null; - } - - return player; - } - } - - private EC_ElsePlayer SeekOutElsePlayer(int cid) - { - if (!m_PlayerTab.TryGetValue(cid, out var player)) - { - // Couldn't find this else player, put it into unknown player table - m_UkPlayerTab[cid] = cid; - return null; - } - - return player; - } - - - public bool OnMsgPlayerStopMove(ECMSG Msg) - { - cmd_object_stop_move pCmd = GPDataTypeHelper.FromBytes((byte[])Msg.dwParam1); - EC_ElsePlayer pPlayer = SeekOutElsePlayer(pCmd.id); - if (pPlayer) - pPlayer.StopMoveTo(pCmd); - return true; - } - - //private cmd_object_move ConvertToStruct(byte[] bytes) - //{ - // if (bytes.Length < Marshal.SizeOf()) - // { - // return default; - // } - - // cmd_object_move result = new cmd_object_move(); - // int preLenghtData = 0; - // int lenghtDataType = Marshal.SizeOf(); - // byte[] arrByteData = GetBytes(bytes, lenghtDataType, preLenghtData); - // result.id = BitConverter.ToInt32(arrByteData); - - // preLenghtData += lenghtDataType; - // lenghtDataType = Marshal.SizeOf(); - // arrByteData = GetBytes(bytes, lenghtDataType, preLenghtData); - // result.dest_X = BitConverter.ToSingle(arrByteData); - - // preLenghtData += lenghtDataType; - // lenghtDataType = Marshal.SizeOf(); - // arrByteData = GetBytes(bytes, lenghtDataType, preLenghtData); - // result.dest_Y = BitConverter.ToSingle(arrByteData); - - // preLenghtData += lenghtDataType; - // lenghtDataType = Marshal.SizeOf(); - // arrByteData = GetBytes(bytes, lenghtDataType, preLenghtData); - // result.dest_Z = BitConverter.ToSingle(arrByteData); - - // preLenghtData += lenghtDataType; - // lenghtDataType = Marshal.SizeOf(); - // arrByteData = GetBytes(bytes, lenghtDataType, preLenghtData); - // result.use_time = BitConverter.ToUInt16(arrByteData); - - // preLenghtData += lenghtDataType; - // lenghtDataType = Marshal.SizeOf(); - // arrByteData = GetBytes(bytes, lenghtDataType, preLenghtData); - // result.sSpeed = BitConverter.ToInt16(arrByteData); - - // preLenghtData += lenghtDataType; - // result.move_mode = bytes[preLenghtData + 1]; - // return result; - //} - - private byte[] GetBytes(byte[] bytes, int length, int index) - { - byte[] arrByteData = new byte[length]; - for (int i = 0; i < length; i++) - { - arrByteData[i] = bytes[i + index]; - } - return arrByteData; - } - - public void Initialize() - { - - } - public bool TransmitMessage(ECMSG msg) - { - int cid = 0; - var host = GameController.Instance.GetHostPlayer(); - - switch (msg.dwMsg) - { - /*case long value when value == EC_MsgDef.MSG_PM_PLAYEREQUIPDATA: - if (msg.dwParam2 == S2C.EQUIP_DATA) - cid = ((cmd_equip_data)msg.dwParam1).idPlayer; - else // EQUIP_DATA_CHANGED - cid = ((cmd_equip_data_changed)msg.dwParam1).idPlayer; - break;*/ - - case long value when value == EC_MsgDef.MSG_PM_PLAYERBASEINFO: - cid = (int)((playerbaseinfo_re)msg.dwParam1).Player.id; - // Xoá khỏi cache - //g_pGame.GetGameSession().GetC2SCmdCache().RemovePlayerBaseInfo(cid); - break; - - /*case long value when value == EC_MsgDef.MSG_PM_PLAYERCUSTOM: - cid = ((GetCustomData_Re)msg.dwParam1).cus_roleid; - break; - - case long value when value == EC_MsgDef.MSG_PM_PLAYERFLY: - if (msg.dwParam2 == S2C.OBJECT_TAKEOFF) - cid = ((cmd_object_takeoff)msg.dwParam1).object_id; - else - cid = ((cmd_object_landing)msg.dwParam1).object_id; - break;*/ - case long value when value == EC_MsgDef.MSG_PM_PLAYERATKRESULT: - cmd_object_atk_result pCmdAtk = GPDataTypeHelper.FromBytes((byte[])msg.dwParam1); - cid = pCmdAtk.attacker_id; - break; - // ⚠️ Các case khác cũng tương tự, chỉ việc lấy ra đúng trường id / caster / user ... - // Do quá dài nên bạn có thể copy dần từng case từ C++ sang. - - default: - System.Diagnostics.Debug.Assert(false, "Unknown message"); - return false; - } - - if (cid == 0) - { - System.Diagnostics.Debug.Assert(false, "cid = 0"); - return false; - } - - if (host != null && cid == host.GetCharacterID()) - { - host.ProcessMessage(msg); - } - else - { - var elsePlayer = SeekOutElsePlayer(cid); - if (elsePlayer != null) - elsePlayer.ProcessMessage(msg); - } - - return true; - } - - // Get a player (may be host or else player) by id - public CECPlayer GetPlayer(int cid, uint dwBornStamp = 0) - { - CECHostPlayer pHost = GetHostPlayer(); - if (pHost && pHost.GetCharacterID() == cid) - return pHost; - else - return GetElsePlayer(cid, dwBornStamp); - } - - public CECHostPlayer GetHostPlayer() - { - return GameController.Instance.GetHostPlayer(); - } - } - } +using BrewMonster; +using BrewMonster.Network; +using CSNetwork; +using CSNetwork.GPDataType; +using CSNetwork.Protocols; +using CSNetwork.Protocols.RPCData; +using PerfectWorld.Scripts.Player; +using System; +using System.Collections; +using System.Collections.Generic; +using System.Runtime.InteropServices; +using TMPro; +using UnityEngine; +using UnityEngine.SceneManagement; + +namespace PerfectWorld.Scripts.Managers +{ + namespace BrewMonster.Managers + { + [Serializable] + public class EC_ManPlayer : IMsgHandler + { + Dictionary m_UkPlayerTab = new Dictionary(); + Dictionary m_PlayerTab = new Dictionary(); + private readonly object m_csPlayerTab = new object(); + CECHostPlayer m_pHostPlayer; + public int HandlerId => (int)MANAGER_INDEX.MAN_PLAYER; + public bool ProcessMessage(ECMSG Msg) + { + if (Msg.iSubID == 0) + { + if (GameController.Instance == null) return true; + if (GameController.Instance.GetHostPlayer() == null) return true; + GameController.Instance.GetHostPlayer().ProcessMessage(Msg); + } + else if (Msg.iSubID < 0) + { + switch ((int)Msg.dwMsg) + { + case int value when value == EC_MsgDef.MSG_PM_PLAYERINFO: + { + OnMsgPlayerInfo(Msg); + break; + } + case int value when value == EC_MsgDef.MSG_PM_PLAYERMOVE: + { + OnMsgPlayerMove(Msg); + break; + } + case int value when value == EC_MsgDef.MSG_PM_PLAYERSTOPMOVE: + { + OnMsgPlayerStopMove(Msg); + break; + } + case int value when value == EC_MsgDef.MSG_PM_FACTION_PVP_MASK_MODIFY: + case int value1 when value1 == EC_MsgDef.MSG_PM_PLAYERATKRESULT: + Debug.Log("EC_MsgDef.MSG_PM_FACTION_PVP_MASK_MODIFY"); + TransmitMessage(Msg); + break; + case int value when value == EC_MsgDef.MSG_PM_PLAYERDIED: + OnMsgPlayerDied(Msg); + break; + case int value when value == EC_MsgDef.MSG_PM_PLAYERREVIVE: + OnMsgPlayerRevive(Msg); + break; + } + } + else + { + + } + return true; + } + + private void OnMsgPlayerDied(ECMSG Msg) + { + cmd_player_died pCmd = GPDataTypeHelper.FromBytes((byte[])Msg.dwParam1); + EC_ElsePlayer pPlayer = SeekOutElsePlayer(pCmd.idPlayer); + //if (pPlayer && !pPlayer.IsAboutToDie()) + // pPlayer.Killed(pCmd.idKiller); + + EventBus.PublishChannel(pPlayer.GetCharacterID(), new CECPlayer.CleearComActFlagAllRankNodesEvent(true)); + pPlayer.PlayAction((int)CECPlayer.PLAYER_ACTION_TYPE.ACT_GROUNDDIE); + } + + private void OnMsgPlayerRevive(ECMSG Msg) + { + cmd_player_revive pCmd = GPDataTypeHelper.FromBytes((byte[])Msg.dwParam1); + CECHostPlayer pHost = GetHostPlayer(); + if (pHost && pHost.GetCharacterID() == pCmd.idPlayer) + { + pHost.HandleRevive(pCmd.sReviveType, pCmd.pos); + } + else + { + EC_ElsePlayer pPlayer = SeekOutElsePlayer(pCmd.idPlayer); + if (pPlayer) + pPlayer.HandleRevive(pCmd.sReviveType, pCmd.pos); + } + } + + public void OnMsgPlayerInfo(ECMSG Msg) + { + int iHostID = Convert.ToInt32(Msg.dwParam3); + int lenghtByte = Marshal.SizeOf(); + byte[] byteArray = new byte[lenghtByte]; + byte[] data = (byte[])Msg.dwParam1; + for (int i = 0; i < lenghtByte; i++) + { + byteArray[i] = data[i]; + } + int cid = BitConverter.ToInt32(byteArray); + int commandID = Convert.ToInt32(Msg.dwParam2); + switch (commandID) + { + case CommandID.PLAYER_INFO_1: + case CommandID.PLAYER_ENTER_WORLD: + case CommandID.PLAYER_ENTER_SLICE: + { + if (cid != iHostID) + { + info_player_1 info_Player_1 = GPDataTypeHelper.FromBytes((byte[])Msg.dwParam1); + RoleInfo roleInfo = (RoleInfo)Msg.dwParam4; + ElsePlayerEnter(info_Player_1, commandID, roleInfo); + GameController.Instance.Log("ElsePlayer has join"); + } + break; + } + case CommandID.SELF_INFO_1: + cmd_self_info_1 info = GPDataTypeHelper.FromBytes((byte[])Msg.dwParam1); + HostPlayerInfo1(info); + break; + case CommandID.PLAYER_INFO_2: break; + case CommandID.PLAYER_INFO_3: break; + case CommandID.PLAYER_INFO_4: break; + + case CommandID.PLAYER_INFO_1_LIST: + { + byte[] bytes = (byte[])Msg.dwParam1; + cmd_player_info_1_list pCmd = GPDataTypeHelper.FromBytes(bytes); + if (pCmd.count == 0) + { + break; + } + int lenght = Marshal.SizeOf(); + int preSize = 0; + byte[] pDataBuf = null; + preSize += Marshal.SizeOf(); + RoleInfo roleInfo = (RoleInfo)Msg.dwParam4; + for (int i = 0; i < pCmd.count; i++) + { + pDataBuf = new byte[lenght]; + for (int j = 0; j < pDataBuf.Length; j++) + { + pDataBuf[j] = bytes[preSize + j]; + } + info_player_1 Info = GPDataTypeHelper.FromBytes(pDataBuf); + if (Info.cid != iHostID) + { + EC_ElsePlayer pPlayer = ElsePlayerEnter(Info, commandID, roleInfo); + } + + // Calculate player info data size and skip it + int iSize = Marshal.SizeOf(); + if ((Info.state & PlayerNPCState.GP_STATE_ADV_MODE) != 0) + iSize += Marshal.SizeOf() * 2; + + if ((Info.state & PlayerNPCState.GP_STATE_SHAPE) != 0) + iSize += Marshal.SizeOf(); + + if ((Info.state & PlayerNPCState.GP_STATE_EMOTE) != 0) + iSize += Marshal.SizeOf(); + + if ((Info.state & PlayerNPCState.GP_STATE_EXTEND_PROPERTY) != 0) + iSize += Marshal.SizeOf() * NumberDWORDsPlayerNPC.OBJECT_EXT_STATE_COUNT; + + if ((Info.state & PlayerNPCState.GP_STATE_FACTION) != 0) + iSize += (Marshal.SizeOf() + Marshal.SizeOf()); + + if ((Info.state & PlayerNPCState.GP_STATE_BOOTH) != 0) + iSize += Marshal.SizeOf(); + + //// Parse effect data + if ((Info.state & PlayerNPCState.GP_STATE_EFFECT) != 0) + { + iSize += Marshal.SizeOf(); + byte byNum = bytes[preSize + iSize]; + + if (byNum > 0) + iSize += byNum * Marshal.SizeOf(); + } + + if ((Info.state & PlayerNPCState.GP_STATE_PARIAH) != 0) + iSize += Marshal.SizeOf(); + + if ((Info.state & PlayerNPCState.GP_STATE_IN_MOUNT) != 0) + iSize += Marshal.SizeOf() + Marshal.SizeOf(); + + // Parse bind data + if ((Info.state & PlayerNPCState.GP_STATE_IN_BIND) != 0) + iSize += Marshal.SizeOf() + Marshal.SizeOf(); + + // Parse spouse data + if ((Info.state & PlayerNPCState.GP_STATE_SPOUSE) != 0) + iSize += Marshal.SizeOf(); + + if ((Info.state & PlayerNPCState.GP_STATE_EQUIPDISABLED) != 0) + iSize += Marshal.SizeOf(); + + if ((Info.state & PlayerNPCState.GP_STATE_PLAYERFORCE) != 0) + iSize += Marshal.SizeOf(); + + if ((Info.state & PlayerNPCState.GP_STATE_MULTIOBJ_EFFECT) != 0) + { + int effectNum = Marshal.ReadInt32(bytes, iSize);//*(int*)(pDataBuf + iSize); + iSize += Marshal.SizeOf(); + + if (effectNum > 0) + iSize += effectNum * (Marshal.SizeOf() + Marshal.SizeOf()); + } + + if ((Info.state & PlayerNPCState.GP_STATE_COUNTRY) != 0) + iSize += Marshal.SizeOf(); + if ((Info.state2 & PlayerNPCState2.GP_STATE2_TITLE) != 0) + iSize += Marshal.SizeOf(); + if ((Info.state2 & PlayerNPCState2.GP_STATE2_REINCARNATION) != 0) + iSize += Marshal.SizeOf(); + if ((Info.state2 & PlayerNPCState2.GP_STATE2_REALM) != 0) + iSize += Marshal.SizeOf(); + if ((Info.state2 & PlayerNPCState2.GP_STATE2_FACTION_PVP_MASK) != 0) + iSize += Marshal.SizeOf(); + + // Goblin refine data + if ((Info.state & PlayerNPCState.GP_STATE_GOBLINREFINE) != 0) + iSize += Marshal.SizeOf(); + + //pDataBuf += iSize; + + preSize += iSize; + } + break; + } + } + } + + public void OnMsgPlayerMove(ECMSG Msg) + { + int iHostID = Convert.ToInt32(Msg.dwParam3); + cmd_object_move pCmd = GPDataTypeHelper.FromBytes((byte[])Msg.dwParam1); + if (pCmd.use_time == 0) + return; + if (pCmd.id != iHostID) + { + EC_ElsePlayer pPlayer = SeekOutElsePlayer(pCmd.id); + if (pPlayer) + { + pPlayer.MoveTo(pCmd); + } + } + } + + public bool HostPlayerInfo1(cmd_self_info_1 info) + { + //bool isDoneWorldRender = false; + //bool isDoneNPCRender = false; + //Action actLoadChar = () => + //{ + // if (!isDoneNPCRender || !isDoneWorldRender) + // { + // return; + // } + // GameController.Instance.InitCharacter(info); + //}; + //string nameScene = "NPCRender"; + //UnityGameSession.Instance.LoadScene(nameScene, LoadSceneMode.Single, (value) => + //{ + // isDoneNPCRender = value; + // actLoadChar?.Invoke(); + //}); + //nameScene = "WorldRender"; + //UnityGameSession.Instance.LoadScene(nameScene, LoadSceneMode.Additive, (value) => + //{ + // isDoneWorldRender = value; + // actLoadChar?.Invoke(); + //}); + //UnityGameSession.Instance.LoadScene("HoangTest", LoadSceneMode.Single, (value) => + //{ + // isDoneWorldRender = value; + // actLoadChar?.Invoke(); + //}); + GameController.Instance.InitCharacter(info); + return true; + } + + public EC_ElsePlayer ElsePlayerEnter(info_player_1 info, int iCmd, RoleInfo roleInfo) + { + // If this player's id is in unknown table, remove it because this player + // won't be unknown anymore + if (m_UkPlayerTab.TryGetValue(info.cid, out int value)) + { + if (value != 0) // Pair.second != 0 + { + m_UkPlayerTab.Remove(info.cid); + } + } + + int iAppearFlag = (iCmd == (int)CommandID.PLAYER_ENTER_WORLD) ? + (int)PlayerAppearFlag.APPEAR_ENTERWORLD : (int)PlayerAppearFlag.APPEAR_RUNINTOVIEW; + + // Has player been in active player table ? + EC_ElsePlayer pPlayer = GetElsePlayer(info.cid); + if (pPlayer) + { + // This player has existed in player table, call special initial function + // TODO: fix after pPlayer init + pPlayer.Init(roleInfo, info); + return pPlayer; + } + + // Create a new player + if (!(pPlayer = CreateElsePlayer(roleInfo, info, iAppearFlag))) + { + return null; + } + lock (m_csPlayerTab) + { + if (m_PlayerTab.ContainsKey(info.cid)) + { + m_PlayerTab[info.cid] = pPlayer; + } + else + { + m_PlayerTab.Add(info.cid, pPlayer); + } + } + return pPlayer; + } + + private EC_ElsePlayer CreateElsePlayer(RoleInfo roleInfo, info_player_1 info, int iAppearFlag) + { + GameObject ob = GameController.Instance.InitCharacter(info); + EC_ElsePlayer elsePlayer = ob.AddComponent(); + elsePlayer.GetComponent().enabled = false; + //init + elsePlayer.Init(roleInfo, info); + return elsePlayer; + } + + public EC_ElsePlayer GetElsePlayer(int cid, long dwBornStamp = 0) + { + lock (m_csPlayerTab) + { + if (!m_PlayerTab.TryGetValue(cid, out var player)) + return null; + if (dwBornStamp != 0) + { + //TO DO: fix after GetBornStamp() is create in code + //if (player.GetBornStamp() != dwBornStamp) + return null; + } + + return player; + } + } + + private EC_ElsePlayer SeekOutElsePlayer(int cid) + { + if (!m_PlayerTab.TryGetValue(cid, out var player)) + { + // Couldn't find this else player, put it into unknown player table + m_UkPlayerTab[cid] = cid; + return null; + } + + return player; + } + + + public bool OnMsgPlayerStopMove(ECMSG Msg) + { + cmd_object_stop_move pCmd = GPDataTypeHelper.FromBytes((byte[])Msg.dwParam1); + EC_ElsePlayer pPlayer = SeekOutElsePlayer(pCmd.id); + if (pPlayer) + pPlayer.StopMoveTo(pCmd); + return true; + } + + //private cmd_object_move ConvertToStruct(byte[] bytes) + //{ + // if (bytes.Length < Marshal.SizeOf()) + // { + // return default; + // } + + // cmd_object_move result = new cmd_object_move(); + // int preLenghtData = 0; + // int lenghtDataType = Marshal.SizeOf(); + // byte[] arrByteData = GetBytes(bytes, lenghtDataType, preLenghtData); + // result.id = BitConverter.ToInt32(arrByteData); + + // preLenghtData += lenghtDataType; + // lenghtDataType = Marshal.SizeOf(); + // arrByteData = GetBytes(bytes, lenghtDataType, preLenghtData); + // result.dest_X = BitConverter.ToSingle(arrByteData); + + // preLenghtData += lenghtDataType; + // lenghtDataType = Marshal.SizeOf(); + // arrByteData = GetBytes(bytes, lenghtDataType, preLenghtData); + // result.dest_Y = BitConverter.ToSingle(arrByteData); + + // preLenghtData += lenghtDataType; + // lenghtDataType = Marshal.SizeOf(); + // arrByteData = GetBytes(bytes, lenghtDataType, preLenghtData); + // result.dest_Z = BitConverter.ToSingle(arrByteData); + + // preLenghtData += lenghtDataType; + // lenghtDataType = Marshal.SizeOf(); + // arrByteData = GetBytes(bytes, lenghtDataType, preLenghtData); + // result.use_time = BitConverter.ToUInt16(arrByteData); + + // preLenghtData += lenghtDataType; + // lenghtDataType = Marshal.SizeOf(); + // arrByteData = GetBytes(bytes, lenghtDataType, preLenghtData); + // result.sSpeed = BitConverter.ToInt16(arrByteData); + + // preLenghtData += lenghtDataType; + // result.move_mode = bytes[preLenghtData + 1]; + // return result; + //} + + private byte[] GetBytes(byte[] bytes, int length, int index) + { + byte[] arrByteData = new byte[length]; + for (int i = 0; i < length; i++) + { + arrByteData[i] = bytes[i + index]; + } + return arrByteData; + } + + public void Initialize() + { + + } + public bool TransmitMessage(ECMSG msg) + { + int cid = 0; + var host = GameController.Instance.GetHostPlayer(); + + switch (msg.dwMsg) + { + /*case long value when value == EC_MsgDef.MSG_PM_PLAYEREQUIPDATA: + if (msg.dwParam2 == S2C.EQUIP_DATA) + cid = ((cmd_equip_data)msg.dwParam1).idPlayer; + else // EQUIP_DATA_CHANGED + cid = ((cmd_equip_data_changed)msg.dwParam1).idPlayer; + break;*/ + + case long value when value == EC_MsgDef.MSG_PM_PLAYERBASEINFO: + cid = (int)((playerbaseinfo_re)msg.dwParam1).Player.id; + // Xoá khỏi cache + //g_pGame.GetGameSession().GetC2SCmdCache().RemovePlayerBaseInfo(cid); + break; + + /*case long value when value == EC_MsgDef.MSG_PM_PLAYERCUSTOM: + cid = ((GetCustomData_Re)msg.dwParam1).cus_roleid; + break; + + case long value when value == EC_MsgDef.MSG_PM_PLAYERFLY: + if (msg.dwParam2 == S2C.OBJECT_TAKEOFF) + cid = ((cmd_object_takeoff)msg.dwParam1).object_id; + else + cid = ((cmd_object_landing)msg.dwParam1).object_id; + break;*/ + case long value when value == EC_MsgDef.MSG_PM_PLAYERATKRESULT: + cmd_object_atk_result pCmdAtk = GPDataTypeHelper.FromBytes((byte[])msg.dwParam1); + cid = pCmdAtk.attacker_id; + break; + // ⚠️ Các case khác cũng tương tự, chỉ việc lấy ra đúng trường id / caster / user ... + // Do quá dài nên bạn có thể copy dần từng case từ C++ sang. + + default: + System.Diagnostics.Debug.Assert(false, "Unknown message"); + return false; + } + + if (cid == 0) + { + System.Diagnostics.Debug.Assert(false, "cid = 0"); + return false; + } + + if (host != null && cid == host.GetCharacterID()) + { + host.ProcessMessage(msg); + } + else + { + var elsePlayer = SeekOutElsePlayer(cid); + if (elsePlayer != null) + elsePlayer.ProcessMessage(msg); + } + + return true; + } + + // Get a player (may be host or else player) by id + public CECPlayer GetPlayer(int cid, uint dwBornStamp = 0) + { + CECHostPlayer pHost = GetHostPlayer(); + if (pHost && pHost.GetCharacterID() == cid) + return pHost; + else + return GetElsePlayer(cid, dwBornStamp); + } + + public CECHostPlayer GetHostPlayer() + { + return GameController.Instance.GetHostPlayer(); + } + } + } } \ No newline at end of file diff --git a/Assets/PerfectWorld/Scripts/Network/CSNetwork/GameSession.cs b/Assets/PerfectWorld/Scripts/Network/CSNetwork/GameSession.cs index d1be236edd..0a58379999 100644 --- a/Assets/PerfectWorld/Scripts/Network/CSNetwork/GameSession.cs +++ b/Assets/PerfectWorld/Scripts/Network/CSNetwork/GameSession.cs @@ -252,6 +252,26 @@ namespace CSNetwork SendProtocol(gamedatasendRequest, callback); } + public void RequestReviveBase(int param = 0) + { + gamedatasend gamedatasendRequest = new gamedatasend(); + gamedatasendRequest.Data = C2SCommandFactory.CreateReviveBase(param); + SendProtocol(gamedatasendRequest); + } + public void RequestReviveItem(int param = 0) + { + gamedatasend gamedatasendRequest = new gamedatasend(); + gamedatasendRequest.Data = C2SCommandFactory.CreateReviveBase(param); + SendProtocol(gamedatasendRequest); + } + public void RequestReviveByPlayer(int param = 0) + { + gamedatasend gamedatasendRequest = new gamedatasend(); + gamedatasendRequest.Data = C2SCommandFactory.CreateReviveBase(param); + SendProtocol(gamedatasendRequest); + } + + public void RequestMallShopping(uint count, CMD_MallShopping.goods[] goodsArray) { gamedatasend gamedatasendRequest = new gamedatasend(); @@ -478,6 +498,18 @@ namespace CSNetwork EC_ManMessage.PostMessage(EC_MsgDef.MSG_HST_OWNITEMINFO, (int)MANAGER_INDEX.MAN_PLAYER, 0, pDataBuf, pCmdHeader, iHostID); break; + case CommandID.PLAYER_DIED: + EC_ManMessage.PostMessage(EC_MsgDef.MSG_PM_PLAYERDIED, (int)MANAGER_INDEX.MAN_PLAYER, -1, pDataBuf, pCmdHeader); + break; + case CommandID.HOST_DIED: + EC_ManMessage.PostMessage(EC_MsgDef.MSG_HST_DIED, (int)MANAGER_INDEX.MAN_PLAYER, 0, pDataBuf, pCmdHeader); + break; + case CommandID.PLAYER_REVIVE: + EC_ManMessage.PostMessage(EC_MsgDef.MSG_PM_PLAYERREVIVE, (int)MANAGER_INDEX.MAN_PLAYER, -1, pDataBuf, pCmdHeader); + break; + case CommandID.NOTIFY_HOSTPOS: + EC_ManMessage.PostMessage(EC_MsgDef.MSG_HST_GOTO, (int)MANAGER_INDEX.MAN_PLAYER, 0, pDataBuf, pCmdHeader); + break; case CommandID.NPC_ENTER_SLICE: case CommandID.NPC_INFO_LIST: case CommandID.NPC_INFO_00: diff --git a/Assets/PerfectWorld/Scripts/Network/UnityGameSession.cs b/Assets/PerfectWorld/Scripts/Network/UnityGameSession.cs index d493a1d2ba..f381ea8300 100644 --- a/Assets/PerfectWorld/Scripts/Network/UnityGameSession.cs +++ b/Assets/PerfectWorld/Scripts/Network/UnityGameSession.cs @@ -180,6 +180,18 @@ namespace BrewMonster.Network public static void RequestCheckSecurityPassWd(string password) { Instance._gameSession.RequestCheckSecurityPassWd(password); + } + public static void RequestReviveBase() + { + Instance._gameSession.RequestReviveBase(); + } + public static void RequestReviveItem() + { + Instance._gameSession.RequestReviveItem(); + } + public static void RequestReviveByPlayer() + { + Instance._gameSession.RequestReviveByPlayer(); } public void RequestMallShopping(uint count, int good_id, int good_index, int good_pos)