Files
2022-10-26 12:25:11 +08:00

280 lines
9.1 KiB
C++

#include "StdAfx.h"
#ifdef _NA_006088_20120910_CHAOS_ZONE_FREE_PVP
#include <ChaosZoneSystem/Handler_CG_FREE_PVP.h>
#include <ChaosZoneSystem/PacketStruct_ChaosZoneSystem.h>
#include <ChaosZoneSystem/FreePVPManager.h>
#include <ChaosZoneSystem/FreePVPRoom.h>
#include <Zone/ZoneManager.h>
#include <Zone/InstanceDungeon.h>
#include <PacketHandler/Handler_FromClient.h>
#include <ServerOptionParserEx.h>
#include <ChaosZoneSystem/BattleGroundManager.h>
void Handler_CG_FREE_PVP::OnCG_ProcessPacket(User* user, MSG_BASE* packet, WORD size)
{
MSG_CG_FREE_PVP_PACKET* recv_packet = static_cast<MSG_CG_FREE_PVP_PACKET*>(packet);
switch(recv_packet->packet_type)
{
case CG_FREE_PVP_ROOM_LIST_SYN:
{
OnCG_FREE_PVP_ROOM_LIST_SYN(user, packet, size);
}
break;
case CG_FREE_PVP_CREATE_ROOM_SYN:
{
OnCG_FREE_PVP_CREATE_ROOM_SYN(user, packet, size);
}
break;
case CG_FREE_PVP_JOIN_ROOM_SYN:
{
OnCG_FREE_PVP_JOIN_ROOM_SYN(user, packet, size);
}
break;
default:
{
user->SendToLinkedServer(static_cast<MSG_BASE_FORWARD*>(packet), size);
}
break;
}
}
void Handler_CG_FREE_PVP::OnCG_FREE_PVP_ROOM_LIST_SYN(User* user, MSG_BASE* packet, WORD size)
{
const MSG_CG_FREE_PVP_ROOM_LIST_SYN* recv_packet =
static_cast<MSG_CG_FREE_PVP_ROOM_LIST_SYN*>(packet);
FreePVPManager* free_pvp_manager = FreePVPManager::Instance();
MSG_CG_FREE_PVP_ROOM_LIST_ACK ack_msg;
ack_msg.count_of_list = free_pvp_manager->ArchiveRoomList(ack_msg.free_pvp_room_info,
_countof(ack_msg.free_pvp_room_info));
user->SendPacket(&ack_msg, ack_msg.GetSize());
}
void Handler_CG_FREE_PVP::OnCG_FREE_PVP_CREATE_ROOM_SYN(User* user, MSG_BASE* packet, WORD size)
{
MSG_CG_FREE_PVP_CREATE_ROOM_SYN* recv_packet = \
static_cast<MSG_CG_FREE_PVP_CREATE_ROOM_SYN*>(packet);
MSG_CG_FREE_PVP_CREATE_ROOM_ACK ack_msg;
ack_msg.result_code = RC::RC_FREE_PVP_CREATE_SUCCESS;
FreePVPManager* free_pvp_manager = FreePVPManager::Instance();
// 자유전투실 활성화 여부..
if (free_pvp_manager->GetFreePVPActive() == false)
{
ack_msg.result_code = RC::RC_FREE_PVP_CREATE_FAIL_INACTIVE;
user->SendPacket(&ack_msg, sizeof(ack_msg));
return;
}
// 다른 행동 중 일때..(거래, 상점)
if (user->GetBehaveState() != PLAYER_BEHAVE_IDLE_STATE)
{
ack_msg.result_code = RC::RC_FREE_PVP_CREATE_FAIL_TRANSACTION;
user->SendPacket(&ack_msg, sizeof(ack_msg));
return;
}
// 전장 입장 예약 중 일때..
BattleGroundManager* const battle_ground_manager = BattleGroundManager::Instance();
if (battle_ground_manager)
{
if (battle_ground_manager->IsValidReservationMember(user->GetUserKey()))
{
ack_msg.result_code = RC::RC_FREE_PVP_CREATE_FAIL_ALREADY_BATTLE_GROUND_RESERVATION;
user->SendPacket(&ack_msg, sizeof(ack_msg));
return;
}
}
SERVER_COMMON_OPTION& server_option_info = ServerOptionParserEx::Instance()->GetServerOption();
// 자유전투실 방 갯수 제한..
if (free_pvp_manager->GetRoomCount() > server_option_info.free_pvp_max_room_count) //script..
{
ack_msg.result_code = RC::RC_FREE_PVP_CREATE_FAIL_MAX_ROOM;
user->SendPacket(&ack_msg, sizeof(ack_msg));
return;
}
// 현재 방 입장을 대기 중인 유저가 방을 만들려고 할때..
if (free_pvp_manager->IstMoveZoneWaitPlayer(user->GetUserGUID()) == true)
{
ack_msg.result_code = RC::RC_FREE_PVP_CREATE_FAIL_WAIT_MOVE_ZONE;
user->SendPacket(&ack_msg, sizeof(ack_msg));
return;
}
// 이미 트랜잭션중이면
if(user->IsBeginTransaction())
{
ack_msg.result_code = RC::RC_FREE_PVP_CREATE_FAIL_TRANSACTION;
user->SendPacket(&ack_msg, sizeof(ack_msg));
return;
}
user->BeginTransaction(TR_CREATE_INSTANCE_DUNGEON);
// 인스턴스 던전 생성..
const MAPCODE map_code = recv_packet->base_free_pvp_info.map_code;
InstanceDungeon* instance_dungeon = NULL;
const RC::eROOM_RESULT rt = g_ZoneManager.CreateInstanceDungeon( \
0, NULL,
map_code, (InstanceDungeon *&)instance_dungeon,
INDUN_KIND_CHAOS_ZONE, FALSE);
if (!instance_dungeon || rt != RC::RC_ROOM_SUCCESS)
{
ack_msg.result_code = RC::RC_FREE_PVP_CREATE_FAIL_ZONE;
user->SendPacket(&ack_msg, sizeof(ack_msg));
user->EndTransaction();
return;
}
instance_dungeon->SetRoomState(eROOMSTATE_GENERNAL);
// 리스트 생성
KEYTYPE room_key = 0;
if (free_pvp_manager->CreateRoom(recv_packet->base_free_pvp_info, room_key) == false)
{
ack_msg.result_code = RC::RC_FREE_PVP_CREATE_FAIL;
user->SendPacket(&ack_msg, sizeof(ack_msg));
user->EndTransaction();
return;
}
// 룸에 존 키 셋팅
FreePVPRoom* const free_pvp_room = free_pvp_manager->FindRoom(room_key);
if (free_pvp_room == NULL)
{
ack_msg.result_code = RC::RC_FREE_PVP_CREATE_FAIL;
user->SendPacket(&ack_msg, sizeof(ack_msg));
user->EndTransaction();
return;
}
free_pvp_room->SetZoneKey(instance_dungeon->GetKey());
SUNLOG(eCRITICAL_LOG, " [%s|%d] Create FreePVP Room Guid = %d | Room Key(%d) ",
__FUNCTION__,
__LINE__,
user->GetUserGUID(),
free_pvp_room->GetZoneKey());
user->EndTransaction();
// 바로 조인..
MSG_CG_FREE_PVP_JOIN_ROOM_SYN request;
{
request.join_room_key = room_key;
_tcsncpy(request.password, recv_packet->base_free_pvp_info.room_password,
_countof(request.password));
}
OnCG_FREE_PVP_JOIN_ROOM_SYN(user, &request, request.GetSize());
}
void Handler_CG_FREE_PVP::OnCG_FREE_PVP_JOIN_ROOM_SYN(User* user, MSG_BASE* packet, WORD size)
{
MSG_CG_FREE_PVP_JOIN_ROOM_SYN* recv_packet = static_cast<MSG_CG_FREE_PVP_JOIN_ROOM_SYN*>(packet);
const KEYTYPE room_key = recv_packet->join_room_key;
const bool is_private_room = recv_packet->is_private_room;
MSG_CG_FREE_PVP_JOIN_ROOM_ACK ack_msg;
FreePVPManager* free_pvp_manager = FreePVPManager::Instance();
if (free_pvp_manager == NULL)
{
ack_msg.result_code = RC::RC_FREE_PVP_JOIN_FAIL;
user->SendPacket(&ack_msg,sizeof(ack_msg));
return;
}
// 자유전투실 활성화 여부..
if (free_pvp_manager->GetFreePVPActive() == false)
{
ack_msg.result_code = RC::RC_FREE_PVP_JOIN_FAIL_INACTIVE;
user->SendPacket(&ack_msg,sizeof(ack_msg));
return;
}
// 다른 행동 중 일때..(거래, 상점)
if (user->GetBehaveState() != PLAYER_BEHAVE_IDLE_STATE)
{
ack_msg.result_code = RC::RC_FREE_PVP_JOIN_FAIL;
user->SendPacket(&ack_msg, sizeof(ack_msg));
return;
}
// 전장 입장 예약 중 일때..
BattleGroundManager* const battle_ground_manager = BattleGroundManager::Instance();
if (battle_ground_manager)
{
if (battle_ground_manager->IsValidReservationMember(user->GetUserKey()))
{
ack_msg.result_code = RC::RC_FREE_PVP_CREATE_FAIL_ALREADY_BATTLE_GROUND_RESERVATION;
user->SendPacket(&ack_msg, sizeof(ack_msg));
return;
}
}
// 방이 없을 경우..
FreePVPRoom* const free_pvp_room = free_pvp_manager->FindRoom(room_key);
if (free_pvp_room == NULL)
{
ack_msg.result_code = RC::RC_FREE_PVP_JOIN_FAIL_ISNOT_ROOM;
user->SendPacket(&ack_msg,sizeof(ack_msg));
return;
}
// 해당 존이 존재하지 않을 경우..
InstanceDungeon* const instance_dugeon = \
static_cast<InstanceDungeon*>(g_ZoneManager.FindZone(free_pvp_room->GetZoneKey()));
if (instance_dugeon == NULL)
{
ack_msg.result_code = RC::RC_FREE_PVP_JOIN_FAIL_ISNOT_ROOM;
user->SendPacket(&ack_msg,sizeof(ack_msg));
free_pvp_manager->DestroyRoom(room_key);
return;
}
// 해당 존 상태가 일반적이지 않을 경우..
if (instance_dugeon->GetRoomState() != eROOMSTATE_GENERNAL)
{
ack_msg.result_code = RC::RC_FREE_PVP_JOIN_FAIL;
user->SendPacket(&ack_msg,sizeof(ack_msg));
return;
}
// 정원이 다 찼을경우..
if (free_pvp_room->CanJoinRoomByMemberCount() == false)
{
ack_msg.result_code = RC::RC_FREE_PVP_JOIN_FAIL_MAX_USER;
user->SendPacket(&ack_msg,sizeof(ack_msg));
return;
}
// 비번방일 경우..
if (recv_packet->is_private_room)
{
if (free_pvp_room->CheckPassword(recv_packet->password) == false)
{
ack_msg.result_code = RC::RC_FREE_PVP_JOIN_FAIL_DIFFER_PASSWORD;
user->SendPacket(&ack_msg,sizeof(ack_msg));
return;
}
}
// 필드에서 파티중일 경우.. 파티를 탈퇴하고 입장한다..
MSG_CG_PARTY_LEAVE_SYN request;
Handler_CG::OnCG_PARTY_LEAVE_SYN(user, &request, sizeof(request));
MSG_CG_FREE_PVP_JOIN_ROOM_COUNT_CMD cmd_msg;
user->SendPacket(&cmd_msg,sizeof(cmd_msg));
free_pvp_manager->InsertFreePVPUser(user->GetUserGUID(), room_key);
}
#endif // _NA_006088_20120910_CHAOS_ZONE_FREE_PVP