From df936e8c9c0fc5e9a6b5b8872a48224807fde7ae Mon Sep 17 00:00:00 2001 From: kamilprzyb Date: Thu, 24 Sep 2020 21:51:25 +0200 Subject: [PATCH 1/5] set up "go to the time machine" button working --- src/NPCManager.cpp | 22 +++++++++++++++++----- src/NPCManager.hpp | 3 +++ src/PlayerManager.cpp | 2 +- src/PlayerManager.hpp | 2 +- 4 files changed, 22 insertions(+), 7 deletions(-) diff --git a/src/NPCManager.cpp b/src/NPCManager.cpp index 45249f1..3a7926e 100644 --- a/src/NPCManager.cpp +++ b/src/NPCManager.cpp @@ -18,6 +18,7 @@ std::vector NPCManager::RespawnPoints; void NPCManager::init() { REGISTER_SHARD_PACKET(P_CL2FE_REQ_PC_WARP_USE_NPC, npcWarpHandler); + REGISTER_SHARD_PACKET(P_CL2FE_REQ_PC_TIME_TO_GO_WARP, npcWarpTimeMachine); REGISTER_SHARD_PACKET(P_CL2FE_REQ_NPC_SUMMON, npcSummonHandler); REGISTER_SHARD_PACKET(P_CL2FE_REQ_NPC_UNSUMMON, npcUnsummonHandler); REGISTER_SHARD_PACKET(P_CL2FE_REQ_BARKER, npcBarkHandler); @@ -499,17 +500,28 @@ void NPCManager::npcWarpHandler(CNSocket* sock, CNPacketData* data) { return; // malformed packet sP_CL2FE_REQ_PC_WARP_USE_NPC* warpNpc = (sP_CL2FE_REQ_PC_WARP_USE_NPC*)data->buf; - PlayerView& plrv = PlayerManager::players[sock]; + handleWarp(sock, warpNpc->iWarpID); +} +void NPCManager::npcWarpTimeMachine(CNSocket* sock, CNPacketData* data) { + if (data->size != sizeof(sP_CL2FE_REQ_PC_TIME_TO_GO_WARP)) + return; // malformed packet + // this is just a warp request + handleWarp(sock, 28); +} + +void NPCManager::handleWarp(CNSocket* sock, int32_t warpId) { // sanity check - if (Warps.find(warpNpc->iWarpID) == Warps.end()) + if (Warps.find(warpId) == Warps.end()) return; + PlayerView& plrv = PlayerManager::players[sock]; + // send to client INITSTRUCT(sP_FE2CL_REP_PC_WARP_USE_NPC_SUCC, resp); - resp.iX = Warps[warpNpc->iWarpID].x; - resp.iY = Warps[warpNpc->iWarpID].y; - resp.iZ = Warps[warpNpc->iWarpID].z; + resp.iX = Warps[warpId].x; + resp.iY = Warps[warpId].y; + resp.iZ = Warps[warpId].z; // force player & NPC reload PlayerManager::removePlayerFromChunks(plrv.currentChunks, sock); diff --git a/src/NPCManager.hpp b/src/NPCManager.hpp index aee6553..7e40950 100644 --- a/src/NPCManager.hpp +++ b/src/NPCManager.hpp @@ -28,6 +28,7 @@ namespace NPCManager { void npcSummonHandler(CNSocket* sock, CNPacketData* data); void npcUnsummonHandler(CNSocket* sock, CNPacketData* data); void npcWarpHandler(CNSocket* sock, CNPacketData* data); + void npcWarpTimeMachine(CNSocket* sock, CNPacketData* data); void npcVendorStart(CNSocket* sock, CNPacketData* data); void npcVendorTable(CNSocket* sock, CNPacketData* data); @@ -36,4 +37,6 @@ namespace NPCManager { void npcVendorBuyback(CNSocket* sock, CNPacketData* data); void npcVendorBuyBattery(CNSocket* sock, CNPacketData* data); void npcCombineItems(CNSocket* sock, CNPacketData* data); + + void handleWarp(CNSocket* sock, int32_t warpId); } diff --git a/src/PlayerManager.cpp b/src/PlayerManager.cpp index 5fd1e5f..6ff9247 100644 --- a/src/PlayerManager.cpp +++ b/src/PlayerManager.cpp @@ -37,7 +37,7 @@ void PlayerManager::init() { REGISTER_SHARD_PACKET(P_CL2FE_REQ_PC_SPECIAL_STATE_SWITCH, PlayerManager::setSpecialSwitchPlayer); REGISTER_SHARD_PACKET(P_CL2FE_REQ_PC_VEHICLE_ON, PlayerManager::enterPlayerVehicle); REGISTER_SHARD_PACKET(P_CL2FE_REQ_PC_VEHICLE_OFF, PlayerManager::exitPlayerVehicle); - REGISTER_SHARD_PACKET(P_CL2FE_REQ_PC_CHANGE_MENTOR, PlayerManager::changePlayerGuide); + REGISTER_SHARD_PACKET(P_CL2FE_REQ_PC_CHANGE_MENTOR, PlayerManager::changePlayerGuide); } void PlayerManager::addPlayer(CNSocket* key, Player plr) { diff --git a/src/PlayerManager.hpp b/src/PlayerManager.hpp index b67b7ac..1fdd4d3 100644 --- a/src/PlayerManager.hpp +++ b/src/PlayerManager.hpp @@ -50,7 +50,7 @@ namespace PlayerManager { void setSpecialPlayer(CNSocket* sock, CNPacketData* data); void heartbeatPlayer(CNSocket* sock, CNPacketData* data); void revivePlayer(CNSocket* sock, CNPacketData* data); - void exitGame(CNSocket* sock, CNPacketData* data); + void exitGame(CNSocket* sock, CNPacketData* data); void setSpecialSwitchPlayer(CNSocket* sock, CNPacketData* data); void changePlayerGuide(CNSocket *sock, CNPacketData *data); From 1874f1081b5c5509d1271952e40eea6a33493498 Mon Sep 17 00:00:00 2001 From: kamilprzyb Date: Thu, 24 Sep 2020 22:32:09 +0200 Subject: [PATCH 2/5] warping to the past now sets PayZoneFlag and removes all active missions --- src/MissionManager.cpp | 12 ++++++++---- src/MissionManager.hpp | 1 + src/PlayerManager.cpp | 12 +++++++++++- 3 files changed, 20 insertions(+), 5 deletions(-) diff --git a/src/MissionManager.cpp b/src/MissionManager.cpp index e70beb3..c77e775 100644 --- a/src/MissionManager.cpp +++ b/src/MissionManager.cpp @@ -157,13 +157,17 @@ void MissionManager::quitMission(CNSocket* sock, CNPacketData* data) { return; // malformed packet sP_CL2FE_REQ_PC_TASK_STOP* missionData = (sP_CL2FE_REQ_PC_TASK_STOP*)data->buf; + quitTask(sock, missionData->iTaskNum); +} + +void MissionManager::quitTask(CNSocket* sock, int32_t TaskNum) { INITSTRUCT(sP_FE2CL_REP_PC_TASK_STOP_SUCC, response); - Player *plr = PlayerManager::getPlayer(sock); + Player* plr = PlayerManager::getPlayer(sock); // update player int i; for (i = 0; i < ACTIVE_MISSION_COUNT; i++) { - if (plr->tasks[i] == missionData->iTaskNum) + if (plr->tasks[i] == TaskNum) { plr->tasks[i] = 0; for (int j = 0; j < 3; j++) { @@ -177,7 +181,7 @@ void MissionManager::quitMission(CNSocket* sock, CNPacketData* data) { // remove current mission plr->CurrentMissionID = 0; - TaskData& task = *Tasks[missionData->iTaskNum]; + TaskData& task = *Tasks[TaskNum]; // clean up quest items for (i = 0; i < 3; i++) { @@ -193,7 +197,7 @@ void MissionManager::quitMission(CNSocket* sock, CNPacketData* data) { memset(&plr->QInven[j], 0, sizeof(sItemBase)); } - response.iTaskNum = missionData->iTaskNum; + response.iTaskNum = TaskNum; sock->sendPacket((void*)&response, P_FE2CL_REP_PC_TASK_STOP_SUCC, sizeof(sP_FE2CL_REP_PC_TASK_STOP_SUCC)); } diff --git a/src/MissionManager.hpp b/src/MissionManager.hpp index 4ecf75c..991622d 100644 --- a/src/MissionManager.hpp +++ b/src/MissionManager.hpp @@ -56,4 +56,5 @@ namespace MissionManager { void mobKilled(CNSocket *sock, int mobid); void saveMission(Player* player, int missionId); + void quitTask(CNSocket* sock, int32_t TaskNum); } diff --git a/src/PlayerManager.cpp b/src/PlayerManager.cpp index 6ff9247..02395b9 100644 --- a/src/PlayerManager.cpp +++ b/src/PlayerManager.cpp @@ -815,7 +815,17 @@ void PlayerManager::changePlayerGuide(CNSocket *sock, CNPacketData *data) { resp.iFusionMatter = plr->fusionmatter; // no cost sock->sendPacket((void*)&resp, P_FE2CL_REP_PC_CHANGE_MENTOR_SUCC, sizeof(sP_FE2CL_REP_PC_CHANGE_MENTOR_SUCC)); - //save it on player + // if it's changed from computress + if (plr->mentor == 5) { + // we're warping to the past + plr->PCStyle2.iPayzoneFlag = 1; + // remove all active missions + for (int i = 0; i < ACTIVE_MISSION_COUNT; i++) { + if (plr->tasks[i] != 0) + MissionManager::quitTask(sock, plr->tasks[i]); + } + } + // save it on player plr->mentor = pkt->iMentor; } From 86c1cbd0f228002870eeedc031404bcc435269f9 Mon Sep 17 00:00:00 2001 From: kamilprzyb Date: Fri, 25 Sep 2020 02:14:11 +0200 Subject: [PATCH 3/5] added gumballs functionality --- src/ItemManager.cpp | 57 +++++++++++++++++++++++++++++++++++++++++++++ src/ItemManager.hpp | 1 + src/NanoManager.cpp | 9 +++++++ src/NanoManager.hpp | 7 ++++++ src/TableData.cpp | 12 ++++++++++ 5 files changed, 86 insertions(+) diff --git a/src/ItemManager.cpp b/src/ItemManager.cpp index 45a5376..11feb73 100644 --- a/src/ItemManager.cpp +++ b/src/ItemManager.cpp @@ -2,6 +2,7 @@ #include "CNStructs.hpp" #include "ItemManager.hpp" #include "PlayerManager.hpp" +#include "NanoManager.hpp" #include "Player.hpp" #include // for memset() and memcmp() @@ -15,6 +16,8 @@ void ItemManager::init() { REGISTER_SHARD_PACKET(P_CL2FE_REQ_ITEM_MOVE, itemMoveHandler); REGISTER_SHARD_PACKET(P_CL2FE_REQ_PC_ITEM_DELETE, itemDeleteHandler); REGISTER_SHARD_PACKET(P_CL2FE_REQ_PC_GIVE_ITEM, itemGMGiveHandler); + //this one is for gumballs + REGISTER_SHARD_PACKET(P_CL2FE_REQ_ITEM_USE, itemUseHandler); // Bank REGISTER_SHARD_PACKET(P_CL2FE_REQ_PC_BANK_OPEN, itemBankOpenHandler); // Trade handlers @@ -186,6 +189,60 @@ void ItemManager::itemGMGiveHandler(CNSocket* sock, CNPacketData* data) { } } +void ItemManager::itemUseHandler(CNSocket* sock, CNPacketData* data) { + if (data->size != sizeof(sP_CL2FE_REQ_ITEM_USE)) + return; // ignore the malformed packet + sP_CL2FE_REQ_ITEM_USE* request = (sP_CL2FE_REQ_ITEM_USE*)data->buf; + Player* player = PlayerManager::getPlayer(sock); + + //gumball can only be used from inventory, so we ignore eIL + sItemBase gumball = player->Inven[request->iSlotNum]; + sNano nano = player->Nanos[player->equippedNanos[request->iNanoSlot]]; + + //sanity check, check if gumball exists + if (!(gumball.iOpt > 0 && gumball.iType == 7 && gumball.iID>=119 && gumball.iID<=121)) { + std::cout << "[WARN] Gumball not found" << std::endl; + INITSTRUCT(sP_FE2CL_REP_PC_ITEM_USE_FAIL, response); + sock->sendPacket((void*)&response, P_FE2CL_REP_PC_ITEM_USE_FAIL, sizeof(sP_FE2CL_REP_PC_ITEM_USE_FAIL)); + return; + } + + //sanity check, check if gumball type matches nano style + int nanoStyle = NanoManager::nanoStyle(nano.iID); + if (!((gumball.iID == 119 && nanoStyle == 0) || + ( gumball.iID == 120 && nanoStyle == 1) || + ( gumball.iID == 121 && nanoStyle == 2))) { + std::cout << "[WARN] Gumball type doesn't match nano type" << std::endl; + INITSTRUCT(sP_FE2CL_REP_PC_ITEM_USE_FAIL, response); + sock->sendPacket((void*)&response, P_FE2CL_REP_PC_ITEM_USE_FAIL, sizeof(sP_FE2CL_REP_PC_ITEM_USE_FAIL)); + return; + } + + gumball.iOpt -= 1; + if (gumball.iOpt == 0) + gumball = {}; + + INITSTRUCT(sP_FE2CL_REP_PC_ITEM_USE_SUCC, response); + response.iPC_ID = player->iID; + response.eIL = 1; + response.iSlotNum = request->iSlotNum; + response.RemainItem = gumball; + // response.iTargetCnt = ? + // response.eST = ? + // response.iSkillID = ? + + sock->sendPacket((void*)&response, P_FE2CL_REP_PC_ITEM_USE_SUCC, sizeof(sP_FE2CL_REP_PC_ITEM_USE_SUCC)); + //update inventory serverside + player->Inven[response.iSlotNum] = response.RemainItem; + + //this is a temporary way of calling buff efect + //TODO: send buff data via response packet + int value1 = CSB_BIT_STIMPAKSLOT1 << request->iNanoSlot; + int value2 = ECSB_STIMPAKSLOT1 + request->iNanoSlot; + + NanoManager::nanoBuff(sock, nano.iID, 144, EST_NANOSTIMPAK, value1, value2, 0); +} + void ItemManager::itemBankOpenHandler(CNSocket* sock, CNPacketData* data) { if (data->size != sizeof(sP_CL2FE_REQ_PC_BANK_OPEN)) return; // ignore the malformed packet diff --git a/src/ItemManager.hpp b/src/ItemManager.hpp index 7972734..b7221c3 100644 --- a/src/ItemManager.hpp +++ b/src/ItemManager.hpp @@ -31,6 +31,7 @@ namespace ItemManager { void itemMoveHandler(CNSocket* sock, CNPacketData* data); void itemDeleteHandler(CNSocket* sock, CNPacketData* data); void itemGMGiveHandler(CNSocket* sock, CNPacketData* data); + void itemUseHandler(CNSocket* sock, CNPacketData* data); // Bank void itemBankOpenHandler(CNSocket* sock, CNPacketData* data); void itemTradeOfferHandler(CNSocket* sock, CNPacketData* data); diff --git a/src/NanoManager.cpp b/src/NanoManager.cpp index a132b54..fbe6217 100644 --- a/src/NanoManager.cpp +++ b/src/NanoManager.cpp @@ -36,6 +36,8 @@ std::set TreasureFinderPowers = {26, 40, 74}; * worker functions so we don't have to have unsightly function declarations. */ +std::map NanoManager::NanoTable; + }; // namespace void NanoManager::init() { @@ -593,6 +595,13 @@ void NanoManager::nanoUnbuff(CNSocket* sock, int32_t iCBFlag, int16_t eCharStatu sock->sendPacket((void*)&resp1, P_FE2CL_PC_BUFF_UPDATE, sizeof(sP_FE2CL_PC_BUFF_UPDATE)); } +// 0=A 1=B 2=C -1=Not found +int NanoManager::nanoStyle(int nanoId) { + if (nanoId < 0 || nanoId >= NanoTable.size()) + return -1; + return NanoTable[nanoId].style; +} + namespace NanoManager { std::vector PassivePowers = { diff --git a/src/NanoManager.hpp b/src/NanoManager.hpp index 8a6f3fd..246474d 100644 --- a/src/NanoManager.hpp +++ b/src/NanoManager.hpp @@ -34,9 +34,14 @@ struct PassivePower { PassivePower(std::set p, int16_t t, int32_t f, int16_t b, int16_t a) : powers(p), eSkillType(t), iCBFlag(f), eCharStatusTimeBuffID(b), iValue(a) {} }; +struct NanoData { + int style; +}; + namespace NanoManager { extern std::vector ActivePowers; extern std::vector PassivePowers; + extern std::map NanoTable; void init(); void nanoSummonHandler(CNSocket* sock, CNPacketData* data); @@ -56,4 +61,6 @@ namespace NanoManager { void nanoBuff(CNSocket* sock, int16_t nanoId, int skillId, int16_t eSkillType, int32_t iCBFlag, int16_t eCharStatusTimeBuffID, int16_t iValue = 0); void nanoUnbuff(CNSocket* sock, int32_t iCBFlag, int16_t eCharStatusTimeBuffID, int16_t iValue = 0); + + int nanoStyle(int nanoId); } diff --git a/src/TableData.cpp b/src/TableData.cpp index f1a5312..a4d1c43 100644 --- a/src/TableData.cpp +++ b/src/TableData.cpp @@ -6,6 +6,7 @@ #include "MissionManager.hpp" #include "MobManager.hpp" #include "ChunkManager.hpp" +#include "NanoManager.hpp" #include "contrib/JSON.hpp" @@ -152,6 +153,17 @@ void TableData::init() { } std::cout << "[INFO] Loaded " << ItemManager::CrocPotTable.size() << " croc pot value sets" << std::endl; + + //load nano info + nlohmann::json nanoInfo = xdtData["m_pNanoTable"]["m_pNanoData"]; + for (nlohmann::json::iterator _nano = nanoInfo.begin(); _nano != nanoInfo.end(); _nano++) { + auto nano = _nano.value(); + NanoData nanoData; + nanoData.style = nano["m_iStyle"]; + NanoManager::NanoTable[nano["m_iNanoNumber"]] = nanoData; + } + + std::cout << "[INFO] Loaded " << NanoManager::NanoTable.size() << " nanos" << std::endl; } catch (const std::exception& err) { std::cerr << "[WARN] Malformed xdt.json file! Reason:" << err.what() << std::endl; From d87306930d7c7c43acf600f3acfe3deb0b00649d Mon Sep 17 00:00:00 2001 From: kamilprzyb Date: Fri, 25 Sep 2020 02:39:30 +0200 Subject: [PATCH 4/5] added nano potions functionality --- src/NanoManager.cpp | 30 ++++++++++++++++++++++++++++++ src/NanoManager.hpp | 1 + 2 files changed, 31 insertions(+) diff --git a/src/NanoManager.cpp b/src/NanoManager.cpp index fbe6217..220bf97 100644 --- a/src/NanoManager.cpp +++ b/src/NanoManager.cpp @@ -49,6 +49,7 @@ void NanoManager::init() { REGISTER_SHARD_PACKET(P_CL2FE_REQ_PC_GIVE_NANO_SKILL, nanoSkillSetGMHandler); REGISTER_SHARD_PACKET(P_CL2FE_REQ_NANO_SKILL_USE, nanoSkillUseHandler); REGISTER_SHARD_PACKET(P_CL2FE_REQ_WARP_USE_RECALL, nanoRecallHandler); + REGISTER_SHARD_PACKET(P_CL2FE_REQ_CHARGE_NANO_STAMINA, nanoPotionHandler); } void NanoManager::nanoEquipHandler(CNSocket* sock, CNPacketData* data) { @@ -171,6 +172,35 @@ void NanoManager::nanoRecallHandler(CNSocket* sock, CNPacketData* data) { // stubbed for now } +void NanoManager::nanoPotionHandler(CNSocket* sock, CNPacketData* data) { + if (data->size != sizeof(sP_CL2FE_REQ_CHARGE_NANO_STAMINA)) + return; + + Player* player = PlayerManager::getPlayer(sock); + //sanity check + if (player->activeNano == -1 || player->batteryN == 0) + return; + + sNano nano = player->Nanos[player->activeNano]; + int difference = 150 - nano.iStamina; + if (player->batteryN < difference) + difference = player->batteryN; + + if (difference == 0) + return; + + INITSTRUCT(sP_FE2CL_REP_CHARGE_NANO_STAMINA, response); + response.iNanoID = nano.iID; + response.iNanoStamina = nano.iStamina + difference; + response.iBatteryN = player->batteryN - difference; + + sock->sendPacket((void*)&response, P_FE2CL_REP_CHARGE_NANO_STAMINA, sizeof(sP_FE2CL_REP_CHARGE_NANO_STAMINA)); + //now update serverside + player->batteryN -= difference; + player->Nanos[nano.iID].iStamina += difference; + +} + #pragma region Helper methods void NanoManager::addNano(CNSocket* sock, int16_t nanoId, int16_t slot) { if (nanoId > 36) diff --git a/src/NanoManager.hpp b/src/NanoManager.hpp index 246474d..13cc2a1 100644 --- a/src/NanoManager.hpp +++ b/src/NanoManager.hpp @@ -52,6 +52,7 @@ namespace NanoManager { void nanoSkillSetHandler(CNSocket* sock, CNPacketData* data); void nanoSkillSetGMHandler(CNSocket* sock, CNPacketData* data); void nanoRecallHandler(CNSocket* sock, CNPacketData* data); + void nanoPotionHandler(CNSocket* sock, CNPacketData* data); // Helper methods void addNano(CNSocket* sock, int16_t nanoId, int16_t slot); From 320a82997a5c919f4a276ac615559ea5c06e6ea9 Mon Sep 17 00:00:00 2001 From: kamilprzyb Date: Fri, 25 Sep 2020 03:00:50 +0200 Subject: [PATCH 5/5] formatting fix --- src/MissionManager.cpp | 8 ++++---- src/MissionManager.hpp | 2 +- src/PlayerManager.hpp | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/MissionManager.cpp b/src/MissionManager.cpp index c77e775..25e4005 100644 --- a/src/MissionManager.cpp +++ b/src/MissionManager.cpp @@ -160,14 +160,14 @@ void MissionManager::quitMission(CNSocket* sock, CNPacketData* data) { quitTask(sock, missionData->iTaskNum); } -void MissionManager::quitTask(CNSocket* sock, int32_t TaskNum) { +void MissionManager::quitTask(CNSocket* sock, int32_t taskNum) { INITSTRUCT(sP_FE2CL_REP_PC_TASK_STOP_SUCC, response); Player* plr = PlayerManager::getPlayer(sock); // update player int i; for (i = 0; i < ACTIVE_MISSION_COUNT; i++) { - if (plr->tasks[i] == TaskNum) + if (plr->tasks[i] == taskNum) { plr->tasks[i] = 0; for (int j = 0; j < 3; j++) { @@ -181,7 +181,7 @@ void MissionManager::quitTask(CNSocket* sock, int32_t TaskNum) { // remove current mission plr->CurrentMissionID = 0; - TaskData& task = *Tasks[TaskNum]; + TaskData& task = *Tasks[taskNum]; // clean up quest items for (i = 0; i < 3; i++) { @@ -197,7 +197,7 @@ void MissionManager::quitTask(CNSocket* sock, int32_t TaskNum) { memset(&plr->QInven[j], 0, sizeof(sItemBase)); } - response.iTaskNum = TaskNum; + response.iTaskNum = taskNum; sock->sendPacket((void*)&response, P_FE2CL_REP_PC_TASK_STOP_SUCC, sizeof(sP_FE2CL_REP_PC_TASK_STOP_SUCC)); } diff --git a/src/MissionManager.hpp b/src/MissionManager.hpp index 991622d..a6a27af 100644 --- a/src/MissionManager.hpp +++ b/src/MissionManager.hpp @@ -56,5 +56,5 @@ namespace MissionManager { void mobKilled(CNSocket *sock, int mobid); void saveMission(Player* player, int missionId); - void quitTask(CNSocket* sock, int32_t TaskNum); + void quitTask(CNSocket* sock, int32_t taskNum); } diff --git a/src/PlayerManager.hpp b/src/PlayerManager.hpp index 1fdd4d3..b67b7ac 100644 --- a/src/PlayerManager.hpp +++ b/src/PlayerManager.hpp @@ -50,7 +50,7 @@ namespace PlayerManager { void setSpecialPlayer(CNSocket* sock, CNPacketData* data); void heartbeatPlayer(CNSocket* sock, CNPacketData* data); void revivePlayer(CNSocket* sock, CNPacketData* data); - void exitGame(CNSocket* sock, CNPacketData* data); + void exitGame(CNSocket* sock, CNPacketData* data); void setSpecialSwitchPlayer(CNSocket* sock, CNPacketData* data); void changePlayerGuide(CNSocket *sock, CNPacketData *data);