diff --git a/Assets/PerfectWorld/Scripts/Managers/EC_ManPlayer.cs b/Assets/PerfectWorld/Scripts/Managers/EC_ManPlayer.cs index e6ee8e3f25..02b1458ec8 100644 --- a/Assets/PerfectWorld/Scripts/Managers/EC_ManPlayer.cs +++ b/Assets/PerfectWorld/Scripts/Managers/EC_ManPlayer.cs @@ -58,25 +58,26 @@ namespace PerfectWorld.Scripts.Managers OnMsgPlayerStopMove(Msg); break; } - case int value when value == EC_MsgDef.MSG_PM_PLAYERBASEINFO: - case int value2 when value2 == EC_MsgDef.MSG_PM_FACTION_PVP_MASK_MODIFY: - case int value3 when value3 == EC_MsgDef.MSG_PM_PLAYERATKRESULT: - case int value4 when value4 == EC_MsgDef.MSG_PM_CASTSKILL: - case int value5 when value5 == EC_MsgDef.MSG_PM_ENCHANTRESULT: - case int value6 when value6 == EC_MsgDef.MSG_PM_PLAYERDOEMOTE: - case int value7 when value7 == EC_MsgDef.MSG_PM_PLAYERGATHER: - case int value8 when value8 == EC_MsgDef.MSG_PM_PLAYERFLY: - case int value9 when value9 == EC_MsgDef.MSG_PM_PLAYERMOUNT: - case int value10 when value10 == EC_MsgDef.MSG_PM_PLAYERCHGSHAPE: + case EC_MsgDef.MSG_PM_PLAYEREQUIPDATA: + case EC_MsgDef.MSG_PM_PLAYERBASEINFO: + case EC_MsgDef.MSG_PM_FACTION_PVP_MASK_MODIFY: + case EC_MsgDef.MSG_PM_PLAYERATKRESULT: + case EC_MsgDef.MSG_PM_CASTSKILL: + case EC_MsgDef.MSG_PM_ENCHANTRESULT: + case EC_MsgDef.MSG_PM_PLAYERDOEMOTE: + case EC_MsgDef.MSG_PM_PLAYERGATHER: + case EC_MsgDef.MSG_PM_PLAYERFLY: + case EC_MsgDef.MSG_PM_PLAYERMOUNT: + case EC_MsgDef.MSG_PM_PLAYERCHGSHAPE: TransmitMessage(Msg); break; - case int value when value == EC_MsgDef.MSG_PM_PLAYERDIED: + case EC_MsgDef.MSG_PM_PLAYERDIED: OnMsgPlayerDied(Msg); break; - case int value when value == EC_MsgDef.MSG_PM_PLAYERREVIVE: + case EC_MsgDef.MSG_PM_PLAYERREVIVE: OnMsgPlayerRevive(Msg); break; - case int value when value == EC_MsgDef.MSG_PM_PLAYERRUNOUT: + case EC_MsgDef.MSG_PM_PLAYERRUNOUT: OnMsgPlayerRunOut(Msg); break; case EC_MsgDef.MSG_PM_PICKUPMATTER: @@ -622,14 +623,26 @@ namespace PerfectWorld.Scripts.Managers switch (Msg.dwMsg) { - case long value when value == EC_MsgDef.MSG_PM_PLAYEREQUIPDATA: - if ((int)Msg.dwParam2 == CommandID.EQUIP_DATA) - cid = GPDataTypeHelper.FromBytes((byte[])Msg.dwParam1).idPlayer; + case EC_MsgDef.MSG_PM_PLAYEREQUIPDATA: + var param2 = Convert.ToInt32(Msg.dwParam2); + if (param2 == CommandID.EQUIP_DATA) + { + // cid = GPDataTypeHelper.FromBytes((byte[])Msg.dwParam1).idPlayer; + var buffer = new byte[4]; + Array.Copy((byte[])Msg.dwParam1, 2, buffer, 0, 4); + cid = BitConverter.ToInt32(buffer, 0); + } else // EQUIP_DATA_CHANGED - cid = GPDataTypeHelper.FromBytes((byte[])Msg.dwParam1).idPlayer; + { + // cid = GPDataTypeHelper.FromBytes((byte[])Msg.dwParam1).idPlayer; + var buffer = new byte[4]; + Array.Copy((byte[])Msg.dwParam1, 2, buffer, 0, 4); + cid = BitConverter.ToInt32(buffer, 0); + } + break; - case long value when value == EC_MsgDef.MSG_PM_PLAYERBASEINFO: + case EC_MsgDef.MSG_PM_PLAYERBASEINFO: cid = (int)((playerbaseinfo_re)Msg.dwParam1).Player.id; // Xoá khỏi cache UnityGameSession.Instance.GetC2SCmdCache().RemovePlayerBaseInfo(cid); @@ -645,22 +658,22 @@ namespace PerfectWorld.Scripts.Managers else cid = ((cmd_object_landing)msg.dwParam1).object_id; break;*/ - case long value when value == EC_MsgDef.MSG_PM_PLAYERATKRESULT: + case EC_MsgDef.MSG_PM_PLAYERATKRESULT: cmd_object_atk_result pCmdAtk = GPDataTypeHelper.FromBytes((byte[])Msg.dwParam1); cid = pCmdAtk.attacker_id; break; - case long value when value == EC_MsgDef.MSG_PM_CASTSKILL: + case EC_MsgDef.MSG_PM_CASTSKILL: switch (Convert.ToInt32(Msg.dwParam2)) { - case int value2 when value2 == CommandID.OBJECT_CAST_SKILL: cid = (GPDataTypeHelper.FromBytes((byte[])Msg.dwParam1)).caster; break; - case int value2 when value2 == CommandID.OBJECT_CAST_INSTANT_SKILL: cid = (GPDataTypeHelper.FromBytes((byte[])Msg.dwParam1)).caster; break; - case int value2 when value2 == CommandID.OBJECT_CAST_POS_SKILL: cid = (GPDataTypeHelper.FromBytes((byte[])Msg.dwParam1)).caster; break; - case int value2 when value2 == CommandID.SKILL_INTERRUPTED: cid = (GPDataTypeHelper.FromBytes((byte[])Msg.dwParam1)).caster; break; - case int value2 when value2 == CommandID.PLAYER_CAST_RUNE_SKILL: cid = (GPDataTypeHelper.FromBytes((byte[])Msg.dwParam1)).caster; break; - case int value2 when value2 == CommandID.PLAYER_CAST_RUNE_INSTANT_SKILL: cid = (GPDataTypeHelper.FromBytes((byte[])Msg.dwParam1)).caster; break; + case CommandID.OBJECT_CAST_SKILL: cid = (GPDataTypeHelper.FromBytes((byte[])Msg.dwParam1)).caster; break; + case CommandID.OBJECT_CAST_INSTANT_SKILL: cid = (GPDataTypeHelper.FromBytes((byte[])Msg.dwParam1)).caster; break; + case CommandID.OBJECT_CAST_POS_SKILL: cid = (GPDataTypeHelper.FromBytes((byte[])Msg.dwParam1)).caster; break; + case CommandID.SKILL_INTERRUPTED: cid = (GPDataTypeHelper.FromBytes((byte[])Msg.dwParam1)).caster; break; + case CommandID.PLAYER_CAST_RUNE_SKILL: cid = (GPDataTypeHelper.FromBytes((byte[])Msg.dwParam1)).caster; break; + case CommandID.PLAYER_CAST_RUNE_INSTANT_SKILL: cid = (GPDataTypeHelper.FromBytes((byte[])Msg.dwParam1)).caster; break; } break; - case long value when value == EC_MsgDef.MSG_PM_PLAYERDOEMOTE: + case EC_MsgDef.MSG_PM_PLAYERDOEMOTE: if (Convert.ToInt32(Msg.dwParam2) == CommandID.OBJECT_DO_EMOTE) { @@ -673,11 +686,11 @@ namespace PerfectWorld.Scripts.Managers } break; - case long value when value == EC_MsgDef.MSG_PM_ENCHANTRESULT: + case EC_MsgDef.MSG_PM_ENCHANTRESULT: cid = GPDataTypeHelper.FromBytes((byte[])Msg.dwParam1).caster; break; - case long value when value == EC_MsgDef.MSG_PM_PLAYERGATHER: + case EC_MsgDef.MSG_PM_PLAYERGATHER: if (Convert.ToInt32(Msg.dwParam2) == CommandID.PLAYER_GATHER_START) { @@ -696,7 +709,7 @@ namespace PerfectWorld.Scripts.Managers } break; - case long value when value == EC_MsgDef.MSG_PM_PLAYERFLY: + case EC_MsgDef.MSG_PM_PLAYERFLY: if (Convert.ToInt32(Msg.dwParam2) == CommandID.OBJECT_TAKEOFF) cid = (GPDataTypeHelper.FromBytes((byte[])Msg.dwParam1)).object_id; @@ -704,12 +717,12 @@ namespace PerfectWorld.Scripts.Managers cid = (GPDataTypeHelper.FromBytes((byte[])Msg.dwParam1)).object_id; break; - case long value when value == EC_MsgDef.MSG_PM_PLAYERMOUNT: + case EC_MsgDef.MSG_PM_PLAYERMOUNT: cid = (GPDataTypeHelper.FromBytes((byte[])Msg.dwParam1)).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. - case long value when value == EC_MsgDef.MSG_PM_PLAYERCHGSHAPE: + case EC_MsgDef.MSG_PM_PLAYERCHGSHAPE: cid = (GPDataTypeHelper.FromBytes((byte[])Msg.dwParam1)).idPlayer; break; default: @@ -719,7 +732,7 @@ namespace PerfectWorld.Scripts.Managers if (cid == 0) { - System.Diagnostics.Debug.Assert(false, "cid = 0"); + BMLogger.LogError("cid = 0, Msg.dwMsg = " + Msg.dwMsg); return false; } diff --git a/Assets/PerfectWorld/Scripts/Network/CSNetwork/CSNetwork.csproj.meta b/Assets/PerfectWorld/Scripts/Network/CSNetwork/CSNetwork.csproj.meta new file mode 100644 index 0000000000..333a9b1482 --- /dev/null +++ b/Assets/PerfectWorld/Scripts/Network/CSNetwork/CSNetwork.csproj.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: d0c06c588e2a6442488a3542551fb243 +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PerfectWorld/Scripts/Network/CSNetwork/GPDataType.cs b/Assets/PerfectWorld/Scripts/Network/CSNetwork/GPDataType.cs index dd96c4f617..a8ad0cd69e 100644 --- a/Assets/PerfectWorld/Scripts/Network/CSNetwork/GPDataType.cs +++ b/Assets/PerfectWorld/Scripts/Network/CSNetwork/GPDataType.cs @@ -702,7 +702,6 @@ namespace CSNetwork.GPDataType public ushort crc; public int idPlayer; public long mask; - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)] public int[] data; //0 ~ 29 // bool CheckValid(size_t buf_size, size_t& sz) const @@ -720,6 +719,72 @@ namespace CSNetwork.GPDataType // return buf_size >= sz; // } + + public static cmd_equip_data FromBytes(byte[] buffer) + { + cmd_equip_data cmd = new cmd_equip_data(); + + if (buffer.Length > 0) + { + byte[] tempBuf = new byte[2]; + Array.Copy(buffer, 0, tempBuf, 0, 2); + cmd.crc = BitConverter.ToUInt16(tempBuf, 0); + tempBuf = new byte[4]; + Array.Copy(buffer, 2, tempBuf, 0, 4); + cmd.idPlayer = BitConverter.ToInt32(tempBuf, 0); + tempBuf = new byte[8]; + Array.Copy(buffer, 6, tempBuf, 0, 8); + cmd.mask = BitConverter.ToInt64(tempBuf, 0); + + byte sz = 0; + for (int i = 0; i < 32; i++) + { + if ((cmd.mask & (1L << i)) != 0) + sz += 4; // sizeof(int) + } + + if (buffer.Length < sz) + return cmd; + + tempBuf = new byte[4]; + cmd.data = new int[sz / 4]; + for (int i = 0; i < cmd.data.Length; i++) + { + Array.Copy(buffer, 14 + i * 4, tempBuf, 0, 4); + cmd.data[i] = BitConverter.ToInt32(tempBuf, 0); + } + return cmd; + } + + return cmd; + } + } + + public struct cmd_equip_data_changed + { + public ushort crc; + public int idPlayer; + public long mask_add; + public long mask_del; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)] + public int[] data_add; //0 ~ 29 + + public bool CheckValid(uint buf_size, uint sz) + { + // sz = sizeof(*this) - sizeof(data_add); + + // if (buf_size < sz) + // return false; + + // for (int i = 0; i < 32; i++) + // { + // if (mask_add & (1 << i)) + // sz += sizeof(int); + // } + + // return buf_size >= sz; + return true; + } } [StructLayout(LayoutKind.Sequential, Pack = 1)] diff --git a/Assets/PerfectWorld/Scripts/Network/CSNetwork/GameSession.cs b/Assets/PerfectWorld/Scripts/Network/CSNetwork/GameSession.cs index f527d312b2..a8bd66659d 100644 --- a/Assets/PerfectWorld/Scripts/Network/CSNetwork/GameSession.cs +++ b/Assets/PerfectWorld/Scripts/Network/CSNetwork/GameSession.cs @@ -817,7 +817,9 @@ namespace CSNetwork break; case CommandID.EQUIP_DATA: case CommandID.EQUIP_DATA_CHANGED: - BMLogger.Log($"### EQUIP_DATA: CMDID {pCmdHeader}"); + // BMLogger.Log($"### EQUIP_DATA: CMDID {pCmdHeader}"); + // MSG_PM_PLAYEREQUIPDATA, MAN_PLAYER, -1, (DWORD)pDataBuf, pCmdHeader->cmd, dwDataSize); + EC_ManMessage.PostMessage(EC_MsgDef.MSG_PM_PLAYEREQUIPDATA, MANAGER_INDEX.MAN_PLAYER, -1, pDataBuf, pCmdHeader); break; case CommandID.PLAYER_EQUIP_DETAIL: // View other player profile/equip detail — parse and log with real game data (item names, slot names) diff --git a/Assets/PerfectWorld/Scripts/Players/EC_ElsePlayer.cs b/Assets/PerfectWorld/Scripts/Players/EC_ElsePlayer.cs index 4c8e9affdf..7376e6d17c 100644 --- a/Assets/PerfectWorld/Scripts/Players/EC_ElsePlayer.cs +++ b/Assets/PerfectWorld/Scripts/Players/EC_ElsePlayer.cs @@ -16,6 +16,7 @@ using Cysharp.Threading.Tasks; using PerfectWorld.Scripts; using PerfectWorld.Scripts.Managers; using UnityEngine; +using System.Collections.Generic; namespace BrewMonster { @@ -47,6 +48,9 @@ namespace BrewMonster CECEPWorkMan m_pEPWorkMan; private CECEPWork _workStand; CECHostPlayer pHost => EC_ManMessageMono.Instance?.GetECManPlayer?.GetHostPlayer(); + + public int[] m_aNewEquips = new int[InventoryConst.SIZE_ALL_EQUIPIVTR]; // New equipment item ID array + public long m_i64NewEqpMask; // New equipment mask public void Init(info_player_1 Info, int iAppearFlag) { @@ -428,21 +432,12 @@ namespace BrewMonster { switch (Msg.dwMsg) { - case long value when value == EC_MsgDef.MSG_PM_PLAYERBASEINFO: - OnMsgPlayerBaseInfo(Msg); - break; - case long value when value == EC_MsgDef.MSG_PM_PLAYERATKRESULT: - OnMsgPlayerAtkResult(Msg); - break; - case long value when value == EC_MsgDef.MSG_PM_PLAYERDOEMOTE: - OnMsgPlayerDoEmote(Msg); - break; - case long value when value == EC_MsgDef.MSG_PM_PLAYERGATHER: - OnMsgPlayerGather(Msg); - break; - case long value when value == EC_MsgDef.MSG_PM_PLAYERMOUNT: - OnMsgPlayerMount(Msg); - break; + case EC_MsgDef.MSG_PM_PLAYERBASEINFO: OnMsgPlayerBaseInfo(Msg); break; + case EC_MsgDef.MSG_PM_PLAYEREQUIPDATA: OnMsgPlayerEquipData(Msg); break; + case EC_MsgDef.MSG_PM_PLAYERATKRESULT: OnMsgPlayerAtkResult(Msg); break; + case EC_MsgDef.MSG_PM_PLAYERDOEMOTE: OnMsgPlayerDoEmote(Msg); break; + case EC_MsgDef.MSG_PM_PLAYERGATHER: OnMsgPlayerGather(Msg); break; + case EC_MsgDef.MSG_PM_PLAYERMOUNT: OnMsgPlayerMount(Msg); break; } return true; } @@ -482,6 +477,44 @@ namespace BrewMonster } } + public void OnMsgPlayerEquipData(ECMSG Msg) + { + // using namespace S2C; + + // int crc, *aAdded=NULL; + int crc = -1; + int[] aAdded = null; + bool bReset = false; + long iAddMask = 0; + long iDelMask = 0; + + int dwParam2 = Convert.ToInt32(Msg.dwParam2); + if (dwParam2 == CommandID.EQUIP_DATA) + { + cmd_equip_data pCmd = cmd_equip_data.FromBytes((byte[])Msg.dwParam1); + + bReset = true; + crc = pCmd.crc; + iAddMask = pCmd.mask; + iDelMask = 0; + aAdded = pCmd.data; + } + // else // Msg.dwParam2 == EQUIP_DATA_CHANGED + // { + // cmd_equip_data_changed* pCmd = (cmd_equip_data_changed*)Msg.dwParam1; + // ASSERT(pCmd); + + // bReset = false; + // crc = pCmd->crc; + // iAddMask = pCmd->mask_add; + // iDelMask = pCmd->mask_del; + // aAdded = iAddMask ? pCmd->data_add : NULL; + // } + + // // Change equipment + ChangeEquipments(bReset, crc, iAddMask, iDelMask, aAdded); + } + void OnMsgPlayerAtkResult(ECMSG Msg) { @@ -636,6 +669,124 @@ namespace BrewMonster // return new A3DVECTOR3(transform.position.x, transform.position.y, transform.position.z); //} + // Change equipment + bool ChangeEquipments(bool bReset, int crc, long iAddMask, long iDelMask, int[] aAddedEquip) + { + m_PlayerInfo.crc_e = crc; + + if (bReset) + { + // m_i64NewEqpMask = EQUIP_MASK64_ALL; + m_bEquipReady = true; + + // memset(m_aEquips, 0xff, sizeof (m_aEquips)); + // memset(m_aNewEquips, 0, sizeof (m_aNewEquips)); + } + + // Remove equipment at first + if (iDelMask != 0) + { + for (int i=0; i < InventoryConst.SIZE_ALL_EQUIPIVTR; i++) + { + if ((iDelMask & (1L << i)) != 0) + { + m_aNewEquips[i] = 0; + m_i64NewEqpMask |= (1L << i); + } + } + } + + if (iAddMask != 0 && aAddedEquip != null) + { + int iCount = 0; + for (int i=0; i < InventoryConst.SIZE_ALL_EQUIPIVTR; i++) + { + if ((iAddMask & (1L << i)) != 0) + { + m_aNewEquips[i] = aAddedEquip[iCount++]; + m_i64NewEqpMask |= (1L << i); + } + } + } + + // this is some sort of hack to get the equipment to load immediately + // TODO: Check again if this should be done here + ShowEquipments(m_aNewEquips, true, true); + + // TODO: Implement the rest of the equipment logic + /*/ + if (!ShouldUseModel()) + return true; + + if (IsSkeletonReady()) + LoadPlayerEquipments(); + + // Deal with goblin£¨¼òµ¥Ä£ÐͲ»¼ÓÔØÐ¡¾«Á飩 + if(m_aNewEquips[EQUIPIVTR_GOBLIN] != 0 && ShouldUseClothedModel()) + { + int tid = m_aNewEquips[EQUIPIVTR_GOBLIN] & 0x0000ffff; + int idModel = (m_aNewEquips[EQUIPIVTR_GOBLIN] >>16) & 0x000000ff; + int iRefineLvl = (m_aNewEquips[EQUIPIVTR_GOBLIN] >>24) & 0x000000ff; + + ASSERT(idModel >= 1 && idModel <= 4); + ASSERT(iRefineLvl >=0 && iRefineLvl <= 36); + + if( !m_pGoblin ) + { + m_pGoblin = new CECGoblin(); + if(!m_pGoblin->Init(tid, idModel,iRefineLvl,this)) + { + ASSERT(0); + m_pGoblin->Release(); + delete m_pGoblin; + m_pGoblin = NULL; + } + } + else + { + if(tid != m_pGoblin->GetTemplateID() || + idModel != (int)m_pGoblin->GetModelID() || + iRefineLvl != m_pGoblin->GetRefineLevel()) + { + m_pGoblin->Release(); + delete m_pGoblin; + m_pGoblin = NULL; + + m_pGoblin = new CECGoblin(); + if(!m_pGoblin->Init(tid, idModel,iRefineLvl,this)) + { + ASSERT(0); + m_pGoblin->Release(); + delete m_pGoblin; + m_pGoblin = NULL; + } + } + } + } + else // m_aNewEquips[EQUIPIVTR_GOBLIN] == 0 + { + if(m_pGoblin) + { + m_pGoblin->Release(); + delete m_pGoblin; + m_pGoblin = NULL; + } + } + + // Deal with armet + if(InFashionMode()) + { + UpdateHairModel(true, m_aNewEquips[EQUIPIVTR_FASHION_HEAD]); + } + else + { + UpdateHairModel(true, m_aNewEquips[EQUIPIVTR_HEAD]); + } + //*/ + + return true; + } + private void SetPlayerBriefInfo(int iProf, int iGender, string szName) { m_iProfession = iProf; diff --git a/Assets/Settings/SampleSceneProfile.asset b/Assets/Settings/PC_SceneProfile.asset similarity index 98% rename from Assets/Settings/SampleSceneProfile.asset rename to Assets/Settings/PC_SceneProfile.asset index bd2b823ee9..910c984584 100644 --- a/Assets/Settings/SampleSceneProfile.asset +++ b/Assets/Settings/PC_SceneProfile.asset @@ -18,7 +18,7 @@ MonoBehaviour: m_Value: 0 threshold: m_OverrideState: 1 - m_Value: 0.5 + m_Value: 0.8 intensity: m_OverrideState: 1 m_Value: 1 @@ -85,7 +85,7 @@ MonoBehaviour: m_Enabled: 1 m_EditorHideFlags: 0 m_Script: {fileID: 11500000, guid: d7fd9488000d3734a9e00ee676215985, type: 3} - m_Name: SampleSceneProfile + m_Name: PC_SceneProfile m_EditorClassIdentifier: components: - {fileID: 849379129802519247} diff --git a/Assets/Settings/SampleSceneProfile.asset.meta b/Assets/Settings/PC_SceneProfile.asset.meta similarity index 100% rename from Assets/Settings/SampleSceneProfile.asset.meta rename to Assets/Settings/PC_SceneProfile.asset.meta