730 lines
26 KiB
C++
730 lines
26 KiB
C++
#include "stdafx.h"
|
|
|
|
//==================================================================================================
|
|
//
|
|
#include <float.h>
|
|
//////////////////////////////////////////////////////////////////////////
|
|
#include <Struct.h>
|
|
#include <AIParamParser.h>
|
|
#include <ServerOptionParser.h>
|
|
#include <Global.h>
|
|
#include <PublicMath.h>
|
|
#include <NumericValues.h>
|
|
#include <PacketControl/WarMessages_Sync.h>
|
|
#include <ServerOptionParserEx.h>
|
|
#include <PacketStruct_GZ.h>
|
|
#include <PacketStruct_CG.h>
|
|
#include <PacketStruct_AG.h>
|
|
#include <ServerSession.h>
|
|
//////////////////////////////////////////////////////////////////////////
|
|
#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 <World/SSQ/SSQHandlerInGame.h>
|
|
#include "PlayerWings.h" //_NA001955_110210_WING_COSTUME
|
|
#include <PacketStruct_PointSystem.h>
|
|
|
|
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<ePHASE_SHIFT>(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<BYTE>(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<MSG_AG_SYNC_PLAYER_ENTER_SYN*>(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;
|
|
}
|
|
}
|
|
|
|
//任务窗口跳转命令包
|
|
// <NOTE>在任务房里这个条件就当是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<MSG_AG_SYNC_PLAYER_WARP_SYN *>(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;
|
|
}
|
|
}
|
|
|
|
//任务窗口跳转命令包
|
|
// <NOTE>在任务房间里这个条件就当是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<MSG_CG_SYNC_MOVE_SYN*>(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<MSG_CG_SYNC_KBMOVE_SYN*>(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<MSG_CG_SYNC_STOP_SYN*>(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<MSG_CG_SYNC_FAST_KBMOVE_SYN*>(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<MSG_CG_SYNC_FAST_KBMOVE_SYN*>(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();
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
// <PATTERN>
|
|
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<MSG_CG_SYNC_WINGS_CONTROL_SYN*>(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
|
|
}
|
|
|
|
//==================================================================================================
|