Files
Sun1602/Server/GameServer/PacketHandler/Handler_AG_ZONE.cpp
T
2022-10-26 12:25:11 +08:00

2491 lines
157 KiB
C++

#include "stdafx.h"
#include "./Handler_AG_ZONE.h"
//==================================================================================================
#include <PacketStruct_AG.h>
#include <PacketStruct_DG.h>
#include <PacketStruct_GZ.h>
#include <MapInfoParser.h>
//==================================================================================================
#include <ServerSession.h>
#include <WayPoint.h>
//==================================================================================================
#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 <World/GameWarControlManager.h>
#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 <GameParty/NewGamePartyManager.h>
#include <GameParty/NewGameParty.h>
#include "WarehouseSlotContainer.h"
#include "GuildWarehouseSlotContainer.h"
#include "StatusManager.h"
#ifdef _NA_20100307_BETAKEY_SYSTEM
#include <BetaKeyImpl.h>
#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<ePHASE_SHIFT>(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<GameLobbyRoom *>(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<GameHuntingRoom *>(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<GameMissionRoom*>(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<GamePVPRoom *>(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<GameCHuntingRoom *>(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<GameVillage *>(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<GameHuntingField *>(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<MSG_AG_ZONE_DOMINATION_FIELD_CREATE_CMD *>(pMsg);
#ifdef __NA_PACKETFLOW_TEST
SUNLOG( eFULL_LOG, "Handler_AG_ZONE_IMPL( MSG_AG_ZONE_DOMINATION_FIELD_CREATE_CMD )" );
#endif
GameDominationField* zone =
static_cast<GameDominationField *>(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<MSG_AG_ZONE_SPAFIELD_CREATE_CMD*>(pMsg);
GameSpaField* zone = static_cast<GameSpaField*>(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<MSG_AG_ZONE_SPA_ENTER_SYN*>(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<MSG_AG_ZONE_SPA_LEAVE_SYN*>(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<MSG_AG_ZONE_DOMINATION_FIELD_INFO_SYN *>(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<GameDominationField*>(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<GamePVPRoom *>(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<MAPCODE>(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<GameDominationField*>(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<GameDominationField*>(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<MSG_AG_ZONE_CAN_CREATE_INSTANCE_DUNGEON_SYN*>(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;
//////////////////////////////////////////////////////////////////////////
// <LOGIC CONTROL>
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<GameInstanceDungeon *>(
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<DWORD>(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<MSG_AG_ZONE_QUEST_PORTAL_ENTER_SYN*>(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<WORD>(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<WORD>(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<MSG_AG_ZONE_CAN_CREATE_ROOM_OF_PARTY_SYN*>(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<MSG_AG_ZONE_CAN_CREATE_ROOM_SYN*>(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<MSG_AG_ZONE_LOBBY_CREATE_SYN*>(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_AG_ZONE_LOBBY_CREATE_SYN&>(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<MSG_AG_ZONE_LOBBY_JOIN_SYN*>(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_AG_ZONE_LOBBY_JOIN_SYN&>(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<MSG_AG_ZONE_CHECK_MISSION_ROOM_LIST_SYN*>(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<MSG_AG_ZONE_CHANGE_MONSTER_ABILITY_CMD*>(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<GameRoom*>(pGameZone);
pGameRoom->PrepareNumberOfExpectedPlayers(pRecvMsg->number_of_players);
g_ChangeMonsterAbility.UpdateAllMonster(pGameRoom);
}