#include "stdafx.h" #include "./Handler_AG_ZONE.h" //================================================================================================== #include #include #include #include //================================================================================================== #include #include //================================================================================================== #include "FunctionalRestrictManager.h" #include "ObjectFactory.h" #include "ChangeMonsterAbility.h" #include "Player.h" #include "ItemManager.h" #include "GameServerEx.h" #include "GamePartyManager.h" #include "MissionManager.h" #include "QuestManager.h" #include "PVPManager.h" #include #include "GameZoneManager.h" #include "GameLobbyRoom.h" #include "GameHuntingRoom.h" #include "GameMissionRoom.h" #include "GameVillage.h" #include "GameInstanceDungeon.h" #include "GamePVPRoom.h" #include "GameCHuntingRoom.h" #include "GameHuntingField.h" #include "QuestManager_Concrete.h" #include "GameDominationField.h" #include "GameDominationManager.h" #include "TriggerManagerEx.h" #include "GameGuildManager.h" #include "ChaoState.h" #include #include #include "WarehouseSlotContainer.h" #include "GuildWarehouseSlotContainer.h" #include "StatusManager.h" #ifdef _NA_20100307_BETAKEY_SYSTEM #include #endif //_NA_20110630_BATTLE_ZONE_RENEWAL #include "BattlezoneMissionTreeParser.h" #ifdef _NA_006826_20130722_DOMINATION_RENEWAL #include "GameDominationField.h" #endif // _NA_006826_20130722_DOMINATION_RENEWAL #ifdef _NA_008069_20150210_ADD_SPA_SYSTEM #include "GameSpaField.h" #endif //_NA_008069_20150210_ADD_SPA_SYSTEM #ifdef _NA_008832_20160523_DOMINATIONFIELD_ENTER_LIMIT #include "GameGuild.h" #endif //(_NA_008832_20160523_DOMINATIONFIELD_ENTER_LIMIT) Handler_AG_ZONE::Handler_AG_ZONE(void) { } Handler_AG_ZONE::~Handler_AG_ZONE(void) { } //-------------------------------------------------------------------------------------------------- // changes, f100819.1L const nsPacket::PacketHandlerInfo Handler_AG_ZONE::GetPacketHandlerNodes() { #define HANDLER_NODE_INFO(c, p, phase) { MAKEWORD(c, p), phase, Handler_AG_ZONE::On##p } #define HANDLER_NODE_INFO_EOR() { 0, static_cast(0), NULL } static const nsPacket::PacketHandlerNode handlers_static_[] = { HANDLER_NODE_INFO(AG_ZONE, AG_ZONE_LOBBY_CREATE_CMD, PHASE_SERVICE), HANDLER_NODE_INFO(AG_ZONE, AG_ZONE_HUNTING_CREATE_CMD, PHASE_SERVICE), HANDLER_NODE_INFO(AG_ZONE, AG_ZONE_MISSION_CREATE_CMD, PHASE_SERVICE), HANDLER_NODE_INFO(AG_ZONE, AG_ZONE_VILLAGE_CREATE_CMD, PHASE_SERVICE), HANDLER_NODE_INFO(AG_ZONE, AG_ZONE_PVP_CREATE_CMD, PHASE_SERVICE), HANDLER_NODE_INFO(AG_ZONE, AG_ZONE_CHUNTION_CREATE_CMD, PHASE_SERVICE), HANDLER_NODE_INFO(AG_ZONE, AG_ZONE_FIELD_CREATE_CMD, PHASE_SERVICE), //_NA001385_20090924_DOMINATION_BASE HANDLER_NODE_INFO(AG_ZONE, AG_ZONE_DOMINATION_FIELD_CREATE_CMD, PHASE_SERVICE), HANDLER_NODE_INFO(AG_ZONE, AG_ZONE_DOMINATION_FIELD_INFO_SYN, PHASE_SERVICE), // HANDLER_NODE_INFO(AG_ZONE, AG_ZONE_ROOM_DESTROY_CMD, PHASE_SERVICE), HANDLER_NODE_INFO(AG_ZONE, AG_ZONE_ROOM_JOIN_CMD, PHASE_SERVICE), HANDLER_NODE_INFO(AG_ZONE, AG_ZONE_ROOM_JOIN_SYN, PHASE_SERVICE), HANDLER_NODE_INFO(AG_ZONE, AG_ZONE_ROOM_LEAVE_CMD, PHASE_SERVICE), HANDLER_NODE_INFO(AG_ZONE, AG_ZONE_ROOM_LEAVE_SYN, PHASE_SERVICE), HANDLER_NODE_INFO(AG_ZONE, AG_ZONE_MASTER_CHANGED_CMD, PHASE_SERVICE), HANDLER_NODE_INFO(AG_ZONE, AG_ZONE_PVP_INFO_CMD, PHASE_SERVICE), HANDLER_NODE_INFO(AG_ZONE, AG_ZONE_PORTAL_FIELD_MOVE_SYN, PHASE_SERVICE), HANDLER_NODE_INFO(AG_ZONE, AG_ZONE_RETURN_VILLAGE_SYN, PHASE_SERVICE), HANDLER_NODE_INFO(AG_ZONE, AG_ZONE_CHANGE_SPECIALTYPE_CMD, PHASE_SERVICE), HANDLER_NODE_INFO(AG_ZONE, AG_ZONE_INSTANCE_CREATE_CMD, PHASE_SERVICE), HANDLER_NODE_INFO(AG_ZONE, AG_ZONE_CAN_CREATE_INSTANCE_DUNGEON_SYN, PHASE_SERVICE), HANDLER_NODE_INFO(AG_ZONE, AG_ZONE_TUTORIAL_SKIP_SYN, PHASE_SERVICE), HANDLER_NODE_INFO(AG_ZONE, AG_ZONE_RETURN_TO_ROOM_INFO_SYN, PHASE_SERVICE), HANDLER_NODE_INFO(AG_ZONE, AG_ZONE_CAN_CREATE_100LEVEL_QUEST_MISSION_SYN, PHASE_SERVICE), HANDLER_NODE_INFO(AG_ZONE, AG_ZONE_SSQ_JOIN_INFO_SYN, PHASE_SERVICE), HANDLER_NODE_INFO(AG_ZONE, AG_ZONE_SSQ_JOIN_SYN, PHASE_SERVICE), HANDLER_NODE_INFO(AG_ZONE, AG_ZONE_SSQ_ROOM_CTRL_CMD, PHASE_SERVICE), //__NA1279_1281_090209_TIMELINE_QUEST_BASED_MISSION__ HANDLER_NODE_INFO(AG_ZONE, AG_ZONE_QUEST_PORTAL_ENTER_SYN, PHASE_SERVICE), //{__NA001281_BATTLEZONE_ENTER_CONSTRAINTS_CHANGE_IN_LOBBY__ HANDLER_NODE_INFO(AG_ZONE, AG_ZONE_CAN_CREATE_ROOM_SYN, PHASE_SERVICE), HANDLER_NODE_INFO(AG_ZONE, AG_ZONE_LOBBY_CREATE_SYN, PHASE_SERVICE), HANDLER_NODE_INFO(AG_ZONE, AG_ZONE_LOBBY_JOIN_SYN, PHASE_SERVICE), //} //_NA_000038_20100316_VIEW_TO_JOINABLE_ROOM_IN_LOBBY HANDLER_NODE_INFO(AG_ZONE, AG_ZONE_CHECK_MISSION_ROOM_LIST_SYN, PHASE_SERVICE), HANDLER_NODE_INFO(AG_ZONE, AG_ZONE_CHANGE_MONSTER_ABILITY_CMD, PHASE_SERVICE), //_NA_20110630_BATTLE_ZONE_RENEWAL HANDLER_NODE_INFO(AG_ZONE, AG_ZONE_CAN_CREATE_ROOM_OF_PARTY_SYN, PHASE_SERVICE), #ifdef _NA_008069_20150210_ADD_SPA_SYSTEM HANDLER_NODE_INFO(AG_ZONE, AG_ZONE_SPAFIELD_CREATE_CMD, PHASE_SERVICE), HANDLER_NODE_INFO(AG_ZONE, AG_ZONE_SPA_ENTER_SYN, PHASE_SERVICE), HANDLER_NODE_INFO(AG_ZONE, AG_ZONE_SPA_LEAVE_SYN, PHASE_SERVICE), #endif //_NA_008069_20150210_ADD_SPA_SYSTEM 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; }; //-------------------------------------------------------------------------------------------------- //(lst1024)(090410) 中国道具复制错误修正 //检查队员们是否准备好移动. class CheckReadyPartyMember { public : CheckReadyPartyMember() : m_AllReady(TRUE) {} ~CheckReadyPartyMember(){} VOID operator () ( Player * pPlayer ) { if( pPlayer->GetField() && pPlayer->GetBehave() == PLAYER_BEHAVE_IDLE_STATE ) return; m_AllReady = FALSE; } BOOL m_AllReady; }; Handler_AG_ZONE_IMPL( AG_ZONE_LOBBY_CREATE_CMD ) { __TOUCHED((pServerSession, pMsg, wSize)); MSG_AG_ZONE_LOBBY_CREATE_CMD * pRecvMsg = (MSG_AG_ZONE_LOBBY_CREATE_CMD *)pMsg; #ifdef __NA_PACKETFLOW_TEST SUNLOG( eFULL_LOG, "Handler_AG_ZONE_IMPL( AG_ZONE_LOBBY_CREATE_CMD )" ); #endif GameLobbyRoom * pZone = static_cast(g_GameZoneManager.CreateZone( eZONETYPE_LOBBY, pRecvMsg->m_RoomKey, pRecvMsg->m_MapCode )); if( pZone ) { pZone->SetRoomTitle(pRecvMsg->m_pszRoomTitle); pZone->SetRoomPWD(pRecvMsg->m_pszRoomPWD); pZone->SetBaseRoomInfo(&pRecvMsg->m_RoomInfo); pZone->SetMasterUserKey( pRecvMsg->m_dwKey ); pZone->OnCreate(); } } Handler_AG_ZONE_IMPL( AG_ZONE_HUNTING_CREATE_CMD ) { __TOUCHED((pServerSession, pMsg, wSize)); // (WAVERIX) (090624) (CHANGES) Remove unused section 'Hunting' ASSERT("Function Not Suported!!"); return; // MSG_AG_ZONE_HUNTING_CREATE_CMD * pRecvMsg = (MSG_AG_ZONE_HUNTING_CREATE_CMD *)pMsg; // //#ifdef __NA_PACKETFLOW_TEST // SUNLOG( eFULL_LOG, "Handler_AG_ZONE_IMPL( AG_ZONE_HUNTING_CREATE_CMD )" ); //#endif // // GameHuntingRoom * pZone = static_cast(g_GameZoneManager.CreateZone( // eZONETYPE_HUNTING, pRecvMsg->m_RoomKey, pRecvMsg->m_MapCode )); // if( pZone ) // { // pZone->SetRoomTitle(pRecvMsg->m_pszRoomTitle); // pZone->SetRoomPWD(pRecvMsg->m_pszRoomPWD); // pZone->SetBaseRoomInfo(&pRecvMsg->m_RoomInfo); // pZone->SetMasterUserKey(pRecvMsg->m_dwKey); // // pZone->SetAdditionalRoomInfo(&pRecvMsg->m_AdditionalInfo); // // pZone->OnCreate(); // } } Handler_AG_ZONE_IMPL( AG_ZONE_MISSION_CREATE_CMD ) { __TOUCHED((pServerSession, pMsg, wSize)); MSG_AG_ZONE_MISSION_CREATE_CMD* pRecvMsg = (MSG_AG_ZONE_MISSION_CREATE_CMD *)pMsg; #ifdef __NA_PACKETFLOW_TEST SUNLOG( eFULL_LOG, "Handler_AG_ZONE_IMPL( AG_ZONE_MISSION_CREATE_CMD )" ); #endif GameZone* pBaseZone = g_GameZoneManager.CreateZone(eZONETYPE_MISSION, pRecvMsg->m_RoomKey, pRecvMsg->m_MapCode, pRecvMsg->m_Rules); GameMissionRoom* pZone = static_cast(pBaseZone); if( pZone ) { pZone->SetRoomTitle(pRecvMsg->m_pszRoomTitle); pZone->SetRoomPWD(pRecvMsg->m_pszRoomPWD); pZone->SetBaseRoomInfo(&pRecvMsg->m_RoomInfo); pZone->SetMasterUserKey(pRecvMsg->m_dwKey); #ifdef _NA_003649_20111115_BATTLE_ZONE_HARDMODE pZone->SetPartyZoneType(pRecvMsg->party_zone_type); #endif //_NA_003649_20111115_BATTLE_ZONE_HARDMODE pZone->OnCreate(); } } Handler_AG_ZONE_IMPL( AG_ZONE_PVP_CREATE_CMD ) { __TOUCHED((pServerSession, pMsg, wSize)); MSG_AG_ZONE_PVP_CREATE_CMD * pRecvMsg = (MSG_AG_ZONE_PVP_CREATE_CMD *)pMsg; #ifdef __NA_PACKETFLOW_TEST SUNLOG( eFULL_LOG, "Handler_AG_ZONE_IMPL( AG_ZONE_PVP_CREATE_CMD )" ); #endif GamePVPRoom * pZone = static_cast(g_GameZoneManager.CreateZone( eZONETYPE_PVP, pRecvMsg->m_RoomKey, pRecvMsg->m_MapCode )); if( pZone ) { pZone->SetRoomTitle(pRecvMsg->m_pszRoomTitle); pZone->SetRoomPWD(pRecvMsg->m_pszRoomPWD); pZone->SetBaseRoomInfo(&pRecvMsg->m_RoomInfo); pZone->SetMasterUserKey(pRecvMsg->m_dwKey); pZone->SetAdditionalPVPInfo(&pRecvMsg->m_AdditionalPVPInfo); pZone->OnCreate(); } } Handler_AG_ZONE_IMPL( AG_ZONE_CHUNTION_CREATE_CMD ) { __TOUCHED((pServerSession, pMsg, wSize)); MSG_AG_ZONE_CHUNTION_CREATE_CMD* pRecvMsg = (MSG_AG_ZONE_CHUNTION_CREATE_CMD*)pMsg; #ifdef __NA_PACKETFLOW_TEST SUNLOG( eFULL_LOG, "Handler_AG_ZONE_IMPL( AG_ZONE_CHUNTION_CREATE_CMD )" ); #endif GameCHuntingRoom * pZone = static_cast(g_GameZoneManager.CreateZone( eZONETYPE_CHUNTING, pRecvMsg->m_RoomKey, pRecvMsg->m_MapCode )); if( pZone ) { pZone->SetRoomTitle(pRecvMsg->m_pszRoomTitle); pZone->SetRoomPWD(pRecvMsg->m_pszRoomPWD); pZone->SetBaseRoomInfo(&pRecvMsg->m_RoomInfo); pZone->SetMasterUserKey(pRecvMsg->m_dwKey); pZone->SetAdditionalCHuntingInfo(&pRecvMsg->m_AdditionalInfo); pZone->OnCreate(); } } Handler_AG_ZONE_IMPL( AG_ZONE_VILLAGE_CREATE_CMD ) { __TOUCHED((pServerSession, pMsg, wSize)); MSG_AG_ZONE_VILLAGE_CREATE_CMD * pRecvMsg = (MSG_AG_ZONE_VILLAGE_CREATE_CMD *)pMsg; #ifdef __NA_PACKETFLOW_TEST SUNLOG( eFULL_LOG, "Handler_AG_ZONE_IMPL( AG_ZONE_VILLAGE_CREATE_CMD )" ); #endif GameVillage * pZone = static_cast(g_GameZoneManager.CreateZone( eZONETYPE_VILLAGE, pRecvMsg->m_RoomKey, pRecvMsg->m_MapCode )); if( pZone ) { SUNLOG( eFULL_LOG, "[%u,%u]:创建城镇", pRecvMsg->m_RoomKey, pRecvMsg->m_MapCode ); #ifndef _SUSUNLOVE_DRIVE_NOT_FOUND_ pZone->OnCreate(); #endif } } Handler_AG_ZONE_IMPL( AG_ZONE_FIELD_CREATE_CMD ) { __TOUCHED((pServerSession, pMsg, wSize)); MSG_AG_ZONE_FIELD_CREATE_CMD * pRecvMsg = (MSG_AG_ZONE_FIELD_CREATE_CMD *)pMsg; #ifdef __NA_PACKETFLOW_TEST SUNLOG( eFULL_LOG, "Handler_AG_ZONE_IMPL( AG_ZONE_FIELD_CREATE_CMD )" ); #endif GameHuntingField * pZone = static_cast(g_GameZoneManager.CreateZone( eZONETYPE_FIELD, pRecvMsg->m_RoomKey, pRecvMsg->m_MapCode )); if( pZone ) { SUNLOG( eFULL_LOG, "[%u,%u]:创建场景", pRecvMsg->m_RoomKey, pRecvMsg->m_MapCode ); #ifndef _SUSUNLOVE_DRIVE_NOT_FOUND_ pZone->OnCreate(); #endif } } Handler_AG_ZONE_IMPL(AG_ZONE_DOMINATION_FIELD_CREATE_CMD) { __TOUCHED((pServerSession, pMsg, wSize)); MSG_AG_ZONE_DOMINATION_FIELD_CREATE_CMD * recv_msg = static_cast(pMsg); #ifdef __NA_PACKETFLOW_TEST SUNLOG( eFULL_LOG, "Handler_AG_ZONE_IMPL( MSG_AG_ZONE_DOMINATION_FIELD_CREATE_CMD )" ); #endif GameDominationField* zone = static_cast(g_GameZoneManager.CreateZone(eZONETYPE_DOMINATION_FIELD, recv_msg->m_RoomKey, recv_msg->m_MapCode )); if (zone == NULL) { SUNLOG(eCRITICAL_LOG,"["__FUNCTION__"]未创建区域[map:%d]", recv_msg->m_MapCode); return; } SUNLOG(eCRITICAL_LOG,"[%u,%u]:统治领域创建失败", recv_msg->m_RoomKey, recv_msg->m_MapCode); #ifndef _SUSUNLOVE_DRIVE_NOT_FOUND_ zone->OnCreate(); #endif } #ifdef _NA_008069_20150210_ADD_SPA_SYSTEM Handler_AG_ZONE_IMPL(AG_ZONE_SPAFIELD_CREATE_CMD) { MSG_AG_ZONE_SPAFIELD_CREATE_CMD* recv_msg = static_cast(pMsg); GameSpaField* zone = static_cast(g_GameZoneManager.CreateZone(eZONETYPE_SPA_FIELD, recv_msg->room_key, recv_msg->map_code)); if (zone == NULL) { SUNLOG(eCRITICAL_LOG,"["__FUNCTION__"]无法创建区域[map:%d]", recv_msg->map_code); return; } SUNLOG(eCRITICAL_LOG,"[%u,%u]:特殊场景创建完成!", recv_msg->room_key,recv_msg->map_code); zone->OnCreate(); } //_NA_008069_20150210_ADD_SPA_SYSTEM Handler_AG_ZONE_IMPL(AG_ZONE_SPA_ENTER_SYN) { __TOUCHED((pServerSession, pMsg, wSize)); MSG_AG_ZONE_SPA_ENTER_SYN* recv_msg = static_cast(pMsg); CODETYPE ticket_item_code = recv_msg->item_code; Player * player = PlayerManager::Instance()->FindPlayerByUserKey( recv_msg->m_dwKey ); if ( player == NULL ) { // 没有玩家 MSG_AG_ZONE_SPA_ENTER_ACK ack_msg; ack_msg.m_dwKey = 0; ack_msg.spa_mapcode = 0; pServerSession->Send((BYTE*)&ack_msg, sizeof(ack_msg)); return; } BASE_ITEMINFO* ticket_info = ItemInfoParser::Instance()->GetItemInfo(ticket_item_code); if (ticket_info == NULL) { //移动失败 MSG_AG_ZONE_SPA_ENTER_ACK ack_msg; ack_msg.m_dwKey = player->GetUserKey(); ack_msg.spa_mapcode = 0; pServerSession->Send((BYTE*)&ack_msg, sizeof(ack_msg)); return; } MAPCODE spa_field_code = ticket_info->m_wSkillCode; // 检查票证是否存在----------------------------------------------------- ItemManager* item_manager = player->GetItemManager(); int ticket_count = item_manager->ExistItem(SI_INVENTORY, ticket_item_code, 1); if (ticket_count == 0) { // 没有票 MSG_AG_ZONE_SPA_ENTER_ACK ack_msg; ack_msg.m_dwKey = player->GetUserKey(); ack_msg.spa_mapcode = 0; pServerSession->Send((BYTE*)&ack_msg, sizeof(ack_msg)); return; } // 进入温泉前清除龙变神像-------------------------------------- player->RemoveDragonTransformStatus(); { MSG_AG_ZONE_SPA_ENTER_ACK ack_msg; ack_msg.m_dwKey = player->GetUserKey(); ack_msg.spa_mapcode = spa_field_code; pServerSession->Send((BYTE*)&ack_msg, sizeof(ack_msg)); } } Handler_AG_ZONE_IMPL(AG_ZONE_SPA_LEAVE_SYN) { __TOUCHED((pServerSession, pMsg, wSize)); MSG_AG_ZONE_SPA_LEAVE_SYN* recv_msg = static_cast(pMsg); //GameServer单位相关条件检查 DWORD UserKey = recv_msg->m_dwKey; Player* player = PlayerManager::Instance()->FindPlayerByUserKey( UserKey ); ASSERT( player ); if( player == NULL ) return; // 有什么条件在这里检查. { MSG_AG_ZONE_SPA_LEAVE_ACK ack_msg; ack_msg.m_dwKey = player->GetUserKey(); ack_msg.village_map_code = player->GetPreVillageMapCode(); pServerSession->Send((BYTE*)&ack_msg, sizeof(ack_msg)); } } #endif //_NA_008069_20150210_ADD_SPA_SYSTEM Handler_AG_ZONE_IMPL(AG_ZONE_DOMINATION_FIELD_INFO_SYN) { __TOUCHED((pServerSession, pMsg, wSize)); MSG_AG_ZONE_DOMINATION_FIELD_INFO_SYN * recv_msg = static_cast(pMsg); #ifdef __NA_PACKETFLOW_TEST SUNLOG( eFULL_LOG, "Handler_AG_ZONE_IMPL( MSG_AG_ZONE_DOMINATION_FIELD_INFO_SYN )" ); #endif GameZone* zone = g_GameZoneManager.GetZone(recv_msg->m_RoomKey); if (zone == NULL) { SUNLOG( eCRITICAL_LOG, "["__FUNCTION__"]房间[%d]未找到", recv_msg->m_RoomKey ); MSG_AG_ZONE_DOMINATION_FIELD_INFO_NAK nak_msg; nak_msg.m_RoomKey = recv_msg->m_RoomKey; nak_msg.m_dwErrorCode = RC::RC_ROOM_NOTEXISTROOM; pServerSession->Send((BYTE*)&nak_msg, sizeof(nak_msg)); return; } if (zone->GetZoneType() != eZONETYPE_DOMINATION_FIELD) { SUNLOG(eCRITICAL_LOG, "["__FUNCTION__"]这不是统治领域[%d]", recv_msg->m_RoomKey); MSG_AG_ZONE_DOMINATION_FIELD_INFO_NAK nak_msg; nak_msg.m_RoomKey = recv_msg->m_RoomKey; nak_msg.m_dwErrorCode = RC::RC_ROOM_INVALIDROOMTYPE; pServerSession->Send((BYTE*)&nak_msg, sizeof(nak_msg)); return; } GameDominationField* domination_field = static_cast(zone); domination_field->SetEventState(recv_msg->m_byEventState); MSG_AG_ZONE_DOMINATION_FIELD_INFO_ACK ack_msg; ack_msg.m_RoomKey = recv_msg->m_RoomKey; ack_msg.m_offenceGuild = domination_field->GetOffenseGuild(); ack_msg.m_defenceGuild = domination_field->GetDefenseGuild(); ack_msg.m_eSetType = DOMINATION_INIT; pServerSession->Send((BYTE*)&ack_msg, sizeof(ack_msg)); } Handler_AG_ZONE_IMPL( AG_ZONE_ROOM_DESTROY_CMD ) { __TOUCHED((pServerSession, pMsg, wSize)); MSG_AG_ZONE_ROOM_DESTROY_CMD * pRecvMsg = (MSG_AG_ZONE_ROOM_DESTROY_CMD *)pMsg; #ifdef __NA_PACKETFLOW_TEST SUNLOG( eFULL_LOG, "Handler_AG_ZONE_IMPL( AG_ZONE_ROOM_DESTROY_CMD )" ); #endif g_GameZoneManager.DestroyZone( pRecvMsg->m_RoomKey ); } Handler_AG_ZONE_IMPL( AG_ZONE_ROOM_JOIN_CMD ) { __TOUCHED((pServerSession, pMsg, wSize)); MSG_AG_ZONE_ROOM_JOIN_CMD * pRecvMsg = (MSG_AG_ZONE_ROOM_JOIN_CMD *)pMsg; #ifdef __NA_PACKETFLOW_TEST SUNLOG( eFULL_LOG, "Handler_AG_ZONE_IMPL( AG_ZONE_ROOM_JOIN_CMD )" ); #endif DWORD UserKey = pRecvMsg->m_dwKey; Player * pPlayer = PlayerManager::Instance()->FindPlayerByUserKey( UserKey ); ASSERT( pPlayer ); if( !pPlayer ) return; GameZone * pZone = g_GameZoneManager.GetZone( pRecvMsg->m_RoomKey ); if(!pZone) { SUNLOG( eCRITICAL_LOG, "[AG_ZONE_ROOM_JOIN_CMD]房间[%d]未找到", pRecvMsg->m_RoomKey ); return; } //获取域代码. WORD wFieldCode = 0; if( pRecvMsg->m_wFieldCode == 0 ) wFieldCode = (WORD)pZone->GetEntryFieldCode(); else wFieldCode = pRecvMsg->m_wFieldCode; //获取区号. DWORD dwAreaID = 0; if( pRecvMsg->m_dwAreaID == 0 ) dwAreaID = pZone->GetEntryAreaID(); else dwAreaID = pRecvMsg->m_dwAreaID; g_GameZoneManager.ReadyPlayer( pRecvMsg->m_RoomKey, pPlayer, wFieldCode, dwAreaID, &pRecvMsg->m_vStartPos ); //SUNLOG( eFULL_LOG, "[U:%d,P:%d,ID:%s][%d]:玩家连接到游戏服务器CMD", UserKey, pPlayer->GetObjectKey(), pPlayer->GetUserID(), pRecvMsg->m_RoomKey ); } Handler_AG_ZONE_IMPL( AG_ZONE_ROOM_JOIN_SYN ) { __TOUCHED((pServerSession, pMsg, wSize)); MSG_AG_ZONE_ROOM_JOIN_SYN * pRecvMsg = (MSG_AG_ZONE_ROOM_JOIN_SYN *)pMsg; #ifdef __NA_PACKETFLOW_TEST SUNLOG( eFULL_LOG, "Handler_AG_ZONE_IMPL( AG_ZONE_ROOM_JOIN_SYN )" ); #endif DWORD UserKey = pRecvMsg->m_dwKey; Player * pPlayer = PlayerManager::Instance()->FindPlayerByUserKey( UserKey ); if( pPlayer ) { SUNLOG( eCRITICAL_LOG, "[AG_ZONE_ROOM_JOIN_SYN]玩家存在:%d, %s", UserKey, pPlayer->GetCharName() ); return; } ////////////////////////////////////////////////////////////// // 由于重复登录的问题,您可能会卡在这里。!!!!!!!! ////////////////////////////////////////////////////////////// GameZone * pZone = g_GameZoneManager.GetZone( pRecvMsg->m_RoomKey ); if(!pZone) { SUNLOG( eCRITICAL_LOG, "[AG_ZONE_ROOM_JOIN_SYN]Room[%d]IsNotFound", pRecvMsg->m_RoomKey ); return; } //---------------------------------------------------------------------------------------------- // CHANGES: f110426.2L, changes to forwarding message to make successful replication process. MSG_DG_CHARINFO_CONNECT_CHAR_CMD msg_syn; msg_syn.m_dwKey = UserKey; msg_syn.char_guid = pRecvMsg->m_dwCharGUID; msg_syn.session_index = pServerSession->GetSessionIndex(); msg_syn.forward_msg = *pRecvMsg; if (g_pGameServer->SendToServer(GAME_DBPROXY, &msg_syn, msg_syn.GetSize()) == false) { SUNLOG(eCRITICAL_LOG, "|["__FUNCTION__"]|斤口=fails, network problem|"); MSG_AG_ZONE_ROOM_JOIN_NAK msg_nak; msg_nak.m_dwKey = UserKey; msg_nak.m_dwErrorCode = RC::RC_ZONE_DISCONNECTED_DBPROXY; // CHANGES: f110712.4L, 修复了空对象处理问题 // 因为这个处理程序基于第一个实例. pServerSession->SendPacket(&msg_nak, sizeof(msg_nak)); return; }; // 下一个过程:从数据库代理服务器接收 MSG_DG_CHARINFO_CONNECT_CHAR_CMD return; } Handler_AG_ZONE_IMPL( AG_ZONE_ROOM_LEAVE_CMD ) { __TOUCHED((pServerSession, pMsg, wSize)); MSG_AG_ZONE_ROOM_LEAVE_CMD * pRecvMsg = (MSG_AG_ZONE_ROOM_LEAVE_CMD *)pMsg; #ifdef __NA_PACKETFLOW_TEST SUNLOG( eFULL_LOG, "Handler_AG_ZONE_IMPL( AG_ZONE_ROOM_LEAVE_CMD )" ); #endif DWORD UserKey = pRecvMsg->m_dwKey; Player * pPlayer = PlayerManager::Instance()->FindPlayerByUserKey( UserKey ); ASSERT( pPlayer ); if( !pPlayer ) return; GameZone * pEnterZone = NULL; MAPCODE EnterFieldCode = 0; eZONE_STATE eRoomState = pPlayer->GetGameZone( pEnterZone, EnterFieldCode ); if( eRoomState & ePRS_AT_ZONE ) { g_GameZoneManager.LeavePlayer( pRecvMsg->m_RoomKey, pPlayer ); //SUNLOG( eFULL_LOG, "[Room:%d][U:%d]:AG_ZONE_ROOM_LEAVE_CMD패킷옴", pRecvMsg->m_RoomKey, UserKey ); } } Handler_AG_ZONE_IMPL( AG_ZONE_ROOM_LEAVE_SYN ) { __TOUCHED((pServerSession, pMsg, wSize)); MSG_AG_ZONE_ROOM_LEAVE_SYN * pRecvMsg = (MSG_AG_ZONE_ROOM_LEAVE_SYN *)pMsg; #ifdef __NA_PACKETFLOW_TEST SUNLOG( eFULL_LOG, "Handler_AG_ZONE_IMPL( AG_ZONE_ROOM_LEAVE_SYN )" ); #endif DWORD UserKey = pRecvMsg->m_dwKey; Player * pPlayer = PlayerManager::Instance()->FindPlayerByUserKey( UserKey ); if( !pPlayer ) { // 如果你不在房间,你不需要处理,也不需要通知。... /* MSG_AG_ZONE_ROOM_LEAVE_NAK NakMsg; NakMsg.m_dwErrorCode = RC_ROOM_NOT_EXIST_MEMBER; pServerSession->Send( &NakMsg, sizeof(NakMsg) );*/ // 连续进行猎杀的情况发生. ASSERT( ! "玩家在游戏服务器上不存在" ); return; } //DISPMSG( "Leave\n" ); GameZone * pEnterZone = NULL; MAPCODE EnterFieldCode = 0; eZONE_STATE eRoomState = pPlayer->GetGameZone( pEnterZone, EnterFieldCode ); if( eRoomState & ePRS_AT_ZONE ) { g_GameZoneManager.LeavePlayer( pRecvMsg->m_RoomKey, pPlayer ); } //__NA_0_20090311_ITEMCOPY_BUG_FOR_LEAVESYN_ERROR else if( eRoomState & ePRS_BEFORE_ENTER_ZONE ) { // 可能是为了进入其他区域而等待Player Enter Syn的状态。村庄->场景移动的加载状态时,直接移动到低塔时可能发生。 //已经做好了LeavePlayer处理,只要解除之前挂着的Ready状态就可以了. pPlayer->SetGameZone( ePRS_NOT_AT_ZONE, NULL, 0 ); } else { ASSERT( ! "[AG_ZONE_ROOM_LEAVE_SYN] 玩家的区域属性不是ePRS_AT_ZONE区域" ); // 可能还没有收到来自DB的MSG_DG_CHARINFO_UDPATE_ACK 信息, //发送NAK以避免重复登录. // MSG_AG_ZONE_ROOM_LEAVE_NAK NakMsg; // pServerSession->Send( (BYTE*)&NakMsg, sizeof(NakMsg) ); return; } //SUNLOG( eFULL_LOG, "MSG_AG_ZONE_ROOM_LEAVE_SYN[%s][%d]", pPlayer->GetCharName(), pPlayer->GetBehave() ); MSG_DG_CHARINFO_UPDATE_TRANSACTION_CONTROL_SYN msg_transaction; msg_transaction.m_byTransControl = msg_transaction.DBUPDATE_LOCKING; msg_transaction.char_guid_ = pPlayer->GetCharGuid(); // CHANGES: f110412.2L pPlayer->SendToGameDBPServer(&msg_transaction, sizeof(msg_transaction)); //公会存在时. if( pPlayer->GetCharInfo()->m_GuildGuid != 0 ) { // 移动到角色生成窗口后,必须进行角色注销处理. if( pRecvMsg->m_ToRoomType == eZONETYPE_CHARSELECT ) { MSG_GZ_GUILD_LOGOUT_CHAR_SYN synMsg; synMsg.m_GuildGuid = pPlayer->GetCharInfo()->m_GuildGuid; synMsg.m_CharGuid = pPlayer->GetCharGuid(); if( !pPlayer->SendToGuildServer( &synMsg, sizeof( synMsg ) ) ) { // 如果不能送到公会服务器,无法正常处理,在此删除客体. g_GameGuildManager.DestroyMember( pPlayer->GetCharInfo()->m_GuildGuid, pPlayer->GetCharGuid() ); SUNLOG( eCRITICAL_LOG, "[Handler_AG_ZONE_IMPL( AG_ZONE_ROOM_LEAVE_SYN )] 发送GuildServer和DestroyMember失败, GuildGuid = %u, CharGuid = %d", pPlayer->GetCharInfo()->m_GuildGuid, pPlayer->GetCharGuid() ); } } else { //不是角色生成,就是游戏服务器之间的移动,游戏服务器删除公会成员信息. g_GameGuildManager.LeaveServer( pPlayer->GetGuildGuid(), pPlayer->GetCharGuid() ); } } //错误修正:5898文尚贤2010-02-19(所有国家共同)移动到大厅时,初始化再购买目录. if( pRecvMsg->m_ToRoomType == eZONETYPE_CHARSELECT ) { pPlayer->GetItemManager()->GetTradingImpl()->ClearRepurchasItemList(); } if( FALSE == pPlayer->SerializeInfoToDBProxy(UPDATE_FACTOR_LOGOUT)) { SUNLOG( eFULL_LOG, "[Handler_AG_ZONE_IMPL( AG_ZONE_ROOM_LEAVE_SYN )] [ERROR]DBP包装(AG_ZONE_ROOM_LEAVE_SYN:SerializeInfoToDBProxy)无法传递." ); MSG_AG_ZONE_ROOM_LEAVE_NAK nmsg; nmsg.m_dwErrorCode = RC::RC_DISCONNECT_DBP_CONNETION_ERROR; pPlayer->SendPacket( &nmsg, sizeof(nmsg) ); PlayerManager::Instance()->RemovePlayer( pPlayer ); return; } MSG_DG_CHARINFO_UPDATE_SYN msg; msg.m_ChannelID = g_pGameServer->GetKey().GetChannelID(); msg.char_guid_ = pPlayer->GetCharGuid(); // CHANGES: f110412.2L pPlayer->SendToGameDBPServer( &msg, sizeof(msg) ); // 重要!!:未从DB获得ACK的状态下发生Trade时发生复制 pPlayer->Release(); } Handler_AG_ZONE_IMPL( AG_ZONE_MASTER_CHANGED_CMD ) { __TOUCHED((pServerSession, pMsg, wSize)); MSG_AG_ZONE_MASTER_CHANGED_CMD * pRecvMsg = (MSG_AG_ZONE_MASTER_CHANGED_CMD *)pMsg; #ifdef __NA_PACKETFLOW_TEST SUNLOG( eFULL_LOG, "Handler_AG_ZONE_IMPL( AG_ZONE_MASTER_CHANGED_CMD )" ); #endif DWORD UserKey = pRecvMsg->m_dwKey; Player *pPlayer = PlayerManager::Instance()->FindPlayerByUserKey( UserKey ); ASSERT( pPlayer ); if( !pPlayer ) return; GameZone *pZone = g_GameZoneManager.GetZone( pRecvMsg->m_RoomKey ); if( !pZone || pZone->GetZoneType() == eZONETYPE_VILLAGE ) { return; } // 变更房主及队长. GameRoom *pRoom = (GameRoom*)pZone; pRoom->ChangeMaster( UserKey ); } Handler_AG_ZONE_IMPL( AG_ZONE_PVP_INFO_CMD ) { __TOUCHED((pServerSession, pMsg, wSize)); MSG_AG_ZONE_PVP_INFO_CMD * recv_msg = (MSG_AG_ZONE_PVP_INFO_CMD *)pMsg; GameZone* zone = g_GameZoneManager.GetZone(recv_msg->m_RoomKey); if (zone == NULL || zone->GetZoneType() != eZONETYPE_PVP) { SUNLOG( eCRITICAL_LOG, __FUNCTION__" : 不是pvp区域 : %d", zone->GetZoneType() ); return; } if (recv_msg->m_Count < 0 || recv_msg->m_Count > _countof(recv_msg->m_Info)) { SUNLOG( eCRITICAL_LOG, __FUNCTION__" : 用户计数已结束 : %d", recv_msg->m_Count); return; } GamePVPRoom* pvp_room = static_cast(zone); for (int i = 0 ; i < recv_msg->m_Count ; ++i) { pvp_room->GetPVPManager()->AddPVPInfo(recv_msg->m_Info[i].m_dwPlayerKey, recv_msg->m_Info[i].m_Team ); } pvp_room->GetPVPManager()->StartPVP(); } Handler_AG_ZONE_IMPL( AG_ZONE_PORTAL_FIELD_MOVE_SYN ) { __TOUCHED((pServerSession, pMsg, wSize)); MSG_AG_ZONE_PORTAL_FIELD_MOVE_SYN* pRecvMsg = (MSG_AG_ZONE_PORTAL_FIELD_MOVE_SYN*)pMsg; #ifdef __NA_PACKETFLOW_TEST SUNLOG( eFULL_LOG, "Handler_AG_ZONE_IMPL( AG_ZONE_PORTAL_FIELD_MOVE_SYN )" ); #endif DWORD UserKey = pRecvMsg->m_dwKey; Player *pPlayer = PlayerManager::Instance()->FindPlayerByUserKey( UserKey ); ASSERT( pPlayer ); if( !pPlayer ) return; //1. 自带门户信息. sMAP_ENTERENCE_PORTAL* pPortalInfo = MapInfoParser::Instance()->GetMapPortal( pRecvMsg->m_wIndex ); if( !pPortalInfo ) { MSG_AG_ZONE_PORTAL_FIELD_MOVE_NAK msg; msg.m_byErrorCode = RC::RC_ROOM_INVALID_MAPCODE; pPlayer->SendPacket( &msg, sizeof(msg) ); return; } const MAPCODE to_field_mapcode = static_cast(pPortalInfo->wFieldTo); GameZone* const to_field_zone = g_GameZoneManager.GetFieldVillageZone(to_field_mapcode); GameZone* pZone = pPlayer->GetGameZonePtr(); GameField* pField = pPlayer->GetField(); #ifdef __NA002642_TUTORIAL_LOAD_BALANCE_SUPPORT if (!pZone) { MSG_AG_ZONE_PORTAL_FIELD_MOVE_NAK msg; msg.m_byErrorCode = RC::RC_ROOM_INVALID_PLAYER_STATE; pPlayer->SendPacket( &msg, sizeof(msg) ); return; } if ( pZone->GetMapCode() != HardCode::MAPCODE_for_TUTORIAL_FIELD ) { if( !pField || (pZone->GetMapCode() != pPortalInfo->wWorldFrom) || (pField->GetFieldCode() != pPortalInfo->wFieldFrom) ) { MSG_AG_ZONE_PORTAL_FIELD_MOVE_NAK msg; msg.m_byErrorCode = RC::RC_ROOM_INVALID_PLAYER_STATE; pPlayer->SendPacket( &msg, sizeof(msg) ); return; } } #else if( !pZone || !pField || (pZone->GetMapCode() != pPortalInfo->wWorldFrom) || (pField->GetFieldCode() != pPortalInfo->wFieldFrom) ) { MSG_AG_ZONE_PORTAL_FIELD_MOVE_NAK msg; msg.m_byErrorCode = RC::RC_ROOM_INVALID_PLAYER_STATE; pPlayer->SendPacket( &msg, sizeof(msg) ); return; } #endif //__NA002642_TUTORIAL_LOAD_BALANCE_SUPPORT eZONE_STATE ZoneState = pPlayer->GetGameZoneState(); //如果当前玩家在城里并且死了……他们不会移动。. // #3149 在征服战争中,即使你死了,也应该回到战场。 (查看策划组) if ((pPlayer->GetHP() == 0) && (ZoneState == ePRS_AT_VILLAGE || ZoneState == ePRS_AT_FIELD /*|| ZoneState == ePRS_AT_DOMINATION_FIELD*/)) // _NA001385_20090924_DOMINATION_BASE (코드정리) { MSG_AG_ZONE_PORTAL_FIELD_MOVE_NAK msg; msg.m_byErrorCode = RC::RC_ROOM_INVALID_PLAYER_STATE; pPlayer->SendPacket( &msg, sizeof(msg) ); return; } // 如果是航点,检查是否保存 //if( pPortalInfo->bMoveType == sMAP_ENTERENCE_PORTAL::MOVE_TYPE_WAYPOINT && // FALSE == pPlayer->GetWayPoint()->IsExist(pPortalInfo->wWorldTo) ) //{ // MSG_AG_ZONE_PORTAL_FIELD_MOVE_NAK msg; // msg.m_byErrorCode = RC::RC_ROOM_DONT_EXIST_WAYPOINT; // pPlayer->SendPacket( &msg, sizeof(msg) ); // return; //} // 如果是航点,khao 不可用. if( pPortalInfo->bMoveType == sMAP_ENTERENCE_PORTAL::MOVE_TYPE_WAYPOINT && !pPlayer->GetChaoState().CanUseFuction( CHAO_USE_PORTAL ) ) { MSG_AG_ZONE_PORTAL_FIELD_MOVE_NAK msg; msg.m_byErrorCode = RC::RC_ROOM_UNABLE_FUNCTION_FOR_CHAOSTATE; pPlayer->SendPacket( &msg, sizeof(msg) ); return; } if( pPortalInfo->bMoveType == sMAP_ENTERENCE_PORTAL::MOVE_TYPE_WAYPOINT && pPlayer->GetBehave() == PLAYER_BEHAVE_UNEXPECTED_WAITING ) { MSG_AG_ZONE_PORTAL_FIELD_MOVE_NAK msg; msg.m_byErrorCode = RC::RC_ROOM_INVALID_PLAYER_STATE; pPlayer->SendPacket( &msg, sizeof(msg) ); return; } // 普通支票 //2. 任务清除检查 //3. 检查任务 //4. 水平检查 #ifdef _NA_008832_20160523_DOMINATIONFIELD_ENTER_LIMIT //4.1 公会等级检查 #endif //(_NA_008832_20160523_DOMINATIONFIELD_ENTER_LIMIT) //5. 物品检查 //6. 确认钱 //2. 任务清除检查 if( 0 != pPortalInfo->byMissionCode && 0 == pPlayer->GetMissionManager()->GetMissionPoint( pPortalInfo->byMissionCode ) ) { MSG_AG_ZONE_PORTAL_FIELD_MOVE_NAK nmsg; nmsg.m_byErrorCode = RC::RC_ROOM_PREVIOUS_MISSION_CLEAR; pPlayer->SendPacket( &nmsg, sizeof(nmsg) ); return; } //3. 确认任务 ////////////////////////////////////////////////////////////////////////// if( 0 != pPortalInfo->wQuestCode ) { QUESTPART_COMPL * pComplQuest = pPlayer->GetQuestManager()->FindComplQuest( pPortalInfo->wQuestCode ); if( !pComplQuest || pComplQuest->m_Num == 0 ) { MSG_AG_ZONE_PORTAL_FIELD_MOVE_NAK nmsg; nmsg.m_byErrorCode = RC::RC_ROOM_PREVIOUS_MISSION_CLEAR; pPlayer->SendPacket( &nmsg, sizeof(nmsg) ); return; } } //4. 等级检查 if( (pPlayer->GetLevel() < pPortalInfo->byMin_Level) || (0 != pPortalInfo->byMax_Level && //< pPortalInfo->byMax Level 0 Max LV不检查 (pPlayer->GetLevel() > pPortalInfo->byMax_Level)) ) { MSG_AG_ZONE_PORTAL_FIELD_MOVE_NAK nmsg; nmsg.m_byErrorCode = RC::RC_ROOM_INVALID_LIMITLEVEL; pPlayer->SendPacket( &nmsg, sizeof(nmsg) ); return; } #ifdef _NA_008832_20160523_DOMINATIONFIELD_ENTER_LIMIT // 4.1 行会等级限制 if (to_field_zone == NULL) { return; } // 要移动的地方类型在占领地区前一天。 if(to_field_zone->GetZoneType() == eZONETYPE_DOMINATION_FIELD) { GameDominationField* const domination_field = static_cast(to_field_zone); if(domination_field) { // 获取该玩家的公会信息 GameGuild* guild = g_GameGuildManager.FindGuild(pPlayer->GetGuildGuid()); if (guild == NULL) { SUNLOG( eFULL_LOG, __FUNCTION__" : 找不到当前玩家的帮会信息 : guid = %d", pPlayer->GetCharGuid() ); MSG_AG_ZONE_PORTAL_FIELD_MOVE_NAK nmsg; nmsg.m_byErrorCode = RC::RC_ROOM_NOT_INCLUDE_GUILD; pPlayer->SendPacket( &nmsg, sizeof(nmsg) ); return; } // 获取等级限制相关脚本信息 const sDOMINATION_INFO* const parser_info = DominationInfoParser::Instance()->GetDominationInfo(to_field_mapcode); if (parser_info == NULL) { SUNLOG( eCRITICAL_LOG, __FUNCTION__" : 找不到脚本数据 : map code = %d", to_field_mapcode); return; } BYTE check_guild_level = parser_info->m_BattingGuildLevelLimit; if (check_guild_level > guild->GetGuildGrade()) { MSG_AG_ZONE_PORTAL_FIELD_MOVE_NAK nmsg; nmsg.m_byErrorCode = RC::RC_ROOM_LIMIT_GUILD_LEVEL; pPlayer->SendPacket( &nmsg, sizeof(nmsg) ); return; } } } #endif //(_NA_008832_20160523_DOMINATIONFIELD_ENTER_LIMIT) #ifdef _NA_20100307_BETAKEY_SYSTEM if(!pPlayer->GetBetaKeyInfo()->CanAbilityContent(pPlayer->GetGameZonePtr()->GetMAPINFO()->nBetaKey)) { MSG_AG_ZONE_PORTAL_FIELD_MOVE_NAK nmsg; nmsg.m_byErrorCode = RC::RC_ROOM_CANNOT_BETAKEY; pPlayer->SendPacket( &nmsg, sizeof(nmsg) ); return; } DWORD portal_heim = BetaKeyImpl::GetPortalMoney(pPlayer->GetBetaKeyInfo(), pPortalInfo); #else DWORD portal_heim = pPortalInfo->dwHeim; #endif //5. 确认钱。 if( 0 != portal_heim && portal_heim > pPlayer->GetMoney() ) { MSG_AG_ZONE_PORTAL_FIELD_MOVE_NAK nmsg; nmsg.m_byErrorCode = RC::RC_ROOM_INSUFFICIENT_MONEY; pPlayer->SendPacket( &nmsg, sizeof(nmsg) ); return; } //5. 检查物品 ////////////////////////////////////////////////////////////////////////// // 怎么办。什么。几个?没有定义。首先使用物品代码,1个数量时确认. if( 0 != pPortalInfo->wItemCode && 0 != pPortalInfo->wItemNum ) { if( pPortalInfo->bWaste_Item ) { #ifdef _NA_006826_20130722_DOMINATION_RENEWAL if (to_field_zone == NULL) { return; } MSG_CG_ITEM_LOSE_ACK ack_msg; POSTYPE ItemNum = (POSTYPE)pPortalInfo->wItemNum; WORD item_code = (WORD)pPortalInfo->wItemCode; SCItemSlot deleted_item_slot; if(to_field_zone->GetZoneType() == eZONETYPE_DOMINATION_FIELD) { GameDominationField* const domination_field = static_cast(to_field_zone); if (domination_field && (domination_field->GetEventState() == DOMINATION_EVENT_START || domination_field->GetEventState() == DOMINATION_EVENT_WAIT)) { if( RC::RC_ITEM_SUCCESS != pPlayer->GetItemManager()->DeleteAllKindOfItem( \ 1, &pPortalInfo->wItemCode, &ItemNum, &(ack_msg.m_ItemInfo), &deleted_item_slot ) ) { MSG_AG_ZONE_PORTAL_FIELD_MOVE_NAK nmsg; nmsg.m_byErrorCode = RC::RC_ROOM_NEED_ITEM; pPlayer->SendPacket( &nmsg, sizeof(nmsg) ); return; } } } else { if( RC::RC_ITEM_SUCCESS != pPlayer->GetItemManager()->DeleteAllKindOfItem( \ 1, &pPortalInfo->wItemCode, &ItemNum, \ &(ack_msg.m_ItemInfo), &deleted_item_slot ) ) { MSG_AG_ZONE_PORTAL_FIELD_MOVE_NAK nmsg; nmsg.m_byErrorCode = RC::RC_ROOM_NEED_ITEM; pPlayer->SendPacket( &nmsg, sizeof(nmsg) ); return; } } pPlayer->SendPacket(&ack_msg, ack_msg.GetSize()); GAMELOG->LogItem(ITEM_USE, pPlayer, &deleted_item_slot, 0, ItemNum); #else POSTYPE ItemNum = (POSTYPE)pPortalInfo->wItemNum; INVEN_DELETE_TOTAL_INFO tmp_info; //< 보내지 않는 임시 구조체 if( RC::RC_ITEM_SUCCESS != pPlayer->GetItemManager()->DeleteAllKindOfItem( 1, &pPortalInfo->wItemCode, &ItemNum, &tmp_info ) ) { MSG_AG_ZONE_PORTAL_FIELD_MOVE_NAK nmsg; nmsg.m_byErrorCode = RC::RC_ROOM_NEED_ITEM; pPlayer->SendPacket( &nmsg, sizeof(nmsg) ); return; } #endif // _NA_006826_20130722_DOMINATION_RENEWAL } else { if( pPortalInfo->wItemNum != pPlayer->GetItemManager()->ExistItem( SI_INVENTORY, pPortalInfo->wItemCode, pPortalInfo->wItemNum ) ) { MSG_AG_ZONE_PORTAL_FIELD_MOVE_NAK nmsg; nmsg.m_byErrorCode = RC::RC_ROOM_NEED_ITEM; pPlayer->SendPacket( &nmsg, sizeof(nmsg) ); return; } } } // 追加仓库状态预约:使用道具移动时正在确认, //如果是微博积分,只检查与NPC的距离 [8/11/2009 lst1024] //6. 检查仓库状态 ////////////////////////////////////////////////////////////////////////// const RC::ePORTAL_RESULT retValue = pPlayer->CanPortal(); if (RC::RC_PORTAL_CAN_SUCCESS != retValue) { MSG_AG_ZONE_PORTAL_FIELD_MOVE_NAK nmsg; nmsg.m_byErrorCode = RC::RC_ROOM_INVALID_PLAYER_STATE; pPlayer->SendPacket( &nmsg, sizeof(nmsg) ); return; } //_NA_20110406_CHANGE_RULE_FOR_DOMINATION_JOIN //进入占领战地图时 GameDominationManager* const domination_manager = GameDominationManager::Instance(); if (domination_manager->IsDominationArea(to_field_mapcode) == true) { if (domination_manager->CanEnterDominationField(pPlayer, to_field_mapcode) == false) { MSG_AG_ZONE_PORTAL_FIELD_MOVE_NAK nak_msg; nak_msg.m_byErrorCode = RC::RC_ROOM_ISNOT_JOINMEMBER; pPlayer->SendPacket(&nak_msg, sizeof(nak_msg)); return; } } // 成功时:差价 if( 0 != portal_heim ) { pPlayer->MinusMoney( portal_heim ); // CHANGES: f110103.2L if (ns_object::PlayerZoneTransaction* trans_info = pPlayer->GetZoneTransactionInfo()) { ns_object::PlayerZoneTransaction::Data data = { 0, }; data.consumed_money = portal_heim; trans_info->BeginTransaction(data); }; GAMELOG->LogMoney( MONEY_SPEND_WAYPOINT, pPlayer, portal_heim ); g_pGameServer->NotifyHeimConsumption(pPlayer->GetCharGuid(), eHEIM_CONSUMPTION_WAYPOINT, portal_heim); } MSG_AG_ZONE_PORTAL_FIELD_MOVE_ACK ack; ack.m_wIndex = pRecvMsg->m_wIndex; pPlayer->SendPacket( &ack, sizeof(ack) ); return; } Handler_AG_ZONE_IMPL( AG_ZONE_RETURN_VILLAGE_SYN ) { __TOUCHED((pServerSession, pMsg, wSize)); MSG_AG_ZONE_RETURN_VILLAGE_SYN* pRecvMsg = (MSG_AG_ZONE_RETURN_VILLAGE_SYN*)pMsg; #ifdef __NA_PACKETFLOW_TEST SUNLOG( eFULL_LOG, "Handler_AG_ZONE_IMPL( AG_ZONE_RETURN_VILLAGE_SYN )" ); #endif DWORD UserKey = pRecvMsg->m_dwKey; Player *pPlayer = PlayerManager::Instance()->FindPlayerByUserKey( UserKey ); ASSERT( pPlayer ); if( !pPlayer ) return; // 有什么条件在这里检查. if( pPlayer->GetHP() != 0 ) { MSG_AG_ZONE_RETURN_VILLAGE_NAK msg; msg.m_byErrorCode = RC::RC_ROOM_INVALID_PLAYER_STATE; pPlayer->SendPacket( &msg, sizeof(msg) ); return; } MSG_AG_ZONE_RETURN_VILLAGE_ACK ack; ack.m_wMapCode = pPlayer->GetPreVillageMapCode(); pPlayer->SendPacket( &ack, sizeof(ack) ); } Handler_AG_ZONE_IMPL( AG_ZONE_CHANGE_SPECIALTYPE_CMD ) { __TOUCHED((pServerSession, pMsg, wSize)); MSG_AG_ZONE_CHANGE_SPECIALTYPE_CMD* pRecvMsg = (MSG_AG_ZONE_CHANGE_SPECIALTYPE_CMD*)pMsg; #ifdef __NA_PACKETFLOW_TEST SUNLOG( eFULL_LOG, "Handler_AG_ZONE_IMPL( AG_ZONE_CHANGE_SPECIALTYPE_CMD )" ); #endif GameZone * pZone = g_GameZoneManager.GetZone( pRecvMsg->m_RoomKey ); if( !pZone ) { SUNLOG( eCRITICAL_LOG, "[AG_ZONE_CHANGE_SPECIALTYPE_CMD]找不到房间[%d]", pRecvMsg->m_RoomKey ); return; } // 超级房主出去后,将 m_SpecialType换成普通. pZone->SetSpecialType( (eROOM_SPECIAL_TYPE)pRecvMsg->m_SpecialType ); } Handler_AG_ZONE_IMPL(AG_ZONE_CAN_CREATE_INSTANCE_DUNGEON_SYN) { __TOUCHED((pServerSession, pMsg, wSize)); MSG_AG_ZONE_CAN_CREATE_INSTANCE_DUNGEON_SYN* const pRecvMsg = static_cast(pMsg); #ifdef __NA_PACKETFLOW_TEST SUNLOG(eFULL_LOG, "Handler_AG_ZONE_IMPL("__FUNCTION__")"); #endif const DWORD user_key = pRecvMsg->m_dwKey; Player* const pPlayer = PlayerManager::Instance()->FindPlayerByUserKey(user_key); if(!pPlayer) return; MSG_AG_ZONE_CAN_CREATE_INSTANCE_DUNGEON_NAK msgNAK; BYTE error_group = msgNAK.eErr_ItemRC; ////////////////////////////////////////////////////////////////////////// // FlowControl flow; FLOWCONTROL_START() { MSG_AG_ZONE_CAN_CREATE_INSTANCE_DUNGEON_ACK msgACK; ItemManager* const pItemManager = pPlayer->GetItemManager(); error_group = msgNAK.eErr_ItemRC; RC::eITEM_RESULT ret_CanUseItemForIndun = pItemManager->GetItemFunctionBattlezoneEnterance().CanUseItemForTopOfTrial( pRecvMsg->m_ItemPos, msgACK.m_MapCode, msgACK.m_UseCharge); // side-effect: item lock IfFailThenBreak(RC::RC_ITEM_SUCCESS == ret_CanUseItemForIndun, ret_CanUseItemForIndun); // (BUGFIX) (091211) (WAVERIX) 在企划中,即使阻止了约翰的设定,也存在很多打开项目的事例。 //虽然一定要解决,但实际上并不能认为所有的测试都能进行 //执行错误处理. error_group = msgNAK.eErr_RoomRC; const sMAPINFO* const pMapInfo = MapInfoParser::Instance()->FindMapInfo(msgACK.m_MapCode); IfFailThenBreak(pMapInfo != NULL, RC::RC_ROOM_INVALID_MAPCODE); const eZONE_RULESET& ruleset = pMapInfo->Ruleset; if(ruleset.rules & ruleset.ZONE_RULE_INDUN_CANT_EQUIP_WEAPON_AND_BLOCK) { // 设备限制检查 error_group = msgNAK.eErr_RoomRC; const BASE_ITEMINFO* const pItemInfo = pPlayer->GetEquipItemInfo(eEQUIPCONTAINER_WEAPON); IfFailThenBreak(!pItemInfo, RC::RC_ROOM_NEED_UNEQUIP_WEAPON_FOR_ENTER); } BOOLEAN partyProblemOccurred = 0; //(lst1024)(090410) 中国道具复制错误修正 //检查队员们是否准备好移动. const WORD partyKey = pPlayer->GetPartyState().GetPartyKey(); if(0 != partyKey) { // (WAVERIX) (WOPS:3943) 约翰移动队伍检查失败后,当事人不可移动 //修正维护问题,修正Result Code Group设置遗漏 error_group = msgNAK.eErr_RoomRC; CheckReadyPartyMember check_ready; if(NewGamePartyManager::Instance()->For_eachPlayers(partyKey, check_ready)) { IfFailThenBreak(check_ready.m_AllReady, RC::RC_ROOM_CANNOT_JOIN_SOMEONE_PARTY_MEMBER); } else partyProblemOccurred = TRUE; } if(partyProblemOccurred) { SUNLOG(eCRITICAL_LOG, "[AG_ZONE_CAN_CREATE_INSTANCE_DUNGEON_SYN] 找不到[%s]的队伍. " "partyKey[%d]", pPlayer->GetCharName(), partyKey); } // NOTE, __NA001281_BATTLEZONE_ENTER_CONSTRAINTS_CHANGE_IN_LOBBY__ // 检查组织者的约束条件(Timeline - Quest|Mission|FreePass|...) // CanuseitemForTopOffTrial是引起状态变更的函数。寻求简单化的方案. //BOOLEAN checkParty = FALSE == (ruleset.rules & ruleset.ZONE_RULE_INDUN_SINGLE_PLAYING_MODE); ;{ // (CHANGES) (f100514.3L) 添加标志以防止任何 //无论球员是否要求离开,他都会延迟扣球. pPlayer->GetStatusManager()->ChangeInterState(eCHAR_STATE_ZONE_TRANSACTION, true); }; pPlayer->SendPacket(&msgACK, sizeof(msgACK)); return /*SUCCESS RESULT*/; } FLOWCONTROL_END; SUNLOG(eCRITICAL_LOG, "["__FUNCTION__"][ErrCode:%2u] {%s} {CharName:%s,Party:%u}", flow.GetErrorCode(), flow.GetErrorString(), pPlayer->GetCharName(), pPlayer->GetPartyState().GetPartyKey()); msgNAK.m_ErrorKind = (BYTE)error_group; msgNAK.m_dwErrorCode = flow.GetErrorCode(); pPlayer->SendPacket(&msgNAK, sizeof(msgNAK)); } Handler_AG_ZONE_IMPL( AG_ZONE_INSTANCE_CREATE_CMD ) { __TOUCHED((pServerSession, pMsg, wSize)); MSG_AG_ZONE_INSTANCE_CREATE_CMD * pRecvMsg = (MSG_AG_ZONE_INSTANCE_CREATE_CMD *)pMsg; #ifdef __NA_PACKETFLOW_TEST SUNLOG( eFULL_LOG, "Handler_AG_ZONE_IMPL( AG_ZONE_INSTANCE_CREATE_CMD )" ); #endif GameInstanceDungeon* pZone = static_cast( g_GameZoneManager.CreateZone( eZONETYPE_INSTANCE , pRecvMsg->m_RoomKey , pRecvMsg->m_MapCode )); if( pZone ) { //pZone->SetRoomTitle(pRecvMsg->m_pszRoomTitle); //pZone->SetRoomPWD(pRecvMsg->m_pszRoomPWD); pZone->SetBaseRoomInfo(&pRecvMsg->m_RoomInfo); pZone->SetMasterUserKey(pRecvMsg->m_dwKey); #ifdef _NA_004204_20120131_BATTLE_ZONE_PARTY_OBTAIN pZone->SetPartyZoneType(pRecvMsg->party_zone_info_); #endif //_NA_004204_20120131_BATTLE_ZONE_PARTY_OBTAIN BOOST_STATIC_ASSERT( INDUN_KIND_MAX == 7 ); // 追加类型存在时追加下端内容 const eINSTANCE_DUNGEON_KIND kindOfIndun = (eINSTANCE_DUNGEON_KIND)pRecvMsg->m_TypeOfIndun; switch( kindOfIndun ) { case INDUN_KIND_TOP_OF_TRIAL: case INDUN_KIND_SS_QUEST: case INDUN_KIND_100LEVEL_QUEST: case INDUN_KIND_EXT_03: case INDUN_KIND_EXT_04: case INDUN_KIND_MAYA_SCROLL: pZone->SetTypeOfIndun( kindOfIndun ); break; //_NA_005026_20120527_CHAOS_ZONE_BATTLE_GROUND case INDUN_KIND_CHAOS_ZONE: pZone->SetTypeOfIndun(kindOfIndun); pZone->SetChaosZoneType(pRecvMsg->chaos_zone_type_); break; default: ASSERT( !"Invalid TypeOfIndun : INSTANCE_CREATE" ); pZone->SetTypeOfIndun( INDUN_KIND_MAX ); break; } pZone->OnCreate(); } } Handler_AG_ZONE_IMPL( AG_ZONE_TUTORIAL_SKIP_SYN ) { // NOTE: f110809.6L, 有些情况像中国版,很多玩家会一次玩。 //根据计划者的要求,这个处理器恢复了. __TOUCHED((pServerSession, pMsg, wSize)); #ifdef __NA002642_TUTORIAL_LOAD_BALANCE_SUPPORT Player* const player = PlayerManager::Instance()->FindPlayerByUserKey(pMsg->m_dwKey); GameField* const game_field = player ? player->GetField() : NULL; if (FlowControl::FCAssert(player != NULL && game_field != NULL) == false) { return; }; GameZone* const game_zone = game_field->GetGameZone(); const MAPCODE entered_map_code = game_zone->GetMapCode(); if (entered_map_code != HardCode::MAPCODE_for_TUTORIAL_FIELD) { SUNLOG(eCRITICAL_LOG, _T("|["__FUNCTION__"]|斤口=违反游戏规则, CharName='%s', CurrendMap=%d|"), player->GetCharName(), entered_map_code); return; }; WzVector standing_pos = { 0.0f }; player->Portal(ePORTAL_TYPE_GM, HardCode::MAPCODE_for_VALDCHEN, standing_pos, 0); #endif #if SUN_CODE_BACKUP // NOTE: old-contents support const MAPCODE HARDCODED_TUTORIAL_MISSION_MAPCODE = 31; const DWORD CHAR_VILLAGE_TRINGGEL_BITMAP = (1 << eCHAR_BERSERKER | 1 << eCHAR_ELEMENTALIST); const DWORD CHAR_VILLAGE_VALDCHEN_BITMAP = (1 << eCHAR_DRAGON | 1 << eCHAR_VALKYRIE | 1 << eCHAR_SHADOW); MSG_AG_ZONE_TUTORIAL_SKIP_SYN* pRecvMsg = (MSG_AG_ZONE_TUTORIAL_SKIP_SYN*)pMsg; DWORD dwUserKey = pRecvMsg->m_dwKey; Player* pPlayer = PlayerManager::Instance()->FindPlayerByUserKey(dwUserKey); if(!pPlayer) return; GameZone* pEnterZone = NULL; MAPCODE EnterFieldCode = 0; eZONE_STATE eRoomState = pPlayer->GetGameZone(pEnterZone, EnterFieldCode); if(HardCode::MAPCODE_for_TUTORIAL_FIELD != EnterFieldCode) { // error 처리? return; } DWORD dwCharClass = (DWORD)pPlayer->GetCharType(); dwCharClass = 1 << dwCharClass; MAPCODE mcRETURN_MAPCODE = CHAR_VILLAGE_TRINGGEL_BITMAP & dwCharClass ? HardCode::MAPCODE_for_TRINGGEL : CHAR_VILLAGE_VALDCHEN_BITMAP & dwCharClass ? HardCode::MAPCODE_for_VALDCHEN : 0; if(mcRETURN_MAPCODE) { WzVector vecDestPos; ZeroMemory(&vecDestPos, sizeof(vecDestPos)); pPlayer->Portal(ePORTAL_TYPE_GM, mcRETURN_MAPCODE, vecDestPos, 0); } #endif } Handler_AG_ZONE_IMPL( AG_ZONE_RETURN_TO_ROOM_INFO_SYN ) { __TOUCHED((pServerSession, pMsg, wSize)); MSG_AG_ZONE_RETURN_TO_ROOM_INFO_SYN* pRecvMsg = (MSG_AG_ZONE_RETURN_TO_ROOM_INFO_SYN*)pMsg; #ifdef __NA_PACKETFLOW_TEST SUNLOG( eFULL_LOG, "Handler_AG_ZONE_IMPL( AG_ZONE_RETURN_TO_ROOM_INFO_SYN )" ); #endif PlayerManager* pPlayerManager = PlayerManager::Instance(); DWORD dwUserKey = pRecvMsg->m_dwKey; Player* pPlayer = pPlayerManager->FindPlayerByUserKey( dwUserKey ); MSG_AG_ZONE_RETURN_TO_ROOM_INFO_ACK msgACK; FlowControl flow; FLOWCONTROL_START() { // start LOGIC_BLOCK IfFailThenBreak(pPlayer, 10); IfFailThenBreak(g_FunctionalRestrictMgr.IsPossibleFunction( eFUNCTIONALRESTRICT_PARTY_RETURN_FOR_UCUSER), 20); // (WAVERIX) (090224) (NOTE) 事实上,Abusing防止处理后,就不需要房主的存在了. // 但是保留这个Flow的理由是中间需要什么样的处理时, //为了维持可以插入的流程。还有游戏服务器的场景无缺性检查。 //充分需要。附加事项…如果是2人派对的话,那就没用了…) NewGamePartyManager* pPartyManager = NewGamePartyManager::Instance(); WORD partyKey = pRecvMsg->PARTY_KEY(); IfFailThenBreak(pPartyManager->FindParty(partyKey), 30); // msgACK.m_byResult = MSG_AG_ZONE_RETURN_TO_ROOM_INFO_ACK::SUCCESS; msgACK.REQUEST_USER_KEY() = pRecvMsg->REQUEST_USER_KEY(); msgACK.PARTY_KEY() = partyKey; pPlayer->SendPacket(&msgACK, msgACK.GetSize()); return; } FLOWCONTROL_END; msgACK.m_byResult = MSG_AG_ZONE_RETURN_TO_ROOM_INFO_ACK::FAIL; msgACK.REQUEST_USER_KEY() = pRecvMsg->REQUEST_USER_KEY(); if(pPlayer) pPlayer->SendPacket(&msgACK, msgACK.GetSize()); MessageOut(eCRITICAL_LOG, _T("MSG_AG_ZONE_RETURN_TO_ROOM_INFO_SYN - ERROR %s"), flow.GetErrorString()); } Handler_AG_ZONE_IMPL( AG_ZONE_CAN_CREATE_100LEVEL_QUEST_MISSION_SYN ) { __TOUCHED((pServerSession, pMsg, wSize)); MSG_AG_ZONE_CAN_CREATE_100LEVEL_QUEST_MISSION_SYN* pRecvMsg = (MSG_AG_ZONE_CAN_CREATE_100LEVEL_QUEST_MISSION_SYN*)pMsg; DWORD userKey = pRecvMsg->m_dwKey; Player* pPlayer = PlayerManager::Instance()->FindPlayerByUserKey( userKey ); if( !pPlayer ) return; ItemManager* pItemMGR = pPlayer->GetItemManager(); MAPCODE rMapCode = 0; RC::eITEM_RESULT rt = pItemMGR->GetItemFunctionBattlezoneEnterance().CanUseItemForPortalQuest( pRecvMsg->m_ItemPos, rMapCode); //(lst1024)(090410) 中国道具复制错误修正 BOOL bAllReady = TRUE; if( rt == RC::RC_ITEM_SUCCESS ) { // 检查队员们是否准备好移动. const WORD PartyKey = pPlayer->GetPartyState().GetPartyKey(); if( 0 != PartyKey ) { CheckReadyPartyMember opr; if( NewGamePartyManager::Instance()->For_eachPlayers(PartyKey,opr) ) bAllReady = opr.m_AllReady; } } MSG_AG_ZONE_CAN_JOIN_100LEVEL_QUEST_MISSION_ACK msgACK; if (RC::RC_ITEM_SUCCESS == rt && bAllReady && rMapCode) { // (CHANGES) (f100514.3L) 添加标志以防止任何 //无论球员是否要求离开,他都会延迟扣球. pPlayer->GetStatusManager()->ChangeInterState(eCHAR_STATE_ZONE_TRANSACTION, true); msgACK.SetSuccessResult(rMapCode); } else if (bAllReady) { msgACK.SetFailResult(MSG_AG_ZONE_CAN_JOIN_100LEVEL_QUEST_MISSION_ACK::RET_ITEM, static_cast(rt)); } else { msgACK.SetFailResult(MSG_AG_ZONE_CAN_JOIN_100LEVEL_QUEST_MISSION_ACK::RET_ROOM, RC::RC_ROOM_CANNOT_JOIN_SOMEONE_PARTY_MEMBER); } // MSG_AG_ZONE_CAN_JOIN_100LEVEL_QUEST_MISSION_ACK msgACK; // // RC::RC_ITEM_SUCCESS == rt && rMapCode ? // msgACK.SetSuccessResult( rMapCode ) // : msgACK.SetFailResult( MSG_AG_ZONE_CAN_JOIN_100LEVEL_QUEST_MISSION_ACK::eFAIL_RC_CODE::RET_ITEM, (DWORD)rt ); pPlayer->SendPacket( &msgACK, msgACK.GetSize() ); } Handler_AG_ZONE_IMPL( AG_ZONE_SSQ_JOIN_INFO_SYN ) { GameWarControlManager::OnRecv( pMsg, wSize, GameSSQSessionCmd::FromAgent( pServerSession ) ); } Handler_AG_ZONE_IMPL( AG_ZONE_SSQ_JOIN_SYN ) { GameWarControlManager::OnRecv( pMsg, wSize, GameSSQSessionCmd::FromAgent( pServerSession ) ); } Handler_AG_ZONE_IMPL( AG_ZONE_SSQ_ROOM_CTRL_CMD ) { GameWarControlManager::OnRecv( pMsg, wSize, GameSSQSessionCmd::FromAgent( pServerSession ) ); } //{__NA1279_1281_090209_TIMELINE_QUEST_BASED_MISSION__ namespace nsQuestPortal { typedef MSG_CG_ZONE_EX_QUEST_PORTAL_ENTER_SYN ENTER_SYNC_TYPE; struct EnterSynArg { const sMAPINFO* pMapInfo; const sMAP_ENTERENCE_PORTAL* pMapPortal; const MSG_AG_ZONE_QUEST_PORTAL_ENTER_SYN* pRecvMsg; // 只检查条件可能是NULL。. MSG_AG_ZONE_QUEST_PORTAL_ENTER_ACK* pReplyMsg; // 只检查条件可能是NULL。. }; static BOOLEAN IsValidPlayerState(BOOLEAN isTempPortal, Player* pPlayer, EnterSynArg* pArg) { GameField* pGameField = pPlayer->GetField(); if(pGameField == NULL) { if(pArg->pReplyMsg) { pArg->pReplyMsg->errorCode = RC::RC_ROOM_INVALIDROOMTYPE; pPlayer->SendPacket(pArg->pReplyMsg, sizeof(*pArg->pReplyMsg)); } return FALSE; } eZONE_STATE zoneState = pPlayer->GetGameZoneState(); BOOLEAN isValidState = zoneState == ePRS_AT_VILLAGE || zoneState == ePRS_AT_DOMINATION_FIELD || zoneState == ePRS_AT_FIELD; if(isTempPortal == FALSE ) { if (isValidState) { GameZone* game_zone = pGameField->GetGameZone(); bool validated_field_check = (pGameField->GetFieldCode() == pArg->pMapPortal->wFieldFrom); #ifdef __NA002642_TUTORIAL_LOAD_BALANCE_SUPPORT if ((validated_field_check == false) && (game_zone->GetMapCode() == HardCode::MAPCODE_for_TUTORIAL_FIELD)) { validated_field_check = true; } #endif isValidState = validated_field_check && game_zone->GetMapCode() == pArg->pMapPortal->wWorldFrom; }; } isValidState = isValidState && pPlayer->IsAlive(); if(isValidState == FALSE) { if(pArg->pReplyMsg) { pArg->pReplyMsg->errorCode = RC::RC_ROOM_INVALID_PLAYER_STATE; pPlayer->SendPacket(pArg->pReplyMsg, sizeof(*pArg->pReplyMsg)); } return FALSE; } if(isTempPortal == FALSE ) { if(pArg->pMapPortal->bMoveType == sMAP_ENTERENCE_PORTAL::MOVE_TYPE_WAYPOINT) { BOOLEAN isDisableFuncChao = pPlayer->GetChaoState().CanUseFuction(CHAO_USE_PORTAL); // 对于下面的情况不是WAYPOINT也可以听听情况. BOOLEAN isUnexpected = pPlayer->GetBehave() == PLAYER_BEHAVE_UNEXPECTED_WAITING; if(isDisableFuncChao || isUnexpected) { if(pArg->pReplyMsg) { pArg->pReplyMsg->errorCode = isDisableFuncChao ? RC::RC_ROOM_UNABLE_FUNCTION_FOR_CHAOSTATE : RC::RC_ROOM_INVALID_PLAYER_STATE; pPlayer->SendPacket(pArg->pReplyMsg, sizeof(*pArg->pReplyMsg)); } return FALSE; } } } return TRUE; } static BOOLEAN IsEnterableMap(BOOLEAN isTempPortal, Player* pPlayer, EnterSynArg* pArg) { if(pArg->pMapInfo == NULL || !(pArg->pMapInfo->byMKind == eZONETYPE_MISSION || pArg->pMapInfo->byMKind == eZONETYPE_INSTANCE)) { if(pArg->pReplyMsg) { pArg->pReplyMsg->errorCode = RC::RC_ROOM_INVALID_MAPCODE; pPlayer->SendPacket(pArg->pReplyMsg, sizeof(*pArg->pReplyMsg)); } return FALSE; } return TRUE; } static BOOLEAN IsValidPosition(BOOLEAN isTempPortal, Player* pPlayer, EnterSynArg* pArg) { BOOLEAN isPositionPass = FALSE; if(isTempPortal) { isPositionPass = TRUE; // 只是在检查条件时,pArg->pRecvMsg=NULL。 if(pArg->pRecvMsg) { WzVector portalPosition = pArg->pRecvMsg->portalPosision; portalPosition -= *pPlayer->GetPosPtr(); const FLOAT LengthSquareLimit = 10.0f * 10.0f; isPositionPass = VectorLength2(&portalPosition) <= LengthSquareLimit; } } else { if (pArg->pMapPortal) { GameField* pGameField = pPlayer->GetField(); GameZone* game_zone = pGameField->GetGameZone(); bool validated_field_check = (pGameField->GetFieldCode() == pArg->pMapPortal->wFieldFrom); #ifdef __NA002642_TUTORIAL_LOAD_BALANCE_SUPPORT if ((validated_field_check == false) && (game_zone->GetMapCode() == HardCode::MAPCODE_for_TUTORIAL_FIELD)) { validated_field_check = true; } #endif isPositionPass = validated_field_check; }; } if(isPositionPass == FALSE) { if(pArg->pReplyMsg) { pArg->pReplyMsg->errorCode = RC::RC_ROOM_FAILED; // 位置问题 pPlayer->SendPacket(pArg->pReplyMsg, sizeof(*pArg->pReplyMsg)); } } return isPositionPass; } // (WAVERIX) (090330) (LOGIC-UPDATE) 任务奖励处理未完成时,违反入场条件相关处理 static BOOLEAN ProcessEnterRestrictCondition(BOOLEAN isTempPortal, Player* pPlayer, EnterSynArg* pArg) { MissionManager* pMissionManager = pPlayer->GetMissionManager(); BOOLEAN isOpened = !!pMissionManager->EnableWindowOpen(); if(isOpened && pArg->pReplyMsg) { pArg->pReplyMsg->errorCode = RC::RC_ROOM_FAILED; // 进入失败 pPlayer->SendPacket(pArg->pReplyMsg, sizeof(*pArg->pReplyMsg)); } if(isOpened) TriggerManagerEx::Process_RewardWindow(pPlayer); return isOpened == FALSE; } static BOOLEAN IsFreePassLevel(BOOLEAN isTempPortal, Player* pPlayer, EnterSynArg* pArg) { const LEVELTYPE playerLevel = pPlayer->GetLevel(); return (pArg->pMapInfo->freePassLV <= playerLevel); } struct QuestOrMissionResult { BOOLEAN bQuestCheckSkip; BOOLEAN bMissionCheckSkip; BOOLEAN isQuestPass; BOOLEAN isMissionPass; }; static BOOLEAN IsMissionOrQuestPass(BOOLEAN isTempPortal, Player* pPlayer, EnterSynArg* pArg, QuestOrMissionResult* pResult) { ZeroMemory(pResult, sizeof(*pResult)); //BOOLEAN bQuestCheckSkip = FALSE; //BOOLEAN bMissionCheckSkip = FALSE; //BOOLEAN isQuestPass = FALSE; //BOOLEAN isMissionPass = FALSE; QuestManager_Concrete* pQuestManager = pPlayer->GetQuestManager(); MissionManager* pMissionManager = pPlayer->GetMissionManager(); if(isTempPortal) { pResult->bQuestCheckSkip = pArg->pMapInfo->completeQCode == 0; if(pArg->pMapInfo->completeQCode) { QUESTPART_COMPL* pComplete = pQuestManager->FindComplQuest(pArg->pMapInfo->completeQCode); pResult->isQuestPass = pComplete && pComplete->m_Num; } pResult->bMissionCheckSkip = pArg->pMapInfo->completeMCode == 0; if(pArg->pMapInfo->completeMCode) pResult->isMissionPass = !!pMissionManager->GetMissionPoint((BYTE)pArg->pMapInfo->completeMCode); } else { pResult->bQuestCheckSkip = pArg->pMapPortal->wQuestCode == 0; if(pArg->pMapPortal->wQuestCode) { QUESTPART_COMPL* pComplete = pQuestManager->FindComplQuest(pArg->pMapPortal->wQuestCode); pResult->isQuestPass = pComplete && pComplete->m_Num; } pResult->bMissionCheckSkip = pArg->pMapPortal->byMissionCode == 0; if(pArg->pMapPortal->byMissionCode) pResult->isMissionPass = !!pMissionManager->GetMissionPoint(pArg->pMapPortal->byMissionCode); } if(pResult->isQuestPass || pResult->isMissionPass) return TRUE; if(pResult->bQuestCheckSkip && pResult->bMissionCheckSkip) return TRUE; // 任务|任务错误处理. if(pArg->pReplyMsg) { if(pResult->bQuestCheckSkip == FALSE && pResult->isQuestPass == FALSE) pArg->pReplyMsg->errorCode = RC::RC_ROOM_PREVIOUS_QUEST_CLEAR; else if(pResult->bMissionCheckSkip == FALSE && pResult->isMissionPass == FALSE) pArg->pReplyMsg->errorCode = RC::RC_ROOM_NEED2_CLEAR_PRE_MISSION; pPlayer->SendPacket(pArg->pReplyMsg, sizeof(*pArg->pReplyMsg)); } return FALSE; } static BOOLEAN IsLevelPass(BOOLEAN isTempPortal, Player* pPlayer, EnterSynArg* pArg) { const LEVELTYPE playerLevel = pPlayer->GetLevel(); BOOLEAN isLevelPass = FALSE; if(isTempPortal) { LEVELTYPE minLevel = pArg->pMapInfo->minLV; LEVELTYPE maxLevel = pArg->pMapInfo->maxLV; isLevelPass = minLevel <= playerLevel && playerLevel <= maxLevel; } else { LEVELTYPE minLevel = pArg->pMapPortal->byMin_Level; LEVELTYPE maxLevel = pArg->pMapPortal->byMax_Level; isLevelPass = minLevel <= playerLevel && (maxLevel && playerLevel <= maxLevel); } if(isLevelPass == FALSE) { if(pArg->pReplyMsg) { pArg->pReplyMsg->errorCode = RC::RC_ROOM_INVALID_LIMITLEVEL; pPlayer->SendPacket(pArg->pReplyMsg, sizeof(*pArg->pReplyMsg)); } } return isLevelPass; } static BOOLEAN IsAcceptHeim(BOOLEAN isTempPortal, Player* pPlayer, EnterSynArg* pArg) { const MONEY playerHeim = pPlayer->GetMoney(); BOOLEAN isAcceptHeim = FALSE; if(isTempPortal) { return TRUE; } else { MONEY heim = pArg->pMapPortal->dwHeim; isAcceptHeim = !heim || heim <= playerHeim; } if(isAcceptHeim == FALSE) { if(pArg->pReplyMsg) { pArg->pReplyMsg->errorCode = RC::RC_ROOM_INSUFFICIENT_MONEY; pPlayer->SendPacket(pArg->pReplyMsg, sizeof(*pArg->pReplyMsg)); } } return isAcceptHeim; } static BOOLEAN ProcessItemAndHeim(BOOLEAN isTempPortal, Player* pPlayer, EnterSynArg* pArg) { if(isTempPortal) return TRUE; // (WAVERIX) (NOTE) 带来了带来了AG ZONE PORTAL FIELD MOVE SYN的逻辑的逻辑. // ... // 怎么办。什么。几个?没有定义。首先使用物品代码,1个数量时确认. BOOLEAN needItemDelete = pArg->pMapPortal->wItemCode && pArg->pMapPortal->wItemNum; if(needItemDelete) { BOOLEAN isItemProcessed = FALSE; SLOTCODE itemCode = (SLOTCODE)pArg->pMapPortal->wItemCode; POSTYPE itemNum = (POSTYPE)pArg->pMapPortal->wItemNum; ItemManager* pItemManager = pPlayer->GetItemManager(); INVEN_DELETE_TOTAL_INFO tmp_info; //< 不发送的临时结构体 if(pArg->pMapPortal->bWaste_Item) { isItemProcessed = RC::RC_ITEM_SUCCESS == pItemManager->DeleteAllKindOfItem(1, &itemCode, &itemNum, &tmp_info); } else { isItemProcessed = itemNum == pItemManager->ExistItem(SI_INVENTORY, itemCode, itemNum); } if(isItemProcessed == FALSE) { if(pArg->pReplyMsg) { pArg->pReplyMsg->errorCode = RC::RC_ROOM_NEED_ITEM; pPlayer->SendPacket(pArg->pReplyMsg, sizeof(*pArg->pReplyMsg)); } return isItemProcessed; } } if(const MONEY decreaseHeim = pArg->pMapPortal->dwHeim) { pPlayer->MinusMoney(decreaseHeim); // CHANGES: f110103.2L if (ns_object::PlayerZoneTransaction* trans_info = pPlayer->GetZoneTransactionInfo()) { ns_object::PlayerZoneTransaction::Data data = { 0, }; data.consumed_money = decreaseHeim; trans_info->BeginTransaction(data); }; GAMELOG->LogMoney(MONEY_SPEND_WAYPOINT, pPlayer, decreaseHeim); // waypoint는 아닐터... g_pGameServer->NotifyHeimConsumption(pPlayer->GetCharGuid(), eHEIM_CONSUMPTION_WAYPOINT, decreaseHeim); } return TRUE; } }; // end of namespace nsQuestPortal Handler_AG_ZONE_IMPL( AG_ZONE_QUEST_PORTAL_ENTER_SYN ) { __TOUCHED((pServerSession, pMsg, wSize)); const MSG_AG_ZONE_QUEST_PORTAL_ENTER_SYN* pRecvMsg = static_cast(pMsg); const DWORD userKey = pRecvMsg->m_dwKey; Player* pPlayer = PlayerManager::Instance()->FindPlayerByUserKey(userKey); if(pPlayer == NULL) return; using nsQuestPortal::ENTER_SYNC_TYPE; const ENTER_SYNC_TYPE::eSYNC syncType = ENTER_SYNC_TYPE::eSYNC(pRecvMsg->syncType); const BOOLEAN isTempPortal = syncType == ENTER_SYNC_TYPE::eSYNC_TEMP_PORTAL; MSG_AG_ZONE_QUEST_PORTAL_ENTER_ACK msg; msg.errorType = msg.eRESULT_ROOM; msg.errorCode = RC::RC_ROOM_SUCCESS; msg.syncType = syncType; msg.portalKey = pRecvMsg->portalKey; msg.mapEnterancePortalIndex = 0; if(!isTempPortal) { if(syncType != ENTER_SYNC_TYPE::eSYNC_FIXED_PORTAL || !FlowControl::FCAssert(pRecvMsg->mapEnterancePortalIndex)) { msg.errorCode = RC::RC_ROOM_FAILED; // 任务|任务错误处理. pPlayer->SendPacket(&msg, sizeof(msg)); return; } } MapInfoParser* const pMapInfoParser = MapInfoParser::Instance(); // Agent设定enterable MapCode. nsQuestPortal::EnterSynArg arg = { 0, }; arg.pMapInfo = pMapInfoParser->FindMapInfo(pRecvMsg->enterableMapCode); if(!isTempPortal) arg.pMapPortal = pMapInfoParser->GetMapPortal(pRecvMsg->mapEnterancePortalIndex); arg.pRecvMsg = pRecvMsg; arg.pReplyMsg = &msg; if(nsQuestPortal::IsValidPlayerState(isTempPortal, pPlayer, &arg) == FALSE) return; if(nsQuestPortal::IsEnterableMap(isTempPortal, pPlayer, &arg) == FALSE) return; BOOLEAN isLevelPass = FALSE; if(nsQuestPortal::IsValidPosition(isTempPortal, pPlayer, &arg) == FALSE) return; // (WAVERIX) (090330) (LOGIC-UPDATE) 任务奖励处理未完成时违反入场条件 if(nsQuestPortal::ProcessEnterRestrictCondition(isTempPortal, pPlayer, &arg) == FALSE) return; const BOOLEAN isFreePass = nsQuestPortal::IsFreePassLevel(isTempPortal, pPlayer, &arg); if(isFreePass == FALSE) { nsQuestPortal::QuestOrMissionResult result; if(nsQuestPortal::IsMissionOrQuestPass(isTempPortal, pPlayer, &arg, &result) == FALSE) return; if(nsQuestPortal::IsLevelPass(isTempPortal, pPlayer, &arg) == FALSE) return; } if(nsQuestPortal::IsAcceptHeim(isTempPortal, pPlayer, &arg) == FALSE) return; if(nsQuestPortal::ProcessItemAndHeim(isTempPortal, pPlayer, &arg) == FALSE) return; // Success pPlayer->SendPacket(&msg, sizeof(msg)); } //}__NA1279_1281_090209_TIMELINE_QUEST_BASED_MISSION__ //{__NA001281_BATTLEZONE_ENTER_CONSTRAINTS_CHANGE_IN_LOBBY__ //_NA_20110630_BATTLE_ZONE_RENEWAL void CheckMemberConditionToChangeOptionOperator::operator()(_PARTY_MEMBER_INFO* party_memeber_info) { DWORD player_key = party_memeber_info->m_dwMemberKey; if (m_ExceptKey && m_ExceptKey == player_key) { return; } if (m_SuccessFlag == FALSE) { return; } Player* player = PlayerManager::Instance()->FindPlayerByObjKey(player_key); if (player == NULL) { return; } if (_countof(list_of_msg_->member_state_) < number_of_list_) { return; } typedef MSG_AG_PARTY_CAN_CHANGE_OPTION_ACK MemberListMsg; MemberListMsg::MemberState* member_state = &(list_of_msg_->member_state_[number_of_list_++]); member_state->object_key_ = static_cast(player_key); member_state->status_ = list_of_msg_->eStatus_PartialOk; const bool is_free_pass_level = nsPartyRoomMission::IsFreePassLevel(player, enter_arg_); if (is_free_pass_level == FALSE) { nsPartyRoomMission::QuestOrMissionResult result; if (nsPartyRoomMission::IsMissionOrQuestPass(player, enter_arg_, &result) == false) { if(result.quest_check_skip_ == false && result.is_quest_pass_ == false) { member_state->status_ = list_of_msg_->eStatus_RequireQuestClear; } else if(result.mission_check_skip_ == false && result.is_mission_pass_ == false) { member_state->status_ = list_of_msg_->eStatus_RequireMissionClear; } } if (nsPartyRoomMission::IsLevelPass(player, enter_arg_) == false) { member_state->status_ = list_of_msg_->eStatus_LevelViolation; } } } void CheckMemberConditionToEnterRoomOperator::operator()(_PARTY_MEMBER_INFO* party_memeber_info) { DWORD player_key = party_memeber_info->m_dwMemberKey; if (m_ExceptKey && m_ExceptKey == player_key) { return; } if (m_SuccessFlag == FALSE) { return; } Player* player = PlayerManager::Instance()->FindPlayerByObjKey(player_key); if (player == NULL) { return; } if (_countof(list_of_msg_->member_info_) < number_of_list_) { return; } typedef MSG_AG_ZONE_CAN_CREATE_ROOM_OF_PARTY_ACK MemberListMsg; MemberListMsg::MemberInfo* member_info = &(list_of_msg_->member_info_[number_of_list_++]); member_info->object_key_ = static_cast(player_key); member_info->status_ = list_of_msg_->eStatus_PartialOk; if (nsPartyRoomMission::ProcessEnterRestrictCondition(player, enter_arg_) == false) { member_info->status_ = list_of_msg_->eStatus_PartialFail; return; } const bool is_free_pass_level = nsPartyRoomMission::IsFreePassLevel(player, enter_arg_); if (is_free_pass_level == FALSE) { if (nsPartyRoomMission::IsLevelPass(player, enter_arg_) == false) { member_info->status_ = list_of_msg_->eStatus_LevelViolation; } } } void GameMemberEnterConditonOperator::operator()(_PARTY_MEMBER_INFO* pMemberInfo) { if(m_ExceptKey && m_ExceptKey == pMemberInfo->m_dwMemberKey) return; // 已经失败的检查程序,不必再转了. if(m_SuccessFlag == FALSE) return; Player* pPlayer = PlayerManager::Instance()->FindPlayerByObjKey(pMemberInfo->m_dwMemberKey); if(pPlayer == NULL) return; operator()(pPlayer, pMemberInfo->m_dwMemberKey); } void GameMemberEnterConditonOperator::operator()(Player* pPlayer, DWORD playerKey) { const BOOLEAN isTempPortal = TRUE; if(!FlowControl::FCAssert(_countof(m_pListMsg->m_CheckArgMembers.members) >= m_ListNumber)) return; MSG_AG_ZONE_CAN_CREATE_ROOM_ACK::MemberInfo* pMemberInfo = &m_pListMsg->m_CheckArgMembers.members[m_ListNumber++]; pMemberInfo->objectKey = (WORD)playerKey; pMemberInfo->status = m_pListMsg->eStatus_PartialOk; // (WAVERIX) (090330) (LOGIC-UPDATE) 任务奖励处理未完成时违反入场条件 if(nsQuestPortal::ProcessEnterRestrictCondition(isTempPortal, pPlayer, m_pEnterArg) == FALSE) { pMemberInfo->status = m_pListMsg->eStatus_PartialFail; return; } // KAO、GetBehave等状态暂时无视。根据使用案例需要添加 const BOOLEAN isFreePass = nsQuestPortal::IsFreePassLevel(isTempPortal, pPlayer, m_pEnterArg); if(isFreePass == FALSE) { nsQuestPortal::QuestOrMissionResult result; if(nsQuestPortal::IsMissionOrQuestPass(isTempPortal, pPlayer, m_pEnterArg, &result) == FALSE) { if(result.bQuestCheckSkip == FALSE && result.isQuestPass == FALSE) pMemberInfo->status = m_pListMsg->eStatus_RequireQuestClear; else if(result.bMissionCheckSkip == FALSE && result.isMissionPass == FALSE) pMemberInfo->status = m_pListMsg->eStatus_RequireMissionClear; } if(nsQuestPortal::IsLevelPass(isTempPortal, pPlayer, m_pEnterArg) == FALSE) pMemberInfo->status = m_pListMsg->eStatus_LevelViolation; } } //_NA_20110630_BATTLE_ZONE_RENEWAL Handler_AG_ZONE_IMPL(AG_ZONE_CAN_CREATE_ROOM_OF_PARTY_SYN) { __TOUCHED((pServerSession, pMsg, wSize)); const MSG_AG_ZONE_CAN_CREATE_ROOM_OF_PARTY_SYN* recv_msg = static_cast(pMsg); PlayerManager* player_manager = PlayerManager::Instance(); MSG_AG_ZONE_CAN_CREATE_ROOM_OF_PARTY_ACK msg; msg.Clear(); msg.result_value_ = msg.eResult_NoMemberFail; msg.party_key_ = recv_msg->party_key_; const DWORD user_key = recv_msg->m_dwKey; Player* request_player = player_manager->FindPlayerByUserKey(user_key); if (request_player == NULL) { SUNLOG(eCRITICAL_LOG, __FUNCTION__" : 找不到用户 : %d", user_key); return; } MapInfoParser* const map_info_parser = MapInfoParser::Instance(); nsPartyRoomMission::EnterSynArg arg = { 0, }; arg.map_info_ = map_info_parser->FindMapInfo(recv_msg->map_code_); if (arg.map_info_ == NULL) { msg.result_value_ = msg.eResult_InvalidMap; request_player->SendPacket(&msg, msg.GetSize()); return; } msg.map_code_ = recv_msg->map_code_; if (nsPartyRoomMission::IsEnterableMap(&arg) == false) { msg.result_value_ = msg.eResult_InvalidMap; request_player->SendPacket(&msg, msg.GetSize()); return; } const MAPCODE map_code = msg.map_code_; const SLOTCODE item_code = recv_msg->require_item_; const PartyZoneType party_room_type = recv_msg->party_room_type_; msg.is_cash_item_ = false; if (item_code != 0) { BASE_ITEMINFO* item_info = ItemInfoParser::Instance()->GetItemInfo(item_code); if (item_info == NULL) { SUNLOG(eCRITICAL_LOG, __FUNCTION__" : 未找到任务物品 : %d", item_code); return; } msg.is_cash_item_ = item_info->IsChargeItem(); } RC::ePARTY_RESULT result_code; NewGamePartyManager* const party_manager = NewGamePartyManager::Instance(); result_code = party_manager->CheckRoomTerms(request_player, item_code, 1, party_room_type, recv_msg->map_code_); if (result_code != RC::RC_PARTY_SUCCESS) { msg.result_value_ = msg.eResult_FailCheckTerms; request_player->SendPacket(&msg, msg.GetSize()); return; } static CheckMemberConditionToEnterRoomOperator oper; oper.Init(eGAMEPARTY_OPERATOR_ENTER_ZONE_CONDITION_PARTYMEMBER_INFO, 0, &msg, &arg); msg.result_value_ = msg.eResult_CheckedMembers; msg.number_of_partymember_ = party_manager->GetMemberConditionForEnterRoom(oper, recv_msg->party_key_); msg.require_item_ = recv_msg->require_item_; if (msg.number_of_partymember_ == 0 || msg.number_of_partymember_ > _countof(msg.member_info_)) { SUNLOG(eCRITICAL_LOG, __FUNCTION__" : 成员计数的异常数据 : %d", msg.number_of_partymember_); return; } request_player->SendPacket(&msg, msg.GetSize()); } Handler_AG_ZONE_IMPL(AG_ZONE_CAN_CREATE_ROOM_SYN) { __TOUCHED((pServerSession, pMsg, wSize)); const MSG_AG_ZONE_CAN_CREATE_ROOM_SYN* pRecvMsg = static_cast(pMsg); PlayerManager* pPlayerManager = PlayerManager::Instance(); MSG_AG_ZONE_CAN_CREATE_ROOM_ACK msg; msg.Clear(); msg.m_CheckMethod = msg.eCheck_None; msg.m_Result = msg.eResult_NoMemberFail; msg.m_CheckArgMembers.partyKey = pRecvMsg->m_CheckArgMembers.partyKey; msg.m_CheckArgMembers.roomKey = pRecvMsg->m_CheckArgMembers.roomKey; const DWORD userKey = pRecvMsg->m_dwKey; Player* pRequester = pPlayerManager->FindPlayerByUserKey(userKey); if(pRequester == NULL) // pPlayer is MasterUser return; // 嗯…在in transaction的情况下是没有办法的吗?? MapInfoParser* const pMapInfoParser = MapInfoParser::Instance(); // Agent设定enterableMapCode. nsQuestPortal::EnterSynArg arg = { 0, }; arg.pMapInfo = pMapInfoParser->FindMapInfo(pRecvMsg->m_MapCode); if(!FlowControl::FCAssert(arg.pMapInfo != NULL)) { msg.m_Result = msg.eResult_InvalidMap; pRequester->SendPacket(&msg, msg.GetSize()); return; } msg.m_MapCode = pRecvMsg->m_MapCode; //IsEnterableMap()只使用arg的sMAPINFO*pMapInfo. if(nsQuestPortal::IsEnterableMap(FALSE, pRequester, &arg) == FALSE) { msg.m_Result = msg.eResult_InvalidMap; pRequester->SendPacket(&msg, msg.GetSize()); return; } static GameMemberEnterConditonOperator oper; oper.Init(eGAMEPARTY_OPERATOR_ENTER_ZONE_CONDITION_MEMBER_INFO, 0, &msg, &arg); msg.m_CheckMethod = pRecvMsg->m_CheckMethod ; msg.m_Result = msg.eResult_CheckedMembers; if(msg.m_CheckMethod == msg.eCheck_Party) { //To party memeber check NewGamePartyManager::Instance()->GetEnterRoomConditionInfoCollect(oper, pRequester); } else if(msg.m_CheckMethod == msg.eCheck_Members) { //To Zone memeber check (ex : lobby) const MSG_AG_ZONE_CAN_CREATE_ROOM_SYN::CheckArgMembers& rMembers = pRecvMsg->m_CheckArgMembers; for(int i = 0; i < _countof(rMembers.members); ++i) { const DWORD playerKey = rMembers.members[i].objectKey; if(playerKey == 0) break; Player* pPlayer = pPlayerManager->FindPlayerByObjKey(playerKey); if(pPlayer != 0) oper(pPlayer, playerKey); } } else { SUNLOG(eCRITICAL_LOG, __FUNCTION__" : Incorrect check method type : %d", msg.m_CheckMethod); return; } pRequester->SendPacket(&msg, msg.GetSize()); } Handler_AG_ZONE_IMPL(AG_ZONE_LOBBY_CREATE_SYN) { __TOUCHED((pServerSession, pMsg, wSize)); const MSG_AG_ZONE_LOBBY_CREATE_SYN* pRecvMsg = static_cast(pMsg); PlayerManager* pPlayerManager = PlayerManager::Instance(); const DWORD userKey = pRecvMsg->m_dwKey; Player* pRequester = pPlayerManager->FindPlayerByUserKey(userKey); if(pRequester == NULL) // pPlayer is MasterUser return; // 嗯…在in transaction的情况下是没有办法的吗?? MSG_AG_ZONE_LOBBY_CREATE_ACK msg; static_cast(msg) = *pRecvMsg; new (&msg) MSG_AG_ZONE_LOBBY_CREATE_ACK; // NOTE: changes protocol msg.m_RoomInfo = pRecvMsg->m_RoomInfo; msg.m_1stCheckResultInGameServer = RC::RC_ROOM_SUCCESS; MapInfoParser* const pMapInfoParser = MapInfoParser::Instance(); //// Agent设定enterableMapCode. nsQuestPortal::EnterSynArg arg = { 0, }; arg.pMapInfo = pMapInfoParser->FindMapInfo(pRecvMsg->m_MapCode); if(!FlowControl::FCAssert(arg.pMapInfo != NULL)) { msg.m_1stCheckResultInGameServer = RC::RC_ROOM_INVALID_MAPCODE; pRequester->SendPacket(&msg, msg.GetSize()); return; } if(nsQuestPortal::IsEnterableMap(TRUE, pRequester, &arg) == FALSE) { msg.m_1stCheckResultInGameServer = RC::RC_ROOM_INVALID_MAPCODE; pRequester->SendPacket(&msg, msg.GetSize()); return; } // (WAVERIX) (090330) (LOGIC-UPDATE) 任务奖励处理未完成时违反入场条件 if(nsQuestPortal::ProcessEnterRestrictCondition(TRUE, pRequester, &arg) == FALSE) { msg.m_1stCheckResultInGameServer = RC::RC_ROOM_FAILED; pRequester->SendPacket(&msg, msg.GetSize()); return; } const BOOLEAN isFreePass = nsQuestPortal::IsFreePassLevel(TRUE, pRequester, &arg); if(isFreePass == FALSE) { nsQuestPortal::QuestOrMissionResult result; if(nsQuestPortal::IsMissionOrQuestPass(TRUE, pRequester, &arg, &result) == FALSE) { if(result.bQuestCheckSkip == FALSE && result.isQuestPass == FALSE) msg.m_1stCheckResultInGameServer = RC::RC_ROOM_PREVIOUS_QUEST_CLEAR; else if(result.bMissionCheckSkip == FALSE && result.isMissionPass == FALSE) msg.m_1stCheckResultInGameServer = RC::RC_ROOM_NEED2_CLEAR_PRE_MISSION; } if(nsQuestPortal::IsLevelPass(TRUE, pRequester, &arg) == FALSE) msg.m_1stCheckResultInGameServer = RC::RC_ROOM_INVALID_LIMITLEVEL_FOR_ME; } pRequester->SendPacket(&msg, msg.GetSize()); } //_NA_000038_20100316_VIEW_TO_JOINABLE_ROOM_IN_LOBBY // (ADD)(20100318)(hukim)(REQ_0038) 检查任务室是否可以进入的逻辑重复。 //分离为函数以防止 RC::eROOM_RESULT IsEnterableMissionRoom(const MAPCODE map_code, Player* const player) { MapInfoParser* const map_info_parser = MapInfoParser::Instance(); nsQuestPortal::EnterSynArg enter_sync_argument = { 0, }; enter_sync_argument.pMapInfo = map_info_parser->FindMapInfo(map_code); if (FlowControl::FCAssert(enter_sync_argument.pMapInfo != NULL) == FALSE) { return RC::RC_ROOM_INVALID_MAPCODE; } if (nsQuestPortal::IsEnterableMap(TRUE, player, &enter_sync_argument) == FALSE) { return RC::RC_ROOM_INVALID_MAPCODE; } if (nsQuestPortal::ProcessEnterRestrictCondition(TRUE, player, &enter_sync_argument) == FALSE) { return RC::RC_ROOM_FAILED; } if (nsQuestPortal::IsFreePassLevel(TRUE, player, &enter_sync_argument) == FALSE) { nsQuestPortal::QuestOrMissionResult result; if (nsQuestPortal::IsMissionOrQuestPass(TRUE, player, &enter_sync_argument, &result) == FALSE) { if (result.bQuestCheckSkip == FALSE && result.isQuestPass == FALSE) { return RC::RC_ROOM_PREVIOUS_QUEST_CLEAR; } else if (result.bMissionCheckSkip == FALSE && result.isMissionPass == FALSE) { return RC::RC_ROOM_NEED2_CLEAR_PRE_MISSION; } } if (nsQuestPortal::IsLevelPass(TRUE, player, &enter_sync_argument) == FALSE) { return RC::RC_ROOM_INVALID_LIMITLEVEL_FOR_ME; } } return RC::RC_ROOM_SUCCESS; } Handler_AG_ZONE_IMPL(AG_ZONE_LOBBY_JOIN_SYN) { __TOUCHED((pServerSession, pMsg, wSize)); const MSG_AG_ZONE_LOBBY_JOIN_SYN* const receive_msg = static_cast(pMsg); const PlayerManager* const player_manager = PlayerManager::Instance(); const DWORD user_key = receive_msg->m_dwKey; Player* const player = player_manager->FindPlayerByUserKey(user_key); if (player == NULL) // pPlayer is MasterUser { return; // 嗯…在in transaction的情况下没有办法吗? } MSG_AG_ZONE_LOBBY_JOIN_ACK msg; static_cast(msg) = *receive_msg; new (&msg) MSG_AG_ZONE_LOBBY_JOIN_ACK; // NOTE: changes protocol msg.m_1stCheckResultInGameServer = IsEnterableMissionRoom(receive_msg->m_MapCode, player); player->SendPacket(&msg, msg.GetSize()); } //}__NA001281_BATTLEZONE_ENTER_CONSTRAINTS_CHANGE_IN_LOBBY__ //_NA_000038_20100316_VIEW_TO_JOINABLE_ROOM_IN_LOBBY Handler_AG_ZONE_IMPL(AG_ZONE_CHECK_MISSION_ROOM_LIST_SYN) { __TOUCHED((pServerSession, pMsg, wSize)); MSG_AG_ZONE_CHECK_MISSION_ROOM_LIST_SYN* const receive_msg = static_cast(pMsg); const DWORD user_key = receive_msg->m_dwKey; const PlayerManager* const player_manager = PlayerManager::Instance(); Player* const player = player_manager->FindPlayerByUserKey(user_key); if (player == NULL) { return; } MSG_AG_ZONE_CHECK_MISSION_ROOM_LIST_ACK msg; msg.current_room_count_ = receive_msg->current_room_count_; // (NOTE)(20100322)(hukim)(REQ_0038) dest의 오버플로우를 검사한다. BOOST_STATIC_ASSERT(_countof(msg.room_info_list_) >= _countof(receive_msg->room_info_list_)); for (int i = 0; i < receive_msg->current_room_count_; ++i) { MISSION_ROOMINFO& room_info = receive_msg->room_info_list_[i]; if (room_info.m_RoomInfo.can_join_room_ == true) { if (IsEnterableMissionRoom(room_info.m_MapCode, player) != RC::RC_ROOM_SUCCESS) { room_info.m_RoomInfo.can_join_room_ = false; } } // (NOTE)(20100318)(hukim)(REQ_0038) 现在检查的时候只需要MapCode //整体交换方式可能会显得沉重。但是规则有点变了。 //如果需要更多关于//几个房间的信息,需要随时更换协议。 //因此,我认为把整个房间的信息传给对方的方式更有利益。 //房间数量最多会在40个以下减少,所以性能上问题不大 //判断了. msg.room_info_list_[i] = room_info; } player->SendPacket(&msg, msg.GetSize()); } Handler_AG_ZONE_IMPL(AG_ZONE_CHANGE_MONSTER_ABILITY_CMD) { __TOUCHED((pServerSession, pMsg, wSize)); const MSG_AG_ZONE_CHANGE_MONSTER_ABILITY_CMD* pRecvMsg = static_cast(pMsg); GameZone* pGameZone = g_GameZoneManager.GetZone(pRecvMsg->roomKey); if(pGameZone == 0) return; const DWORD AcceptMask = (1 << eZONETYPE_MISSION) | (1 << eZONETYPE_HUNTING) | (1 << eZONETYPE_CHUNTING) | (1 << eZONETYPE_INSTANCE); DWORD zone_type_flag = pGameZone->GetZoneType(); zone_type_flag = 1 << zone_type_flag; if((AcceptMask & zone_type_flag) == 0) return; // (WAVERIX) (090622) (NOTE) 这是根据正在进行中的Room人数的怪物能力值变化的 //进行处理. GameRoom* pGameRoom = static_cast(pGameZone); pGameRoom->PrepareNumberOfExpectedPlayers(pRecvMsg->number_of_players); g_ChangeMonsterAbility.UpdateAllMonster(pGameRoom); }