#include "stdafx.h" //================================================================================================== // #include ////////////////////////////////////////////////////////////////////////// #include #include #include #include #include #include #include #include #include #include #include #include ////////////////////////////////////////////////////////////////////////// #include "FieldServer.h" #include "Map.h" #include "GameField.h" #include "Player.h" #include "PlayerManager.h" #include "Handler_CG_SYNC.h" #include "MissionManager.h" #include "MovementChecker.h" #include "GameZone.h" #include "GameZoneManager.h" #include "MoveStateControl.h" #include "StatusManager.h" #include "MissionRewardManager.h" #include "TriggerManagerEx.h" #include "QuestManager_Concrete.h" #include #include "PlayerWings.h" //_NA001955_110210_WING_COSTUME #include Handler_CG_SYNC::Handler_CG_SYNC() { } Handler_CG_SYNC::~Handler_CG_SYNC() { } //-------------------------------------------------------------------------------------------------- // changes, f100819.1L const nsPacket::PacketHandlerInfo Handler_CG_SYNC::GetPacketHandlerNodes() { #define HANDLER_NODE_INFO(c, p, phase) { MAKEWORD(c, p), phase, Handler_CG_SYNC::On##p } #define HANDLER_NODE_INFO_EOR() { 0, static_cast(0), NULL } static const nsPacket::PacketHandlerNode handlers_static_[] = { HANDLER_NODE_INFO(AG_SYNC, AG_SYNC_PLAYER_ENTER_SYN, PHASE_SERVICE), HANDLER_NODE_INFO(AG_SYNC, AG_SYNC_PLAYER_WARP_SYN, PHASE_SERVICE), // CG_SYNC HANDLER_NODE_INFO(CG_SYNC, CG_SYNC_MOVE_SYN, PHASE_SERVICE), HANDLER_NODE_INFO(CG_SYNC, CG_SYNC_TARGET_MOVE_SYN, PHASE_SERVICE), HANDLER_NODE_INFO(CG_SYNC, CG_SYNC_KBMOVE_SYN, PHASE_SERVICE), HANDLER_NODE_INFO(CG_SYNC, CG_SYNC_STOP_SYN, PHASE_SERVICE), HANDLER_NODE_INFO(CG_SYNC, CG_SYNC_FAST_KBMOVE_SYN, PHASE_SERVICE), HANDLER_NODE_INFO(CG_SYNC, CG_SYNC_JUMP_SYN, PHASE_SERVICE), HANDLER_NODE_INFO(CG_SYNC, CG_SYNC_JUMP_STOP_SYN, PHASE_SERVICE), // _NA001955_110210_WING_COSTUME HANDLER_NODE_INFO(CG_SYNC, CG_SYNC_WINGS_CONTROL_SYN, PHASE_SERVICE), HANDLER_NODE_INFO_EOR() // end of records }; // BOOST_STATIC_ASSERT(_countof(handlers_static_) >= 1); nsPacket::PacketHandlerInfo return_value = { handlers_static_, _countof(handlers_static_) - 1 }; // return return_value; }; //-------------------------------------------------------------------------------------------------- namespace util { namespace internal { ; static void NotifyEnterFieldVersionFault(Player* player, const EngineFileChecksum& client_checksums, const EngineFileChecksum& server_checksums) { MSG_CG_ETC_DEBUGINFO_CMD msg_debug; msg_debug.m_dwObjectKey = player->GetObjectKey(); int written = _snprintf(msg_debug.m_pszChatMsg, _countof(msg_debug.m_pszChatMsg), "|MSG=WMO版本不一样|WmoChecksum=[%8u:%8u]|", server_checksums.checksum_wmo, client_checksums.checksum_wmo); msg_debug.m_pszChatMsg[_countof(msg_debug.m_pszChatMsg) - 1] = '\0'; msg_debug.m_byMsgLength = static_cast(written); player->SendPacket(&msg_debug, msg_debug.GetSize()); } }}; //end of namespace //================================================================================================== // ZONE CONTROL SYNC Handler_CG_SYNC_IMPL(AG_SYNC_PLAYER_ENTER_SYN) { __TOUCHED((pServerSession, pMsg, wSize)); const MSG_AG_SYNC_PLAYER_ENTER_SYN* pRecvMsg = static_cast(pMsg); #ifdef __NA_PACKETFLOW_TEST SUNLOG(eFULL_LOG, "Handler_CG_SYNC(AG_SYNC_PLAYER_ENTER_SYN)"); #endif Player* pPlayer = PlayerManager::Instance()->FindPlayerByUserKey(pRecvMsg->m_dwKey); FlowControl flow; FLOWCONTROL_START() { // start LOGIC_BLOCK if(FALSE == flow.FCAssert(pPlayer)) { SetFailFc(pPlayer, RC::RC_ZONE_FAILED); break; } //检查是否像虚拟客户端一样进入的太快 util::SimpleTimer& loadingTimer = pPlayer->GetLoadingCheckTimer(); if(loadingTimer.GetExpireTime() && !loadingTimer.IsExpired()) { const SERVER_COMMON_OPTION& option = ServerOptionParserEx::Instance()->GetServerOption(); SECURELOG(SECURELOG_PLAYERINFO(pPlayer, eABUSE_LOGIC_VIOLATION, eABUSE_SUB_LOGIC_VIOLATION_LOADING_TIME_SHORT), "[OnAG_SYNC_PLAYER_ENTER_SYN] Loading Time(%d) is Short!", option.m_wABUSE_MIN_CLIENT_LOADING_TIME - loadingTimer.GetRemainedTime()); } loadingTimer.Clear(); GameZone* pEnterZone = NULL; MAPCODE fieldCode = 0; WzID areaID = 0; WzVector vStartPos; const eZONE_STATE eRoom_State = pPlayer->GetGameZone(pEnterZone, fieldCode, &areaID, &vStartPos); IfFailThenBreak(eRoom_State != ePRS_NOT_AT_ZONE, RC::RC_ZONE_FAILED); const KEYTYPE roomKey = pEnterZone->GetKey(); pEnterZone = g_GameZoneManager.GetZone(roomKey); IfFailThen(pEnterZone, RC::RC_ZONE_CANT_FIND_ZONE) { SUNLOG(eCRITICAL_LOG, "["__FUNCTION__"] [U:%d][Room:%d]没图进去.", pPlayer->GetUserKey(), roomKey); break; } //这部分绝对不要注释处理!!请注意!) // (f100623.1L) 更改接口以支持多重校验和检查器 const EngineFileChecksum& client_checksums = pRecvMsg->checksum_list_; EngineFileChecksum checksums = { 0, }; if (g_GameZoneManager.FieldVersionCheck(roomKey, fieldCode, &checksums, client_checksums) == false) { SUNLOG(eCRITICAL_LOG, _T("|ID=%s|信息=C/S Map(%d) 地图版本不匹配|") _T("|FieldCheckSum=[%8u:%8u]|WmoChecksum=[%8u:%8u]|"), pPlayer->GetUserID(), fieldCode, checksums.checksum_map, client_checksums.checksum_map, checksums.checksum_wmo, client_checksums.checksum_wmo); const RC::eZONE_RESULT selected_result = checksums.checksum_map != client_checksums.checksum_map ? RC::RC_ZONE_NOT_MATCHED_MAP_VERSION : RC::RC_ZONE_NOT_MATCHED_WMO_VERSION; // f100916.2L, 支持代理服务器虚拟客户端 if (pRecvMsg->is_dummy_client_test_ != 1) { SetFailFc(FieldVersionCheck, selected_result); break; } } //任务窗口跳转命令包 // 在任务房里这个条件就当是NAK处理吧。. BOOLEAN is_reward_window_open = !!pPlayer->GetMissionManager()->EnableWindowOpen(); if(is_reward_window_open) { IfFailThenBreak(TriggerManagerEx::Check_RewardWindow(pPlayer), RC::RC_ZONE_ASSERTION_FLOW_VIOLATION); } IfFailThenBreak( g_GameZoneManager.JoinPlayer(roomKey, pPlayer, fieldCode, areaID, &vStartPos), RC::RC_ZONE_MAP_PROBLEM); //因为累计经验值需要与现有存储值不同的计算,所以在这里进行检查! pPlayer->FixLevel(); if(is_reward_window_open) TriggerManagerEx::Process_RewardWindow(pPlayer); #if WAVERIX_CODE_BACKUP if(FIELD_SERVER == g_pGameServer->GetServerType()) { //SSQ(堕落的职员)补偿/退款信息有无处理 ISSQHandlerInGame& rHandler = pPlayer->SSQHandler; if(rHandler.IsValidState()) rHandler->Send_RewardProcess(pPlayer); }; #endif GUILDGUID guild_guid = pPlayer->GetGuildGuid(); if(guild_guid != 0) { //向公会服务器发送登录包。嗯。每次乘坐Potal的时候都会用公会发送这个分组..。以后还要考虑别的办法. MSG_GZ_GUILD_LOGIN_CHAR_SYN msgGzSYN; msgGzSYN.m_GuildGuid = guild_guid; msgGzSYN.m_CharGuid = pPlayer->GetCharGuid(); if(pPlayer->SendToGuildServer(&msgGzSYN, sizeof(msgGzSYN)) == 0) { SUNLOG(eCRITICAL_LOG, "["__FUNCTION__"] Fail, Send MSG_GZ_GUILD_LOGIN_CHAR_SYN, " "GuildGuid = %u, CharGuid = %u", guild_guid, pPlayer->GetCharGuid()); } } #ifdef _NA_007330_20140620_GUILD_SYSTEM_EXTENSION else { // 加入公会申请系统时,角色选择窗口中有不重新加载角色信息的问题. // 在这种情况下,由于公会信息无法正常传达,所以向DBP发送分组,确认是否加入公会. MSG_GZ_GUILD_RELOAD_SYN sync_msg; sync_msg.m_dwKey = pPlayer->GetUserKey(); sync_msg.char_guid = pPlayer->GetCharGuid(); pPlayer->SendToGuildServer(&sync_msg, sizeof(sync_msg)); } #endif //_NA_007330_20140620_GUILD_SYSTEM_EXTENSION //__NA001277_090205_NAVI_SYSTEM_SUPPORT__ MSG_CG_QUEST_OBJECT_NAVI_POS_CMD msgNavi; if(pPlayer->GetQuestManager()->MakeInfoQuestNpcNaviStream(&msgNavi)) pPlayer->SendPacket(&msgNavi, msgNavi.GetSize()); // if (client_checksums.pass_result == client_checksums.Passed_But_NotMatchedWmo) { util::internal::NotifyEnterFieldVersionFault(pPlayer, client_checksums, checksums); }; return /*RETURN TRUE VALUE*/; } FLOWCONTROL_END; MSG_CG_SYNC_PLAYER_ENTER_NAK msgNAK; switch(flow.GetErrorCode()) { case RC::RC_ZONE_FAILED: case RC::RC_ZONE_ASSERTION_FLOW_VIOLATION: msgNAK.m_dwErrorCode = RC::RC_ZONE_FAILED; break; case RC::RC_ZONE_CANT_FIND_ZONE: case RC::RC_ZONE_NOT_MATCHED_MAP_VERSION: case RC::RC_ZONE_NOT_MATCHED_WMO_VERSION: // added by _NA000000_100623_CHECK_WMO_CHECKSUM_ case RC::RC_ZONE_MAP_PROBLEM: msgNAK.m_dwErrorCode = flow.GetErrorCode(); break; default: flow.FCAssert("Unexpected flow"); return; } if(pPlayer) pPlayer->SendPacket(&msgNAK, sizeof(msgNAK)); return /*RETURN FALSE VALUE*/; } //================================================================================================== // ZONE CONTROL SYNC Handler_CG_SYNC_IMPL(AG_SYNC_PLAYER_WARP_SYN) { __TOUCHED((pServerSession, pMsg, wSize)); const MSG_AG_SYNC_PLAYER_WARP_SYN* pRecvMsg = static_cast(pMsg); #ifdef __NA_PACKETFLOW_TEST SUNLOG(eFULL_LOG, "Handler_CG_SYNC(AG_SYNC_PLAYER_WARP_SYN)"); #endif Player* pPlayer = PlayerManager::Instance()->FindPlayerByUserKey(pRecvMsg->m_dwKey); FlowControl flow; FLOWCONTROL_START() { // start LOGIC_BLOCK if(FALSE == flow.FCAssert(pPlayer)) { SetFailFc(pPlayer, RC::RC_ZONE_FAILED); break; } GameZone* pEnterZone = NULL; MAPCODE fieldCode = 0; WzID areaID = 0; const eZONE_STATE eRoom_State = pPlayer->GetGameZone(pEnterZone, fieldCode, &areaID); IfFailThenBreak(ePRS_NOT_AT_ZONE != eRoom_State, RC::RC_ZONE_FAILED); const KEYTYPE roomKey = pEnterZone->GetKey(); IfFailThenBreak(pEnterZone = g_GameZoneManager.GetZone(roomKey), RC::RC_ZONE_CANT_FIND_ZONE); // 这部分绝对不要注释处理!!请注意!) // (f100623.1L)更改接口以支持多重校验和检查器 const EngineFileChecksum& client_checksums = pRecvMsg->checksum_list_; EngineFileChecksum checksums = { 0, }; if (g_GameZoneManager.FieldVersionCheck(roomKey, fieldCode, &checksums, client_checksums) == false) { SUNLOG(eCRITICAL_LOG, _T("|ID=%s|信息=C/S Map(%d) 版本不匹配|") _T("|FieldCheckSum=[%8u:%8u]|WmoChecksum=[%8u:%8u]|"), pPlayer->GetUserID(), fieldCode, checksums.checksum_map, client_checksums.checksum_map, checksums.checksum_wmo, client_checksums.checksum_wmo); const RC::eZONE_RESULT selected_result = checksums.checksum_map != client_checksums.checksum_map ? RC::RC_ZONE_NOT_MATCHED_MAP_VERSION : RC::RC_ZONE_NOT_MATCHED_WMO_VERSION; // f100916.2L, 支持代理服务器虚拟客户端 if (pRecvMsg->is_dummy_client_test_ != 1) { SetFailFc(FieldVersionCheck, selected_result); break; } } //任务窗口跳转命令包 // 在任务房间里这个条件就当是NAK处理吧 BOOLEAN is_reward_window_open = !!pPlayer->GetMissionManager()->EnableWindowOpen(); if(is_reward_window_open) { IfFailThenBreak(TriggerManagerEx::Check_RewardWindow(pPlayer), RC::RC_ZONE_ASSERTION_FLOW_VIOLATION); } g_GameZoneManager.WarpPlayer(roomKey, pPlayer, fieldCode, areaID); if(is_reward_window_open) TriggerManagerEx::Process_RewardWindow(pPlayer); if (client_checksums.pass_result == client_checksums.Passed_But_NotMatchedWmo) { util::internal::NotifyEnterFieldVersionFault(pPlayer, client_checksums, checksums); }; return /*RETURN TRUE VALUE*/; } FLOWCONTROL_END; MSG_CG_SYNC_PLAYER_ENTER_NAK msgNAK; switch(flow.GetErrorCode()) { case RC::RC_ZONE_FAILED: case RC::RC_ZONE_ASSERTION_FLOW_VIOLATION: msgNAK.m_dwErrorCode = RC::RC_ZONE_FAILED; break; case RC::RC_ZONE_CANT_FIND_ZONE: case RC::RC_ZONE_NOT_MATCHED_MAP_VERSION: case RC::RC_ZONE_NOT_MATCHED_WMO_VERSION: // added by _NA000000_100623_CHECK_WMO_CHECKSUM_ case RC::RC_ZONE_MAP_PROBLEM: msgNAK.m_dwErrorCode = flow.GetErrorCode(); break; default: flow.FCAssert("Unexpected flow"); return; } if(pPlayer) pPlayer->SendPacket(&msgNAK, sizeof(msgNAK)); return /*RETURN FALSE VALUE*/; } //================================================================================================== // 移动、跳跃等所有移动相关的Common Functions // VOID Handler_CG_SYNC::Send_SYNC_MOVE_NAK(Player* pPlayer, RC::eSYNC_RESULT error_code, DWORD IN error_level, BOOL bThrustMove) { // Common Block MSG_CG_SYNC_MOVE_NAK msgNAK; msgNAK.m_wvCurPos = *pPlayer->GetPosPtr(); msgNAK.m_byErrorCode = error_code; pPlayer->SendPacket(&msgNAK, sizeof(msgNAK)); //停止移动 pPlayer->StopMoving(); // Pre-process filter switch(RC::eSYNC_RESULT skip_filter = error_code) { case RC::RC_SYNC_ANIMATION_DELAY_PROCESSING: return; } switch(error_code) { case RC::RC_SYNC_FAILED: break; case RC::RC_SYNC_SUCCESS: case RC::RC_SYNC_PLAYER_IS_DEAD: // 玩家死亡移动失败 case RC::RC_SYNC_FIELD_IS_NULL: // 玩家的场值为NULL。 case RC::RC_SYNC_PLAYER_IS_UNMOVABLE_STATE: // 玩家处于无法移动的状态。 case RC::RC_SYNC_SETPATH_ERROR: case RC::RC_SYNC_ROUTE_SIZE_EXCESS: // 路径数量超过最大值 case RC::RC_SYNC_INVALID_MOVESATE: // 移动状态异常(行走:跑步) case RC::RC_SYNC_CUR_POSITION_IS_INVALID: // 克莱发来的当前坐标无效. case RC::RC_SYNC_DEST_POSITION_IS_INVALID: // 目的地坐标无效. case RC::RC_SYNC_JUMP_LENGTH_TOO_LONG: // 跳跃距离太远 case RC::RC_SYNC_CUR_POSITION_IS_INVALID_NO_HACK: // 克莱发来的当前坐标无效。在地图的边界线上,Clara可能会发错一些坐标. { // 通知周围停止. MSGSUB_SYNC_STOP_BRD msg; msg.m_dwObjectKey = pPlayer->GetObjectKey(); msg.m_wvCurPos = msgNAK.m_wvCurPos; pPlayer->SendPacketAroundForSync(&msg); } break; default: break; } { // Post Block MovementChecker& rMoveChecker = *pPlayer->GetMovementChecker(); rMoveChecker.AbusingNotify(error_code, error_level, .0f); } } Handler_CG_SYNC_IMPL(CG_SYNC_MOVE_SYN) { __TOUCHED((pServerSession, pMsg, wSize)); MSG_CG_SYNC_MOVE_SYN* pRecvMsg = static_cast(pMsg); Player* pPlayer = PlayerManager::Instance()->FindPlayerByUserKey(pRecvMsg->m_dwKey); if (pPlayer == NULL || pPlayer->GetField() == NULL) { return; //< 玩家会话中断时 }; BOOLEAN is_valid_size = pRecvMsg->GetPacketSize() == wSize; if(is_valid_size == 0) { SUNLOG(eDEV_LOG, _T("[RNDPROTOCOL_REPORT][SIZE] "__FUNCTION__"")); return; } pRecvMsg->Decode(); DWORD error_level = 0; MovementChecker& rMoveChecker = *pPlayer->GetMovementChecker(); RC::eSYNC_RESULT rcResult = rMoveChecker.OnRecvCG_SYNC_MOVE_SYN(pRecvMsg, error_level); if(rcResult != RC::RC_SYNC_SUCCESS) Send_SYNC_MOVE_NAK(pPlayer, rcResult, error_level, TRUE); } Handler_CG_SYNC_IMPL(CG_SYNC_TARGET_MOVE_SYN) { __TOUCHED((pServerSession, pMsg, wSize)); MSG_CG_SYNC_TARGET_MOVE_SYN* pRecvMsg = (MSG_CG_SYNC_TARGET_MOVE_SYN*)pMsg; Player* pPlayer = PlayerManager::Instance()->FindPlayerByUserKey(pRecvMsg->m_dwKey); if(pPlayer == 0) return; //< 玩家会话中断时 if(!pPlayer->GetField()) { SUNLOG(eCRITICAL_LOG, "[Handler_CG_SYNC_IMPL(CG_SYNC_TARGET_MOVE_SYN)] 不存在游戏场景"); return; } BOOLEAN is_valid_size = pRecvMsg->GetPacketSize() == wSize; if(is_valid_size == 0) { SUNLOG(eDEV_LOG, _T("[RNDPROTOCOL_REPORT][SIZE] "__FUNCTION__"")); return; } DWORD error_level = 0; MovementChecker& rMoveChecker = *pPlayer->GetMovementChecker(); RC::eSYNC_RESULT rcResult = rMoveChecker.OnRecvCG_SYNC_TARGET_MOVE_SYN(pRecvMsg, error_level); if(rcResult != RC::RC_SYNC_SUCCESS) Send_SYNC_MOVE_NAK(pPlayer, rcResult, error_level, TRUE); } Handler_CG_SYNC_IMPL(CG_SYNC_KBMOVE_SYN) { __TOUCHED((pServerSession, pMsg, wSize)); Player* const pPlayer = PlayerManager::Instance()->FindPlayerByUserKey(pMsg->m_dwKey); GameField* const game_field = (pPlayer == NULL) ? NULL : pPlayer->GetField(); if (pPlayer == NULL || game_field == NULL) { return; }; MSG_CG_SYNC_KBMOVE_SYN* pRecvMsg = (MSG_CG_SYNC_KBMOVE_SYN*)pMsg; BOOLEAN is_valid_size = sizeof(*pRecvMsg) == wSize; if(is_valid_size == 0) { SUNLOG(eDEV_LOG, _T("[RNDPROTOCOL_REPORT][SIZE] "__FUNCTION__"")); return; }; uint8_t copied_stream[sizeof(*pRecvMsg) << 1]; CopyMemory(copied_stream, pRecvMsg, sizeof(*pRecvMsg)); pRecvMsg = reinterpret_cast(copied_stream); pRecvMsg->Decode(); #ifdef _NA_0_20110803_PLAYER_MOVEMENT_SYNC pPlayer->GetMovementChecker()->KeyBoard_Move(pRecvMsg); #else DWORD error_level = 0; MovementChecker& rMoveChecker = *pPlayer->GetMovementChecker(); RC::eSYNC_RESULT rcResult = rMoveChecker.OnRecvCG_SYNC_KBMOVE_SYN(pRecvMsg, error_level); if(rcResult != RC::RC_SYNC_SUCCESS) Send_SYNC_MOVE_NAK(pPlayer, rcResult, error_level, TRUE); else { // (NOTE)支持阴影控件, __NA_S00015_20080828_NEW_HOPE_SHADOW // 如果当前玩家正在使用SUCTION技能,则STOP。 BaseStatus* pStatus = NULL; pStatus = pPlayer->GetStatusManager()->FindStatus(eCHAR_STATE_HP_SUCTION); if(pStatus) pStatus->StopStatus(); pStatus = pPlayer->GetStatusManager()->FindStatus(eCHAR_STATE_MP_SUCTION); if(pStatus) pStatus->StopStatus(); } #endif } // 停止播放 Handler_CG_SYNC_IMPL(CG_SYNC_STOP_SYN) { __TOUCHED((pServerSession, pMsg, wSize)); MSG_CG_SYNC_STOP_SYN* pRecvMsg = static_cast(pMsg); Player* pPlayer = PlayerManager::Instance()->FindPlayerByUserKey(pRecvMsg->m_dwKey); //ASSERT(pPlayer); if(pPlayer == 0) return; //< 玩家会话中断时 if(!pPlayer->GetField()) { SUNLOG(eCRITICAL_LOG, "[Handler_CG_SYNC_IMPL(CG_SYNC_STOP_SYN)] Not Exist GameField"); return; } #ifdef _NA_0_20110803_PLAYER_MOVEMENT_SYNC pPlayer->GetMovementChecker()->Move_Stop(pRecvMsg); #else DWORD error_level = 0; MovementChecker& rMoveChecker = *pPlayer->GetMovementChecker(); RC::eSYNC_RESULT rcResult = rMoveChecker.OnRecvCG_SYNC_STOP_SYN(pRecvMsg, error_level); if(rcResult != RC::RC_SYNC_SUCCESS) Send_SYNC_MOVE_NAK(pPlayer, rcResult, error_level, TRUE); #endif } Handler_CG_SYNC_IMPL(CG_SYNC_FAST_KBMOVE_SYN) { __TOUCHED((pServerSession, pMsg, wSize)); Player* const pPlayer = PlayerManager::Instance()->FindPlayerByUserKey(pMsg->m_dwKey); GameField* const game_field = (pPlayer == NULL) ? NULL : pPlayer->GetField(); if (pPlayer == NULL || game_field == NULL) { return; }; MSG_CG_SYNC_FAST_KBMOVE_SYN* pRecvMsg = static_cast(pMsg); if (sizeof(*pRecvMsg) != wSize) { SUNLOG(eDEV_LOG, _T("[RNDPROTOCOL_REPORT][SIZE] "__FUNCTION__"")); return; }; #ifdef _NA000000_SPEED_HACK_PREVENTION_SUPPORT uint8_t copied_stream[sizeof(*pRecvMsg) << 1]; CopyMemory(copied_stream, pRecvMsg, sizeof(*pRecvMsg)); pRecvMsg = reinterpret_cast(copied_stream); pRecvMsg->Decode(); #endif DWORD error_level = 0; MovementChecker& rMoveChecker = *pPlayer->GetMovementChecker(); RC::eSYNC_RESULT rcResult = rMoveChecker.OnRecvCG_SYNC_FAST_KBMOVE_SYN(pRecvMsg, error_level); if(rcResult != RC::RC_SYNC_SUCCESS) Send_SYNC_MOVE_NAK(pPlayer, rcResult, error_level, TRUE); } Handler_CG_SYNC_IMPL(CG_SYNC_JUMP_SYN) { __TOUCHED((pServerSession, pMsg, wSize)); MSG_CG_SYNC_JUMP_SYN* pRecvMsg = (MSG_CG_SYNC_JUMP_SYN*)pMsg; PlayerManager* pPlayerManager = PlayerManager::Instance(); ////////////////////////////////////////////////////////////////////////// // Player* pPlayer = pPlayerManager->FindPlayerByUserKey(pRecvMsg->m_dwKey); if(!pPlayer || (sizeof(*pRecvMsg) != wSize)) return; if(!pPlayer->GetField()) { SUNLOG(eCRITICAL_LOG, "[Handler_CG_SYNC_IMPL(CG_SYNC_JUMP_SYN)] Not Exist GameField"); return; } DWORD error_level = 0; MovementChecker& rMoveChecker = *pPlayer->GetMovementChecker(); RC::eSYNC_RESULT rcResult = rMoveChecker.OnRecvCG_SYNC_JUMP_SYN(pRecvMsg, error_level); if(rcResult != RC::RC_SYNC_SUCCESS) { MSG_CG_SYNC_JUMP_NAK msgNAK; msgNAK.m_wvCurPos = *pPlayer->GetPosPtr(); pPlayer->SendPacket(&msgNAK, sizeof(msgNAK)); rMoveChecker.AbusingNotify(rcResult, 0, .0f); } } Handler_CG_SYNC_IMPL(CG_SYNC_JUMP_STOP_SYN) { __TOUCHED((pServerSession, pMsg, wSize)); MSG_CG_SYNC_JUMP_STOP_SYN* pRecvMsg = (MSG_CG_SYNC_JUMP_STOP_SYN *)pMsg; Player* pPlayer = PlayerManager::Instance()->FindPlayerByUserKey(pRecvMsg->m_dwKey); if(pPlayer == 0) return ; if(!pPlayer->GetField()) { SUNLOG(eCRITICAL_LOG, "[Handler_CG_SYNC_IMPL(CG_SYNC_JUMP_STOP_SYN)] Not Exist GameField"); return; } DWORD error_level = 0; MovementChecker& rMoveChecker = *pPlayer->GetMovementChecker(); RC::eSYNC_RESULT rcResult = rMoveChecker.OnRecvCG_SYNC_JUMP_STOP_SYN(pRecvMsg, error_level); if(rcResult != RC::RC_SYNC_SUCCESS) { MSG_CG_SYNC_JUMP_STOP_NAK msgNAK; msgNAK.m_byErrorCode = rcResult; pPlayer->SendPacket(&msgNAK, sizeof(msgNAK)); rMoveChecker.AbusingNotify(rcResult, error_level, .0f); } } // //================================================================================================== // CHANGES: f110315.2L, _NA001955_110210_WING_COSTUME Handler_CG_SYNC_IMPL(CG_SYNC_WINGS_CONTROL_SYN) { __TOUCHED((pServerSession, pMsg, wSize)); #if !defined(_NA001955_110210_WING_COSTUME) ASSERT(!"Currently not supported"); return; #endif #ifdef _NA001955_110210_WING_COSTUME // using ns_object::PlayerWings; // const MSG_CG_SYNC_WINGS_CONTROL_SYN* recv_msg = \ static_cast(pMsg); if (sizeof(*recv_msg) != wSize) { // pass assert(sizeof(*recv_msg) != wSize); return; } // const DWORD user_key = recv_msg->m_dwKey; Player* const player = PlayerManager::Instance()->FindPlayerByUserKey(user_key); if (player == NULL || player->GetField() == NULL) { // low level return; } // MSG_CG_SYNC_WINGS_CONTROL_CMD msg_brd; const WingControl& header = recv_msg->header; bool success = (header.request < header.eReq_Counts); if (success == false) { msg_brd.header = header; msg_brd.data.Clear(); player->SendPacket(&msg_brd, msg_brd.GetSize()); return; } // assert(success != 0); // IPlayerWingsD& wings = player->Wings; PlayerWings::eResult notify_result = PlayerWings::eResult_Fail; // switch (header.request) { case header.eReq_SpreadWings: success = PlayerWings::SpreadWings(player, header, &msg_brd.header, &msg_brd.data, ¬ify_result); break; case header.eReq_FurlWings: success = PlayerWings::FurlWings(player, header, &msg_brd.header, &msg_brd.data, ¬ify_result); break; default: success = false; if (WingControl* const result_header = &msg_brd.header) { result_header->Clear(); msg_brd.data.Clear(); result_header->request = header.request; result_header->args = header.args; result_header->result = header.eRet_Failed; result_header->result_code = header.eRetCode_Unknown; }; break; } // if (notify_result != ns_object::PlayerWings::eResult_1toN) { player->SendPacket(&msg_brd, msg_brd.GetSize()); } else { player->SendPacketAround(&msg_brd, msg_brd.GetSize()); } #endif } //==================================================================================================