Restructure repository to include all source folders
Move git root from Client/ to src/ to track all source code: - Client: Game client source (moved to Client/Client/) - Server: Game server source - GameTools: Development tools - CryptoSource: Encryption utilities - database: Database scripts - Script: Game scripts - rylCoder_16.02.2008_src: Legacy coder tools - GMFont, Game: Additional resources 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,910 @@
|
||||
#include "stdafx.h"
|
||||
#include "AdminToolDispatch.h"
|
||||
|
||||
#include <Log/ServerLog.h>
|
||||
#include <Network/Address/INET_Addr.h>
|
||||
#include <Network/Packet/PacketCommand.h>
|
||||
#include <Network/Packet/PacketStruct/ServerInfo.h>
|
||||
#include <Network/Packet/PacketStruct/ServerPacket.h>
|
||||
#include <Network/Packet/PacketStruct/CharAdminPacket.h>
|
||||
#include <Network/Packet/PacketStruct/GameEventPacket.h>
|
||||
#include <Network/Packet/PacketStruct/CharLoginOutPacketStruct.h>
|
||||
|
||||
#include <Network/SendPacket/SendAdminTool.h>
|
||||
#include <Network/SendPacket/SendServerInfo.h>
|
||||
|
||||
#include <Network/Dispatch/GameDispatch.h>
|
||||
#include <Network/Dispatch/GameClient/SendCharAdmin.h>
|
||||
|
||||
#include <DataStorage/AdminDataMgr.h>
|
||||
#include <DataStorage/SessionData.h>
|
||||
#include <DataStorage/SessionDataMgr.h>
|
||||
#include <DataStorage/StoreData.h>
|
||||
#include <DataStorage/StoreDataMgr.h>
|
||||
#include <DataStorage/CharacterData.h>
|
||||
#include <DataStorage/CharacterDataMgr.h>
|
||||
|
||||
#include <DB/DBComponent.h>
|
||||
#include <DB/GameDBComponent.h>
|
||||
#include <DB/GuildDBComponent.h>
|
||||
#include <GameEvent/GameEventDBMgr.h>
|
||||
#include <Utility/Setup/ServerSetup.h>
|
||||
#include <Creature/Character/CharacterClass.h>
|
||||
|
||||
#include <Network/Packet/PacketStruct/GuildPacket.h>
|
||||
|
||||
#include <Community/Guild/GuildDB.h>
|
||||
#include <Community/Guild/GuildDBMgr.h>
|
||||
|
||||
namespace DBAgent
|
||||
{
|
||||
|
||||
// forward decl.
|
||||
bool GetUIDCIDFromName(const char* szName, unsigned long& dwUID_Out,
|
||||
unsigned long& dwCID_Out, unsigned char& cOldServerGroupID);
|
||||
|
||||
|
||||
CMultiDispatch& CAdminToolDispatch::GetDispatchTable()
|
||||
{
|
||||
static CMultiDispatch gameDispatch;
|
||||
return gameDispatch;
|
||||
}
|
||||
|
||||
|
||||
CAdminToolDispatch::CAdminToolDispatch(CSession& Session)
|
||||
: CRylServerDispatch(Session, MAX_PACKET_DISPATCH_PER_PULSE),
|
||||
m_dwServerID(0)
|
||||
{
|
||||
|
||||
|
||||
}
|
||||
|
||||
CAdminToolDispatch::~CAdminToolDispatch()
|
||||
{
|
||||
|
||||
|
||||
}
|
||||
|
||||
void CAdminToolDispatch::Connected()
|
||||
{
|
||||
DETLOG3(g_Log, "SS:0x%08x/DP:0x%08x/IP:%15s/AdminToolServer Connected",
|
||||
&GetSession(), this, GetRemoteAddr().get_addr_string());
|
||||
}
|
||||
|
||||
void CAdminToolDispatch::Disconnected()
|
||||
{
|
||||
DETLOG3(g_Log, "SS:0x%08x/DP:0x%08x/IP:%15s/AdminToolServer Disconnected",
|
||||
&GetSession(), this, GetRemoteAddr().get_addr_string());
|
||||
|
||||
if(0 != m_dwServerID)
|
||||
{
|
||||
GetDispatchTable().RemoveDispatch(m_dwServerID);
|
||||
|
||||
if(0LL != m_AdminItemSerialMgr.GetItemSerial())
|
||||
{
|
||||
// 아이템 시리얼 DB에 저장
|
||||
m_AdminItemSerialMgr.SaveItemSerial(
|
||||
CDBSingleObject::GetInstance(), m_dwServerID);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool CAdminToolDispatch::DispatchPacket(PktBase* lpPktBase)
|
||||
{
|
||||
bool bResult = false;
|
||||
PktBase::CMDType cCmd = lpPktBase->GetCmd();
|
||||
|
||||
switch(cCmd)
|
||||
{
|
||||
case CmdSysServerLogin: bResult = ParseServerLogin(static_cast<PktSL*>(lpPktBase)); break;
|
||||
case CmdSysServerLogout: bResult = ParseServerLogout(lpPktBase); break;
|
||||
case CmdUserKill: bResult = ParseUserKill(static_cast<PktUK*>(lpPktBase)); break;
|
||||
case CmdAdminToolGetData: bResult = ParseGetData(static_cast<PktAdminToolGetData*>(lpPktBase)); break;
|
||||
case CmdAdminToolSetData: bResult = ParseSetData(static_cast<PktAdminToolSetData*>(lpPktBase)); break;
|
||||
case CmdItemQtyCheck: bResult = ParseItemQtyCheck(static_cast<PktItemQtyControl*>(lpPktBase)); break;
|
||||
case CmdGuildPosition: bResult = ParseGuildPosition(static_cast<PktGuildPosition*>(lpPktBase)); break;
|
||||
|
||||
default:
|
||||
|
||||
ERRLOG4(g_Log, "SS:0x%08x/DP:0x%08x/IP:%15s/Cmd:0x%02X/ 운영툴 서버 패킷 처리 실패 : 없는 커맨드입니다",
|
||||
&GetSession(), this, GetRemoteAddr().get_addr_string(), cCmd);
|
||||
|
||||
bResult = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if(!bResult)
|
||||
{
|
||||
ERRLOG4(g_Log, "SS:0x%08x/DP:0x%08x/IP:%15s/Cmd:0x%02X/ 운영툴 서버 패킷 처리 실패 : 처리를 실패했습니다",
|
||||
&GetSession(), this, GetRemoteAddr().get_addr_string(), cCmd);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CAdminToolDispatch::ParseServerLogin(PktSL* lpPktSL)
|
||||
{
|
||||
m_dwServerID = lpPktSL->m_dwServerID;
|
||||
|
||||
INFLOG4(g_Log, "SS:0x%08x/DP:0x%08x/IP:%15s/ServerID:0x%08X/ 운영툴 서버 연결 시도 : 패킷 받음",
|
||||
&GetSession(), this, GetRemoteAddr().get_addr_string(), m_dwServerID);
|
||||
|
||||
GET_MULTI_DISPATCH(lpAdminToolDispatch, m_dwServerID,
|
||||
CAdminToolDispatch, GetDispatchTable());
|
||||
|
||||
if(0 != lpAdminToolDispatch)
|
||||
{
|
||||
ERRLOG4(g_Log, "SS:0x%08x/DP:0x%08x/IP:%15s/ServerID:0x%08X/ 운영툴 서버 연결 실패 : 이미 연결이 있습니다",
|
||||
&GetSession(), this, GetRemoteAddr().get_addr_string(), m_dwServerID);
|
||||
|
||||
CloseSession();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Dispatch 세팅.
|
||||
GetDispatchTable().SetDispatch(m_dwServerID, this);
|
||||
|
||||
// 아이템 시리얼 로드.
|
||||
if(!m_AdminItemSerialMgr.LoadItemSerial(CDBSingleObject::GetInstance(), m_dwServerID))
|
||||
{
|
||||
ERRLOG4(g_Log, "SS:0x%08x/DP:0x%08x/IP:%15s/ServerID:0x%08X/ 운영툴 서버 연결 실패 : 아이템 시리얼 로드 실패. 접속을 끊습니다",
|
||||
&GetSession(), this, GetRemoteAddr().get_addr_string(), m_dwServerID);
|
||||
|
||||
CloseSession();
|
||||
return false;
|
||||
}
|
||||
|
||||
return SendPacket::ServerLoginAck(m_SendStream,
|
||||
m_dwServerID, m_AdminItemSerialMgr.GetItemSerial());
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CAdminToolDispatch::ParseServerLogout(PktBase* lpPktBase)
|
||||
{
|
||||
// 받은 패킷 그대로 돌려 준다.
|
||||
|
||||
char* lpBuffer = m_SendStream.GetBuffer(sizeof(PktBase));
|
||||
if(0 != lpBuffer)
|
||||
{
|
||||
return m_SendStream.WrapHeader(sizeof(PktBase), CmdSysServerLogout, 0, 0);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CAdminToolDispatch::ParseUserKill(PktUK* lpPktUK)
|
||||
{
|
||||
using namespace DataStorage;
|
||||
|
||||
// 접속 DB를 전부 뒤져서, 계정과 IP가 일치하는 넘한테 뜨거운 맛을 보여 준다.
|
||||
CSessionData* lpSessionData =
|
||||
CSessionDataMgr::GetInstance().GetOpenSession(lpPktUK->m_dwUserID);
|
||||
|
||||
if(0 == lpSessionData)
|
||||
{
|
||||
ERRLOG1(g_Log, "UID:%10u / 운영툴 서버 유저 접속 끊기 실패 : 유저가 없습니다", lpPktUK->m_dwUserID);
|
||||
}
|
||||
else
|
||||
{
|
||||
SERVER_ID serverID;
|
||||
serverID.dwID = lpSessionData->GetServerID();
|
||||
CSessionData::SessionState eSessionState = lpSessionData->GetSessionState();
|
||||
|
||||
if ((serverID.GetType() == CServerSetup::AuthServer && CSessionData::SE_USER_ENABLED != eSessionState) ||
|
||||
(serverID.GetType() == CServerSetup::GameServer && CSessionData::SE_CHAR_ENABLED != eSessionState))
|
||||
{
|
||||
ERRLOG3(g_Log, "UID:%10u / ServerID:0x%08X / ST:%s / 운영툴 서버 유저 접속 끊기 실패 : 유저나 캐릭터가 비활성화되어 있습니다",
|
||||
lpPktUK->m_dwUserID, serverID.dwID, g_szSessionStateString[lpSessionData->GetSessionState()]);
|
||||
}
|
||||
else if(!SendPacket::UserKill(*lpSessionData))
|
||||
{
|
||||
ERRLOG3(g_Log, "UID:%10u / ServerID:0x%08X / ST:%s / 운영툴 서버 유저 접속 끊기 실패 : 접속 끊기 패킷 보내기 실패",
|
||||
lpPktUK->m_dwUserID, serverID.dwID, g_szSessionStateString[lpSessionData->GetSessionState()]);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool CAdminToolDispatch::ParseGetData(PktBase* lpPktBase)
|
||||
{
|
||||
// 데이터 얻어 오기. 패킷 오면 캐릭터 정보 및 창고 정보를 준다.
|
||||
PktAdminToolGetData* lpPktAdminToolGetData = static_cast<PktAdminToolGetData*>(lpPktBase);
|
||||
|
||||
switch(lpPktAdminToolGetData->m_cType)
|
||||
{
|
||||
case PktAdminToolGetData::GET_CHAR_DATA:
|
||||
|
||||
return ParseAdminToolGetData(lpPktAdminToolGetData);
|
||||
|
||||
case PktAdminToolGetData::CHANGE_CHAR_NAME:
|
||||
|
||||
return ParseAdminToolChangeName(lpPktAdminToolGetData);
|
||||
|
||||
default:
|
||||
|
||||
ERRLOG2(g_Log, "IP:%15s / Cmd:%d / 알 수 없는 운영툴 데이터 얻기 커맨드입니다.",
|
||||
GetRemoteAddr().get_addr_string(), lpPktAdminToolGetData->m_cType);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool CAdminToolDispatch::ParseSetData(PktBase* lpPktBase)
|
||||
{
|
||||
// 데이터 기록하기. 패킷 오면 캐릭터 관련 데이터를 쓴다.
|
||||
// CharLogin때 보내주는 데이터, 창고 데이터 1, 창고 데이터 2, 창고 정보
|
||||
|
||||
// 데이터 얻어 오기. 패킷 오면 캐릭터 정보 및 창고 정보를 준다.
|
||||
PktAdminToolSetData* lpPktAdminToolSetData = static_cast<PktAdminToolSetData*>(lpPktBase);
|
||||
|
||||
switch(lpPktAdminToolSetData->m_cType)
|
||||
{
|
||||
case PktAdminToolSetData::CHAR_BASIC_DATA:
|
||||
case PktAdminToolSetData::CHAR_EXTRA_DATA:
|
||||
case PktAdminToolSetData::CHAR_FRIEND_DATA:
|
||||
case PktAdminToolSetData::CHAR_BAN_DATA:
|
||||
case PktAdminToolSetData::STORE_12_DATA:
|
||||
case PktAdminToolSetData::STORE_34_DATA:
|
||||
case PktAdminToolSetData::OPEN_UPDATE_DATA:
|
||||
case PktAdminToolSetData::FINISH_UPDATE_DATA:
|
||||
|
||||
return ParseAdminToolSetData(lpPktAdminToolSetData);
|
||||
|
||||
case PktAdminToolSetData::RELOAD_ADMINLIST:
|
||||
|
||||
return DataStorage::CAdminDataMgr::GetInstance().LoadAdminList(CDBSingleObject::GetInstance());
|
||||
|
||||
default:
|
||||
|
||||
ERRLOG2(g_Log, "IP:%15s / Cmd:%d / 알 수 없는 운영자 데이터 셋 패킷 커맨드입니다",
|
||||
GetRemoteAddr().get_addr_string(), lpPktAdminToolSetData->m_cType);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CAdminToolDispatch::ParseAdminToolGetData(PktAdminToolGetData* lpPktAdminToolGetData)
|
||||
{
|
||||
// DBRequestKey.
|
||||
unsigned long dwRequestKey = lpPktAdminToolGetData->m_dwRequestKey;
|
||||
unsigned long dwUID = lpPktAdminToolGetData->m_dwUID;
|
||||
unsigned long dwCID = lpPktAdminToolGetData->m_dwCID;
|
||||
unsigned char cOldServerGroupID = 0;
|
||||
|
||||
if (UnifiedConst::Part2Selectable == CServerSetup::GetInstance().GetAgentServerType())
|
||||
{
|
||||
cOldServerGroupID = lpPktAdminToolGetData->m_cOldServerGroupID;
|
||||
}
|
||||
else
|
||||
{
|
||||
cOldServerGroupID = static_cast<unsigned char>(
|
||||
CServerSetup::GetInstance().GetAgentServerType());
|
||||
}
|
||||
|
||||
PktAdminToolGetData::GetDataType eDataType =
|
||||
static_cast<PktAdminToolGetData::GetDataType>(lpPktAdminToolGetData->m_cType);
|
||||
|
||||
unsigned short wError = 0;
|
||||
|
||||
if(eDataType != PktAdminToolGetData::GET_CHAR_DATA)
|
||||
{
|
||||
// 잘못된 패킷임
|
||||
wError = PktAdminToolGetData::INVALID_REQUEST;
|
||||
}
|
||||
else
|
||||
{
|
||||
// UID, CID가 없으면 캐릭터 이름을 가지고 UID와 CID를 얻어 온다.
|
||||
if(0 == dwUID || 0 == dwCID || 0 == cOldServerGroupID)
|
||||
{
|
||||
if(!GetUIDCIDFromName(lpPktAdminToolGetData->m_szName,
|
||||
dwUID, dwCID, cOldServerGroupID))
|
||||
{
|
||||
// DB Query 실패.
|
||||
wError = PktAdminToolGetData::GET_UIDCID_QUERY_FAILED;
|
||||
}
|
||||
|
||||
if(0 == dwUID || 0 == dwCID || 0 == cOldServerGroupID)
|
||||
{
|
||||
// 얻어온 데이터가 이상함.
|
||||
wError = PktAdminToolGetData::INVALID_UID_CID_DATA;
|
||||
}
|
||||
}
|
||||
|
||||
DETLOG4(g_Log, "UID:%10u / ServerGroupID:%d / CID:%10u / IP:%15s / 운영툴로부터 데이터 요청 받음",
|
||||
dwUID, cOldServerGroupID, dwCID, GetRemoteAddr().get_addr_string());
|
||||
|
||||
if(0 == wError)
|
||||
{
|
||||
using namespace DataStorage;
|
||||
|
||||
CStoreData* lpStoreData = 0;
|
||||
CCharacterData* lpCharacterData = 0;
|
||||
|
||||
CSessionData* lpSessionData = CSessionDataMgr::GetInstance().GetOpenSession(dwUID);
|
||||
|
||||
if(0 != lpSessionData)
|
||||
{
|
||||
// 이미 로드된 세션에서 데이터 가져옴.
|
||||
if(dwUID == lpSessionData->GetUID())
|
||||
{
|
||||
lpStoreData = lpSessionData->GetStoreData();
|
||||
}
|
||||
|
||||
if(dwCID == lpSessionData->GetCID())
|
||||
{
|
||||
lpCharacterData = lpSessionData->GetCharacterData();
|
||||
}
|
||||
}
|
||||
|
||||
// 캐쉬에서 데이터 로드. 캐쉬에 데이터가 없으면, DB에서 로드해서 캐쉬에 추가.
|
||||
if(0 == lpStoreData)
|
||||
{
|
||||
lpStoreData = CStoreDataMgr::GetInstance().GetLogoutData(
|
||||
UnifiedStoreKey(dwUID, cOldServerGroupID));
|
||||
}
|
||||
|
||||
if(0 == lpCharacterData)
|
||||
{
|
||||
lpCharacterData = CCharacterDataMgr::GetInstance().GetLogoutData(dwCID);
|
||||
}
|
||||
|
||||
|
||||
if(0 == lpStoreData)
|
||||
{
|
||||
wError = PktAdminToolGetData::GET_STORE_QUERY_FAILED;
|
||||
}
|
||||
else if(0 == lpCharacterData)
|
||||
{
|
||||
wError = PktAdminToolGetData::GET_CHAR_DATA_QUERY_FAILED;
|
||||
}
|
||||
else
|
||||
{
|
||||
SendPacket::TotalDataToAdminTool(GetSendStream(), dwRequestKey,
|
||||
GetRemoteAddr().get_addr_in().sin_addr, *lpStoreData, *lpCharacterData);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 최종 전송
|
||||
return SendPacket::AdminToolGetDataAck(GetSendStream(),
|
||||
PktAdminToolGetData::FINISH_GET_DATA, dwRequestKey, dwUID, dwCID, 0, 0, wError, cOldServerGroupID);
|
||||
}
|
||||
|
||||
bool CAdminToolDispatch::ParseAdminToolSetData(PktAdminToolSetData* lpPktAdminToolSetData)
|
||||
{
|
||||
SERVER_ID serverID;
|
||||
serverID.dwID = m_dwServerID;
|
||||
|
||||
unsigned long dwUID = lpPktAdminToolSetData->m_dwUID;
|
||||
unsigned long dwCID = lpPktAdminToolSetData->m_dwCID;
|
||||
unsigned long dwRequestKey = lpPktAdminToolSetData->m_dwRequestKey;
|
||||
unsigned long dwDataSize = lpPktAdminToolSetData->GetLen() - sizeof(PktAdminToolSetData);
|
||||
unsigned char cType = lpPktAdminToolSetData->m_cType;
|
||||
unsigned char cOldServerGroupID = 0;
|
||||
|
||||
if (UnifiedConst::Part2Selectable == CServerSetup::GetInstance().GetAgentServerType())
|
||||
{
|
||||
cOldServerGroupID = lpPktAdminToolSetData->m_cOldServerGroupID;
|
||||
}
|
||||
else
|
||||
{
|
||||
cOldServerGroupID = static_cast<unsigned char>(
|
||||
CServerSetup::GetInstance().GetAgentServerType());
|
||||
}
|
||||
|
||||
unsigned short wError = 0;
|
||||
|
||||
if(0 == dwUID || 0 == dwCID)
|
||||
{
|
||||
wError = PktAdminToolSetData::INVALID_UID_CID_ERROR;
|
||||
}
|
||||
else
|
||||
{
|
||||
DETLOG3(g_Log, "UID:%10u / CID:%10u / IP:%15s / 운영자가 운영툴로 데이터 세팅 시도",
|
||||
dwUID, dwCID, GetRemoteAddr().get_addr_string());
|
||||
|
||||
using namespace DataStorage;
|
||||
|
||||
CStoreData* lpStoreData = 0;
|
||||
CCharacterData* lpCharacterData = 0;
|
||||
|
||||
CSessionData* lpSessionData = CSessionDataMgr::GetInstance().GetOpenSession(dwUID);
|
||||
|
||||
if(0 != lpSessionData)
|
||||
{
|
||||
if(CSessionData::SE_USER_ENABLED == lpSessionData->GetSessionState() ||
|
||||
CSessionData::SE_CHAR_ENABLED == lpSessionData->GetSessionState())
|
||||
{
|
||||
// 활성화된 캐릭터 편집 에러
|
||||
wError = PktAdminToolSetData::LOGIN_ANOTHER_GAMESERVER;
|
||||
}
|
||||
else
|
||||
{
|
||||
// 이미 로드된 세션에서 데이터 가져옴.
|
||||
if(dwUID == lpSessionData->GetUID())
|
||||
{
|
||||
lpStoreData = lpSessionData->GetStoreData();
|
||||
}
|
||||
|
||||
if(dwCID == lpSessionData->GetCID())
|
||||
{
|
||||
lpCharacterData = lpSessionData->GetCharacterData();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(0 == wError)
|
||||
{
|
||||
// 캐쉬에서 데이터 로드. 캐쉬에 데이터가 없으면, DB에서 로드해서 캐쉬에 추가.
|
||||
if(0 == lpStoreData)
|
||||
{
|
||||
lpStoreData = CStoreDataMgr::GetInstance().GetLogoutData(
|
||||
UnifiedStoreKey(dwUID, cOldServerGroupID));
|
||||
}
|
||||
|
||||
if(0 == lpCharacterData)
|
||||
{
|
||||
lpCharacterData = CCharacterDataMgr::GetInstance().GetLogoutData(dwCID);
|
||||
}
|
||||
|
||||
if(0 != lpStoreData && 0 != lpCharacterData)
|
||||
{
|
||||
switch(lpPktAdminToolSetData->m_cType)
|
||||
{
|
||||
case PktAdminToolSetData::OPEN_UPDATE_DATA:
|
||||
// 세션을 열고 DB에 업데이트하려 시도한다. : 이제는 세션 열 필요 없다. 그냥 한다.
|
||||
break;
|
||||
|
||||
case PktAdminToolSetData::FINISH_UPDATE_DATA:
|
||||
// 데이터를 DB에 업데이트하고 세션을 닫는다. : 이제는 세션 닫을 필요 없다. 그냥 한다.
|
||||
break;
|
||||
|
||||
case PktAdminToolSetData::CHAR_BASIC_DATA: // 캐릭터 정보. 다음 정보들이 들어감.
|
||||
|
||||
// 세션이 운영툴에서 연 세션인지 확인한다. 운영툴에서 연 세션이면, 데이터를 세팅한다.
|
||||
{
|
||||
unsigned short* lpSizeArray = reinterpret_cast<unsigned short*>(lpPktAdminToolSetData + 1);
|
||||
char* lpData = reinterpret_cast<char*>(lpSizeArray + DBUpdateData::MAX_UPDATE_DB);
|
||||
|
||||
if(!lpCharacterData->SerializeIn(lpData, lpSizeArray,
|
||||
dwDataSize - sizeof(unsigned short) * DBUpdateData::MAX_UPDATE_DB, DBUpdateData::MAX_UPDATE_DB))
|
||||
{
|
||||
ERRLOG3(g_Log, "UID:%10u / CID:%10u / IP:%15s / 운영툴 데이터 세팅 실패 : CHAR_BASIC_DATA",
|
||||
dwUID, dwCID, GetRemoteAddr().get_addr_string());
|
||||
|
||||
wError = PktAdminToolSetData::SETTING_DATA_FAILED;
|
||||
}
|
||||
else
|
||||
{
|
||||
INFLOG3(g_Log, "UID:%10u / CID:%10u / IP:%15s / 운영툴 데이터 세팅 성공 : CHAR_BASIC_DATA",
|
||||
dwUID, dwCID, GetRemoteAddr().get_addr_string());
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case PktAdminToolSetData::CHAR_EXTRA_DATA: // 캐릭터 추가 정보들. 다음 정보들이 들어감.
|
||||
|
||||
{
|
||||
unsigned long dwExpectDataSize = sizeof(CHAR_INFOEX) + sizeof(QUEST) +
|
||||
sizeof(HISTORY) + sizeof(CONFIG) + sizeof(STORE_INFO);
|
||||
|
||||
if(dwDataSize == dwExpectDataSize)
|
||||
{
|
||||
char* lpCharDataExPos = reinterpret_cast<char*>(lpPktAdminToolSetData + 1);
|
||||
|
||||
// CHAR_INFOEX : 캐릭터 추가 정보
|
||||
lpCharacterData->SetInfoEx(*reinterpret_cast<CHAR_INFOEX*>(lpCharDataExPos));
|
||||
lpCharDataExPos += sizeof(CHAR_INFOEX);
|
||||
|
||||
// QUEST : 퀘스트
|
||||
lpCharacterData->SetQuest(*reinterpret_cast<QUEST*>(lpCharDataExPos));
|
||||
lpCharDataExPos += sizeof(QUEST);
|
||||
|
||||
// HISTORY : 히스토리
|
||||
lpCharacterData->SetHistory(*reinterpret_cast<HISTORY*>(lpCharDataExPos));
|
||||
lpCharDataExPos += sizeof(HISTORY);
|
||||
|
||||
// CONFIG : 설정
|
||||
lpCharacterData->SetConfig(*reinterpret_cast<CONFIG*>(lpCharDataExPos));
|
||||
lpCharDataExPos += sizeof(CONFIG);
|
||||
|
||||
// STORE_INFO : 창고 정보
|
||||
lpStoreData->SetStoreInfo(*reinterpret_cast<STORE_INFO*>(lpCharDataExPos));
|
||||
lpCharDataExPos += sizeof(STORE_INFO);
|
||||
}
|
||||
else
|
||||
{
|
||||
wError = PktAdminToolSetData::SETTING_DATA_FAILED;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case PktAdminToolSetData::CHAR_FRIEND_DATA: // 캐릭터 친구 정보
|
||||
|
||||
if(!lpCharacterData->FriendSerializeIn(
|
||||
reinterpret_cast<char*>(lpPktAdminToolSetData + 1), dwDataSize))
|
||||
{
|
||||
wError = PktAdminToolSetData::SETTING_DATA_FAILED;
|
||||
}
|
||||
break;
|
||||
|
||||
case PktAdminToolSetData::CHAR_BAN_DATA: // 캐릭터 거부 정보
|
||||
|
||||
if(!lpCharacterData->BanSerializeIn(
|
||||
reinterpret_cast<char*>(lpPktAdminToolSetData + 1), dwDataSize))
|
||||
{
|
||||
wError = PktAdminToolSetData::SETTING_DATA_FAILED;
|
||||
}
|
||||
break;
|
||||
|
||||
case PktAdminToolSetData::STORE_12_DATA: // 창고 1, 2탭 데이터
|
||||
|
||||
if(dwDataSize == sizeof(STORE))
|
||||
{
|
||||
const STORE& store1 = *reinterpret_cast<STORE*>(lpPktAdminToolSetData + 1);
|
||||
lpStoreData->SetStore1(store1.Data, store1.dwSize);
|
||||
}
|
||||
else
|
||||
{
|
||||
wError = PktAdminToolSetData::SETTING_DATA_FAILED;
|
||||
}
|
||||
break;
|
||||
|
||||
case PktAdminToolSetData::STORE_34_DATA: // 창고 3, 4탭 데이터
|
||||
|
||||
if(dwDataSize == sizeof(STORE))
|
||||
{
|
||||
const STORE& store2 = *reinterpret_cast<STORE*>(lpPktAdminToolSetData + 1);
|
||||
lpStoreData->SetStore2(store2.Data, store2.dwSize);
|
||||
}
|
||||
else
|
||||
{
|
||||
wError = PktAdminToolSetData::SETTING_DATA_FAILED;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ItemSerial 업데이트
|
||||
if(m_AdminItemSerialMgr.SetItemSerial(lpPktAdminToolSetData->m_dwSerial))
|
||||
{
|
||||
m_AdminItemSerialMgr.SaveItemSerial(CDBSingleObject::GetInstance(), m_dwServerID);
|
||||
}
|
||||
|
||||
return SendPacket::AdminToolSetDataAck(
|
||||
GetSendStream(), dwRequestKey, dwUID, dwCID, cType, wError);
|
||||
}
|
||||
|
||||
|
||||
bool CAdminToolDispatch::ParseGuildPosition(PktGuildPosition* lpPktGuildPosition)
|
||||
{
|
||||
using namespace DataStorage;
|
||||
|
||||
unsigned short wError = PktBase::NO_SERVER_ERR;
|
||||
|
||||
unsigned long dwGID = lpPktGuildPosition->m_dwGID;
|
||||
unsigned long dwCID = lpPktGuildPosition->m_dwCID;
|
||||
unsigned char cPosition = lpPktGuildPosition->m_cPosition;
|
||||
unsigned char cType = lpPktGuildPosition->m_cType;
|
||||
|
||||
using namespace Guild;
|
||||
|
||||
CGuildDB* lpGuild = static_cast<CGuildDB*>(CGuildDBMgr::GetInstance().GetGuild(dwGID));
|
||||
|
||||
char* lpBuffer = GetSendStream().GetBuffer(sizeof(PktGuildPosition));
|
||||
|
||||
PktGuildPosition* pktSendPacket = NULL;
|
||||
|
||||
if(lpBuffer)
|
||||
{
|
||||
pktSendPacket = reinterpret_cast<PktGuildPosition*>(lpBuffer);
|
||||
|
||||
pktSendPacket->m_cPosition = lpPktGuildPosition->m_cPosition;
|
||||
pktSendPacket->m_dwCID = lpPktGuildPosition->m_dwCID;
|
||||
pktSendPacket->m_dwGID = lpPktGuildPosition->m_dwGID;
|
||||
pktSendPacket->m_cType = lpPktGuildPosition->m_cType;
|
||||
}
|
||||
|
||||
if(!lpGuild)
|
||||
{
|
||||
wError = PktGuildPosition::FAIL_GUILD;
|
||||
}
|
||||
else
|
||||
{
|
||||
CSessionData* lpSessionData = CSessionDataMgr::GetInstance().GetCharLoadedSession(dwCID);
|
||||
|
||||
if(lpSessionData)
|
||||
{
|
||||
wError = PktGuildPosition::FAIL_CONNECT_CHAR;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(cType==PktGuildPosition::TYPE_POSITION)
|
||||
{
|
||||
lpGuild->SetTitle(dwCID, cPosition);
|
||||
|
||||
SYSTEMTIME systemTime;
|
||||
::memset(&systemTime, 0, sizeof(SYSTEMTIME));
|
||||
GetLocalTime(&systemTime);
|
||||
|
||||
if(!DBComponent::GuildDB::UpdateMemberTitle(CDBSingleObject::GetInstance(), dwCID, cPosition, systemTime))
|
||||
{
|
||||
wError = PktGuildPosition::FAIL_DB_UPDATE;
|
||||
}
|
||||
}
|
||||
else if(cType==PktGuildPosition::TYPE_MEMBERDELETE)
|
||||
{
|
||||
if(!lpGuild->LeaveMember(dwCID))
|
||||
{
|
||||
wError = PktGuildPosition::FAIL_MEMBER_DELETE;
|
||||
}
|
||||
else
|
||||
{
|
||||
using namespace DBAgent::DataStorage;
|
||||
|
||||
DBComponent::GameDB::UpdateGuildWarFlag(CDBSingleObject::GetInstance(), dwCID, Creature::WAR_OFF);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return GetSendStream().WrapHeader(sizeof(PktGuildPosition), CmdGuildPosition, 0, wError);
|
||||
}
|
||||
|
||||
bool CAdminToolDispatch::ParseItemQtyCheck(PktItemQtyControl* lpPktItemQtyControl)
|
||||
{
|
||||
tm* lpTm = localtime(&lpPktItemQtyControl->m_tStartTime);
|
||||
if(0 == lpTm)
|
||||
{
|
||||
ERRLOG2(g_Log, "IP:%15s / StartTime:%d / 아이템 수량 제어 실패 : 시간이 맞지 않습니다",
|
||||
GetRemoteAddr().get_addr_string(), lpPktItemQtyControl->m_tStartTime);
|
||||
}
|
||||
else
|
||||
{
|
||||
tm tStartTime = *lpTm;
|
||||
|
||||
lpTm = localtime(&lpPktItemQtyControl->m_tEndTime);
|
||||
if(0 == lpTm)
|
||||
{
|
||||
ERRLOG2(g_Log, "IP:%15s / EndTime:%d / 아이템 수량 제어 실패 : 시간이 맞지 않습니다",
|
||||
GetRemoteAddr().get_addr_string(), lpPktItemQtyControl->m_tEndTime);
|
||||
}
|
||||
else
|
||||
{
|
||||
tm tEndTime = *lpTm;
|
||||
|
||||
if(lpPktItemQtyControl->m_cGroup != CServerSetup::GetInstance().GetServerGroup())
|
||||
{
|
||||
ERRLOG3(g_Log, "IP:%15s / CurrentServerGroup:%d / ReceivedServerGroup:%d / 아이템 수량 제어 실패 : 서버 그룹이 맞지 않습니다",
|
||||
GetRemoteAddr().get_addr_string(), CServerSetup::GetInstance().GetServerGroup(), lpPktItemQtyControl->m_cGroup);
|
||||
}
|
||||
else
|
||||
{
|
||||
bool bResult = false;
|
||||
|
||||
switch(lpPktItemQtyControl->m_cType)
|
||||
{
|
||||
case PktItemQtyControl::ADD:
|
||||
|
||||
bResult = CGameEventDBMgr::GetInstance().InsertDropItem(
|
||||
static_cast<unsigned short>(lpPktItemQtyControl->m_dwItemTypeID),
|
||||
static_cast<unsigned short>(lpPktItemQtyControl->m_dwItemQty),
|
||||
tStartTime, tEndTime);
|
||||
|
||||
DETLOG5(g_Log, "아이템 수량 제어 추가 %s : ID:%u/Qty:%u/StartTime:%d/EndTime:%d",
|
||||
bResult ? "성공" : "실패",
|
||||
lpPktItemQtyControl->m_dwItemTypeID, lpPktItemQtyControl->m_dwItemQty,
|
||||
lpPktItemQtyControl->m_tStartTime, lpPktItemQtyControl->m_tEndTime);
|
||||
|
||||
SendPacket::ItemQtyCheck(lpPktItemQtyControl->m_dwItemTypeID,
|
||||
lpPktItemQtyControl->m_dwItemQty, 0,
|
||||
lpPktItemQtyControl->m_tStartTime,
|
||||
lpPktItemQtyControl->m_tEndTime,
|
||||
PktItemQtyControl::ADD, bResult ? 0 : 1);
|
||||
break;
|
||||
|
||||
case PktItemQtyControl::DEL:
|
||||
|
||||
bResult = CGameEventDBMgr::GetInstance().EraseDropItem(
|
||||
static_cast<unsigned short>(lpPktItemQtyControl->m_dwItemTypeID));
|
||||
|
||||
DETLOG5(g_Log, "아이템 수량 제어 삭제 %s : ID:%u/Qty:%u/StartTime:%d/EndTime:%d",
|
||||
bResult ? "성공" : "실패",
|
||||
lpPktItemQtyControl->m_dwItemTypeID, lpPktItemQtyControl->m_dwItemQty,
|
||||
lpPktItemQtyControl->m_tStartTime, lpPktItemQtyControl->m_tEndTime);
|
||||
|
||||
SendPacket::ItemQtyCheck(lpPktItemQtyControl->m_dwItemTypeID,
|
||||
lpPktItemQtyControl->m_dwItemQty, 0,
|
||||
lpPktItemQtyControl->m_tStartTime, lpPktItemQtyControl->m_tEndTime,
|
||||
PktItemQtyControl::DEL, bResult ? 0 : 1);
|
||||
break;
|
||||
|
||||
case PktItemQtyControl::STATUS_REQUEST:
|
||||
|
||||
DETLOG0(g_Log, "아이템 수량 제어 상태 요청");
|
||||
CGameEventDBMgr::GetInstance().SendDropItemInfo();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
class CSendNameChanged
|
||||
{
|
||||
public:
|
||||
|
||||
CSendNameChanged(unsigned long dwUID, unsigned long dwCID, const char* szChangedName,
|
||||
unsigned char cNameChangeCount, unsigned short usError)
|
||||
: m_dwUID(dwUID), m_dwCID(dwCID),
|
||||
m_cNameChangeCount(cNameChangeCount),
|
||||
m_usError(usError)
|
||||
{
|
||||
strncpy(m_szChangedName, szChangedName, CHAR_INFOST::MAX_NAME_LEN);
|
||||
m_szChangedName[ CHAR_INFOST::MAX_NAME_LEN - 1 ] = 0;
|
||||
}
|
||||
|
||||
bool operator () (unsigned long dwServerID, CPacketDispatch& dispatch)
|
||||
{
|
||||
return GameClientSendPacket::SendCharNameChange(
|
||||
static_cast<CRylServerDispatch&>(dispatch).GetSendStream(),
|
||||
m_dwUID, m_dwCID, m_szChangedName, m_cNameChangeCount, NULL, m_usError);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
unsigned long m_dwUID;
|
||||
unsigned long m_dwCID;
|
||||
unsigned char m_cNameChangeCount;
|
||||
unsigned short m_usError;
|
||||
|
||||
char m_szChangedName[CHAR_INFOST::MAX_NAME_LEN];
|
||||
};
|
||||
|
||||
bool CAdminToolDispatch::ParseAdminToolChangeName(PktAdminToolGetData* lpPktAdminToolGetData)
|
||||
{
|
||||
unsigned long dwUID = lpPktAdminToolGetData->m_dwUID;
|
||||
unsigned long dwCID = lpPktAdminToolGetData->m_dwCID;
|
||||
unsigned long dwRequestKey = lpPktAdminToolGetData->m_dwRequestKey;
|
||||
const char* szChangeName = lpPktAdminToolGetData->m_szName;
|
||||
|
||||
unsigned short usError = 0;
|
||||
|
||||
using namespace DBAgent::DataStorage;
|
||||
|
||||
CSessionData* lpSessionData =
|
||||
CSessionDataMgr::GetInstance().GetCharLoadedSession(dwCID);
|
||||
|
||||
CCharacterData* lpCharacterData = 0;
|
||||
|
||||
if (0 == lpSessionData ||
|
||||
lpSessionData->GetUID() != dwUID ||
|
||||
lpSessionData->GetCID() != dwCID ||
|
||||
(0 == (lpCharacterData = lpSessionData->GetCharacterData())) ||
|
||||
dwCID != lpCharacterData->GetCID())
|
||||
{
|
||||
lpCharacterData = CCharacterDataMgr::GetInstance().GetLogoutData(dwCID);
|
||||
}
|
||||
|
||||
if (0 != lpCharacterData)
|
||||
{
|
||||
unsigned long dwResult = 0;
|
||||
|
||||
if (DBComponent::GameDB::ChangeCharName(
|
||||
CDBSingleObject::GetInstance(), dwCID, szChangeName, dwResult))
|
||||
{
|
||||
if (0 == dwResult)
|
||||
{
|
||||
// 이름을 바꾼다.
|
||||
CHAR_INFOST charInfoST = lpCharacterData->GetInfo();
|
||||
|
||||
strncpy(charInfoST.Name, szChangeName, CHAR_INFOST::MAX_NAME_LEN);
|
||||
charInfoST.Name[CHAR_INFOST::MAX_NAME_LEN - 1] = 0;
|
||||
|
||||
lpCharacterData->SetInfo(charInfoST, true);
|
||||
}
|
||||
else if(1 == dwResult)
|
||||
{
|
||||
ERRLOG3(g_Log, "UID:%10u / CID:%10u / ChangeName:%s / 운영툴로 캐릭터 이름 바꾸기 실패 : 이름이 이미 있습니다",
|
||||
dwUID, dwCID, szChangeName);
|
||||
|
||||
usError = PktCharNameChange::ERR_ALREADY_USE_NAME;
|
||||
}
|
||||
else
|
||||
{
|
||||
ERRLOG4(g_Log, "UID:%10u / CID:%10u / ChangeName:%s / dwResult:%10u / 운영툴로 캐릭터 이름 바꾸기 실패 : 알 수 없는 dwResult값입니다",
|
||||
dwUID, dwCID, szChangeName, dwResult);
|
||||
|
||||
usError = PktCharNameChange::ERR_SERVER;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ERRLOG3(g_Log, "UID:%10u / CID:%10u / ChangeName:%s / 운영툴로 캐릭터 이름 바꾸기 실패 : DB호출 에러",
|
||||
dwUID, dwCID, szChangeName);
|
||||
|
||||
usError = PktCharNameChange::ERR_SERVER;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ERRLOG3(g_Log, "UID:%10u / CID:%10u / ChangeName:%s / "
|
||||
"운영툴로 캐릭터 이름 바꾸기 실패 : 해당하는 캐릭터를 찾을 수 없습니다.", dwUID, dwCID, szChangeName);
|
||||
|
||||
usError = PktCharNameChange::ERR_CANNOT_FIND_CHARACTER;
|
||||
}
|
||||
|
||||
if (0 != lpSessionData && 0 != lpCharacterData && 0 == usError)
|
||||
{
|
||||
// 모든 게임 서버에 전송한다.
|
||||
DBAgent::CGameDispatch::GetDispatchTable().Process(
|
||||
CSendNameChanged(dwUID, dwCID, szChangeName,
|
||||
lpCharacterData->GetInfoEx().cNameChangeCount, usError));
|
||||
}
|
||||
|
||||
// 운영툴로 Ack를 전송한다.
|
||||
return SendPacket::AdminToolGetDataAck(GetSendStream(),
|
||||
PktAdminToolGetData::CHANGE_CHAR_NAME, dwRequestKey, dwUID, dwCID, 0, 0, usError);
|
||||
}
|
||||
|
||||
|
||||
bool GetUIDCIDFromName(const char* szName, unsigned long& dwUID_Out,
|
||||
unsigned long& dwCID_Out, unsigned char& cOldServerGroupID)
|
||||
{
|
||||
#pragma pack(1)
|
||||
|
||||
struct UIDCID
|
||||
{
|
||||
unsigned long dwUID;
|
||||
unsigned long dwCID;
|
||||
unsigned char cOldServerGroupID;
|
||||
};
|
||||
|
||||
#pragma pack()
|
||||
|
||||
UIDCID uidcid;
|
||||
|
||||
uidcid.dwUID = 0;
|
||||
uidcid.dwCID = 0;
|
||||
|
||||
const int MAX_BUFFER = 1024;
|
||||
char szQuery[MAX_BUFFER] = { 0, };
|
||||
|
||||
int nLength = _snprintf(szQuery, MAX_BUFFER - 1, "dbo.GetUIDCIDFromName '%s'", szName);
|
||||
szQuery[MAX_BUFFER - 1] = 0;
|
||||
|
||||
if(0 < nLength)
|
||||
{
|
||||
szQuery[nLength] = 0;
|
||||
if(CDBSingleObject::GetInstance().ExecuteQueryGetData(szQuery, &uidcid))
|
||||
{
|
||||
dwUID_Out = uidcid.dwUID;
|
||||
dwCID_Out = uidcid.dwCID;
|
||||
cOldServerGroupID = uidcid.cOldServerGroupID;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
ERRLOG2(g_Log, "캐릭터 이름으로 UID / CID 얻어 오는 쿼리에 실패했습니다. %s : %s",
|
||||
CDBSingleObject::GetInstance().GetErrorString(), szQuery);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
#ifndef _DBAGENT_SERVER_ADMIN_TOOL_DISPATCH_H_
|
||||
#define _DBAGENT_SERVER_ADMIN_TOOL_DISPATCH_H_
|
||||
|
||||
#include <Network/Dispatch/RylServerDispatch.h>
|
||||
#include <Network/Dispatch/MultiDispatchStorage.h>
|
||||
|
||||
#include <Item/ItemSerialMgr.h>
|
||||
|
||||
// forward decl.
|
||||
struct PktSL;
|
||||
struct PktUK;
|
||||
struct PktItemQtyControl;
|
||||
struct PktAdminToolGetData;
|
||||
struct PktAdminToolSetData;
|
||||
struct PktGuildPosition;
|
||||
|
||||
namespace DBAgent
|
||||
{
|
||||
class CAdminToolDispatch : public CRylServerDispatch
|
||||
{
|
||||
public:
|
||||
|
||||
static CMultiDispatch& GetDispatchTable();
|
||||
|
||||
enum Const
|
||||
{
|
||||
MAX_PACKET_DISPATCH_PER_PULSE = 100,
|
||||
MAX_STREAM_BUFFER_SIZE = 16000
|
||||
};
|
||||
|
||||
CAdminToolDispatch(CSession& Session);
|
||||
virtual ~CAdminToolDispatch();
|
||||
|
||||
virtual void Connected();
|
||||
virtual void Disconnected();
|
||||
virtual bool DispatchPacket(PktBase* lpPktBase);
|
||||
|
||||
private:
|
||||
|
||||
bool ParseServerLogin(PktSL* lpPktSL);
|
||||
bool ParseServerLogout(PktBase* lpPktBase);
|
||||
bool ParseUserKill(PktUK* lpPktUK);
|
||||
|
||||
bool ParseGetData(PktBase* lpPktBase);
|
||||
bool ParseSetData(PktBase* lpPktBase);
|
||||
bool ParseItemQtyCheck(PktItemQtyControl* lpPktItemQtyControl); // 이벤트 아이템 수량 관련 패킷
|
||||
|
||||
bool ParseAdminToolGetData(PktAdminToolGetData* lpPktAdminToolGetData); // 현재 운영툴(AdminTool)
|
||||
bool ParseAdminToolSetData(PktAdminToolSetData* lpPktAdminToolSetData); // 현재 운영툴(AdminTool)
|
||||
|
||||
bool ParseAdminToolChangeName(PktAdminToolGetData* lpPktAdminToolGetData); // 운영툴로 캐릭터 이름 바꾸기
|
||||
|
||||
bool ParseGuildPosition(PktGuildPosition* lpPktGuildPosition); // 길드 포지션 설정.
|
||||
|
||||
Item::CItemSerialMgr m_AdminItemSerialMgr;
|
||||
|
||||
unsigned long m_dwServerID;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,232 @@
|
||||
#include "stdafx.h"
|
||||
#include "AuthDispatch.h"
|
||||
|
||||
#include <Log/ServerLog.h>
|
||||
#include <Utility/Setup/ServerSetup.h>
|
||||
#include <Network/Address/INET_Addr.h>
|
||||
#include <Network/SendPacket/SendServerInfo.h>
|
||||
#include <Network/SendPacket/SendLoginout.h>
|
||||
|
||||
#include <Network/ParsePacket/ParseCharManage.h>
|
||||
#include <Network/ParsePacket/ParseGuild.h>
|
||||
#include <Network/ParsePacket/ParseParty.h>
|
||||
#include <Network/ParsePacket/ParseMoveZone.h>
|
||||
|
||||
#include <Network/Packet/PacketCommand.h>
|
||||
|
||||
#include <Network/Dispatch/LoginDispatch.h>
|
||||
|
||||
#include <DB/DBComponent.h>
|
||||
#include <DB/GameDBComponent.h>
|
||||
|
||||
#include <DataStorage/SessionData.h>
|
||||
#include <DataStorage/SessionDataMgr.h>
|
||||
|
||||
|
||||
namespace DBAgent
|
||||
{
|
||||
|
||||
CSingleDispatch& CAuthDispatch::GetDispatchTable()
|
||||
{
|
||||
static CSingleDispatch authDispatch;
|
||||
return authDispatch;
|
||||
}
|
||||
|
||||
|
||||
CAuthDispatch::CAuthDispatch(CSession& Session)
|
||||
: CRylServerDispatch(Session, MAX_PACKET_DISPATCH_PER_PULSE),
|
||||
m_dwServerID(0),
|
||||
m_nUserNum(1)
|
||||
{
|
||||
|
||||
|
||||
}
|
||||
|
||||
CAuthDispatch::~CAuthDispatch()
|
||||
{
|
||||
|
||||
|
||||
}
|
||||
|
||||
void CAuthDispatch::Connected()
|
||||
{
|
||||
DETLOG3(g_Log, "SS:0x%08x/DP:0x%08x/IP:%15s/AuthServer Connected",
|
||||
&GetSession(), this, GetRemoteAddr().get_addr_string());
|
||||
}
|
||||
|
||||
void CAuthDispatch::Disconnected()
|
||||
{
|
||||
DETLOG3(g_Log, "SS:0x%08x/DP:0x%08x/IP:%15s/AuthServer Disconnected",
|
||||
&GetSession(), this, GetRemoteAddr().get_addr_string());
|
||||
|
||||
if(0 != m_dwServerID)
|
||||
{
|
||||
GetDispatchTable().RemoveDispatch(this);
|
||||
|
||||
if(0LL != m_AuthItemSerialMgr.GetItemSerial())
|
||||
{
|
||||
// 아이템 시리얼 DB에 저장
|
||||
m_AuthItemSerialMgr.SaveItemSerial(
|
||||
CDBSingleObject::GetInstance(), m_dwServerID);
|
||||
}
|
||||
|
||||
GET_SINGLE_DISPATCH(lpLoginDispatch, CLoginDispatch,
|
||||
CLoginDispatch::GetDispatchTable());
|
||||
|
||||
if(0 != lpLoginDispatch)
|
||||
{
|
||||
// 로그인서버로 서버 버전 업데이트
|
||||
SendPacket::UpdateServerVersion(lpLoginDispatch->GetSendStream());
|
||||
}
|
||||
|
||||
// 현재 서버에 로그인된 사람을 전부 내려버린다.
|
||||
DataStorage::CSessionDataMgr::GetInstance().SessionCloseCurrentServer(m_dwServerID);
|
||||
}
|
||||
}
|
||||
|
||||
bool CAuthDispatch::DispatchPacket(PktBase* lpPktBase)
|
||||
{
|
||||
// Auth 에서 보낸 패킷을 처리하는 부분이다.
|
||||
|
||||
bool bResult = false;
|
||||
PktBase::CMDType cCmd = lpPktBase->GetCmd();
|
||||
|
||||
switch(cCmd)
|
||||
{
|
||||
case CmdSysServerLogin: bResult = ParseServerLogin(static_cast<PktSL*>(lpPktBase)); break;
|
||||
case CmdSysServerLogout: bResult = ParseServerLogout(lpPktBase); break;
|
||||
case CmdUserKill: bResult = ParseUserKill(static_cast<PktUK*>(lpPktBase)); break;
|
||||
|
||||
case CmdDBGetData:
|
||||
{
|
||||
PktDD* pkDD = static_cast<PktDD*>(lpPktBase);
|
||||
|
||||
// DETLOG4(g_Log, "SS:0x%08x/DP:0x%08x/Len:0x%08x/CMD:0x%04x : CmdDBGetData", &GetSession(), this, pkDD->GetLen(), pkDD->m_wCmd);
|
||||
|
||||
bResult = ParseCharManage::Parse(GetSendStream(), m_dwServerID,
|
||||
m_AuthItemSerialMgr, pkDD);
|
||||
}
|
||||
break;
|
||||
|
||||
case CmdAgentZone: bResult = ParseMoveZone::Parse(GetSendStream(), static_cast<PktDD*>(lpPktBase)); break;
|
||||
case CmdAgentParty: bResult = ParseParty::Parse(GetSendStream(), lpPktBase); break;
|
||||
case CmdGuildCmd: bResult = ParseGuild::GuildCmd(GetSendStream(), lpPktBase); break;
|
||||
|
||||
|
||||
case CmdUnifiedCharSelect:
|
||||
bResult = ParseCharManage::UnifiedCharSelect(GetSendStream(), lpPktBase);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
ERRLOG4(g_Log, "SS:0x%08x/DP:0x%08x/IP:%15s/Cmd:0x%02X/ 인증서버 패킷 처리 실패 : 없는 커맨드입니다",
|
||||
&GetSession(), this, GetRemoteAddr().get_addr_string(), cCmd);
|
||||
|
||||
bResult = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if(!bResult)
|
||||
{
|
||||
ERRLOG4(g_Log, "SS:0x%08x/DP:0x%08x/IP:%15s/Cmd:0x%02X/ 인증서버 패킷 처리 실패 : 처리를 실패했습니다",
|
||||
&GetSession(), this, GetRemoteAddr().get_addr_string(), cCmd);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool CAuthDispatch::ParseServerLogin(PktSL* lpPktSL)
|
||||
{
|
||||
m_dwServerID = lpPktSL->m_dwServerID;
|
||||
|
||||
INFLOG4(g_Log, "SS:0x%08x/DP:0x%08x/IP:%15s/ServerID:0x%08X/ 인증서버 연결 시도 : 패킷 받음",
|
||||
&GetSession(), this, GetRemoteAddr().get_addr_string(), m_dwServerID);
|
||||
|
||||
GET_SINGLE_DISPATCH(lpAuthDispatch,
|
||||
CAuthDispatch, GetDispatchTable());
|
||||
|
||||
if(0 != lpAuthDispatch)
|
||||
{
|
||||
ERRLOG4(g_Log, "SS:0x%08x/DP:0x%08x/IP:%15s/ServerID:0x%08X/ 인증서버 연결 실패 : 이미 연결이 있습니다",
|
||||
&GetSession(), this, GetRemoteAddr().get_addr_string(), m_dwServerID);
|
||||
|
||||
CloseSession();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Dispatch 세팅.
|
||||
GetDispatchTable().SetDispatch(this);
|
||||
|
||||
// 아이템 시리얼 로드.
|
||||
if(!m_AuthItemSerialMgr.LoadItemSerial(CDBSingleObject::GetInstance(), m_dwServerID))
|
||||
{
|
||||
ERRLOG4(g_Log, "SS:0x%08x/DP:0x%08x/IP:%15s/ServerID:0x%08X/인증서버 연결 실패 : 아이템 시리얼 로드 실패. 접속을 끊습니다.",
|
||||
&GetSession(), this, GetRemoteAddr().get_addr_string(), m_dwServerID);
|
||||
|
||||
CloseSession();
|
||||
return false;
|
||||
}
|
||||
|
||||
GET_SINGLE_DISPATCH(lpLoginDispatch, CLoginDispatch,
|
||||
CLoginDispatch::GetDispatchTable());
|
||||
|
||||
if(0 != lpLoginDispatch)
|
||||
{
|
||||
// 로그인서버로 서버 버전 업데이트
|
||||
SendPacket::UpdateServerVersion(lpLoginDispatch->GetSendStream());
|
||||
}
|
||||
|
||||
return SendPacket::ServerLoginAck(m_SendStream,
|
||||
m_dwServerID, m_AuthItemSerialMgr.GetItemSerial());
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CAuthDispatch::ParseServerLogout(PktBase* lpPktBase)
|
||||
{
|
||||
// 받은 패킷 그대로 돌려 준다.
|
||||
|
||||
char* lpBuffer = m_SendStream.GetBuffer(sizeof(PktBase));
|
||||
if(0 != lpBuffer)
|
||||
{
|
||||
return m_SendStream.WrapHeader(sizeof(PktBase), CmdSysServerLogout, 0, 0);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CAuthDispatch::ParseUserKill(PktUK* lpPktUK)
|
||||
{
|
||||
// 유저 죽이기를 실패해서, Ack로 오는 경우이다.
|
||||
|
||||
if(2 == lpPktUK->GetError())
|
||||
{
|
||||
DataStorage::CSessionData* lpSessionData =
|
||||
DataStorage::CSessionDataMgr::GetInstance().GetOpenSession(lpPktUK->m_dwUserID);
|
||||
|
||||
if(0 != lpSessionData &&
|
||||
DataStorage::CSessionData::SE_USER_ENABLED == lpSessionData->GetSessionState())
|
||||
{
|
||||
if(lpSessionData->GetServerID() == lpPktUK->m_dwServerID)
|
||||
{
|
||||
DataStorage::CSessionDataMgr::GetInstance().SessionCloseWithLogout(
|
||||
lpPktUK->m_dwUserID, lpPktUK->m_dwServerID);
|
||||
|
||||
ERRLOG2(g_Log, "UID:%10u / ServerID:0x%08X / 게임서버 세션 강제 종료 : 캐릭터 죽이기 실패",
|
||||
lpPktUK->m_dwUserID, lpPktUK->m_dwServerID);
|
||||
}
|
||||
else
|
||||
{
|
||||
ERRLOG3(g_Log, "UID:%10u / FromServerID:0x%08X / TargetServerID:0x%08X / "
|
||||
"게임서버 세션 강제 종료 실패 : 실패 서버와 죽이기 요청 서버가 다름",
|
||||
lpPktUK->m_dwUserID, lpPktUK->m_dwServerID, lpSessionData->GetServerID());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
#ifndef _DBAGENT_SERVER_AUTH_DISPATCH_H_
|
||||
#define _DBAGENT_SERVER_AUTH_DISPATCH_H_
|
||||
|
||||
#include <Network/Dispatch/RylServerDispatch.h>
|
||||
#include <Network/Dispatch/SingleDispatchStorage.h>
|
||||
|
||||
#include <Item/ItemSerialMgr.h>
|
||||
|
||||
// forward decl.
|
||||
struct PktSL;
|
||||
struct PktUK;
|
||||
struct PktDD;
|
||||
|
||||
namespace DBAgent
|
||||
{
|
||||
class CAuthDispatch : public CRylServerDispatch
|
||||
{
|
||||
public:
|
||||
|
||||
static CSingleDispatch& GetDispatchTable();
|
||||
|
||||
enum Const
|
||||
{
|
||||
MAX_PACKET_DISPATCH_PER_PULSE = 100,
|
||||
MAX_STREAM_BUFFER_SIZE = 16000
|
||||
};
|
||||
|
||||
CAuthDispatch(CSession& Session);
|
||||
virtual ~CAuthDispatch();
|
||||
|
||||
virtual void Connected();
|
||||
virtual void Disconnected();
|
||||
virtual bool DispatchPacket(PktBase* lpPktBase);
|
||||
|
||||
void IncUserNum() { ++m_nUserNum; }
|
||||
void DecUserNum() { --m_nUserNum; }
|
||||
|
||||
int GetUserNum() const { return (m_nUserNum < 1) ? 1 : m_nUserNum; }
|
||||
|
||||
private:
|
||||
|
||||
bool ParseServerLogin(PktSL* lpPktSL);
|
||||
bool ParseServerLogout(PktBase* lpPktBase);
|
||||
bool ParseUserKill(PktUK* lpPktUK);
|
||||
|
||||
unsigned long m_dwServerID;
|
||||
int m_nUserNum;
|
||||
Item::CItemSerialMgr m_AuthItemSerialMgr;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,126 @@
|
||||
#include "stdafx.h"
|
||||
#include "ChatDispatch.h"
|
||||
|
||||
#include <Log/ServerLog.h>
|
||||
#include <Network/Address/INET_Addr.h>
|
||||
#include <Network/Packet/PacketCommand.h>
|
||||
#include <Network/SendPacket/SendServerInfo.h>
|
||||
|
||||
namespace DBAgent
|
||||
{
|
||||
|
||||
CSingleDispatch& CChatDispatch::GetDispatchTable()
|
||||
{
|
||||
static CSingleDispatch chatDispatch;
|
||||
return chatDispatch;
|
||||
}
|
||||
|
||||
CChatDispatch::CChatDispatch(CSession& Session)
|
||||
: CRylServerDispatch(Session, MAX_PACKET_DISPATCH_PER_PULSE)
|
||||
{
|
||||
|
||||
|
||||
}
|
||||
|
||||
CChatDispatch::~CChatDispatch()
|
||||
{
|
||||
|
||||
|
||||
}
|
||||
|
||||
void CChatDispatch::Connected()
|
||||
{
|
||||
DETLOG3(g_Log, "SS:0x%08x/DP:0x%08x/IP:%15s/ChatServer Connected",
|
||||
&GetSession(), this, GetRemoteAddr().get_addr_string());
|
||||
}
|
||||
|
||||
void CChatDispatch::Disconnected()
|
||||
{
|
||||
DETLOG3(g_Log, "SS:0x%08x/DP:0x%08x/IP:%15s/ChatServer Disconnected",
|
||||
&GetSession(), this, GetRemoteAddr().get_addr_string());
|
||||
|
||||
if(0 != m_dwServerID)
|
||||
{
|
||||
GetDispatchTable().RemoveDispatch(this);
|
||||
}
|
||||
}
|
||||
|
||||
bool CChatDispatch::DispatchPacket(PktBase* lpPktBase)
|
||||
{
|
||||
bool bResult = false;
|
||||
PktBase::CMDType cCmd = lpPktBase->GetCmd();
|
||||
|
||||
switch(cCmd)
|
||||
{
|
||||
case CmdSysServerLogin:
|
||||
bResult = ParseServerLogin(static_cast<PktSL*>(lpPktBase));
|
||||
break;
|
||||
|
||||
case CmdSysServerLogout:
|
||||
bResult = ParseServerLogout(lpPktBase);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
ERRLOG4(g_Log, "SS:0x%08x/DP:0x%08x/IP:%15s/Cmd:0x%02X/ 채팅서버 패킷 처리 실패 : 없는 커맨드입니다",
|
||||
&GetSession(), this, GetRemoteAddr().get_addr_string(), cCmd);
|
||||
|
||||
bResult = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if(!bResult)
|
||||
{
|
||||
ERRLOG4(g_Log, "SS:0x%08x/DP:0x%08x/IP:%15s/Cmd:0x%02X/ 채팅서버 패킷 처리 실패 : 처리를 실패했습니다",
|
||||
&GetSession(), this, GetRemoteAddr().get_addr_string(), cCmd);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool CChatDispatch::ParseServerLogin(PktSL* lpPktSL)
|
||||
{
|
||||
m_dwServerID = lpPktSL->m_dwServerID;
|
||||
|
||||
INFLOG4(g_Log, "SS:0x%08x/DP:0x%08x/IP:%15s/ServerID:0x%08X/ 채팅서버 연결 시도 : 패킷 받음",
|
||||
&GetSession(), this, GetRemoteAddr().get_addr_string(), m_dwServerID);
|
||||
|
||||
GET_SINGLE_DISPATCH(lpChatDispatch,
|
||||
CChatDispatch, GetDispatchTable());
|
||||
|
||||
if(0 != lpChatDispatch)
|
||||
{
|
||||
ERRLOG4(g_Log, "SS:0x%08x/DP:0x%08x/IP:%15s/ServerID:0x%08X/ 채팅서버 연결 실패 : 이미 연결이 있습니다",
|
||||
&GetSession(), this, GetRemoteAddr().get_addr_string(), m_dwServerID);
|
||||
|
||||
CloseSession();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Dispatch 세팅.
|
||||
GetDispatchTable().SetDispatch(this);
|
||||
return SendPacket::ServerLoginAck(m_SendStream, m_dwServerID, 0LL);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CChatDispatch::ParseServerLogout(PktBase* lpPktBase)
|
||||
{
|
||||
// 받은 패킷 그대로 돌려 준다.
|
||||
|
||||
char* lpBuffer = m_SendStream.GetBuffer(sizeof(PktBase));
|
||||
if(0 != lpBuffer)
|
||||
{
|
||||
return m_SendStream.WrapHeader(sizeof(PktBase), CmdSysServerLogout, 0, 0);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
#ifndef _DBAGENT_SERVER_CHAT_DISPATCH_H_
|
||||
#define _DBAGENT_SERVER_CHAT_DISPATCH_H_
|
||||
|
||||
#include <Network/Dispatch/RylServerDispatch.h>
|
||||
#include <Network/Dispatch/SingleDispatchStorage.h>
|
||||
|
||||
// forward decl.
|
||||
struct PktSL;
|
||||
|
||||
namespace DBAgent
|
||||
{
|
||||
class CChatDispatch : public CRylServerDispatch
|
||||
{
|
||||
public:
|
||||
|
||||
static CSingleDispatch& GetDispatchTable();
|
||||
|
||||
enum Const
|
||||
{
|
||||
MAX_PACKET_DISPATCH_PER_PULSE = 100,
|
||||
MAX_STREAM_BUFFER_SIZE = 16000
|
||||
};
|
||||
|
||||
CChatDispatch(CSession& Session);
|
||||
virtual ~CChatDispatch();
|
||||
|
||||
virtual void Connected();
|
||||
virtual void Disconnected();
|
||||
virtual bool DispatchPacket(PktBase* lpPktBase);
|
||||
|
||||
private:
|
||||
|
||||
bool ParseServerLogin(PktSL* lpPktSL);
|
||||
bool ParseServerLogout(PktBase* lpPktBase);
|
||||
|
||||
unsigned long m_dwServerID;
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,827 @@
|
||||
#include "stdafx.h"
|
||||
#include "GameDispatch.h"
|
||||
|
||||
#include <Log/ServerLog.h>
|
||||
#include <Utility/Setup/ServerSetup.h>
|
||||
|
||||
#include <Network/Address/INET_Addr.h>
|
||||
#include <Network/Stream/SendStream.h>
|
||||
#include <Network/Packet/PacketDispatchTable.h>
|
||||
#include <Network/Packet/PacketCommand.h>
|
||||
#include <Network/Packet/WrapPacket.h>
|
||||
#include <Network/Packet/PacketStruct/ServerInfo.h>
|
||||
#include <Network/Packet/PacketStruct/ServerPacket.h>
|
||||
#include <Network/Packet/PacketStruct/ServerLogPacket.h>
|
||||
#include <Network/Packet/PacketStruct/CharAdminPacket.h>
|
||||
|
||||
#include <Network/ParsePacket/ParseMoveZone.h>
|
||||
#include <Network/ParsePacket/ParseCharManage.h>
|
||||
#include <Network/ParsePacket/ParseCharUpdate.h>
|
||||
#include <Network/ParsePacket/ParseParty.h>
|
||||
#include <Network/ParsePacket/ParseCastle.h>
|
||||
#include <Network/ParsePacket/ParseGuild.h>
|
||||
|
||||
#include <Network/SendPacket/SendServerInfo.h>
|
||||
#include <Network/Dispatch/GameClient/SendCharAdmin.h>
|
||||
|
||||
#include <Creature/Character/CharacterClass.h>
|
||||
#include <Creature/StatueDBMgr.h>
|
||||
|
||||
#include <DB/DBComponent.h>
|
||||
#include <DB/GameDBComponent.h>
|
||||
#include <DataStorage/SessionData.h>
|
||||
#include <DataStorage/SessionDataMgr.h>
|
||||
|
||||
#include <Castle/CastleDBMgr.h>
|
||||
#include <GameTime/GameTimeDBMgr.h>
|
||||
#include <Creature/Siege/SiegeObjectDBMgr.h>
|
||||
#include <Community/Guild/GuildDBMgr.h>
|
||||
#include <Ranking/RankingDBMgr.h>
|
||||
#include <GameEvent/GiveItemMgr.h>
|
||||
|
||||
#include <DataStorage/SessionDataMgr.h>
|
||||
#include <DataStorage/CharacterDataMgr.h>
|
||||
|
||||
#include <Map/FieldMap/MineralVeinDBMgr.h>
|
||||
|
||||
#include <Ranking/RankingMgr.h>
|
||||
|
||||
#include <Community/Party/PartyDBMgr.h>
|
||||
|
||||
namespace DBAgent
|
||||
{
|
||||
|
||||
typedef bool (*GameDispatchFunc) (CSendStream& SendStream, PktBase* lpPktBase);
|
||||
|
||||
|
||||
// forward delc.
|
||||
bool ParseServerLog(CSendStream& SendStream, PktBase* lpPktBase);
|
||||
|
||||
|
||||
class CGameDispatchTable : public CPacketDispatchTable<GameDispatchFunc>
|
||||
{
|
||||
public:
|
||||
|
||||
static CGameDispatchTable& GetInstance();
|
||||
|
||||
private:
|
||||
|
||||
CGameDispatchTable();
|
||||
};
|
||||
|
||||
|
||||
CGameDispatchTable& CGameDispatchTable::GetInstance()
|
||||
{
|
||||
static CGameDispatchTable gameDispatchTable;
|
||||
return gameDispatchTable;
|
||||
}
|
||||
|
||||
CGameDispatchTable::CGameDispatchTable()
|
||||
: CPacketDispatchTable<GameDispatchFunc>(UCHAR_MAX)
|
||||
{
|
||||
// 데이터 업데이트 관련
|
||||
AddDispatch(CmdDepositUpdate, ParseCharUpdate::UpdateDepositDB);
|
||||
AddDispatch(CmdDeposit, ParseCharUpdate::UpdateDeposit);
|
||||
AddDispatch(CmdFriendDB, ParseCharUpdate::UpdateFriendDB);
|
||||
AddDispatch(CmdQuestDB, ParseCharUpdate::UpdateQuestDB);
|
||||
AddDispatch(CmdConfigInfoDB, ParseCharUpdate::UpdateConfigInfoDB);
|
||||
|
||||
// 존이동 관련
|
||||
AddDispatch(CmdAgentZone, ParseMoveZone::Parse);
|
||||
|
||||
// 파티 관련
|
||||
AddDispatch(CmdAgentParty, ParseParty::Parse);
|
||||
|
||||
// 배틀그라운드 관련
|
||||
AddDispatch(CmdBGServerCharSlot, ParseCharManage::BGServerCharSlot);
|
||||
|
||||
// 로그 관련
|
||||
AddDispatch(CmdServerLog, ParseServerLog);
|
||||
|
||||
// 길드 관련
|
||||
AddDispatch(CmdCreateGuild, ParseGuild::CreateGuild);
|
||||
AddDispatch(CmdGuildCmd, ParseGuild::GuildCmd);
|
||||
AddDispatch(CmdGuildMark, ParseGuild::GuildMark);
|
||||
AddDispatch(CmdGuildLevel, ParseGuild::GuildLevel);
|
||||
AddDispatch(CmdGuildRelation, ParseGuild::GuildRelation);
|
||||
AddDispatch(CmdGuildInclination, ParseGuild::GuildInclination);
|
||||
AddDispatch(CmdGuildRight, ParseGuild::SetGuildRight);
|
||||
AddDispatch(CmdGuildSafe, ParseGuild::GuildSafe);
|
||||
AddDispatch(CmdGuildMemberInfoUpdate, ParseGuild::GuildMemberInfoUpdate);
|
||||
|
||||
// 공성 관련
|
||||
AddDispatch(CmdCreateCamp, ParseCastle::CreateCamp);
|
||||
AddDispatch(CmdCreateSiegeArms, ParseCastle::CreateSiegeArms);
|
||||
AddDispatch(CmdCastleCmd, ParseCastle::CastleCmd);
|
||||
AddDispatch(CmdCampCmd, ParseCastle::CampCmd);
|
||||
AddDispatch(CmdSiegeArmsCmd, ParseCastle::SiegeArmsCmd);
|
||||
AddDispatch(CmdCastleRight, ParseCastle::SetCastleRight);
|
||||
AddDispatch(CmdCampRight, ParseCastle::SetCampRight);
|
||||
AddDispatch(CmdCampMessage, ParseCastle::CampMessage);
|
||||
AddDispatch(CmdMiningCampMineralInfo, ParseCastle::MiningCampMineralInfo);
|
||||
AddDispatch(CmdFertilityInfo, ParseCastle::FertilityInfo);
|
||||
AddDispatch(CmdCampShopInfo, ParseCastle::CampShopInfo);
|
||||
AddDispatch(CmdCastleTaxMove, ParseCastle::CastleTaxMove);
|
||||
AddDispatch(CmdCastleMineralInfo, ParseCastle::CastleMineralInfo);
|
||||
AddDispatch(CmdWarOnOff, ParseCastle::WarOnOff);
|
||||
AddDispatch(CmdStatueCmd, ParseCastle::StatueCmd);
|
||||
|
||||
AddDispatch(CmdAdminCommandLog, ParseCharAdmin::AdminCommandLog);
|
||||
|
||||
AddDispatch(CmdRealmPoint, ParseCastle::RealmPoint);
|
||||
|
||||
// 듀얼 관련.
|
||||
AddDispatch(CmdSaveEnemy, ParseCharUpdate::SaveEnemy);
|
||||
|
||||
// 조이스틱 관련.
|
||||
AddDispatch(CmdKeyInfo, ParseCharUpdate::UpdateKeyInfo);
|
||||
|
||||
// 아이템 관련
|
||||
AddDispatch(CmdCharUseCashItem, ParseCharUpdate::UseCashItem);
|
||||
AddDispatch(CmdExtraEvent, ParseCharUpdate::ExtraEvent);
|
||||
}
|
||||
|
||||
|
||||
CMultiDispatch& CGameDispatch::GetDispatchTable()
|
||||
{
|
||||
static CMultiDispatch gameDispatch;
|
||||
return gameDispatch;
|
||||
}
|
||||
|
||||
|
||||
CGameDispatch::CGameDispatch(CSession& Session)
|
||||
: CRylServerDispatch(Session, MAX_PACKET_DISPATCH_PER_PULSE),
|
||||
m_nHumanNum(1),
|
||||
m_nAkhanNum(1),
|
||||
m_dwServerID(0)
|
||||
{
|
||||
|
||||
|
||||
}
|
||||
|
||||
CGameDispatch::~CGameDispatch()
|
||||
{
|
||||
|
||||
|
||||
}
|
||||
|
||||
void CGameDispatch::Connected()
|
||||
{
|
||||
DETLOG3(g_Log, "SS:0x%08x/DP:0x%08x/IP:%15s/GameServer Connected",
|
||||
&GetSession(), this, GetRemoteAddr().get_addr_string());
|
||||
}
|
||||
|
||||
void CGameDispatch::Disconnected()
|
||||
{
|
||||
DETLOG3(g_Log, "SS:0x%08x/DP:0x%08x/IP:%15s/GameServer Disconnected",
|
||||
&GetSession(), this, GetRemoteAddr().get_addr_string());
|
||||
|
||||
if(0 != m_dwServerID)
|
||||
{
|
||||
GetDispatchTable().RemoveDispatch(m_dwServerID);
|
||||
|
||||
if(0LL != m_GameItemSerialMgr.GetItemSerial())
|
||||
{
|
||||
// 아이템 시리얼 DB에 저장
|
||||
m_GameItemSerialMgr.SaveItemSerial(
|
||||
CDBSingleObject::GetInstance(), m_dwServerID);
|
||||
}
|
||||
|
||||
// 채널 정보 업데이트
|
||||
DBAgent::SendPacket::UpdateChannelAllServer();
|
||||
|
||||
// 현재 서버에 로그인된 사람을 전부 내려버린다.
|
||||
DataStorage::CSessionDataMgr::GetInstance().SessionCloseCurrentServer(m_dwServerID);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool CGameDispatch::DispatchPacket(PktBase* lpPktBase)
|
||||
{
|
||||
// 게임서버에서 DBAgent로 보내는 패킷정보
|
||||
|
||||
PktBase::CMDType cCmd =lpPktBase->GetCmd();
|
||||
|
||||
bool bResult = false;
|
||||
GameDispatchFunc lpDispatchFunc = 0;
|
||||
|
||||
|
||||
CSendStream& SendStream = GetSendStream();
|
||||
|
||||
switch(cCmd)
|
||||
{
|
||||
// 로그인 / 로그아웃 / 데이터 업데이트
|
||||
case CmdDBUpdateData:
|
||||
// 유저가 로그인하거나 로그아웃할때 여기로 메시지를 보낸다.
|
||||
// 여기서 타임DB를 업데이트 하거나 한다.
|
||||
bResult = ParseCharUpdate::Parse(SendStream, m_dwServerID,
|
||||
m_GameItemSerialMgr, static_cast<PktDBUpdate*>(lpPktBase));
|
||||
break;
|
||||
|
||||
case CmdSysServerLogin: bResult = ServerLogin(lpPktBase); break; // 서버 로그인
|
||||
case CmdSysServerLogout: bResult = ServerLogout(lpPktBase); break; // 서버 로그아웃
|
||||
case CmdUserKill: bResult = UserKillAck(lpPktBase); break; // 유저 죽이기
|
||||
case CmdCharAdminCmd: bResult = CharAdminCmd(lpPktBase); break; // 운영자 명령
|
||||
case CmdGiveItemToTempInven: bResult = GiveItemToTempInven(lpPktBase); break; // 임시인벤으로 아이템 주기
|
||||
case CmdCharNameChange: bResult = ChangeName(lpPktBase); break; // 캐릭터 이름을 바꾼다
|
||||
|
||||
default:
|
||||
|
||||
// 기타 명령(테이블에서 검색)
|
||||
lpDispatchFunc = CGameDispatchTable::GetInstance().GetDispatch(cCmd);
|
||||
if(0 != lpDispatchFunc)
|
||||
{
|
||||
bResult = lpDispatchFunc(SendStream, lpPktBase);
|
||||
}
|
||||
else
|
||||
{
|
||||
ERRLOG5(g_Log, "SS:0x%08x/DP:0x%08x/IP:%15s/Cmd:0x%02X/ServerID:0x%08X / "
|
||||
"게임서버 패킷 처리 실패 : 없는 커맨드입니다",
|
||||
&GetSession(), this, GetRemoteAddr().get_addr_string(), cCmd, m_dwServerID);
|
||||
|
||||
bResult = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if(!bResult)
|
||||
{
|
||||
ERRLOG5(g_Log, "SS:0x%08x/DP:0x%08x/IP:%15s/Cmd:0x%02X/ServerID:0x%08X / 게임서버 패킷 처리 실패 : 처리를 실패했습니다",
|
||||
&GetSession(), this, GetRemoteAddr().get_addr_string(), cCmd, m_dwServerID);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
bool CGameDispatch::ServerLogin(PktBase* lpPktBase)
|
||||
{
|
||||
PktSL* lpPktSL = static_cast<PktSL*>(lpPktBase);
|
||||
|
||||
m_dwServerID = lpPktSL->m_dwServerID;
|
||||
|
||||
INFLOG4(g_Log, "SS:0x%08x/DP:0x%08x/IP:%15s/ServerID:0x%08X/게임서버 연결 시도 : 패킷 받음",
|
||||
&GetSession(), this, GetRemoteAddr().get_addr_string(), m_dwServerID);
|
||||
|
||||
GET_MULTI_DISPATCH(lpGameDispatch, m_dwServerID,
|
||||
CGameDispatch, GetDispatchTable());
|
||||
|
||||
if(0 != lpGameDispatch)
|
||||
{
|
||||
ERRLOG4(g_Log, "SS:0x%08x/DP:0x%08x/IP:%15s/ServerID:0x%08X/게임서버 연결 실패 : 이미 연결이 있습니다. 접속을 끊습니다.",
|
||||
&GetSession(), this, GetRemoteAddr().get_addr_string(), m_dwServerID);
|
||||
|
||||
CloseSession();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Dispatch 세팅.
|
||||
GetDispatchTable().SetDispatch(m_dwServerID, this);
|
||||
|
||||
// 아이템 시리얼 로드.
|
||||
if(!m_GameItemSerialMgr.LoadItemSerial(CDBSingleObject::GetInstance(), m_dwServerID))
|
||||
{
|
||||
ERRLOG4(g_Log, "SS:0x%08x/DP:0x%08x/IP:%15s/ServerID:0x%08X/게임서버 연결 실패 : 아이템 시리얼 로드 실패. 접속을 끊습니다.",
|
||||
&GetSession(), this, GetRemoteAddr().get_addr_string(), m_dwServerID);
|
||||
|
||||
CloseSession();
|
||||
return false;
|
||||
}
|
||||
|
||||
CSendStream& SendStream = GetSendStream();
|
||||
|
||||
// 길드 정보 업데이트
|
||||
Guild::CGuildDBMgr::GetInstance().SendGuildDBList(SendStream);
|
||||
|
||||
SERVER_ID serverID;
|
||||
serverID.dwID = m_dwServerID;
|
||||
|
||||
/// 성 및 캠프, 공성병기 관련 정보 업데이트.
|
||||
Castle::CCastleDBMgr::GetInstance().SendCastleInfo(SendStream, serverID.GetZone(), serverID.GetChannel());
|
||||
CGameTimeDBMgr::GetInstance().SendGameTimeInfo(GameTime::TYPE_GAMESERVER_LOGIN, true, true, true, true, true);
|
||||
CSiegeObjectDBMgr::GetInstance().SendWorldWeaponInfo(SendStream, serverID.GetZone(), serverID.GetChannel());
|
||||
CSiegeObjectDBMgr::GetInstance().SendCampInfo(SendStream, serverID.GetZone(), serverID.GetChannel());
|
||||
CSiegeObjectDBMgr::GetInstance().SendSiegeArmsInfo(SendStream, serverID.GetZone(), serverID.GetChannel());
|
||||
|
||||
// 컨텐츠 : 다크 카나번 국가 전쟁
|
||||
if (true == CServerSetup::GetInstance().UseContents(GameRYL::STONE_BATTLE))
|
||||
{
|
||||
// 석상 정보 업데이트
|
||||
// 주의 : 성 정보가 석상 정보보다 먼저 보내져야한다.!!
|
||||
// 성에 의해 석상 인챈트 효과가 영향을 받기 때문이다.!!
|
||||
if (SERVER_ID::STONE_WAR1 <= serverID.GetZone() && serverID.GetZone() <= SERVER_ID::STONE_WAR3)
|
||||
{
|
||||
CStatueDBMgr::GetInstance().SendStatueInfo(SendStream, serverID.GetChannel());
|
||||
}
|
||||
}
|
||||
/*
|
||||
// 컨텐츠 : 신규존
|
||||
if (true == CServerSetup::GetInstance().UseContents(GameRYL::NEWZONE_ZONE9))
|
||||
{
|
||||
// 생명축출기 정보 업데이트
|
||||
// 주의 : 성 정보가 생명축출기 정보보다 먼저 보내져야한다.!!
|
||||
if (serverID.GetZone() == SERVER_ID::ZONE9)
|
||||
{
|
||||
CStatueDBMgr::GetInstance().SendStatueInfo(SendStream, serverID.GetChannel());
|
||||
}
|
||||
}
|
||||
*/
|
||||
// 지력 정보 업데이트
|
||||
CMineralVeinDBMgr::GetInstance().SendFertilityInfo(SendStream, serverID.GetZone(), serverID.GetChannel());
|
||||
|
||||
// 채널 정보 업데이트
|
||||
DBAgent::SendPacket::UpdateChannelAllServer();
|
||||
|
||||
// 랭킹 정보 업데이트
|
||||
CRankingDBMgr::GetInstance().SendRankingInfo(SendStream);
|
||||
|
||||
// 파티 정보가 있으면 보내준다 //
|
||||
CPartyDBMgr::GetInstance().SendToGameServerPartyData(SendStream);
|
||||
|
||||
// 서버 로그인 Ack보냄.
|
||||
return SendPacket::ServerLoginAck(m_SendStream,
|
||||
m_dwServerID, m_GameItemSerialMgr.GetItemSerial());
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CGameDispatch::ServerLogout(PktBase* lpPktBase)
|
||||
{
|
||||
// 받은 패킷 그대로 돌려 준다.
|
||||
|
||||
char* lpBuffer = m_SendStream.GetBuffer(sizeof(PktBase));
|
||||
if(0 != lpBuffer)
|
||||
{
|
||||
return m_SendStream.WrapHeader(sizeof(PktBase), CmdSysServerLogout, 0, 0);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool CGameDispatch::UserKillAck(PktBase* lpPktBase)
|
||||
{
|
||||
// 유저 죽이기를 실패해서, Ack로 오는 경우이다.
|
||||
|
||||
PktUK* lpPktUK = static_cast<PktUK*>(lpPktBase);
|
||||
|
||||
if(2 == lpPktUK->GetError())
|
||||
{
|
||||
using namespace DataStorage;
|
||||
|
||||
CSessionData* lpSessionData =
|
||||
CSessionDataMgr::GetInstance().GetOpenSession(lpPktUK->m_dwUserID);
|
||||
|
||||
if(0 != lpSessionData &&
|
||||
CSessionData::SE_CHAR_ENABLED == lpSessionData->GetSessionState())
|
||||
{
|
||||
if(lpSessionData->GetServerID() == lpPktUK->m_dwServerID)
|
||||
{
|
||||
CSessionDataMgr::GetInstance().SessionCloseWithLogout(
|
||||
lpPktUK->m_dwUserID, lpPktUK->m_dwServerID);
|
||||
|
||||
ERRLOG2(g_Log, "UID:%10u / ServerID:0x%08X / 게임서버 세션 강제 종료 : 유저 죽이기 실패",
|
||||
lpPktUK->m_dwUserID, lpPktUK->m_dwServerID);
|
||||
}
|
||||
else
|
||||
{
|
||||
ERRLOG3(g_Log, "UID:%10u / FromServerID:0x%08X / TargetServerID:0x%08X / "
|
||||
"게임서버 세션 강제 종료 실패 : 실패 서버와 죽이기 요청 서버가 다름",
|
||||
lpPktUK->m_dwUserID, lpPktUK->m_dwServerID, lpSessionData->GetServerID());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool CGameDispatch::CharAdminCmd(PktBase* lpPktBase)
|
||||
{
|
||||
PktAdmin* lpPktAdmin = static_cast<PktAdmin*>(lpPktBase);
|
||||
|
||||
PktAdmin pktSendAdmin;
|
||||
|
||||
// 패킷 내용을 그대로 복사.
|
||||
memcpy(&pktSendAdmin, lpPktAdmin, sizeof(PktAdmin));
|
||||
|
||||
// 중계서버 강제 종료
|
||||
/*if(lpPktAdmin->m_usCmd == PktAdmin::DBAGENT_KILL)
|
||||
{
|
||||
int nZero = 0;
|
||||
int nError = 10 / nZero;
|
||||
*reinterpret_cast<int*>(nError) = 0xFFFFFFFF;
|
||||
}*/
|
||||
|
||||
|
||||
// 추적한 위치 좌표를, 게임 서버로부터 받은 경우라면...
|
||||
if (lpPktAdmin->m_usCmd == PktAdmin::REQUEST_TRACE_POS)
|
||||
{
|
||||
// 해당 게임 서버에게만 TRACE 명령 전송
|
||||
pktSendAdmin.m_usCmd = PktAdmin::TRACE_CHAR;
|
||||
|
||||
SERVER_ID serverID;
|
||||
|
||||
serverID.sID.Type = CServerSetup::GameServer;
|
||||
serverID.sID.Group = CServerSetup::GetInstance().GetServerGroup();
|
||||
serverID.sID.Channel = lpPktAdmin->m_ZoneInfo.m_cChannel;
|
||||
serverID.sID.ID = lpPktAdmin->m_ZoneInfo.m_cZone;
|
||||
|
||||
GET_MULTI_DISPATCH(lpGameDispatch, serverID.dwID,
|
||||
CGameDispatch, CGameDispatch::GetDispatchTable());
|
||||
|
||||
if(0 != lpGameDispatch)
|
||||
{
|
||||
serverID.dwID = m_dwServerID;
|
||||
|
||||
// 게임 서버로 보낼때는 channel 이 -1 이어야 한다. -_-;
|
||||
pktSendAdmin.m_ZoneInfo.m_cZone = serverID.GetZone();
|
||||
pktSendAdmin.m_ZoneInfo.m_cChannel = -1;
|
||||
|
||||
if(PacketWrap::WrapHeader(reinterpret_cast<char*>(&pktSendAdmin),
|
||||
sizeof(PktAdmin), CmdCharAdminCmd, 0, 0))
|
||||
{
|
||||
lpGameDispatch->GetSendStream().PutBuffer(
|
||||
reinterpret_cast<char*>(&pktSendAdmin), sizeof(PktAdmin), CmdCharAdminCmd);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
else if (lpPktAdmin->m_usCmd == PktAdmin::TRACE_CHAR)
|
||||
{
|
||||
using namespace DBAgent::DataStorage;
|
||||
|
||||
// 캐릭터가 로그아웃한 상태라면
|
||||
if (false == CSessionDataMgr::GetInstance().IsLoadedChar(lpPktAdmin->m_stName))
|
||||
{
|
||||
// 해당 게임 서버에게 해당 캐릭터가 로그아웃 했다는 정보를 보낸다.
|
||||
pktSendAdmin.m_usCmd = PktAdmin::TRACE_CHAR;
|
||||
|
||||
GET_MULTI_DISPATCH(lpGameDispatch, m_dwServerID,
|
||||
CGameDispatch, CGameDispatch::GetDispatchTable());
|
||||
|
||||
if(0 != lpGameDispatch)
|
||||
{
|
||||
// 게임 서버로 보낼때는 channel 이 -1 이어야 한다. -_-;
|
||||
pktSendAdmin.m_ZoneInfo.m_cChannel = -1;
|
||||
pktSendAdmin.m_Position.fPointX = 0.0f;
|
||||
pktSendAdmin.m_Position.fPointY = 0.0f;
|
||||
pktSendAdmin.m_Position.fPointZ = 0.0f;
|
||||
|
||||
if(PacketWrap::WrapHeader(reinterpret_cast<char*>(&pktSendAdmin),
|
||||
sizeof(PktAdmin), CmdCharAdminCmd, 0, PktAdmin::E_LOGOUT_CHAR))
|
||||
{
|
||||
lpGameDispatch->GetSendStream().PutBuffer(
|
||||
reinterpret_cast<char*>(&pktSendAdmin), sizeof(PktAdmin), CmdCharAdminCmd);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
pktSendAdmin.m_usCmd = PktAdmin::REQUEST_TRACE_POS;
|
||||
|
||||
SERVER_ID serverID;
|
||||
serverID.dwID = m_dwServerID;
|
||||
|
||||
// TRACE 시켜야 할 캐릭터가 현재 있는 존의 번호를 기억해둔다.
|
||||
pktSendAdmin.m_ZoneInfo.m_cZone = serverID.GetZone();
|
||||
pktSendAdmin.m_ZoneInfo.m_cChannel = 0;
|
||||
}
|
||||
}
|
||||
/*
|
||||
else if (lpPktAdmin->m_usCmd == PktAdmin::INFO_CHAR)
|
||||
{
|
||||
using namespace DBAgent::DataStorage;
|
||||
|
||||
// 캐릭터가 로그아웃한 상태라면
|
||||
if (false == CSessionDataMgr::GetInstance().IsLoadedChar(lpPktAdmin->m_stName))
|
||||
{
|
||||
pktSendAdmin.m_usCmd = PktAdmin::INFO_CHAR;
|
||||
|
||||
GET_MULTI_DISPATCH(lpGameDispatch, m_dwServerID,
|
||||
CGameDispatch, CGameDispatch::GetDispatchTable());
|
||||
|
||||
if(0 != lpGameDispatch)
|
||||
{
|
||||
// 게임 서버로 보낼때는 channel 이 -1 이어야 한다. -_-;
|
||||
pktSendAdmin.m_ZoneInfo.m_cChannel = -1;
|
||||
pktSendAdmin.m_Position.fPointX = 0.0f;
|
||||
pktSendAdmin.m_Position.fPointY = 0.0f;
|
||||
pktSendAdmin.m_Position.fPointZ = 0.0f;
|
||||
|
||||
if (PacketWrap::WrapHeader(reinterpret_cast<char*>(&pktSendAdmin),
|
||||
sizeof(PktAdmin), CmdCharAdminCmd, 0, PktAdmin::E_LOGOUT_CHAR))
|
||||
{
|
||||
lpGameDispatch->GetSendStream().PutBuffer(
|
||||
reinterpret_cast<char*>(&pktSendAdmin), sizeof(PktAdmin), CmdCharAdminCmd);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
if(PacketWrap::WrapHeader(reinterpret_cast<char*>(&pktSendAdmin),
|
||||
sizeof(PktAdmin), CmdCharAdminCmd, 0, 0))
|
||||
{
|
||||
// 모든 게임서버로 전송.
|
||||
GetDispatchTable().Process(CSendPacketAllServer(
|
||||
reinterpret_cast<char*>(&pktSendAdmin), sizeof(PktAdmin), CmdCharAdminCmd));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool CGameDispatch::GiveItemToTempInven(PktBase* lpPktBase)
|
||||
{
|
||||
PktGiveItemToTempInven* lpPktGiveItemToTempInven =
|
||||
static_cast<PktGiveItemToTempInven*>(lpPktBase);
|
||||
|
||||
GiveItemInfo* lpPos = lpPktGiveItemToTempInven->m_GiveItemInfo;
|
||||
GiveItemInfo* lpEnd = lpPos + lpPktGiveItemToTempInven->m_cGiveItemNum;
|
||||
|
||||
CGiveItemMgr& giveItemMgr = CGiveItemMgr::GetInstance();
|
||||
|
||||
for(; lpPos != lpEnd; ++lpPos)
|
||||
{
|
||||
// 아이템 넣기에 성공했으면 아이템 시리얼을 채워서 준다. 채워서 준 시리얼을 DB에 갱신한다.
|
||||
if(0 != lpPos->m_dwItemUID)
|
||||
{
|
||||
giveItemMgr.UpdateItemSerial(
|
||||
lpPos->m_dwCreateID, lpPos->m_dwItemUID);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CGameDispatch::ChangeName(PktBase* lpPktBase)
|
||||
{
|
||||
PktCharNameChange* lpCharNameChange =
|
||||
reinterpret_cast<PktCharNameChange*>(lpPktBase);
|
||||
|
||||
unsigned long dwUID = lpCharNameChange->m_dwUID;
|
||||
unsigned long dwCID = lpCharNameChange->m_dwCID;
|
||||
const char* szChangeName = lpCharNameChange->m_szCharName;
|
||||
Item::ItemPos ItemPos = lpCharNameChange->m_ItemPos; // 계명허가서 위치
|
||||
|
||||
unsigned char cNameChangeCount = 0;
|
||||
unsigned short usError = 0;
|
||||
|
||||
using namespace DBAgent::DataStorage;
|
||||
|
||||
CSessionData* lpSessionData =
|
||||
CSessionDataMgr::GetInstance().GetCharLoadedSession(dwCID);
|
||||
|
||||
CCharacterData* lpCharacterData = 0;
|
||||
|
||||
if (0 != lpSessionData &&
|
||||
lpSessionData->GetUID() == dwUID &&
|
||||
lpSessionData->GetCID() == dwCID &&
|
||||
(0 != (lpCharacterData = lpSessionData->GetCharacterData())) &&
|
||||
dwCID == lpCharacterData->GetCID())
|
||||
{
|
||||
unsigned long dwResult = 0;
|
||||
|
||||
const char* szPrevName = lpCharacterData->GetName();
|
||||
|
||||
// 카운트를 줄인다.
|
||||
CHAR_INFOEX infoEx = lpCharacterData->GetInfoEx();
|
||||
/*
|
||||
if (0 == infoEx.cNameChangeCount)
|
||||
{
|
||||
usError = PktCharNameChange::ERR_NAMECHANGE_COUNT;
|
||||
}
|
||||
else
|
||||
*/
|
||||
// 이상이 없으면 여기서 아이템을 감소시킨다.
|
||||
if (DBComponent::GameDB::ChangeCharName(
|
||||
CDBSingleObject::GetInstance(), dwCID, szChangeName, dwResult))
|
||||
{
|
||||
if (0 == dwResult)
|
||||
{
|
||||
CHAR_INFOST charInfoST = lpCharacterData->GetInfo();
|
||||
|
||||
strncpy(charInfoST.Name, szChangeName, CHAR_INFOST::MAX_NAME_LEN);
|
||||
charInfoST.Name[CHAR_INFOST::MAX_NAME_LEN - 1] = 0;
|
||||
|
||||
lpCharacterData->SetInfo(charInfoST, true);
|
||||
|
||||
infoEx.cNameChangeCount = 0;
|
||||
// --infoEx.cNameChangeCount; // 아이템으로 바뀐후 이부분은 사용안함.
|
||||
|
||||
cNameChangeCount = infoEx.cNameChangeCount;
|
||||
lpCharacterData->SetInfoEx(infoEx);
|
||||
|
||||
// 랭킹에서 찾는다 //
|
||||
if(CRankingMgr::GetInstance().GetRank(szPrevName, (unsigned char)lpCharacterData->GetClass()))
|
||||
{
|
||||
const CHAR_INFOST& charInfo = lpCharacterData->GetInfo();
|
||||
|
||||
// 데이터 삭제 //
|
||||
CRankingDBMgr::GetInstance().DeleteRanking(RankingNode(szPrevName, charInfo.Fame,
|
||||
static_cast<unsigned char>(charInfo.Level), static_cast<unsigned char>(charInfo.Class)));
|
||||
|
||||
// 데이터 업데이트 //
|
||||
CRankingDBMgr::GetInstance().UpdateRanking(RankingNode(szChangeName, charInfo.Fame,
|
||||
static_cast<unsigned char>(charInfo.Level), static_cast<unsigned char>(charInfo.Class)));
|
||||
}
|
||||
}
|
||||
else if(1 == dwResult)
|
||||
{
|
||||
ERRLOG3(g_Log, "UID:%10u / CID:%10u / ChangeName:%s / 캐릭터 이름 바꾸기 실패 : 이름이 이미 있습니다",
|
||||
dwUID, dwCID, szChangeName);
|
||||
|
||||
usError = PktCharNameChange::ERR_ALREADY_USE_NAME;
|
||||
}
|
||||
else
|
||||
{
|
||||
ERRLOG4(g_Log, "UID:%10u / CID:%10u / ChangeName:%s / dwResult:%10u / 캐릭터 이름 바꾸기 실패 : 알 수 없는 dwResult값입니다",
|
||||
dwUID, dwCID, szChangeName, dwResult);
|
||||
|
||||
usError = PktCharNameChange::ERR_SERVER;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ERRLOG3(g_Log, "UID:%10u / CID:%10u / ChangeName:%s / 캐릭터 이름 바꾸기 실패 : DB호출 에러",
|
||||
dwUID, dwCID, szChangeName);
|
||||
|
||||
usError = PktCharNameChange::ERR_SERVER;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ERRLOG3(g_Log, "UID:%10u / CID:%10u / ChangeName:%s / "
|
||||
"캐릭터 이름 바꾸기 실패 : 캐릭터가 활성화 된 세션이 없습니다",
|
||||
dwUID, dwCID, szChangeName);
|
||||
|
||||
usError = PktCharNameChange::ERR_CANNOT_FIND_CHARACTER;
|
||||
}
|
||||
|
||||
GameClientSendPacket::SendCharNameChange(GetSendStream(), dwUID, dwCID,
|
||||
szChangeName, cNameChangeCount, &ItemPos, usError);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void CGameDispatch::IncCharNum(int nRace)
|
||||
{
|
||||
switch(nRace)
|
||||
{
|
||||
case CClass::HUMAN: ++m_nHumanNum; break;
|
||||
case CClass::AKHAN: ++m_nAkhanNum; break;
|
||||
}
|
||||
}
|
||||
|
||||
void CGameDispatch::DecCharNum(int nRace)
|
||||
{
|
||||
switch(nRace)
|
||||
{
|
||||
case CClass::HUMAN: --m_nHumanNum; break;
|
||||
case CClass::AKHAN: --m_nAkhanNum; break;
|
||||
}
|
||||
}
|
||||
|
||||
int CGameDispatch::GetCharNum(int nRace) const
|
||||
{
|
||||
int nNum = -1;
|
||||
|
||||
switch(nRace)
|
||||
{
|
||||
case CClass::HUMAN: nNum = m_nHumanNum; break;
|
||||
case CClass::AKHAN: nNum = m_nAkhanNum; break;
|
||||
}
|
||||
|
||||
return (nNum < 1) ? 1 : nNum;
|
||||
}
|
||||
|
||||
int CGameDispatch::GetCharNum() const
|
||||
{
|
||||
int nUserNumber = m_nHumanNum + m_nAkhanNum - 1;
|
||||
return (nUserNumber < 1) ? 1 : nUserNumber;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// 나중에 개수 많아지면 분리할 것..
|
||||
bool ParseServerLog(CSendStream& SendStream, PktBase* lpPktBase)
|
||||
{
|
||||
PktServerLog* lpPktServerLog = static_cast<PktServerLog*>(lpPktBase);
|
||||
|
||||
switch(lpPktServerLog->m_cLogCmd)
|
||||
{
|
||||
case PktServerLog::ITEM_DUPLICATED_LOG:
|
||||
{
|
||||
PktItemDuplicated* lpPktItemDup = static_cast<PktItemDuplicated*>(lpPktServerLog);
|
||||
|
||||
if(!DBComponent::GameDB::InsertItemDuplicatedLog(CDBSingleObject::GetInstance(),
|
||||
lpPktItemDup->m_dwItemSerial, lpPktItemDup->m_szName,
|
||||
lpPktItemDup->m_dwUID, lpPktItemDup->m_dwCID, lpPktItemDup->m_dwQty))
|
||||
{
|
||||
ERRLOG5(g_Log, "UID:%10u / CID:%10u / CharName:%s / ItemSerial:0x%I64X / Qty:%u / 아이템 복사가 발견되었습니다",
|
||||
lpPktItemDup->m_dwUID, lpPktItemDup->m_dwCID, lpPktItemDup->m_szName,
|
||||
lpPktItemDup->m_dwItemSerial, lpPktItemDup->m_dwQty);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// -----------------------------------------------------------------------------------
|
||||
// 각종 함수자 메서드
|
||||
|
||||
CGetTotalCount::CGetTotalCount(unsigned short& usHumanCount,
|
||||
unsigned short& usAkhanCount,
|
||||
unsigned char& cChannelCount)
|
||||
: m_usHumanCount(usHumanCount),
|
||||
m_usAkhanCount(usAkhanCount),
|
||||
m_cChannelCount(cChannelCount)
|
||||
{
|
||||
m_usHumanCount = 0;
|
||||
m_usAkhanCount = 0;
|
||||
m_cChannelCount = 0;
|
||||
}
|
||||
|
||||
bool CGetTotalCount::operator () (unsigned long dwServerID, CPacketDispatch& packetDispatch)
|
||||
{
|
||||
CGameDispatch& gameDispatch = reinterpret_cast<CGameDispatch&>(packetDispatch);
|
||||
|
||||
int nCharNum = gameDispatch.GetCharNum(CClass::HUMAN);
|
||||
m_usHumanCount += nCharNum;
|
||||
|
||||
nCharNum = gameDispatch.GetCharNum(CClass::AKHAN);
|
||||
m_usAkhanCount += nCharNum;
|
||||
|
||||
++m_cChannelCount;
|
||||
return true;
|
||||
}
|
||||
|
||||
CUserPercentageInZone::CUserPercentageInZone(unsigned short* lpChannelUserNum,
|
||||
unsigned char cZone, unsigned char cChannelNum)
|
||||
: m_lpChannelUserNum(lpChannelUserNum),
|
||||
m_cZone(cZone),
|
||||
m_cChannelNum(cChannelNum),
|
||||
m_nMaxUserNum(CServerSetup::GetInstance().GetUserLimit())
|
||||
{
|
||||
std::fill_n(m_lpChannelUserNum, m_cChannelNum, 0);
|
||||
}
|
||||
|
||||
bool CUserPercentageInZone::operator () (unsigned long dwServerID, CPacketDispatch& packetDispatch)
|
||||
{
|
||||
CGameDispatch& gameDispatch = reinterpret_cast<CGameDispatch&>(packetDispatch);
|
||||
|
||||
SERVER_ID serverID;
|
||||
serverID.dwID = dwServerID;
|
||||
|
||||
if(serverID.GetZone() == m_cZone)
|
||||
{
|
||||
if(serverID.GetChannel() < m_cChannelNum)
|
||||
{
|
||||
m_lpChannelUserNum[serverID.GetChannel()] =
|
||||
gameDispatch.GetCharNum() * 100 / m_nMaxUserNum + 1;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
CSendPacketToZone::CSendPacketToZone(const char* szData, unsigned long dwDataLen,
|
||||
unsigned char cPacketCmd, unsigned char cZone)
|
||||
: m_szData(szData), m_dwDataLen(dwDataLen),
|
||||
m_cPacketCmd(cPacketCmd), m_cZone(cZone)
|
||||
{
|
||||
|
||||
|
||||
}
|
||||
|
||||
bool CSendPacketToZone::operator () (unsigned long dwServerID, CPacketDispatch& packetDispatch)
|
||||
{
|
||||
SERVER_ID serverID;
|
||||
serverID.dwID = dwServerID;
|
||||
|
||||
if(serverID.GetZone() == m_cZone)
|
||||
{
|
||||
return reinterpret_cast<CRylServerDispatch&>(packetDispatch).GetSendStream().PutBuffer(
|
||||
m_szData, m_dwDataLen, m_cPacketCmd);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,118 @@
|
||||
#ifndef _DBAGENT_SERVER_GAME_DISPATCH_H_
|
||||
#define _DBAGENT_SERVER_GAME_DISPATCH_H_
|
||||
|
||||
#include <Network/Dispatch/RylServerDispatch.h>
|
||||
#include <Network/Dispatch/MultiDispatchStorage.h>
|
||||
|
||||
#include <Item/ItemSerialMgr.h>
|
||||
|
||||
// forward decl.
|
||||
struct PktSL;
|
||||
struct PktBase;
|
||||
struct PktUK;
|
||||
struct PktAdmin;
|
||||
|
||||
namespace DBAgent
|
||||
{
|
||||
class CGameDispatch : public CRylServerDispatch
|
||||
{
|
||||
public:
|
||||
|
||||
static CMultiDispatch& GetDispatchTable();
|
||||
|
||||
enum Const
|
||||
{
|
||||
// edith 2008.03.04 CGameDispatch 수정
|
||||
MAX_PACKET_DISPATCH_PER_PULSE = 100,
|
||||
MAX_STREAM_BUFFER_SIZE = 16000
|
||||
};
|
||||
|
||||
CGameDispatch(CSession& Session);
|
||||
virtual ~CGameDispatch();
|
||||
|
||||
virtual void Connected();
|
||||
virtual void Disconnected();
|
||||
virtual bool DispatchPacket(PktBase* lpPktBase);
|
||||
|
||||
void IncCharNum(int nRace);
|
||||
void DecCharNum(int nRace);
|
||||
|
||||
int GetCharNum(int nRace) const; // 항상 실 인원수보다 한명이 많다.
|
||||
int GetCharNum() const; // 항상 실 인원수보다 한명이 많다.
|
||||
|
||||
unsigned long GetServerID() const { return m_dwServerID; }
|
||||
|
||||
private:
|
||||
|
||||
bool ServerLogin(PktBase* lpPktBase);
|
||||
bool ServerLogout(PktBase* lpPktBase);
|
||||
|
||||
bool UserKillAck(PktBase* lpPktBase);
|
||||
bool CharAdminCmd(PktBase* lpPktBase);
|
||||
bool GiveItemToTempInven(PktBase* lpPktBase);
|
||||
bool ChangeName(PktBase* lpPktBase);
|
||||
|
||||
Item::CItemSerialMgr m_GameItemSerialMgr;
|
||||
|
||||
// 인원수는 항상 한명이 많게 관리하고, 보여줄때만 1씩 빼서 보여준다.
|
||||
// 그 이유는 채널의 존재 여부를 인원수가 0인지 아닌지로 파악하기 때문이다.
|
||||
int m_nHumanNum;
|
||||
int m_nAkhanNum;
|
||||
|
||||
unsigned long m_dwServerID;
|
||||
};
|
||||
|
||||
|
||||
// 전체 캐릭터 수를 얻어오는 함수자이다. CMultiDispatch::Process 에 사용한다.
|
||||
class CGetTotalCount
|
||||
{
|
||||
public:
|
||||
|
||||
CGetTotalCount(unsigned short& usHumanCount, unsigned short& usAkhanCount,
|
||||
unsigned char& cChannelCount);
|
||||
bool operator () (unsigned long dwServerID, CPacketDispatch& packetDispatch);
|
||||
|
||||
private:
|
||||
|
||||
unsigned short& m_usHumanCount;
|
||||
unsigned short& m_usAkhanCount;
|
||||
unsigned char& m_cChannelCount;
|
||||
};
|
||||
|
||||
// 존당 캐릭터 수 퍼센티지를 얻어오는 함수자이다. CMultiDispatch::Process 에 사용한다.
|
||||
class CUserPercentageInZone
|
||||
{
|
||||
public:
|
||||
|
||||
CUserPercentageInZone(unsigned short* lpChannelUserNum,
|
||||
unsigned char cZone, unsigned char cChannelNum);
|
||||
bool operator () (unsigned long dwServerID, CPacketDispatch& packetDispatch);
|
||||
|
||||
private:
|
||||
|
||||
int m_nMaxUserNum;
|
||||
unsigned short* m_lpChannelUserNum;
|
||||
unsigned char m_cZone;
|
||||
unsigned char m_cChannelNum;
|
||||
};
|
||||
|
||||
// 특정 존의 모든 채널에 패킷을 보낸다.
|
||||
class CSendPacketToZone
|
||||
{
|
||||
public:
|
||||
|
||||
CSendPacketToZone(const char* szData, unsigned long dwDataLen,
|
||||
unsigned char cPacketCmd, unsigned char cZone);
|
||||
bool operator () (unsigned long dwServerID, CPacketDispatch& packetDispatch);
|
||||
|
||||
private:
|
||||
|
||||
const char* m_szData;
|
||||
unsigned long m_dwDataLen;
|
||||
unsigned char m_cPacketCmd;
|
||||
unsigned char m_cZone;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,64 @@
|
||||
#include "stdafx.h"
|
||||
#include "LoginDispatch.h"
|
||||
|
||||
#include <Log/ServerLog.h>
|
||||
#include <Network/Address/INET_Addr.h>
|
||||
#include <Network/SendPacket/SendServerInfo.h>
|
||||
|
||||
#include <Utility/Setup/ServerSetup.h>
|
||||
|
||||
namespace DBAgent
|
||||
{
|
||||
|
||||
CSingleDispatch& CLoginDispatch::GetDispatchTable()
|
||||
{
|
||||
static CSingleDispatch loginDispatch;
|
||||
return loginDispatch;
|
||||
}
|
||||
|
||||
CLoginDispatch::CLoginDispatch(CSession& Session)
|
||||
: CRylServerDispatch(Session, MAX_PACKET_DISPATCH_PER_PULSE)
|
||||
{
|
||||
|
||||
|
||||
}
|
||||
|
||||
CLoginDispatch::~CLoginDispatch()
|
||||
{
|
||||
|
||||
|
||||
}
|
||||
|
||||
void CLoginDispatch::Connected()
|
||||
{
|
||||
DETLOG3(g_Log, "SS:0x%08x/DP:0x%08x/IP:%15s/LoginServer Connected",
|
||||
&GetSession(), this, GetRemoteAddr().get_addr_string());
|
||||
|
||||
GetDispatchTable().SetDispatch(this);
|
||||
|
||||
CSendStream& SendStream = GetSendStream();
|
||||
unsigned long dwServerID = CServerSetup::GetInstance().GetServerID();
|
||||
|
||||
SendPacket::ServerLogin(SendStream, dwServerID);
|
||||
SendPacket::UpdateServerVersion(SendStream);
|
||||
SendPacket::UpdateChannel(SendStream, dwServerID);
|
||||
}
|
||||
|
||||
void CLoginDispatch::Disconnected()
|
||||
{
|
||||
DETLOG3(g_Log, "SS:0x%08x/DP:0x%08x/IP:%15s/LoginServer Disconnected",
|
||||
&GetSession(), this, GetRemoteAddr().get_addr_string());
|
||||
|
||||
GetDispatchTable().RemoveDispatch(this);
|
||||
}
|
||||
|
||||
bool CLoginDispatch::DispatchPacket(PktBase* lpPktBase)
|
||||
{
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
#ifndef _DBAGENT_SERVER_LOGIN_DISPATCH_H_
|
||||
#define _DBAGENT_SERVER_LOGIN_DISPATCH_H_
|
||||
|
||||
#include <Network/Dispatch/RylServerDispatch.h>
|
||||
#include <Network/Dispatch/SingleDispatchStorage.h>
|
||||
|
||||
namespace DBAgent
|
||||
{
|
||||
class CLoginDispatch : public CRylServerDispatch
|
||||
{
|
||||
public:
|
||||
|
||||
static CSingleDispatch& GetDispatchTable();
|
||||
|
||||
enum Const
|
||||
{
|
||||
MAX_PACKET_DISPATCH_PER_PULSE = 10,
|
||||
MAX_STREAM_BUFFER_SIZE = 16000
|
||||
};
|
||||
|
||||
CLoginDispatch(CSession& Session);
|
||||
virtual ~CLoginDispatch();
|
||||
|
||||
virtual void Connected();
|
||||
virtual void Disconnected();
|
||||
virtual bool DispatchPacket(PktBase* lpPktBase);
|
||||
|
||||
private:
|
||||
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,623 @@
|
||||
#include "stdafx.h"
|
||||
#include "AuthDispatch.h"
|
||||
#include "Part1DBAgentDispatch.h"
|
||||
|
||||
#include <Log/ServerLog.h>
|
||||
#include <Network/Address/INET_Addr.h>
|
||||
#include <Network/SendPacket/SendServerInfo.h>
|
||||
#include <Network/SendPacket/SendCharManage.h>
|
||||
|
||||
#include <Network/Packet/PacketCommand.h>
|
||||
#include <Network/Packet/PacketStruct/UnifiedCharPacket.h>
|
||||
|
||||
#include <Utility/Setup/ServerSetup.h>
|
||||
|
||||
#include <DataStorage/SessionDataMgr.h>
|
||||
#include <DataStorage/StoreDataMgr.h>
|
||||
#include <DataStorage/CharacterDataMgr.h>
|
||||
|
||||
#include <Creature/Creature.h>
|
||||
#include <Creature/Character/CharacterClass.h>
|
||||
|
||||
#include <DB/DBComponent.h>
|
||||
#include <DB/GameDBComponent.h>
|
||||
|
||||
#include <Network/Packet/PacketStruct/CharQuestPacket.h>
|
||||
|
||||
namespace DBAgent
|
||||
{
|
||||
|
||||
class CCharBackupItemData
|
||||
{
|
||||
public:
|
||||
|
||||
CCharBackupItemData()
|
||||
: m_bBackupData(false), m_cOldServerGroupID(0)
|
||||
{
|
||||
memset(&m_CharInfo, 0, sizeof(CHAR_INFOST)); // 기본 정보
|
||||
memset(&m_Skill, 0, sizeof(SKILL)); // 스킬 정보
|
||||
|
||||
memset(&m_Equip, 0, sizeof(EQUIP)); // 장비
|
||||
memset(&m_Inven, 0, sizeof(INVEN)); // 인벤
|
||||
memset(&m_Extra, 0, sizeof(EXTRA)); // 여분
|
||||
memset(&m_Exchange, 0, sizeof(EXCHANGE)); // 교환
|
||||
memset(&m_TempInven, 0, sizeof(TEMPINVEN)); // 임시 인벤토리
|
||||
|
||||
memset(&m_Quest, 0, sizeof(QUEST)); // 퀘스트
|
||||
memset(&m_History, 0, sizeof(HISTORY)); // 히스토리
|
||||
}
|
||||
|
||||
bool IsBackupedData() const { return m_bBackupData; }
|
||||
unsigned char GetOldServerGroupID() const { return m_cOldServerGroupID; }
|
||||
|
||||
void BackupData(DataStorage::CSessionData& sessionData, DataStorage::CCharacterData& charData)
|
||||
{
|
||||
m_CharInfo = charData.GetInfo();
|
||||
m_Skill = charData.GetSkill();
|
||||
m_Equip = charData.GetEquip();
|
||||
m_Inven = charData.GetInven();
|
||||
m_Extra = charData.GetExtra();
|
||||
m_Exchange = charData.GetExchange();
|
||||
m_TempInven = charData.GetTempInven();
|
||||
|
||||
m_Quest = charData.GetQuest();
|
||||
m_History = charData.GetHistory();
|
||||
|
||||
const UnifiedCharData* lpUnifiedCharData =
|
||||
sessionData.GetUnifiedCharData(charData.GetCID());
|
||||
|
||||
if(0 != lpUnifiedCharData)
|
||||
{
|
||||
m_cOldServerGroupID = lpUnifiedCharData->cOldServerGroupID;
|
||||
}
|
||||
|
||||
m_bBackupData = true;
|
||||
}
|
||||
|
||||
void RestoreData(DataStorage::CCharacterData& charData)
|
||||
{
|
||||
if (m_bBackupData)
|
||||
{
|
||||
charData.SetInfo(m_CharInfo);
|
||||
charData.SetSkill(m_Skill);
|
||||
charData.SetEquip(m_Equip.Data, m_Equip.dwSize);
|
||||
charData.SetInven(m_Inven.Data, m_Inven.dwSize);
|
||||
charData.SetExtra(m_Extra.Data, m_Extra.dwSize);
|
||||
charData.SetExchange(m_Exchange.Data, m_Exchange.dwSize);
|
||||
charData.SetTempInven(m_TempInven.Data, m_TempInven.dwSize);
|
||||
|
||||
charData.SetQuest(m_Quest);
|
||||
charData.SetHistory(m_History);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
CHAR_INFOST m_CharInfo; // 기본 정보
|
||||
SKILL m_Skill; // 스킬 정보
|
||||
|
||||
EQUIP m_Equip; // 장비
|
||||
INVEN m_Inven; // 인벤
|
||||
EXTRA m_Extra; // 여분
|
||||
EXCHANGE m_Exchange; // 교환
|
||||
TEMPINVEN m_TempInven; // 임시 인벤토리
|
||||
|
||||
QUEST m_Quest; // 퀘스트
|
||||
HISTORY m_History; // History
|
||||
|
||||
unsigned char m_cOldServerGroupID; // 예전 서버그룹 ID
|
||||
bool m_bBackupData; // 데이터 백업되었는지 여부
|
||||
|
||||
};
|
||||
|
||||
void ProcessUnifiedCharSelect(CSendStream& SendStream, PktBase* lpPktBase);
|
||||
|
||||
|
||||
CSingleDispatch& CPart1DBAgentDispatch::GetDispatchTable()
|
||||
{
|
||||
static CSingleDispatch part1DBAgentDispatch;
|
||||
return part1DBAgentDispatch;
|
||||
}
|
||||
|
||||
CPart1DBAgentDispatch::CPart1DBAgentDispatch(CSession& Session)
|
||||
: CRylServerDispatch(Session, MAX_PACKET_DISPATCH_PER_PULSE)
|
||||
{
|
||||
|
||||
|
||||
}
|
||||
|
||||
CPart1DBAgentDispatch::~CPart1DBAgentDispatch()
|
||||
{
|
||||
|
||||
|
||||
}
|
||||
|
||||
void CPart1DBAgentDispatch::Connected()
|
||||
{
|
||||
DETLOG3(g_Log, "SS:0x%08x/DP:0x%08x/IP:%15s/Part1 DBAgentServer Connected",
|
||||
&GetSession(), this, GetRemoteAddr().get_addr_string());
|
||||
|
||||
GetDispatchTable().SetDispatch(this);
|
||||
|
||||
SendPacket::ServerLogin(GetSendStream(),
|
||||
CServerSetup::GetInstance().GetServerID());
|
||||
}
|
||||
|
||||
|
||||
void CPart1DBAgentDispatch::Disconnected()
|
||||
{
|
||||
DETLOG3(g_Log, "SS:0x%08x/DP:0x%08x/IP:%15s/Part1 DBAgentServer Disconnected",
|
||||
&GetSession(), this, GetRemoteAddr().get_addr_string());
|
||||
|
||||
GetDispatchTable().RemoveDispatch(this);
|
||||
}
|
||||
|
||||
|
||||
bool CPart1DBAgentDispatch::DispatchPacket(PktBase* lpPktBase)
|
||||
{
|
||||
switch(lpPktBase->GetCmd())
|
||||
{
|
||||
case CmdUnifiedCharSelect:
|
||||
ProcessUnifiedCharSelect(GetSendStream(), lpPktBase);
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CPart1DBAgentDispatch::TransferCharPart1ToPart2(CSendStream& SendStream, unsigned long dwUID,
|
||||
unsigned char cSelectedServerGroup,
|
||||
unsigned char cSelectedNation,
|
||||
unsigned long* lpdwSelectedCID,
|
||||
unsigned char cSelectedCharNum)
|
||||
{
|
||||
char* lpBuffer = SendStream.GetBuffer(sizeof(PktUnifiedCharSelectReq));
|
||||
|
||||
if(0 != lpBuffer)
|
||||
{
|
||||
PktUnifiedCharSelectReq* lpPktUnifiedCharSelectReq =
|
||||
reinterpret_cast<PktUnifiedCharSelectReq*>(lpBuffer);
|
||||
|
||||
memset(lpPktUnifiedCharSelectReq->szPassword, 0,
|
||||
sizeof(char) * PktUnifiedCharSelectReq::MAX_PASSWORD_LEN);
|
||||
|
||||
lpPktUnifiedCharSelectReq->cSelectedNation = cSelectedNation;
|
||||
lpPktUnifiedCharSelectReq->cSelectedServerGroupID = cSelectedServerGroup;
|
||||
lpPktUnifiedCharSelectReq->dwRequestKey = 0;
|
||||
|
||||
lpPktUnifiedCharSelectReq->dwUID = dwUID;
|
||||
memcpy(lpPktUnifiedCharSelectReq->dwCID, lpdwSelectedCID,
|
||||
sizeof(unsigned long) * std::min(int(cSelectedCharNum), int(USER_INFO::MAX_CHAR_NUM)));
|
||||
|
||||
return SendStream.WrapHeader(sizeof(PktUnifiedCharSelectReq), CmdUnifiedCharSelect, 0, 0);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void ProcessUnifiedCharSelect(CSendStream& SendStream, PktBase* lpPktBase)
|
||||
{
|
||||
PktUnifiedCharSelectReq* lpPktUnifiedCharSelectReq =
|
||||
reinterpret_cast<PktUnifiedCharSelectReq*>(lpPktBase);
|
||||
|
||||
unsigned long dwUID = lpPktUnifiedCharSelectReq->dwUID;
|
||||
unsigned long dwRequestKey = lpPktUnifiedCharSelectReq->dwRequestKey;
|
||||
unsigned char cSelectedServerGroupID = lpPktUnifiedCharSelectReq->cSelectedServerGroupID;
|
||||
unsigned char cSelectedNation = lpPktUnifiedCharSelectReq->cSelectedNation;
|
||||
|
||||
unsigned short usError = 0;
|
||||
|
||||
using namespace DBAgent::DataStorage;
|
||||
|
||||
unsigned char cAgentServerType = static_cast<unsigned char>(
|
||||
CServerSetup::GetInstance().GetAgentServerType());
|
||||
|
||||
CStoreDataMgr& storeDataMgr = CStoreDataMgr::GetInstance();
|
||||
CCharacterDataMgr& charDataMgr = CCharacterDataMgr::GetInstance();
|
||||
CDBComponent& dbComponent = CDBSingleObject::GetInstance();
|
||||
|
||||
UnifiedStoreKey srcStoreKey(dwUID, cSelectedServerGroupID);
|
||||
UnifiedStoreKey dstStoreKey(dwUID, cAgentServerType);
|
||||
|
||||
CSessionData* lpSessionData = 0;
|
||||
CStoreData* lpStoreData = 0;
|
||||
CCharacterData* lpCharacterData = 0;
|
||||
|
||||
if(0 != lpPktBase->GetError())
|
||||
{
|
||||
// 해당 UID가 없다.
|
||||
ERRLOG2(g_Log, "UID:%10u / Part2Unified 캐릭터 선택 실패 - Part1 DB중계서버에서 %d에러를 전송했습니다.",
|
||||
dwUID, lpPktBase->GetError());
|
||||
|
||||
usError = lpPktBase->GetError();
|
||||
}
|
||||
else if(0 == (lpSessionData = CSessionDataMgr::GetInstance().GetOpenSession(dwUID)))
|
||||
{
|
||||
// 해당 UID가 없다.
|
||||
ERRLOG1(g_Log, "UID:%10u / Part2Unified 캐릭터 선택 실패 - 세션이 닫혀 있습니다", dwUID);
|
||||
|
||||
usError = PktUnifiedCharSelectAck::SERVER_ERROR;
|
||||
}
|
||||
else
|
||||
{
|
||||
// 창고 선택한 적 없음
|
||||
if (!(lpSessionData->GetFirstLogin() & UnifiedConst::SELECTED_PART2))
|
||||
{
|
||||
// 혹시 캐쉬나 loginDB에 데이터가 들어있는지 살핀다. 있으면 전부 제거한다.
|
||||
if(storeDataMgr.IsDataLoginDB(srcStoreKey))
|
||||
{
|
||||
ERRLOG2(g_Log, "UID:%10u / SrcServerGroupID:%d / Part2Unified 창고 선택 실패 - 해당 창고가 로그인해 있습니다.",
|
||||
srcStoreKey.first, srcStoreKey.second);
|
||||
|
||||
usError = PktUnifiedCharSelectAck::SERVER_ERROR;
|
||||
}
|
||||
else if(storeDataMgr.IsDataLoginDB(dstStoreKey))
|
||||
{
|
||||
ERRLOG2(g_Log, "UID:%10u / DstServerGroupID:%d / Part2Unified 창고 선택 실패 - 해당 창고가 로그인해 있습니다.",
|
||||
dstStoreKey.first, dstStoreKey.second);
|
||||
|
||||
usError = PktUnifiedCharSelectAck::SERVER_ERROR;
|
||||
}
|
||||
else
|
||||
{
|
||||
// 일단 캐쉬에서 데이터를 내린다.
|
||||
if(storeDataMgr.RemoveLogoutData(srcStoreKey))
|
||||
{
|
||||
ERRLOG2(g_Log, "UID:%10u / SrcServerGroupID:%d / "
|
||||
"Part2Unified 창고 선택 이상 - 해당 데이터가 캐쉬에 들어 있어 강제로 내립니다.",
|
||||
srcStoreKey.first, srcStoreKey.second);
|
||||
}
|
||||
|
||||
if(storeDataMgr.RemoveLogoutData(dstStoreKey))
|
||||
{
|
||||
ERRLOG2(g_Log, "UID:%10u / DstServerGroupID:%d / "
|
||||
"Part2Unified 창고 선택 이상 - 해당 데이터가 캐쉬에 들어 있어 강제로 내립니다.",
|
||||
dstStoreKey.first, dstStoreKey.second);
|
||||
}
|
||||
|
||||
// 선택한 서버군 창고를 내 서버그룹 창고로 복사한다!
|
||||
if (!lpSessionData->ChangeUnifiedStoreInfoGroup(
|
||||
dbComponent, cSelectedServerGroupID, cAgentServerType))
|
||||
{
|
||||
usError = PktUnifiedCharSelectAck::UNIFIED_STORE_READ_ERROR;
|
||||
}
|
||||
// 복사 잘 됐으면 캐쉬로 로드해서 컨버팅을 한다.
|
||||
else
|
||||
{
|
||||
if(0 == (lpStoreData = storeDataMgr.GetLogoutData(dstStoreKey)))
|
||||
{
|
||||
ERRLOG2(g_Log, "UID:%10u / ServerGroupID:%d / 통합서버 선택 실패 : 창고 캐쉬로 데이터 로드 실패",
|
||||
dwUID, cSelectedServerGroupID);
|
||||
|
||||
usError = PktUnifiedCharSelectAck::UNIFIED_STORE_READ_ERROR;
|
||||
}
|
||||
// 창고 데이터를 Part2아이템으로 컨버팅한다.
|
||||
else if (!lpStoreData->ConvertToPart2Item(true))
|
||||
{
|
||||
ERRLOG2(g_Log, "UID:%10u / ServerGroupID:%d / 통합서버 선택 실패 : 창고 파트2 아이템으로 아이템 컨버팅 실패",
|
||||
dwUID, cSelectedServerGroupID);
|
||||
|
||||
usError = PktUnifiedCharSelectAck::UNIFIED_STORE_WRITE_ERROR;
|
||||
}
|
||||
// 창고 데이터를 저장한다.
|
||||
else if(!lpStoreData->ForceUpdateDBAllData(dbComponent))
|
||||
{
|
||||
ERRLOG2(g_Log, "UID:%10u / ServerGroupID:%d / 통합서버 선택 실패 : 컨버팅된 창고 데이터를 저장 실패",
|
||||
dwUID, cSelectedServerGroupID);
|
||||
|
||||
usError = PktUnifiedCharSelectAck::UNIFIED_STORE_WRITE_ERROR;
|
||||
}
|
||||
else if(!DBComponent::GameDB::UpdateUserFirstLogin(dbComponent, dwUID,
|
||||
lpSessionData->GetFirstLogin() | UnifiedConst::SELECTED_PART2))
|
||||
{
|
||||
ERRLOG2(g_Log, "UID:%10u / ServerGroupID:%d / 통합서버 선택 실패 : 창고 가져왔음을 기록 실패",
|
||||
dwUID, cSelectedServerGroupID);
|
||||
}
|
||||
|
||||
if(0 != usError)
|
||||
{
|
||||
// 에러가 난 건 창고 데이터를 저장을 못 했기 때문이니,
|
||||
// 그냥 캐쉬에서 날리고 다시 세팅하면 된다.
|
||||
storeDataMgr.RemoveLogoutData(dstStoreKey);
|
||||
|
||||
if(!lpSessionData->ChangeUnifiedStoreInfoGroup(
|
||||
dbComponent, cAgentServerType, cSelectedServerGroupID))
|
||||
{
|
||||
ERRLOG3(g_Log, "UID:%10u / ServerGroupID:%d -> %d / 통합서버 선택 실패 : 창고 데이터 롤백 실패",
|
||||
dwUID, cAgentServerType, cSelectedServerGroupID);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
lpSessionData->SetFirstLogin(
|
||||
lpSessionData->GetFirstLogin() | UnifiedConst::SELECTED_PART2);
|
||||
|
||||
INFLOG2(g_Log, "UID:%10u / ServerGroupID:%d / 통합서버 선택 성공",
|
||||
dwUID, cSelectedServerGroupID);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 캐릭터 선택 쪽을 처리한다.
|
||||
|
||||
// 1. 캐릭터를 받으면, 일단 UserInfo를 로드한 후에,
|
||||
// 올바른 슬롯에 넣은 중복되지 않는 캐릭터를 찾는다.
|
||||
|
||||
// 2. 정리가 끝나면 Part1 DB중계서버에, 해당 캐릭터를 캐쉬에서 언로드하고
|
||||
// 길드 / 파티를 탈퇴시키라고 요청한다.
|
||||
|
||||
// 3. 요청 결과가 성공으로 돌아오면, 해당 캐릭터를 DB에서 로드하고
|
||||
// 데이터를 컨버팅 한 후에 저장한다. 컨버팅이나 저장이 실패하면 데이터를 롤백한다.
|
||||
|
||||
// 4. 모든 작업이 무사히 끝나면, DB의 UserInfo를 갱신한다.
|
||||
|
||||
CClass::RaceType eRace =
|
||||
lpSessionData->CheckUnifiedCharRace(lpPktUnifiedCharSelectReq->dwCID);
|
||||
|
||||
USER_INFO userInfo = lpSessionData->GetUserInfo();
|
||||
|
||||
// 유저 바인딩 검사를 한번 더 한다.
|
||||
unsigned long dwSelectedCID[USER_INFO::MAX_CHAR_NUM];
|
||||
unsigned long* lpdwRequestedCID = lpPktUnifiedCharSelectReq->dwCID;
|
||||
|
||||
int nSelectedCount = 0;
|
||||
|
||||
std::fill_n(dwSelectedCID, size_t(USER_INFO::MAX_CHAR_NUM), 0);
|
||||
|
||||
// 데이터를 제대로 얻어 왔다.
|
||||
// 현재 바인딩 된 캐릭터인지 아닌지 판단한다.
|
||||
unsigned char cRestrictedPart1ToPart2Level =
|
||||
CServerSetup::GetInstance().GetRestrictedPart1ToPart2Level();
|
||||
|
||||
for(int nCount = 0; nCount < USER_INFO::MAX_CHAR_NUM; ++nCount)
|
||||
{
|
||||
unsigned long dwBindCID = lpdwRequestedCID[nCount];
|
||||
const UnifiedCharData* lpUnifiedCharData = 0;
|
||||
|
||||
if (0 == userInfo.CharID[nCount] &&
|
||||
0 != dwBindCID && !userInfo.HasCharacter(dwBindCID) &&
|
||||
0 != (lpUnifiedCharData = lpSessionData->GetUnifiedCharData(dwBindCID)) &&
|
||||
(lpUnifiedCharData->cOldServerGroupID < UnifiedConst::Part1 ||
|
||||
(lpUnifiedCharData->cOldServerGroupID == UnifiedConst::Part1Unified &&
|
||||
cRestrictedPart1ToPart2Level <= lpUnifiedCharData->cLevel)))
|
||||
{
|
||||
dwSelectedCID[nCount] = dwBindCID;
|
||||
++nSelectedCount;
|
||||
}
|
||||
}
|
||||
|
||||
if (0 < nSelectedCount && CClass::MAX_RACE == eRace)
|
||||
{
|
||||
usError = PktUnifiedCharSelectAck::PACKET_ERROR;
|
||||
}
|
||||
else if(0 == usError)
|
||||
{
|
||||
// 한바퀴 돌면서 아이템 컨버팅 / 스킬북 컨버팅 등을 수행한다.
|
||||
CCharBackupItemData backupData[USER_INFO::MAX_CHAR_NUM];
|
||||
|
||||
for(int nCount = 0; nCount < USER_INFO::MAX_CHAR_NUM; ++nCount)
|
||||
{
|
||||
if(0 != dwSelectedCID[nCount])
|
||||
{
|
||||
if(0 == (lpCharacterData = charDataMgr.GetLogoutData(dwSelectedCID[nCount])))
|
||||
{
|
||||
ERRLOG3(g_Log, "UID:%10u / CID:%10u / ServerGroupID:%d / 통합서버 선택 실패 : 캐릭터 캐쉬로 데이터 로드 실패",
|
||||
dwUID, dwSelectedCID[nCount], cSelectedServerGroupID);
|
||||
|
||||
usError = PktUnifiedCharSelectAck::UNIFIED_CHAR_READ_ERROR;
|
||||
}
|
||||
else
|
||||
{
|
||||
// 데이터를 백업한다.
|
||||
backupData[nCount].BackupData(*lpSessionData, *lpCharacterData);
|
||||
|
||||
// Part2 아이템으로 컨버팅한다.
|
||||
if (!lpCharacterData->ConvertToPart2Item(true))
|
||||
{
|
||||
ERRLOG3(g_Log, "UID:%10u / CID:%10u / ServerGroupID:%d / 통합서버 선택 실패 : 캐릭터 Part2아이템으로 컨버팅 실패",
|
||||
dwUID, dwSelectedCID[nCount], cSelectedServerGroupID);
|
||||
|
||||
usError = PktUnifiedCharSelectAck::UNIFIED_CHAR_WRITE_ERROR;
|
||||
}
|
||||
// UnifiedCharInfo에서, 캐릭터 서버군 번호를 수정한다.
|
||||
else if (!lpSessionData->ChangeUnifiedCharServerGroupID(
|
||||
dbComponent, dwUID, dwSelectedCID[nCount], cAgentServerType))
|
||||
{
|
||||
usError = PktUnifiedCharSelectAck::UNIFIED_CHAR_WRITE_ERROR;
|
||||
}
|
||||
else if (!lpCharacterData->ForceUpdateDBAllData(dbComponent))
|
||||
{
|
||||
ERRLOG3(g_Log, "UID:%10u / CID:%10u / ServerGroupID:%d / 통합서버 선택 실패 : 캐릭터 아이템 저장 실패",
|
||||
dwUID, dwSelectedCID[nCount], cSelectedServerGroupID);
|
||||
|
||||
usError = PktUnifiedCharSelectAck::UNIFIED_CHAR_WRITE_ERROR;
|
||||
}
|
||||
|
||||
if(0 != usError)
|
||||
{
|
||||
// 에러가 있으면 바로 롤백;;
|
||||
break;
|
||||
}
|
||||
|
||||
// 양국체제로 변경 //
|
||||
if(lpSessionData->GetAccountNation()==Creature::ALMIGHTY_PIRATE)
|
||||
{
|
||||
/* 국적이 신의 해적단이면서, 종족이 휴먼인 사람들의 국적을 카르테란트로 바꿔준다. */
|
||||
if(lpCharacterData->GetRace()==CClass::HUMAN)
|
||||
{
|
||||
lpSessionData->SetAccountNation(Creature::KARTERANT);
|
||||
}
|
||||
/* 국적이 신의 해적단이면서, 종족이 아칸인 사람들의 국적을 메르카디아로 바꿔준다. */
|
||||
else if(lpCharacterData->GetRace()==CClass::AKHAN)
|
||||
{
|
||||
lpSessionData->SetAccountNation(Creature::MERKADIA);
|
||||
}
|
||||
}
|
||||
|
||||
// 친구리스트, 거부 리스트 삭제 //
|
||||
/*unsigned long dwMemberCID[CFriendList::MAX_FRIENDS_NUM] = {0,};
|
||||
unsigned long dwDeleteCID[CFriendList::MAX_FRIENDS_NUM] = {0,};
|
||||
|
||||
// 친구리스트에 CID 만 가지고 온다. //
|
||||
CFriendList friendList = lpCharacterData->GetFriendList();
|
||||
|
||||
friendList.GetCIDList(dwMemberCID);
|
||||
|
||||
for(unsigned char cIndex = 0; cIndex < friendList.GetFriendNum(); cIndex++)
|
||||
{
|
||||
CFriendList::Rebind* lpRebind = friendList.GetFriend(dwMemberCID[cIndex]);
|
||||
|
||||
if(lpCharacterData->GetRace()==CClass::HUMAN)
|
||||
{
|
||||
if(lpRebind->GetClass()>=CClass::Combatant)
|
||||
{
|
||||
dwDeleteCID[cIndex] = dwMemberCID[cIndex];
|
||||
}
|
||||
}
|
||||
else if(lpCharacterData->GetRace()==CClass::AKHAN)
|
||||
{
|
||||
if(lpRebind->GetClass()<CClass::Combatant)
|
||||
{
|
||||
dwDeleteCID[cIndex] = dwMemberCID[cIndex];
|
||||
}
|
||||
}
|
||||
|
||||
// 다른 종족일 경우 삭제 //
|
||||
if(dwDeleteCID[cIndex])
|
||||
{
|
||||
friendList.Remove(dwDeleteCID[cIndex]);
|
||||
}
|
||||
}
|
||||
|
||||
memset(dwMemberCID, 0, sizeof(unsigned long) * CFriendList::MAX_FRIENDS_NUM);
|
||||
memset(dwDeleteCID, 0, sizeof(unsigned long) * CFriendList::MAX_FRIENDS_NUM);
|
||||
|
||||
CBanList banList = lpCharacterData->GetBanList();
|
||||
|
||||
banList.GetCIDList(dwMemberCID);
|
||||
|
||||
for(unsigned char cIndex = 0; cIndex < banList.GetBanNum(); cIndex++)
|
||||
{
|
||||
CBanList::Rebind* lpRebind = banList.GetBan(dwMemberCID[cIndex]);
|
||||
|
||||
if(lpCharacterData->GetRace()==CClass::HUMAN)
|
||||
{
|
||||
if(lpRebind->GetClass()>=CClass::Combatant)
|
||||
{
|
||||
dwDeleteCID[cIndex] = dwMemberCID[cIndex];
|
||||
}
|
||||
}
|
||||
else if(lpCharacterData->GetRace()==CClass::AKHAN)
|
||||
{
|
||||
if(lpRebind->GetClass()<CClass::Combatant)
|
||||
{
|
||||
dwDeleteCID[cIndex] = dwMemberCID[cIndex];
|
||||
}
|
||||
}
|
||||
|
||||
// 다른 종족일 경우 삭제 //
|
||||
if(dwDeleteCID[cIndex])
|
||||
{
|
||||
banList.Remove(dwDeleteCID[cIndex]);
|
||||
}
|
||||
}*/
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 에러가 없으면 데이터를 바인딩한다.
|
||||
if(0 == usError)
|
||||
{
|
||||
// 선택된 캐릭터가 한마리도 없었으면, 국적을 선택한다.
|
||||
if(0 == userInfo.GetCharacterNum())
|
||||
{
|
||||
unsigned char cOldAccountNation = lpSessionData->GetAccountNation();
|
||||
|
||||
// 선택한 국가가 종족과 맞는지 체크한 후 세팅한다.
|
||||
if(Creature::ALMIGHTY_PIRATE == cSelectedNation)
|
||||
{
|
||||
lpSessionData->SetAccountNation(Creature::ALMIGHTY_PIRATE);
|
||||
}
|
||||
else
|
||||
{
|
||||
lpSessionData->SetAccountNation(
|
||||
CClass::HUMAN == eRace ? Creature::KARTERANT : Creature::MERKADIA);
|
||||
}
|
||||
|
||||
if (cOldAccountNation != lpSessionData->GetAccountNation())
|
||||
{
|
||||
INFLOG3(g_Log, "UID:%10u / OldAccountNation:%s / AccountNation:%s / 국적 변경",
|
||||
dwUID, Creature::GetShortNationName(cOldAccountNation),
|
||||
Creature::GetShortNationName(lpSessionData->GetAccountNation()));
|
||||
}
|
||||
}
|
||||
|
||||
if(!lpSessionData->UpdateCharacterBinding(dbComponent, dwSelectedCID))
|
||||
{
|
||||
ERRLOG2(g_Log, "UID:%10u / ServerGroupID:%d / 통합서버 선택 실패 : 최종 캐릭터 바인딩에 실패했습니다",
|
||||
dwUID, cSelectedServerGroupID);
|
||||
|
||||
usError = PktUnifiedCharSelectAck::UNIFIED_CHAR_WRITE_ERROR;
|
||||
}
|
||||
else
|
||||
{
|
||||
// 창고/캐릭터 이전에 성공했다!
|
||||
lpSessionData->SetOldServerGroupID(cAgentServerType);
|
||||
}
|
||||
}
|
||||
|
||||
if(0 != usError)
|
||||
{
|
||||
// 문제가 생겼다. 데이터를 전부 Rollback한다.
|
||||
for(int nCount = 0; nCount < USER_INFO::MAX_CHAR_NUM; ++nCount)
|
||||
{
|
||||
if(0 != dwSelectedCID[nCount] && backupData[nCount].IsBackupedData())
|
||||
{
|
||||
if(0 == (lpCharacterData = charDataMgr.GetLogoutData(dwSelectedCID[nCount])))
|
||||
{
|
||||
ERRLOG3(g_Log, "UID:%10u / CID:%10u / ServerGroupID:%d / 통합서버 선택 실패 - 데이터 복구 실패 : 캐릭터 캐쉬로 데이터 로드 실패",
|
||||
dwUID, dwSelectedCID[nCount], cSelectedServerGroupID);
|
||||
}
|
||||
else
|
||||
{
|
||||
backupData[nCount].RestoreData(*lpCharacterData);
|
||||
|
||||
lpCharacterData->ForceUpdateDBAllData(dbComponent);
|
||||
lpSessionData->ChangeUnifiedCharServerGroupID(dbComponent,
|
||||
dwUID, dwSelectedCID[nCount], backupData[nCount].GetOldServerGroupID());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GET_SINGLE_DISPATCH(lpAuthDispatch, CAuthDispatch,
|
||||
CAuthDispatch::GetDispatchTable());
|
||||
|
||||
if(0 != lpAuthDispatch && SendPacket::UnifiedCharSelectAck(
|
||||
lpAuthDispatch->GetSendStream(), dwUID, dwRequestKey, usError))
|
||||
{
|
||||
if(0 == usError)
|
||||
{
|
||||
INFLOG2(g_Log, "UID:%10u / ServerGroupID:%d / 캐릭터 및 창고 선택 성공",
|
||||
dwUID, cSelectedServerGroupID);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ERRLOG2(g_Log, "UID:%10u / ServerGroupID:%d / 캐릭터 선택 실패 : "
|
||||
"인증서버와 접속이 끊기거나 전송에 실패했습니다.", dwUID, cSelectedServerGroupID);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
#ifndef _DBAGENT_SERVER_PART1_DBAGENT_DISPATCH_H_
|
||||
#define _DBAGENT_SERVER_PART1_DBAGENT_DISPATCH_H_
|
||||
|
||||
#include <Network/Dispatch/RylServerDispatch.h>
|
||||
#include <Network/Dispatch/SingleDispatchStorage.h>
|
||||
#include <Community/FriendList.h>
|
||||
#include <Community/BanList.h>
|
||||
|
||||
namespace DBAgent
|
||||
{
|
||||
// Part1 DBAgent¼¹ö¿¡ Á¢¼ÓÇÑ´Ù.
|
||||
|
||||
class CPart1DBAgentDispatch : public CRylServerDispatch
|
||||
{
|
||||
public:
|
||||
|
||||
static CSingleDispatch& GetDispatchTable();
|
||||
|
||||
enum Const
|
||||
{
|
||||
MAX_PACKET_DISPATCH_PER_PULSE = 100,
|
||||
MAX_STREAM_BUFFER_SIZE = 16000
|
||||
};
|
||||
|
||||
CPart1DBAgentDispatch(CSession& Session);
|
||||
virtual ~CPart1DBAgentDispatch();
|
||||
|
||||
virtual void Connected();
|
||||
virtual void Disconnected();
|
||||
virtual bool DispatchPacket(PktBase* lpPktBase);
|
||||
|
||||
static bool TransferCharPart1ToPart2(CSendStream& SendStream, unsigned long dwUID,
|
||||
unsigned char cSelectedServerGroup, unsigned char cSelectedNation,
|
||||
unsigned long* lpdwSelectedCID, unsigned char cSelectedCharNum);
|
||||
|
||||
private:
|
||||
|
||||
};
|
||||
|
||||
typedef std::map<unsigned short, unsigned short> QuestDelete;
|
||||
typedef std::map<unsigned short, unsigned short> QuestChange;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,731 @@
|
||||
#include "stdafx.h"
|
||||
#include "UIDDispatch.h"
|
||||
|
||||
#include "AuthDispatch.h"
|
||||
#include "GameDispatch.h"
|
||||
#include "ChatDispatch.h"
|
||||
|
||||
#include <DB/DBComponent.h>
|
||||
#include <DB/GameDBComponent.h>
|
||||
|
||||
#include <Log/ServerLog.h>
|
||||
#include <Network/Address/INET_Addr.h>
|
||||
#include <Network/Packet/PacketCommand.h>
|
||||
#include <Network/Packet/PacketStruct/ServerInfo.h>
|
||||
#include <Network/Packet/PacketStruct/ServerPacket.h>
|
||||
#include <Network/Packet/PacketStruct/CharLoginOutPacket.h>
|
||||
#include <Network/Packet/PacketStruct/CharLoginOutPacketStruct.h>
|
||||
#include <Network/SendPacket/SendServerInfo.h>
|
||||
#include <Network/SendPacket/SendLoginout.h>
|
||||
#include <Network/SendPacket/SendCharManage.h>
|
||||
|
||||
#include <DataStorage/Billing.h>
|
||||
#include <DataStorage/SessionData.h>
|
||||
#include <DataStorage/SessionDataMgr.h>
|
||||
|
||||
#include <Utility/Setup/ServerSetup.h>
|
||||
|
||||
namespace DBAgent
|
||||
{
|
||||
|
||||
const char* g_szPktUUTString[PktUUT::MAX_UPDATE_TYPE] =
|
||||
{
|
||||
"UpdateUIDTableNone",
|
||||
"UpdateUIDTableUserLogin",
|
||||
"UpdateUIDTableUserLogout",
|
||||
"UpdateUIDTableUserMove",
|
||||
"UpdateUIDTableCharLogin",
|
||||
"UpdateUIDTableCharLogout",
|
||||
"UpdateUIDTableCharMove",
|
||||
"UpdateUIDTableBillingCheck",
|
||||
};
|
||||
|
||||
|
||||
|
||||
// UpdateUIDTable처리시 유저 로그인 처리를 한다.
|
||||
// 리턴값은 상수 에러 문자열이다. NULL이면 성공이다.
|
||||
const char* ProcessUpdateTableUserLogin(DataStorage::CSessionData& sessionData,
|
||||
DataStorage::RequestData& requestData,
|
||||
unsigned long dwFlag, int nPlayTime,
|
||||
unsigned long dwCRMIndex1,
|
||||
unsigned char cCmd, char cBillingType,
|
||||
unsigned short usUUKAckError);
|
||||
|
||||
// UpdateUIDTable처리시 캐릭터 로그인 처리를 한다.
|
||||
// 리턴값은 상수 에러 문자열이다. NULL이면 성공이다.
|
||||
const char* ProcessUpdateTableCharLogin(DataStorage::CSessionData& sessionData,
|
||||
DataStorage::RequestData& requestData,
|
||||
unsigned long dwFlag, int nPlayTime,
|
||||
unsigned long dwCRMIndex1,
|
||||
unsigned char cCmd, char cBillingType);
|
||||
|
||||
CSingleDispatch& CUIDDispatch::GetDispatchTable()
|
||||
{
|
||||
static CSingleDispatch uidDispatch;
|
||||
return uidDispatch;
|
||||
}
|
||||
|
||||
CUIDDispatch::CUIDDispatch(CSession& Session)
|
||||
: CRylServerDispatch(Session, MAX_PACKET_DISPATCH_PER_PULSE)
|
||||
{
|
||||
|
||||
|
||||
}
|
||||
|
||||
CUIDDispatch::~CUIDDispatch()
|
||||
{
|
||||
|
||||
|
||||
}
|
||||
|
||||
void CUIDDispatch::Connected()
|
||||
{
|
||||
DETLOG3(g_Log, "SS:0x%08x/DP:0x%08x/IP:%15s/UIDServer Connected",
|
||||
&GetSession(), this, GetRemoteAddr().get_addr_string());
|
||||
|
||||
GetDispatchTable().SetDispatch(this);
|
||||
|
||||
SendPacket::ServerLogin(GetSendStream(),
|
||||
CServerSetup::GetInstance().GetServerID());
|
||||
}
|
||||
|
||||
void CUIDDispatch::Disconnected()
|
||||
{
|
||||
DETLOG3(g_Log, "SS:0x%08x/DP:0x%08x/IP:%15s/UIDServer Disconnected",
|
||||
&GetSession(), this, GetRemoteAddr().get_addr_string());
|
||||
|
||||
GetDispatchTable().RemoveDispatch(this);
|
||||
}
|
||||
|
||||
bool CUIDDispatch::DispatchPacket(PktBase* lpPktBase)
|
||||
{
|
||||
PktBase::CMDType cCmd = lpPktBase->GetCmd();
|
||||
|
||||
bool bResult = false;
|
||||
|
||||
switch(cCmd)
|
||||
{
|
||||
case CmdSysServerLogout: bResult = ParseServerLogoutAck(lpPktBase); break;
|
||||
case CmdUserKill: bResult = ParseUserKill(static_cast<PktUK*>(lpPktBase)); break;
|
||||
case CmdBillingTimeoutNotify: bResult = ParseBillingTimeNotify(static_cast<PktBTN*>(lpPktBase)); break;
|
||||
case CmdBillingTimeCheckNotify: bResult = ParseBillingTimeCheckNotify(static_cast<PktBTN*>(lpPktBase)); break;
|
||||
case CmdHanBTNWarning: bResult = ParseHanBTNWarning(static_cast<PktHanBTN*>(lpPktBase)); break;
|
||||
case CmdHanBTNUserKill: bResult = ParseHanBTNUserKill(static_cast<PktHanUserKill*>(lpPktBase)); break;
|
||||
case CmdUpdateUIDTable: bResult = ParseUpdateUIDTable(static_cast<PktUUTAck*>(lpPktBase)); break;
|
||||
|
||||
default:
|
||||
|
||||
ERRLOG4(g_Log, "SS:0x%08x/DP:0x%08x/IP:%15s/Cmd:0x%02X/ UID서버 패킷 처리 실패 : 없는 커맨드입니다",
|
||||
&GetSession(), this, GetRemoteAddr().get_addr_string(), cCmd);
|
||||
|
||||
bResult = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if(!bResult)
|
||||
{
|
||||
ERRLOG4(g_Log, "SS:0x%08x/DP:0x%08x/IP:%15s/Cmd:0x%02X/ UID서버 패킷 처리 실패 : 처리를 실패했습니다",
|
||||
&GetSession(), this, GetRemoteAddr().get_addr_string(), cCmd);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool CUIDDispatch::ParseServerLogoutAck(PktBase* lpPktBase)
|
||||
{
|
||||
INFLOG3(g_Log, "SS:0x%08x/DP:0x%08x/IP:%15s/Cmd:0x%02X/ UID서버 접속 종료 : 서버 로그아웃 패킷을 받았습니다.",
|
||||
&GetSession(), this, GetRemoteAddr().get_addr_string());
|
||||
|
||||
CloseSession();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool CUIDDispatch::ParseUpdateUIDTable(PktUUTAck* lpPktUUTAck)
|
||||
{
|
||||
// edith 2008.01.15 UID에서 보낸 UpdateUIDTable 결과값 처리루틴
|
||||
|
||||
using namespace DBAgent::DataStorage;
|
||||
|
||||
unsigned char cCmd = lpPktUUTAck->m_cCmd;
|
||||
unsigned long dwUID = lpPktUUTAck->m_dwUserID;
|
||||
unsigned long dwFlag = lpPktUUTAck->m_dwFlag;
|
||||
int nPlayTime = lpPktUUTAck->m_nPlayTime;
|
||||
unsigned long dwCRMIndex1 = lpPktUUTAck->m_dwCRMIndex1; // 피시방 ID (0이면 개인유저)
|
||||
char cBillingType = lpPktUUTAck->m_cstrBillingType;
|
||||
|
||||
CBilling::WarningType eOldWarnMsgType = CBilling::WARN_BEFORE_1SEC;
|
||||
CBilling::WarningType eNewWarnMsgType = static_cast<CBilling::WarningType>(lpPktUUTAck->GetState());
|
||||
|
||||
const char* szErrorReason = 0;
|
||||
|
||||
RequestData requestData;
|
||||
memset(&requestData, 0, sizeof(RequestData));
|
||||
|
||||
CSessionData* lpSessionData = CSessionDataMgr::GetInstance().GetOpenSession(dwUID);
|
||||
|
||||
if(PktUUT::MAX_UPDATE_TYPE <= cCmd)
|
||||
{
|
||||
szErrorReason = "로그인 실패 - 알 수 없는 커맨드입니다";
|
||||
}
|
||||
else if(0 == lpSessionData)
|
||||
{
|
||||
szErrorReason = "로그인 실패 - 세션이 없습니다";
|
||||
}
|
||||
else
|
||||
{
|
||||
switch(cCmd)
|
||||
{
|
||||
case PktUUT::UpdateUIDTableUserLogin:
|
||||
|
||||
requestData = lpSessionData->PopRequest();
|
||||
|
||||
if(0 == requestData.m_dwRequestKey)
|
||||
{
|
||||
szErrorReason = "로그인 실패 - RequestKey가 이상합니다";
|
||||
}
|
||||
else
|
||||
{
|
||||
szErrorReason = ProcessUpdateTableUserLogin(*lpSessionData, requestData, dwFlag,
|
||||
nPlayTime, dwCRMIndex1, cCmd, cBillingType, lpPktUUTAck->GetError());
|
||||
|
||||
eOldWarnMsgType = lpSessionData->GetBilling().GetWarnMsgType();
|
||||
lpSessionData->GetBilling().SetWarnMsgType(eNewWarnMsgType);
|
||||
|
||||
if(CBilling::WARN_EVERY_MINUTE == eNewWarnMsgType)
|
||||
{
|
||||
// 경고 상태로 이행. 매분마다 메시지를 보내도록 한다.
|
||||
SendPacket::BillingCheckNotify(*lpSessionData, 5, cBillingType);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case PktUUT::UpdateUIDTableCharLogin:
|
||||
|
||||
requestData = lpSessionData->PopRequest();
|
||||
|
||||
if(0 == requestData.m_dwRequestKey)
|
||||
{
|
||||
szErrorReason = "로그인 실패 - RequestKey가 이상합니다";
|
||||
}
|
||||
else
|
||||
{
|
||||
szErrorReason = ProcessUpdateTableCharLogin(*lpSessionData, requestData,
|
||||
dwFlag, nPlayTime, dwCRMIndex1, cCmd, cBillingType);
|
||||
}
|
||||
break;
|
||||
|
||||
case PktUUT::UpdateUIDTableBillingCheck:
|
||||
|
||||
eOldWarnMsgType = lpSessionData->GetBilling().GetWarnMsgType();
|
||||
|
||||
if(0 == dwFlag)
|
||||
{
|
||||
lpSessionData->GetBilling().SetWarnMsgType(eNewWarnMsgType);
|
||||
|
||||
if (CBilling::NO_WARNING == eOldWarnMsgType &&
|
||||
CBilling::WARN_EVERY_MINUTE == eNewWarnMsgType)
|
||||
{
|
||||
// 무경고 상태에서 경고 상태로 이행. 매분마다 메시지를 보내도록 한다.
|
||||
SendPacket::BillingCheckNotify(*lpSessionData, 5, cBillingType);
|
||||
}
|
||||
else
|
||||
if (CBilling::WARN_EVERY_MINUTE == eOldWarnMsgType &&
|
||||
CBilling::NO_WARNING == eNewWarnMsgType)
|
||||
{
|
||||
// 경고 상태에서 무경고 상태로 이행. 메시지를 그만 보내도록 한다.
|
||||
SendPacket::BillingCheckNotify(*lpSessionData, 20, cBillingType);
|
||||
}
|
||||
}
|
||||
|
||||
lpSessionData->GetBilling().AddYouxiLandPoint(nPlayTime, cBillingType);
|
||||
|
||||
DETLOG4(g_Log, "UID:%10u / CID:%10u / nPlayTime:%d / cBillingType:%c / UpdateUIDTableBillingCheck 성공",
|
||||
lpSessionData->GetUID(), lpSessionData->GetCID(), nPlayTime, cBillingType);
|
||||
|
||||
if (0 != dwFlag)
|
||||
{
|
||||
// 유저 킬 처리 - 특별히 하지 않는다. 나중에 빌링체크에서 끊을 것이다.
|
||||
// KillUser(lpDataSession);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if(0 != szErrorReason)
|
||||
{
|
||||
ERRLOG10(g_Log, "UID:%10u / Cmd:%s / Flag:%u / PlayTime:%d / CRMIndex:%u / BillingType:%c / "
|
||||
" RequestKey:%10u / SelectedCID:%10u / ServerID:0x%08X / ParseUIDTable 실패 : %s",
|
||||
dwUID, g_szPktUUTString[cCmd], dwFlag, nPlayTime, dwCRMIndex1, cBillingType,
|
||||
requestData.m_dwRequestKey, requestData.m_dwSelectedCID,
|
||||
requestData.m_dwServerID, szErrorReason);
|
||||
|
||||
if(0 == dwFlag)
|
||||
{
|
||||
PktUUT::UpdateType eUpdateType = PktUUT::UpdateUIDTableNone;
|
||||
|
||||
switch(cCmd)
|
||||
{
|
||||
case PktUUT::UpdateUIDTableUserLogin:
|
||||
eUpdateType = PktUUT::UpdateUIDTableUserLogout;
|
||||
break;
|
||||
|
||||
case PktUUT::UpdateUIDTableCharLogin:
|
||||
eUpdateType = PktUUT::UpdateUIDTableCharLogout;
|
||||
break;
|
||||
}
|
||||
|
||||
// edith 2008.01.15 UID로 로그인 메시지 전송
|
||||
if(0 == lpSessionData)
|
||||
{
|
||||
ERRLOG1(g_Log, "UID:%10u / UID서버 전송 실패 : 세션이 없습니다.", dwUID);
|
||||
}
|
||||
else if(eUpdateType != PktUUT::UpdateUIDTableNone &&
|
||||
!SendPacket::UpdateUIDTable(eUpdateType, requestData.m_szAccount, requestData.m_szPassword,
|
||||
dwUID, requestData.m_dwSelectedCID, requestData.m_dwSessionID,
|
||||
requestData.m_dwServerID, requestData.m_PeerAddress))
|
||||
{
|
||||
ERRLOG1(g_Log, "UID:%10u / UID서버 전송 실패 : 전송에 실패했습니다.", dwUID);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
const char* ProcessUpdateTableUserLogin(DataStorage::CSessionData& sessionData,
|
||||
DataStorage::RequestData& requestData,
|
||||
unsigned long dwFlag, int nPlayTime, unsigned long dwCRMIndex1,
|
||||
unsigned char cCmd, char cBillingType, unsigned short usUUKAckError)
|
||||
{
|
||||
// edith 2008.01.15 UpdateTableUserLogin에 관련된 프로세싱 로직
|
||||
const char* szErrorReason = 0;
|
||||
unsigned long dwUID = sessionData.GetUID();
|
||||
|
||||
GET_SINGLE_DISPATCH(lpAuthDispatch,
|
||||
CAuthDispatch, CAuthDispatch::GetDispatchTable());
|
||||
|
||||
if(0 == lpAuthDispatch)
|
||||
{
|
||||
szErrorReason = "유저 로그인 실패 - 인증서버 접속 끊김";
|
||||
}
|
||||
else
|
||||
{
|
||||
unsigned short usError = 1; // Default : Server Error(Unknown Error)
|
||||
|
||||
if (0 == dwFlag)
|
||||
{
|
||||
// 통합서버 정보를 얻어서 보내준다.
|
||||
unsigned char cAgentServerType = static_cast<unsigned char>(
|
||||
CServerSetup::GetInstance().GetAgentServerType());
|
||||
|
||||
unsigned char cFirstLogin = 0;
|
||||
|
||||
switch(cAgentServerType)
|
||||
{
|
||||
case UnifiedConst::Part1:
|
||||
case UnifiedConst::Part1Unified:
|
||||
// 서버 세팅 잘못 했음. 나중에 UserLogin
|
||||
szErrorReason = "유저 로그인 실패 - 서버 잘못 켰음";
|
||||
break;
|
||||
|
||||
case UnifiedConst::ROW:
|
||||
sessionData.SetOldServerGroupID(UnifiedConst::ROW);
|
||||
break;
|
||||
|
||||
case UnifiedConst::Part2Unified:
|
||||
case UnifiedConst::Part2Selectable:
|
||||
|
||||
if(!sessionData.GetUnifiedDataFromDB(CDBSingleObject::GetInstance()))
|
||||
{
|
||||
szErrorReason = "유저 로그인 실패 - 통합서버 데이터 얻기 실패";
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
cFirstLogin = sessionData.GetFirstLogin();
|
||||
|
||||
if(0 != szErrorReason)
|
||||
{
|
||||
// 데이터 읽어오다 에러 난 모양이다. UserLogin을 취소한다.
|
||||
}
|
||||
else if(!sessionData.UserEnable(CDBSingleObject::GetInstance(), dwUID))
|
||||
{
|
||||
szErrorReason = "유저 로그인 실패 - 유저 활성화 실패";
|
||||
}
|
||||
else if(!SendPacket::StartSession(lpAuthDispatch->GetSendStream(),
|
||||
requestData.m_dwRequestKey, dwUID, requestData.m_dwSessionID, cFirstLogin, 0))
|
||||
{
|
||||
szErrorReason = "유저 로그인 실패 - 유저 로그인 성공 전송 실패";
|
||||
}
|
||||
else
|
||||
{
|
||||
// 빌링 시작(접속 끊기 시작. 예전 한게임 과금과 요시랜드 과금만 사용함).
|
||||
// 인증서버에서는 과금 안함. 과금 정보 표시를 위해서 세팅함.
|
||||
sessionData.GetBilling().StartBilling(nPlayTime, dwCRMIndex1, cBillingType);
|
||||
|
||||
// edith 2008.01.15 로그인에 성공했으니 세션에 등록한다.
|
||||
// 로그인 성공했을때만 세션 ID등의 데이터를 세팅한다.
|
||||
sessionData.SetRequestData(requestData);
|
||||
|
||||
// 세션 열기 성공
|
||||
usError = 0;
|
||||
|
||||
// StartSession을 받았을 때, 에러가 0이고, 중계서버 타입이 통합서버이면,
|
||||
// 통합서버 데이터를 기다리므로, 데이터를 여기서 전송해 준다.
|
||||
|
||||
switch(cAgentServerType)
|
||||
{
|
||||
case UnifiedConst::Part2Unified:
|
||||
case UnifiedConst::Part2Selectable:
|
||||
|
||||
// 신규 계정인지 아닌지 생각할 필요는 없다. 일단 정보 주고 나면
|
||||
// 선택할 캐릭이 없으면 알아서 그냥 로그인하기 때문이다.
|
||||
if (!SendPacket::UnifiedCharInfo(lpAuthDispatch->GetSendStream(),
|
||||
dwUID, sessionData.GetTransferedCharCount(CDBSingleObject::GetInstance()),
|
||||
sessionData.GetUserInfo(),
|
||||
sessionData.GetUnifiedStoreInfo(), sessionData.GetUnifiedStoreInfoNum(),
|
||||
sessionData.GetUnifiedCharData(), sessionData.GetUnifiedCharDataNum()))
|
||||
{
|
||||
// 정보 전송에 실패했으면 뭐 하는 수 없지;; 알아서 데이터 기다리다 끊어지겠지;;
|
||||
ERRLOG1(g_Log, "UID:%10u / 유저 로그인 실패 - 통합서버 정보 전송 실패", dwUID);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (1 == dwFlag)
|
||||
{
|
||||
switch(usUUKAckError)
|
||||
{
|
||||
default:
|
||||
usError = 41; // 중복로그인
|
||||
break;
|
||||
|
||||
case PktUUT::DISCONNECT_USER:
|
||||
usError = 42; // Disconnect를 했으니 재시도해 봐..
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (2 == dwFlag) { usError = 24; } // 개인,피시방 관련 과금 정보가 없음(한게임)
|
||||
else if (4 == dwFlag) { usError = 1; } // 서버 에러 (DB Query 실패)
|
||||
else if (11 == dwFlag || 13 == dwFlag || 19 == dwFlag)
|
||||
{
|
||||
// 개인,피시방 관련 과금 정보가 없음(대만)
|
||||
usError = 24;
|
||||
}
|
||||
else if (20 == dwFlag) { usError = 40; } // 대만, 일본 중복 로그인 방지
|
||||
// edith 2009.09.11 MY를 위한 AllowIP 처리작업
|
||||
else if (57 == dwFlag) { usError = 57; } // ROW에서 AllowIP 에서 걸림
|
||||
else if (100 >= dwFlag) { usError = (unsigned short)(dwFlag-100); }; // 감마니아 오류
|
||||
|
||||
if(0 != usError)
|
||||
{
|
||||
SendPacket::StartSession(lpAuthDispatch->GetSendStream(),
|
||||
requestData.m_dwRequestKey, dwUID, sessionData.GetSessionID(), 0, usError);
|
||||
}
|
||||
}
|
||||
|
||||
return szErrorReason;
|
||||
}
|
||||
|
||||
|
||||
|
||||
const char* ProcessUpdateTableCharLogin(DataStorage::CSessionData& sessionData,
|
||||
DataStorage::RequestData& requestData,
|
||||
unsigned long dwFlag, int nPlayTime,
|
||||
unsigned long dwCRMIndex1,
|
||||
unsigned char cCmd, char cBillingType)
|
||||
{
|
||||
const char* szErrorReason = 0;
|
||||
unsigned long dwUID = sessionData.GetUID();
|
||||
|
||||
GET_MULTI_DISPATCH(lpGameDispatch, requestData.m_dwServerID,
|
||||
CGameDispatch, CGameDispatch::GetDispatchTable());
|
||||
|
||||
if(0 == lpGameDispatch)
|
||||
{
|
||||
szErrorReason = "캐릭터 로그인 실패 - 게임서버 접속 끊김";
|
||||
}
|
||||
else if(!sessionData.HasCharacter(requestData.m_dwSelectedCID))
|
||||
{
|
||||
szErrorReason = "캐릭터 로그인 실패 - 소유하지 않은 캐릭터 활성화";
|
||||
|
||||
const USER_INFO& userInfo = sessionData.GetUserInfo();
|
||||
|
||||
// WORK_LIST 2.1 계정 국적 추가
|
||||
SERLOG9(g_Log, "UID:%10u / SelectedCID:%10u / Char1:%10u / Char2:%10u / Char3:%10u / Char4:%10u / Char5:%10u / Nation:%d %s",
|
||||
dwUID, requestData.m_dwSelectedCID,
|
||||
userInfo.CharID[0], userInfo.CharID[1], userInfo.CharID[2],
|
||||
userInfo.CharID[3], userInfo.CharID[4], userInfo.Nation, szErrorReason);
|
||||
}
|
||||
else
|
||||
{
|
||||
// 기본값은 실패. 서버 에러.
|
||||
unsigned short usError = 1;
|
||||
|
||||
if (0 == dwFlag)
|
||||
{
|
||||
// 캐릭터 활성화
|
||||
if (!sessionData.CharEnable(requestData.m_dwSelectedCID, requestData.m_dwServerID))
|
||||
{
|
||||
szErrorReason = "캐릭터 로그인 실패 - 세션 활성화 실패";
|
||||
}
|
||||
// 캐릭터 데이터 전송
|
||||
else if (!SendPacket::CharLogin(lpGameDispatch->GetSendStream(),
|
||||
sessionData, requestData.m_dwRequestKey))
|
||||
{
|
||||
szErrorReason = "캐릭터 로그인 실패 - 캐릭터 데이터 전송 실패";
|
||||
|
||||
// 활성화된 캐릭터를 Disable함.
|
||||
sessionData.CharDisable(requestData.m_dwSelectedCID, requestData.m_dwServerID);
|
||||
}
|
||||
else
|
||||
{
|
||||
// 빌링 시작
|
||||
switch(CServerSetup::GetInstance().GetBillingType())
|
||||
{
|
||||
case CServerSetup::GamaBilling:
|
||||
case CServerSetup::GamaUnitedBilling:
|
||||
sessionData.GetBilling().StartBilling(nPlayTime, dwCRMIndex1, cBillingType);
|
||||
break;
|
||||
}
|
||||
|
||||
// 로그인 성공했을때만 세션 ID등의 데이터를 세팅한다.
|
||||
sessionData.SetRequestData(requestData);
|
||||
|
||||
// 접속 성공!
|
||||
usError = 0;
|
||||
}
|
||||
}
|
||||
else if (1 == dwFlag) { usError = 41; } // 중복로그인
|
||||
else if (2 == dwFlag) { usError = 24; } // 개인,피시방 관련 과금 정보가 없음
|
||||
else if (4 == dwFlag) { usError = 1; } // 서버 에러 (DB Query 실패)
|
||||
else if (11 == dwFlag || 13 == dwFlag || 19 == dwFlag)
|
||||
{
|
||||
// 개인,피시방 관련 과금 정보가 없음(대만)
|
||||
usError = 24;
|
||||
}
|
||||
else if (20 == dwFlag) { usError = 40; } // 대만, 일본 중복 로그인 방지
|
||||
// edith 2009.09.11 MY를 위한 AllowIP 처리작업
|
||||
else if (57 == dwFlag) { usError = 57; } // ROW에서 AllowIP 에서 걸림
|
||||
else if (100 >= dwFlag) { usError = (unsigned short)(dwFlag-100); }; // 감마니아 오류
|
||||
|
||||
if (0 != usError)
|
||||
{
|
||||
SendPacket::CharLoginError(lpGameDispatch->GetSendStream(),
|
||||
requestData.m_dwRequestKey, DBUpdateData::LOGIN,
|
||||
dwUID, requestData.m_dwSelectedCID, usError);
|
||||
}
|
||||
}
|
||||
|
||||
return szErrorReason;
|
||||
}
|
||||
|
||||
|
||||
bool CUIDDispatch::ParseBillingTimeNotify(PktBTN* lpPktBTN)
|
||||
{
|
||||
using namespace DataStorage;
|
||||
|
||||
CSessionData* lpSessionData = CSessionDataMgr::GetInstance().GetOpenSession(lpPktBTN->m_dwUserID);
|
||||
if(0 == lpSessionData)
|
||||
{
|
||||
ERRLOG2(g_Log, "UID:%10u / cRemainMin:%u / 시간 만료 공지를 보내기 실패 : 유저가 없습니다",
|
||||
lpPktBTN->m_dwUserID, lpPktBTN->m_cRemainMinute);
|
||||
}
|
||||
else if(CSessionData::SE_CHAR_ENABLED != lpSessionData->GetSessionState())
|
||||
{
|
||||
ERRLOG2(g_Log, "UID:%10u / ST:%s / 시간 만료 공지를 보내기 실패 : 캐릭터가 비활성화되어 있습니다",
|
||||
lpPktBTN->m_dwUserID, g_szSessionStateString[lpSessionData->GetSessionState()]);
|
||||
}
|
||||
else
|
||||
{
|
||||
// 시간이 다 떨어져서 경고 보냄.
|
||||
if(!SendPacket::BillingNotify(*lpSessionData,
|
||||
lpPktBTN->m_cRemainMinute, lpPktBTN->m_cBillingType))
|
||||
{
|
||||
INFLOG4(g_Log, "UID:%10u / ServerID:0x%08X / cRemainMin:%u / cBillingType:%c / 시간 만료 공지 보내기 성공",
|
||||
lpPktBTN->m_dwUserID, lpSessionData->GetServerID(), lpPktBTN->m_cRemainMinute, lpPktBTN->m_cBillingType);
|
||||
}
|
||||
else
|
||||
{
|
||||
ERRLOG2(g_Log, "UID:%10u / ServerID:0x%08X / 시간 만료 공지를 보내기 실패 : 게임서버와의 연결이 끊어져 있습니다",
|
||||
lpPktBTN->m_dwUserID, lpSessionData->GetServerID());
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CUIDDispatch::ParseBillingTimeCheckNotify(PktBTN* lpPktBTN)
|
||||
{
|
||||
using namespace DataStorage;
|
||||
|
||||
CSessionData* lpSessionData = CSessionDataMgr::GetInstance().GetOpenSession(lpPktBTN->m_dwUserID);
|
||||
if(0 == lpSessionData)
|
||||
{
|
||||
ERRLOG2(g_Log, "UID:%10u / cRemainMin:%u / 시간 다시 체크(대만) 공지를 보내기 실패 : 유저가 없습니다",
|
||||
lpPktBTN->m_dwUserID, lpPktBTN->m_cRemainMinute);
|
||||
}
|
||||
else if(CSessionData::SE_CHAR_ENABLED != lpSessionData->GetSessionState())
|
||||
{
|
||||
ERRLOG2(g_Log, "UID:%10u / ST:%s / 시간 다시 체크(대만) 공지를 보내기 실패 : 캐릭터가 비활성화되어 있습니다",
|
||||
lpPktBTN->m_dwUserID, g_szSessionStateString[lpSessionData->GetSessionState()]);
|
||||
}
|
||||
else
|
||||
{
|
||||
// 시간이 다 떨어져서 경고 보냄.
|
||||
if(!SendPacket::BillingCheckNotify(*lpSessionData,
|
||||
lpPktBTN->m_cRemainMinute, lpPktBTN->m_cBillingType))
|
||||
{
|
||||
INFLOG4(g_Log, "UID:%10u / ServerID:0x%08X / cRemainMin:%u / cBillingType:%c / 시간 다시 체크(대만) 공지 보내기 성공",
|
||||
lpPktBTN->m_dwUserID, lpSessionData->GetServerID(), lpPktBTN->m_cRemainMinute, lpPktBTN->m_cBillingType);
|
||||
}
|
||||
else
|
||||
{
|
||||
ERRLOG2(g_Log, "UID:%10u / ServerID:0x%08X / 시간 다시 체크 공지(대만)를 보내기 실패 : 게임서버와의 연결이 끊어져 있습니다",
|
||||
lpPktBTN->m_dwUserID, lpSessionData->GetServerID());
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool CUIDDispatch::ParseHanBTNWarning(PktHanBTN* lpPktHanBTN)
|
||||
{
|
||||
// 채팅서버로 메시지를 Relay한다.
|
||||
using namespace DataStorage;
|
||||
|
||||
IN_ADDR peerAddress;
|
||||
peerAddress.S_un.S_addr = lpPktHanBTN->m_dwIP;
|
||||
|
||||
bool bCheckAddress = (0xFFFFFFFF != peerAddress.S_un.S_addr);
|
||||
|
||||
CSessionData* lpSessionData = CSessionDataMgr::GetInstance().GetOpenSession(
|
||||
lpPktHanBTN->m_szAccount, peerAddress, bCheckAddress);
|
||||
|
||||
if(0 == lpSessionData)
|
||||
{
|
||||
ERRLOG2(g_Log, "AccountName:%16s / IP:%15s / 과금 만료 메시지 전송 실패 : 유저가 없습니다",
|
||||
lpPktHanBTN->m_szAccount, inet_ntoa(peerAddress));
|
||||
}
|
||||
else if(CSessionData::SE_CHAR_ENABLED != lpSessionData->GetSessionState())
|
||||
{
|
||||
ERRLOG4(g_Log, "UID:%10u / AccountName:%16s / IP:%15s / ST:%s / 과금 만료 메시지 전송 실패 : 캐릭터가 비활성화되어 있습니다",
|
||||
lpSessionData->GetUID(), lpPktHanBTN->m_szAccount, inet_ntoa(peerAddress),
|
||||
g_szSessionStateString[lpSessionData->GetSessionState()]);
|
||||
}
|
||||
else
|
||||
{
|
||||
GET_SINGLE_DISPATCH(lpChatDispatch,
|
||||
CChatDispatch, CChatDispatch::GetDispatchTable());
|
||||
|
||||
if(0 != lpChatDispatch)
|
||||
{
|
||||
char* lpBuffer = lpChatDispatch->GetSendStream().GetBuffer(sizeof(PktHanBTN));
|
||||
|
||||
if(0 != lpBuffer)
|
||||
{
|
||||
PktHanBTN* lpPktChatBTN = reinterpret_cast<PktHanBTN*>(lpBuffer);
|
||||
|
||||
*lpPktChatBTN = *lpPktHanBTN;
|
||||
|
||||
lpPktChatBTN->m_dwUID = lpSessionData->GetUID();
|
||||
lpPktChatBTN->m_dwCID = lpSessionData->GetCID();
|
||||
|
||||
return lpChatDispatch->GetSendStream().WrapHeader(
|
||||
sizeof(PktHanBTN), CmdHanBTNWarning, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
ERRLOG5(g_Log, "UID:%10u / AccountName:%16s / IP:%15s / ST:%s / ChatDispatch:%p / 과금 만료 메시지 전송 실패 : 채팅서버와 연결이 끊겼거나, 버퍼 할당 실패",
|
||||
lpSessionData->GetUID(), lpPktHanBTN->m_szAccount, inet_ntoa(peerAddress),
|
||||
g_szSessionStateString[lpSessionData->GetSessionState()], lpChatDispatch);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CUIDDispatch::ParseHanBTNUserKill(PktHanUserKill* lpPktHanUserKill)
|
||||
{
|
||||
using namespace DataStorage;
|
||||
|
||||
IN_ADDR peerAddress;
|
||||
peerAddress.S_un.S_addr = lpPktHanUserKill->m_dwIP;
|
||||
|
||||
// 접속 DB를 전부 뒤져서, 계정과 IP가 일치하는 넘한테 뜨거운 맛을 보여 준다.
|
||||
bool bCheckAddress = (peerAddress.S_un.S_addr != 0xFFFFFFFF);
|
||||
|
||||
CSessionData* lpSessionData = CSessionDataMgr::GetInstance().GetOpenSession(
|
||||
lpPktHanUserKill->m_szAccount, peerAddress, bCheckAddress);
|
||||
|
||||
if(0 == lpSessionData)
|
||||
{
|
||||
ERRLOG2(g_Log, "AccountName:%16s / IP:%15s / 과금 만료 접속 끊기 실패 : 유저가 없습니다",
|
||||
lpPktHanUserKill->m_szAccount, inet_ntoa(peerAddress));
|
||||
}
|
||||
else
|
||||
{
|
||||
SERVER_ID serverID;
|
||||
serverID.dwID = lpSessionData->GetServerID();
|
||||
CSessionData::SessionState eSessionState = lpSessionData->GetSessionState();
|
||||
|
||||
if ((serverID.GetType() == CServerSetup::AuthServer && CSessionData::SE_USER_ENABLED != eSessionState) ||
|
||||
(serverID.GetType() == CServerSetup::GameServer && CSessionData::SE_CHAR_ENABLED != eSessionState))
|
||||
{
|
||||
ERRLOG3(g_Log, "UID:%10u / ServerID:0x%08X / ST:%s / 과금 만료 접속 끊기 실패 : 유저나 캐릭터가 비활성화되어 있습니다",
|
||||
lpSessionData->GetUID(), serverID.dwID, g_szSessionStateString[lpSessionData->GetSessionState()]);
|
||||
}
|
||||
else if(!SendPacket::UserKill(*lpSessionData))
|
||||
{
|
||||
ERRLOG3(g_Log, "UID:%10u / ServerID:0x%08X / ST:%s / 과금 만료 접속 끊기 실패 : 접속 끊기 패킷 보내기 실패",
|
||||
lpSessionData->GetUID(), serverID.dwID, g_szSessionStateString[lpSessionData->GetSessionState()]);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CUIDDispatch::ParseUserKill(PktUK* lpPktUK)
|
||||
{
|
||||
using namespace DataStorage;
|
||||
|
||||
// 접속 DB를 전부 뒤져서, 계정과 IP가 일치하는 넘한테 뜨거운 맛을 보여 준다.
|
||||
CSessionData* lpSessionData =
|
||||
CSessionDataMgr::GetInstance().GetOpenSession(lpPktUK->m_dwUserID);
|
||||
|
||||
if(0 == lpSessionData)
|
||||
{
|
||||
ERRLOG1(g_Log, "UID:%10u / UID 서버 유저 접속 끊기 실패 : 유저가 없습니다", lpPktUK->m_dwUserID);
|
||||
}
|
||||
else
|
||||
{
|
||||
SERVER_ID serverID;
|
||||
serverID.dwID = lpSessionData->GetServerID();
|
||||
CSessionData::SessionState eSessionState = lpSessionData->GetSessionState();
|
||||
|
||||
if ((serverID.GetType() == CServerSetup::AuthServer && CSessionData::SE_USER_ENABLED != eSessionState) ||
|
||||
(serverID.GetType() == CServerSetup::GameServer && CSessionData::SE_CHAR_ENABLED != eSessionState))
|
||||
{
|
||||
ERRLOG3(g_Log, "UID:%10u / ServerID:0x%08X / ST:%s / UID 서버 유저 접속 끊기 실패 : 유저나 캐릭터가 비활성화되어 있습니다",
|
||||
lpPktUK->m_dwUserID, serverID.dwID, g_szSessionStateString[lpSessionData->GetSessionState()]);
|
||||
}
|
||||
else if(!SendPacket::UserKill(*lpSessionData))
|
||||
{
|
||||
ERRLOG3(g_Log, "UID:%10u / ServerID:0x%08X / ST:%s / UID 서버 유저 접속 끊기 실패 : 접속 끊기 패킷 보내기 실패",
|
||||
lpPktUK->m_dwUserID, serverID.dwID, g_szSessionStateString[lpSessionData->GetSessionState()]);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
#ifndef _DBAGENT_SERVER_UID_DISPATCH_H_
|
||||
#define _DBAGENT_SERVER_UID_DISPATCH_H_
|
||||
|
||||
#include <Network/Packet/PacketStruct/ServerPacket.h>
|
||||
#include <Network/Dispatch/RylServerDispatch.h>
|
||||
#include <Network/Dispatch/SingleDispatchStorage.h>
|
||||
|
||||
// forward decl.
|
||||
struct PktBase;
|
||||
struct PktUUTAck;
|
||||
struct PktBTN;
|
||||
struct PktHanBTN;
|
||||
struct PktHanUserKill;
|
||||
struct PktUK;
|
||||
struct PktSLAck;
|
||||
|
||||
namespace DBAgent
|
||||
{
|
||||
extern const char* g_szPktUUTString[PktUUT::MAX_UPDATE_TYPE];
|
||||
|
||||
class CUIDDispatch : public CRylServerDispatch
|
||||
{
|
||||
public:
|
||||
|
||||
static CSingleDispatch& GetDispatchTable();
|
||||
|
||||
enum Const
|
||||
{
|
||||
MAX_PACKET_DISPATCH_PER_PULSE = 100,
|
||||
MAX_STREAM_BUFFER_SIZE = 16000
|
||||
};
|
||||
|
||||
CUIDDispatch(CSession& Session);
|
||||
virtual ~CUIDDispatch();
|
||||
|
||||
virtual void Connected();
|
||||
virtual void Disconnected();
|
||||
virtual bool DispatchPacket(PktBase* lpPktBase);
|
||||
|
||||
private:
|
||||
|
||||
bool ParseServerLoginAck(PktSLAck* lpPktSLAck);
|
||||
bool ParseServerLogoutAck(PktBase* lpPktBase);
|
||||
|
||||
bool ParseUpdateUIDTable(PktUUTAck* lpPktUUTAck);
|
||||
|
||||
bool ParseBillingTimeNotify(PktBTN* lpPktBTN); // 한국 과금 경고 메시지
|
||||
bool ParseBillingTimeCheckNotify(PktBTN* lpPktBTN); // 대만 과금 경고 메시지
|
||||
|
||||
bool ParseHanBTNWarning(PktHanBTN* lpPktHanBTN); // 한국 통합빌링 과금 경고 메시지
|
||||
bool ParseHanBTNUserKill(PktHanUserKill* lpPktHanUserKill); // 한국 통합빌링 과금 접속 끊기
|
||||
|
||||
bool ParseUserKill(PktUK* lpPktUK); // 접속 끊기
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,32 @@
|
||||
#ifndef _DBAGENT_SERVER_PARSE_CASTLE_H_
|
||||
#define _DBAGENT_SERVER_PARSE_CASTLE_H_
|
||||
|
||||
class CSendStream;
|
||||
struct PktBase;
|
||||
|
||||
namespace DBAgent
|
||||
{
|
||||
namespace ParseCastle
|
||||
{
|
||||
bool CastleCmd(CSendStream& SendStream, PktBase* lpPktBase);
|
||||
bool SiegeArmsCmd(CSendStream& SendStream, PktBase* lpPktBase);
|
||||
bool SetCastleRight(CSendStream& SendStream, PktBase* lpPktBase);
|
||||
bool SetCampRight(CSendStream& SendStream, PktBase* lpPktBase);
|
||||
bool CreateCamp(CSendStream& SendStream, PktBase* lpPktBase);
|
||||
bool CreateSiegeArms(CSendStream& SendStream, PktBase* lpPktBase);
|
||||
bool CampCmd(CSendStream& SendStream, PktBase* lpPktBase);
|
||||
bool CampMessage(CSendStream& SendStream, PktBase* lpPktBase);
|
||||
bool MiningCampMineralInfo(CSendStream& SendStream, PktBase* lpPktBase);
|
||||
bool FertilityInfo(CSendStream& SendStream, PktBase* lpPktBase);
|
||||
bool CampShopInfo(CSendStream& SendStream, PktBase* lpPktBase);
|
||||
bool CastleTaxMove(CSendStream& SendStream, PktBase* lpPktBase);
|
||||
bool CastleMineralInfo(CSendStream& SendStream, PktBase* lpPktBase);
|
||||
bool WarOnOff(CSendStream& SendStream, PktBase* lpPktBase);
|
||||
bool StatueCmd(CSendStream& SendSream, PktBase* lpPktBase);
|
||||
bool RealmPoint(CSendStream& SendSream, PktBase* lpPktBase);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,39 @@
|
||||
#ifndef _DBAGENT_SERVER_PARSE_CHAR_MANAGE_H_
|
||||
#define _DBAGENT_SERVER_PARSE_CHAR_MANAGE_H_
|
||||
|
||||
// forward decl;
|
||||
class CSendStream;
|
||||
struct PktDD;
|
||||
struct PktBase;
|
||||
|
||||
namespace DBAgent
|
||||
{
|
||||
|
||||
namespace DataStorage
|
||||
{
|
||||
// forward decl.
|
||||
class CItemSerialMgr;
|
||||
}
|
||||
|
||||
|
||||
namespace ParseCharManage
|
||||
{
|
||||
// --------------------------------------------------------------------
|
||||
// 캐릭터 관리 및 세션 메소드
|
||||
|
||||
bool Parse(CSendStream& SendStream, unsigned long dwServerID,
|
||||
Item::CItemSerialMgr& itemSerialMgr, PktDD* lpPktDD);
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
// 배틀그라운드 서버군 관련 메소드.
|
||||
// 배섭 게임서버가 중계서버로 캐릭터 슬롯 정보 요청.
|
||||
|
||||
bool BGServerCharSlot(CSendStream& SendStream, PktBase* lpPktBase);
|
||||
|
||||
// 서버통합 관련 메소드
|
||||
bool UnifiedCharSelect(CSendStream& SendStream, PktBase* lpPktBase);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,62 @@
|
||||
#ifndef _DBAGENT_SERVER_PARSE_CHAR_UPDATE_H_
|
||||
#define _DBAGENT_SERVER_PARSE_CHAR_UPDATE_H_
|
||||
|
||||
#include <Network/Packet/PacketStruct/CharLoginOutPacket.h>
|
||||
|
||||
// forward delc.
|
||||
class CSendStream;
|
||||
|
||||
|
||||
namespace Item
|
||||
{
|
||||
// forward decl.
|
||||
class CItemSerialMgr;
|
||||
};
|
||||
|
||||
namespace DBAgent
|
||||
{
|
||||
|
||||
namespace ParseCharUpdate
|
||||
{
|
||||
// ------------------------------------------------------------------------
|
||||
// 캐릭터 업데이트 데이터 파싱
|
||||
|
||||
bool Parse(CSendStream& SendStream, unsigned long dwServerID,
|
||||
Item::CItemSerialMgr& itemSerialMgr, PktDBUpdate* lpPktDBUpdate);
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// 데이터 업데이트 메서드
|
||||
|
||||
bool UpdateDeposit(CSendStream& SendStream, PktBase* lpPktBase);
|
||||
bool UpdateDepositDB(CSendStream& SendStream, PktBase* lpPktBase);
|
||||
bool UpdateFriendDB(CSendStream& SendStream, PktBase* lpPktBase);
|
||||
bool UpdateQuestDB(CSendStream& SendStream, PktBase* lpPktBase);
|
||||
bool UpdateConfigInfoDB(CSendStream& SendStream, PktBase* lpPktBase);
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// 듀얼 관련 정보 저장.
|
||||
|
||||
bool SaveEnemy(CSendStream& SendStream, PktBase* lpPktBase);
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// 조이스틱 키 관련.
|
||||
bool UpdateKeyInfo(CSendStream& SendStream, PktBase* lpPktBase);
|
||||
|
||||
|
||||
// 캐쉬아이템 사용
|
||||
bool UseCashItem(CSendStream& SendStream, PktBase* lpPktBase);
|
||||
|
||||
// 엑스트라 이벤트
|
||||
bool ExtraEvent(CSendStream& SendStream, PktBase* lpPktBase);
|
||||
}
|
||||
|
||||
namespace ParseCharAdmin
|
||||
{
|
||||
bool AdminCommandLog(CSendStream& SendStream, PktBase* lpPktBase);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,903 @@
|
||||
#include "stdafx.h"
|
||||
#include "ParseGuild.h"
|
||||
|
||||
#include <Network/Packet/WrapPacket.h>
|
||||
#include <Network/Packet/PacketCommand.h>
|
||||
#include <Network/Packet/PacketStruct/GuildPacket.h>
|
||||
#include <Network/Stream/SendStream.h>
|
||||
#include <Network/Dispatch/GameDispatch.h>
|
||||
#include <Network/SendPacket/SendGuild.h>
|
||||
|
||||
#include <Community/Guild/GuildDB.h>
|
||||
#include <Community/Guild/GuildDBMgr.h>
|
||||
|
||||
#include <DB/DBComponent.h>
|
||||
#include <DB/GuildDBComponent.h>
|
||||
|
||||
#include <Log/ServerLog.h>
|
||||
|
||||
#include <DataStorage/SessionDataMgr.h>
|
||||
#include <DataStorage/CharacterData.h>
|
||||
#include <Network/Packet/PacketStruct/CastlePacket.h>
|
||||
#include <GameTime/GameTimeConstants.h>
|
||||
#include <GameTime/GameTimeDBMgr.h>
|
||||
#include <DB/GameDBComponent.h>
|
||||
|
||||
namespace DBAgent
|
||||
{
|
||||
namespace ParseGuild
|
||||
{
|
||||
|
||||
bool CreateGuild(CSendStream& SendStream, PktBase* lpPktBase)
|
||||
{
|
||||
PktCreateGuild* lpPktCreateGuild = static_cast<PktCreateGuild*>(lpPktBase);
|
||||
|
||||
unsigned short wError = PktBase::NO_SERVER_ERR;
|
||||
|
||||
CGuildDB* lpGuild = Guild::CGuildDBMgr::GetInstance().CreateGuild(
|
||||
lpPktCreateGuild->m_dwCID, lpPktCreateGuild->m_cInclination,
|
||||
lpPktCreateGuild->m_szGuildName, &wError);
|
||||
|
||||
PktCreateGuild pktGCAck;
|
||||
memset(&pktGCAck, 0, sizeof(PktCreateGuild));
|
||||
|
||||
pktGCAck.m_dwCID = lpPktCreateGuild->m_dwCID;
|
||||
pktGCAck.m_dwGID = (NULL != lpGuild) ? lpGuild->GetGID() : 0;
|
||||
pktGCAck.m_cInclination = lpPktCreateGuild->m_cInclination;
|
||||
strncpy(pktGCAck.m_szGuildName, lpPktCreateGuild->m_szGuildName, Guild::MAX_GUILD_NAME_LEN);
|
||||
|
||||
if(PacketWrap::WrapHeader(reinterpret_cast<char*>(&pktGCAck),
|
||||
sizeof(PktCreateGuild), CmdCreateGuild, 0, wError))
|
||||
{
|
||||
if (PktBase::NO_SERVER_ERR == wError)
|
||||
{
|
||||
using namespace DBAgent::DataStorage;
|
||||
|
||||
CSessionData* lpSessionData = CSessionDataMgr::GetInstance().GetCharLoadedSession(lpPktCreateGuild->m_dwCID);
|
||||
|
||||
if(lpSessionData)
|
||||
{
|
||||
CCharacterData* lpCharacterData = lpSessionData->GetCharacterData();
|
||||
|
||||
if(lpCharacterData)
|
||||
{
|
||||
// edith 2008.11.24 길드생성시 전쟁 자동참가
|
||||
lpCharacterData->SetGuildWarFlag(Creature::WAR_ON);
|
||||
|
||||
PktWarOnOff* lpPktWarOnOffAck = reinterpret_cast<PktWarOnOff*>(SendStream.GetBuffer(sizeof(PktWarOnOff)));
|
||||
|
||||
if (lpPktWarOnOffAck)
|
||||
{
|
||||
lpPktWarOnOffAck->m_dwCID = lpCharacterData->GetCID();
|
||||
lpPktWarOnOffAck->m_cType = GameTime::GUILD;
|
||||
lpPktWarOnOffAck->m_cFlag = Creature::WAR_ON;
|
||||
|
||||
SendStream.WrapHeader(sizeof(PktWarOnOff), CmdWarOnOff, 0, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DBAgent::CGameDispatch::GetDispatchTable().Process(CSendPacketAllServer(
|
||||
reinterpret_cast<char*>(&pktGCAck), sizeof(PktCreateGuild), CmdCreateGuild));
|
||||
}
|
||||
else
|
||||
{
|
||||
SendStream.PutBuffer(reinterpret_cast<char*>(&pktGCAck),
|
||||
sizeof(PktCreateGuild), CmdCreateGuild);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool GuildCmd(CSendStream& SendStream, PktBase* lpPktBase)
|
||||
{
|
||||
PktGuildCmd* lpPktGuildCmd = static_cast<PktGuildCmd*>(lpPktBase);
|
||||
|
||||
unsigned short wError = PktBase::NO_SERVER_ERR;
|
||||
|
||||
unsigned long dwGID = lpPktGuildCmd->m_dwGID;
|
||||
unsigned long dwSenderID = lpPktGuildCmd->m_dwSenderID;
|
||||
unsigned long dwReferenceID = lpPktGuildCmd->m_dwReferenceID;
|
||||
unsigned short wCmd = lpPktGuildCmd->m_wCmd;
|
||||
|
||||
using namespace Guild;
|
||||
|
||||
CGuildDB* lpGuild = static_cast<CGuildDB*>(CGuildDBMgr::GetInstance().GetGuild(dwGID));
|
||||
if (0 == lpGuild)
|
||||
{
|
||||
wError = PktBase::SERVER_ERROR;
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (wCmd)
|
||||
{
|
||||
case PktGuildCmd::GC_JOIN:
|
||||
{
|
||||
// 가입한 멤버 정보를 뒤에 붙여 다른 크기의 패킷을 만들기 때문에 함수 내에서 독자적으로 패킷을 보낸다.
|
||||
lpGuild->SendJoinMember(&SendStream, dwSenderID, static_cast<unsigned char>(dwReferenceID));
|
||||
|
||||
return true;
|
||||
}
|
||||
case PktGuildCmd::GC_TACTICS:
|
||||
{
|
||||
// 용병 가입 신청.
|
||||
lpGuild->SendJoinTacticsMember(&SendStream, dwSenderID, static_cast<unsigned char>(dwReferenceID), PktGuildCmd::GC_TACTICS);
|
||||
|
||||
return true;
|
||||
}
|
||||
case PktGuildCmd::GC_TACTICS_JOIN:
|
||||
{
|
||||
// 용병 가입 신청.
|
||||
lpGuild->SendJoinTacticsMember(&SendStream, dwSenderID, static_cast<unsigned char>(dwReferenceID), PktGuildCmd::GC_TACTICS_JOIN);
|
||||
|
||||
return true;
|
||||
}
|
||||
case PktGuildCmd::GC_TACTICS_TITLE:
|
||||
case PktGuildCmd::GC_TACTICS_REQUEST:
|
||||
{
|
||||
using namespace DBAgent::DataStorage;
|
||||
|
||||
// 용병 허가.
|
||||
unsigned char cTitle = static_cast<unsigned char>(dwReferenceID);
|
||||
|
||||
CSessionData* lpSessionData = CSessionDataMgr::GetInstance().GetCharLoadedSession(dwSenderID);
|
||||
|
||||
if(wCmd==PktGuildCmd::GC_TACTICS_REQUEST)
|
||||
goto lb_request;
|
||||
|
||||
if(CGameTimeDBMgr::GetInstance().IsGuildWarTime())
|
||||
{
|
||||
if(lpSessionData)
|
||||
{
|
||||
CCharacterData* lpCharacterData = lpSessionData->GetCharacterData();
|
||||
|
||||
if(lpCharacterData)
|
||||
{
|
||||
SendPacket::GuildCmd(&SendStream, dwGID, dwSenderID, COMMON, PktGuildCmd::GC_TACTICS_REQUEST, NULL, NULL, wError);
|
||||
}
|
||||
else
|
||||
{
|
||||
goto lb_error;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
lb_error:
|
||||
PktGuildCmd pktGuildCmd;
|
||||
memset(&pktGuildCmd, 0, sizeof(PktGuildCmd));
|
||||
strcpy(pktGuildCmd.m_szSenderName, lpPktGuildCmd->m_szSenderName);
|
||||
|
||||
pktGuildCmd.m_dwGID = dwGID;
|
||||
pktGuildCmd.m_dwSenderID = dwSenderID;
|
||||
pktGuildCmd.m_dwReferenceID = COMMON;
|
||||
pktGuildCmd.m_wCmd = PktGuildCmd::GC_TACTICS_TITLE;
|
||||
SendStream.WrapCompress(reinterpret_cast<char*>(&pktGuildCmd), sizeof(PktGuildCmd), CmdGuildCmd, 0, PktGuildCmd::FAIL_TACTICS_LOGOUT);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
lb_request:
|
||||
lpGuild->SetTacticsMember(dwSenderID, Guild::TACTICS);
|
||||
lpGuild->SetTitle(dwSenderID, COMMON);
|
||||
|
||||
SendPacket::GuildCmd(&SendStream, dwGID, dwSenderID, COMMON, PktGuildCmd::GC_TACTICS_TITLE, NULL, NULL, wError);
|
||||
|
||||
DBComponent::GuildDB::UpdateGuildMemberTactics(CDBSingleObject::GetInstance(), lpGuild->GetGID(), dwSenderID, Guild::TACTICS);
|
||||
|
||||
if(lpSessionData)
|
||||
{
|
||||
CCharacterData* lpCharacterData = lpSessionData->GetCharacterData();
|
||||
|
||||
if(lpCharacterData)
|
||||
{
|
||||
lpCharacterData->SetGuildWarFlag(Creature::WAR_ON);
|
||||
|
||||
PktWarOnOff* lpPktWarOnOffAck = reinterpret_cast<PktWarOnOff*>(SendStream.GetBuffer(sizeof(PktWarOnOff)));
|
||||
|
||||
if (lpPktWarOnOffAck)
|
||||
{
|
||||
lpPktWarOnOffAck->m_dwCID = lpCharacterData->GetCID();
|
||||
lpPktWarOnOffAck->m_cType = GameTime::GUILD;
|
||||
lpPktWarOnOffAck->m_cFlag = Creature::WAR_ON;
|
||||
|
||||
SendStream.WrapHeader(sizeof(PktWarOnOff), CmdWarOnOff, 0, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
DBComponent::GameDB::UpdateGuildWarFlag(CDBSingleObject::GetInstance(), dwSenderID, Creature::WAR_ON);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
case PktGuildCmd::GC_TACTICS_KICK:
|
||||
case PktGuildCmd::GC_TACTICS_LEAVE:
|
||||
{
|
||||
// 용병 퇴출 및 탈퇴.
|
||||
if (false == lpGuild->LeaveMember(dwSenderID))
|
||||
{
|
||||
wError = PktBase::SERVER_ERROR;
|
||||
}
|
||||
|
||||
SendPacket::GuildCmd(&SendStream, dwGID, dwSenderID, dwReferenceID, wCmd, NULL, NULL, wError);
|
||||
|
||||
using namespace DBAgent::DataStorage;
|
||||
|
||||
CSessionData* lpSessionData = CSessionDataMgr::GetInstance().GetCharLoadedSession(dwSenderID);
|
||||
|
||||
if(lpSessionData)
|
||||
{
|
||||
CCharacterData* lpCharacterData = lpSessionData->GetCharacterData();
|
||||
|
||||
if(lpCharacterData)
|
||||
{
|
||||
lpCharacterData->SetGuildWarFlag(Creature::WAR_OFF);
|
||||
|
||||
PktWarOnOff* lpPktWarOnOffAck = reinterpret_cast<PktWarOnOff*>(SendStream.GetBuffer(sizeof(PktWarOnOff)));
|
||||
|
||||
if (lpPktWarOnOffAck)
|
||||
{
|
||||
lpPktWarOnOffAck->m_dwCID = lpCharacterData->GetCID();
|
||||
lpPktWarOnOffAck->m_cType = GameTime::GUILD;
|
||||
lpPktWarOnOffAck->m_cFlag = Creature::WAR_OFF;
|
||||
|
||||
SendStream.WrapHeader(sizeof(PktWarOnOff), CmdWarOnOff, 0, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
DBComponent::GameDB::UpdateGuildWarFlag(CDBSingleObject::GetInstance(), dwSenderID, Creature::WAR_OFF);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
case PktGuildCmd::GC_SETUP_TITLE:
|
||||
{
|
||||
unsigned char cTitle = static_cast<unsigned char>(dwReferenceID);
|
||||
|
||||
// 길드 마스터 탈퇴
|
||||
if (dwSenderID == lpGuild->GetMaster().m_dwCID)
|
||||
{
|
||||
unsigned long dwNewMaster = lpGuild->SetNewMaster();
|
||||
if (0 == dwNewMaster)
|
||||
{
|
||||
DETLOG1(g_Log, "GID:%10u 길드가 해체되었습니다. - 길드마스터 탈퇴", lpGuild->GetGID());
|
||||
CGuildDBMgr::GetInstance().DissolveGuild(
|
||||
lpGuild->GetGID(), PktCreateGuild::NONE_NEXT_GUILDMASTER_BY_GUILDMASTER_OUT);
|
||||
break;
|
||||
}
|
||||
|
||||
SendPacket::GuildCmd(&SendStream, dwGID, dwNewMaster, MASTER, PktGuildCmd::GC_SETUP_TITLE, NULL, NULL, wError);
|
||||
|
||||
DETLOG3(g_Log, "GID:%10u 길드마스터(이전:%10u, 현재:%10u)가 변경되었습니다. - 길드마스터 탈퇴",
|
||||
lpGuild->GetGID(), dwSenderID, dwNewMaster);
|
||||
}
|
||||
|
||||
// 길드 마스터 권한 양도
|
||||
if (MASTER == cTitle)
|
||||
{
|
||||
MemberInfo PreMasterInfo = lpGuild->GetMaster();
|
||||
lpGuild->SetTitle(PreMasterInfo.m_dwCID, COMMON);
|
||||
|
||||
SendPacket::GuildCmd(&SendStream, dwGID, PreMasterInfo.m_dwCID, COMMON, PktGuildCmd::GC_SETUP_TITLE, NULL, NULL, wError);
|
||||
|
||||
DETLOG3(g_Log, "GID:%10u 길드마스터(이전:%10u, 현재:%10u)가 변경되었습니다. - 길드마스터 권한 양도",
|
||||
lpGuild->GetGID(), PreMasterInfo.m_dwCID, dwSenderID);
|
||||
}
|
||||
|
||||
lpGuild->SetTitle(dwSenderID, cTitle);
|
||||
|
||||
if(cTitle==COMMON)
|
||||
{
|
||||
using namespace DBAgent::DataStorage;
|
||||
|
||||
// edith 2008.03.15 일반 길드원으로 타이틀을 변경하는데 SenderID가 아닌 dwGID 에서 얻어왔다 잘못됐다.
|
||||
CSessionData* lpSessionData = CSessionDataMgr::GetInstance().GetCharLoadedSession(dwSenderID);
|
||||
// CSessionData* lpSessionData = CSessionDataMgr::GetInstance().GetCharLoadedSession(dwGID);
|
||||
|
||||
if(lpSessionData)
|
||||
{
|
||||
CCharacterData* lpCharacterData = lpSessionData->GetCharacterData();
|
||||
|
||||
if(lpCharacterData)
|
||||
{
|
||||
// edith 2008.11.24 길드마스터가 될시에 전쟁 자동참가
|
||||
// edith 2009.05.20 일반 길드원이 될때 전쟁자동참여 OFF 로 설정.
|
||||
lpCharacterData->SetGuildWarFlag(Creature::WAR_OFF);
|
||||
|
||||
PktWarOnOff* lpPktWarOnOffAck = reinterpret_cast<PktWarOnOff*>(SendStream.GetBuffer(sizeof(PktWarOnOff)));
|
||||
|
||||
if (lpPktWarOnOffAck)
|
||||
{
|
||||
lpPktWarOnOffAck->m_dwCID = lpCharacterData->GetCID();
|
||||
lpPktWarOnOffAck->m_cType = GameTime::GUILD;
|
||||
lpPktWarOnOffAck->m_cFlag = Creature::WAR_OFF;
|
||||
|
||||
SendStream.WrapHeader(sizeof(PktWarOnOff), CmdWarOnOff, 0, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case PktGuildCmd::GC_KICK:
|
||||
{
|
||||
// 길드 마스터의 경우 삭제시 킥 명령이 온다.
|
||||
if (dwSenderID == lpGuild->GetMaster().m_dwCID)
|
||||
{
|
||||
unsigned long dwNewMaster = lpGuild->SetNewMaster();
|
||||
if (0 == dwNewMaster)
|
||||
{
|
||||
DETLOG1(g_Log, "GID:%10u 길드가 해체되었습니다. - 길드마스터 삭제", lpGuild->GetGID());
|
||||
CGuildDBMgr::GetInstance().DissolveGuild(lpGuild->GetGID(),
|
||||
PktCreateGuild::NONE_NEXT_GUILDMASTER_BY_GUILDMASTER_DELETED);
|
||||
break;
|
||||
}
|
||||
|
||||
SendPacket::GuildCmd(&SendStream, dwGID, dwNewMaster, MASTER, PktGuildCmd::GC_SETUP_TITLE, NULL, NULL, wError);
|
||||
|
||||
DETLOG3(g_Log, "GID:%10u 길드마스터(이전:%10u, 현재:%10u)가 변경되었습니다. - 길드마스터 삭제",
|
||||
lpGuild->GetGID(), dwSenderID, dwNewMaster);
|
||||
}
|
||||
|
||||
if (false == lpGuild->LeaveMember(dwSenderID))
|
||||
{
|
||||
wError = PktBase::SERVER_ERROR;
|
||||
}
|
||||
|
||||
using namespace DBAgent::DataStorage;
|
||||
|
||||
CSessionData* lpSessionData = CSessionDataMgr::GetInstance().GetCharLoadedSession(dwSenderID);
|
||||
|
||||
if(lpSessionData)
|
||||
{
|
||||
CCharacterData* lpCharacterData = lpSessionData->GetCharacterData();
|
||||
|
||||
if(lpCharacterData)
|
||||
{
|
||||
lpCharacterData->SetGuildWarFlag(Creature::WAR_OFF);
|
||||
|
||||
PktWarOnOff* lpPktWarOnOffAck = reinterpret_cast<PktWarOnOff*>(SendStream.GetBuffer(sizeof(PktWarOnOff)));
|
||||
|
||||
if (lpPktWarOnOffAck)
|
||||
{
|
||||
lpPktWarOnOffAck->m_dwCID = lpCharacterData->GetCID();
|
||||
lpPktWarOnOffAck->m_cType = GameTime::GUILD;
|
||||
lpPktWarOnOffAck->m_cFlag = Creature::WAR_OFF;
|
||||
|
||||
SendStream.WrapHeader(sizeof(PktWarOnOff), CmdWarOnOff, 0, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
DBComponent::GameDB::UpdateGuildWarFlag(CDBSingleObject::GetInstance(), dwSenderID, Creature::WAR_OFF);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return SendPacket::GuildCmd(&SendStream, dwGID, dwSenderID, dwReferenceID, wCmd, NULL, NULL, wError);
|
||||
}
|
||||
|
||||
bool GuildMark(CSendStream& SendStream, PktBase* lpPktBase)
|
||||
{
|
||||
PktGuildMark* lpPktGuildMark = static_cast<PktGuildMark*>(lpPktBase);
|
||||
|
||||
unsigned short wError = PktBase::NO_SERVER_ERR;
|
||||
|
||||
unsigned long dwCID = lpPktGuildMark->m_dwCID;
|
||||
unsigned long dwGID = lpPktGuildMark->m_dwGID;
|
||||
|
||||
unsigned long dwGold = 0;
|
||||
|
||||
CGuildDB* lpGuild = static_cast<CGuildDB*>(CGuildDBMgr::GetInstance().GetGuild(dwGID));
|
||||
if (0 == lpGuild)
|
||||
{
|
||||
wError = PktBase::SERVER_ERROR;
|
||||
}
|
||||
else
|
||||
{
|
||||
lpGuild->SetMark(lpPktGuildMark->m_szMark);
|
||||
dwGold = lpGuild->GetGold();
|
||||
}
|
||||
|
||||
PktGuildMark pktGuildMark;
|
||||
memset(&pktGuildMark, 0, sizeof(PktGuildMark));
|
||||
|
||||
pktGuildMark.m_dwCID = dwCID;
|
||||
pktGuildMark.m_dwGID = dwGID;
|
||||
pktGuildMark.m_dwGold = dwGold;
|
||||
memcpy(pktGuildMark.m_szMark, lpPktGuildMark->m_szMark, MAX_MARK_SIZE);
|
||||
|
||||
if(PacketWrap::WrapHeader(reinterpret_cast<char*>(&pktGuildMark),
|
||||
sizeof(PktGuildMark), CmdGuildMark, 0, wError))
|
||||
{
|
||||
if (PktBase::NO_SERVER_ERR == wError)
|
||||
{
|
||||
DBAgent::CGameDispatch::GetDispatchTable().Process(CSendPacketAllServer(
|
||||
reinterpret_cast<char*>(&pktGuildMark), sizeof(PktGuildMark), CmdGuildMark));
|
||||
}
|
||||
else
|
||||
{
|
||||
SendStream.PutBuffer(reinterpret_cast<char*>(&pktGuildMark),
|
||||
sizeof(PktGuildMark), CmdGuildMark);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool GuildLevel(CSendStream& SendStream, PktBase* lpPktBase)
|
||||
{
|
||||
PktGuildLevel* lpPktGuildLevel = static_cast<PktGuildLevel*>(lpPktBase);
|
||||
|
||||
unsigned short wError = PktBase::NO_SERVER_ERR;
|
||||
|
||||
unsigned long dwGID = lpPktGuildLevel->m_dwUID;
|
||||
unsigned char cLevel = lpPktGuildLevel->m_cLevel;
|
||||
unsigned long dwGold = 0;
|
||||
|
||||
using namespace Guild;
|
||||
|
||||
CGuildDB* lpGuild = static_cast<CGuildDB*>(CGuildDBMgr::GetInstance().GetGuild(dwGID));
|
||||
if (NULL == lpGuild)
|
||||
{
|
||||
wError = PktBase::SERVER_ERROR;
|
||||
}
|
||||
else
|
||||
{
|
||||
lpGuild->SetLevel(cLevel);
|
||||
dwGold = lpGuild->GetGold();
|
||||
}
|
||||
|
||||
PktGuildLevel pktGuildLevel;
|
||||
memset(&pktGuildLevel, 0, sizeof(PktGuildLevel));
|
||||
|
||||
pktGuildLevel.m_dwUID = dwGID;
|
||||
pktGuildLevel.m_cLevel = cLevel;
|
||||
pktGuildLevel.m_dwGold = dwGold;
|
||||
|
||||
if(PacketWrap::WrapHeader(reinterpret_cast<char*>(&pktGuildLevel),
|
||||
sizeof(PktGuildLevel), CmdGuildLevel, 0, wError))
|
||||
{
|
||||
if (PktBase::NO_SERVER_ERR == wError)
|
||||
{
|
||||
DBAgent::CGameDispatch::GetDispatchTable().Process(CSendPacketAllServer(
|
||||
reinterpret_cast<char*>(&pktGuildLevel), sizeof(PktGuildLevel), CmdGuildLevel));
|
||||
}
|
||||
else
|
||||
{
|
||||
SendStream.PutBuffer(reinterpret_cast<char*>(&pktGuildLevel),
|
||||
sizeof(PktGuildLevel), CmdGuildLevel);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool GuildRelation(CSendStream& SendStream, PktBase* lpPktBase)
|
||||
{
|
||||
PktGuildRelation* lpPktGuildRelation = static_cast<PktGuildRelation*>(lpPktBase);
|
||||
|
||||
unsigned short wError = PktBase::NO_SERVER_ERR;
|
||||
|
||||
unsigned long dwCID = lpPktGuildRelation->m_dwCID;
|
||||
unsigned long dwGID = lpPktGuildRelation->m_dwGID;
|
||||
unsigned long dwTargetGID = lpPktGuildRelation->m_dwTargetGID;
|
||||
unsigned long dwValue = lpPktGuildRelation->m_dwValue;
|
||||
char cSubCmd = lpPktGuildRelation->m_cSubCmd;
|
||||
|
||||
CGuildDB* lpGuild = static_cast<CGuildDB*>(CGuildDBMgr::GetInstance().GetGuild(dwGID));
|
||||
CGuildDB* lpTargetGuild = static_cast<CGuildDB*>(CGuildDBMgr::GetInstance().GetGuild(dwTargetGID));
|
||||
|
||||
if (NULL == lpGuild || NULL == lpTargetGuild)
|
||||
{
|
||||
wError = PktBase::SERVER_ERROR;
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (cSubCmd)
|
||||
{
|
||||
case PktGuildRelation::GR_HOSTILITY:
|
||||
{
|
||||
if (!CGuildDBMgr::GetInstance().SetRelation(dwGID, dwTargetGID, Guild::HOSTILITY))
|
||||
{
|
||||
wError = PktGuildRelation::SERVER_ERROR;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case PktGuildRelation::GR_PEACE:
|
||||
{
|
||||
if (!CGuildDBMgr::GetInstance().SetRelation(dwGID, dwTargetGID, Guild::NEUTRALITY))
|
||||
{
|
||||
wError = PktGuildRelation::SERVER_ERROR;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case PktGuildRelation::GR_HOSTILITYDEL:
|
||||
{
|
||||
// 내가 TargetGuild에게 평화허락을 한다.
|
||||
if (!CGuildDBMgr::GetInstance().SetRelation(dwGID, dwTargetGID, Guild::TARGET_NEUTRALITY))
|
||||
{
|
||||
wError = PktGuildRelation::SERVER_ERROR;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case PktGuildRelation::GR_ALERT:
|
||||
{
|
||||
if (!CGuildDBMgr::GetInstance().SetRelation(dwGID, dwTargetGID, Guild::ALERT_HOSTILITY))
|
||||
{
|
||||
wError = PktGuildRelation::SERVER_ERROR;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case PktGuildRelation::GR_COUNTER:
|
||||
{
|
||||
if (!CGuildDBMgr::GetInstance().SetRelation(dwGID, dwTargetGID, Guild::COUNTER_HOSTILITY))
|
||||
{
|
||||
wError = PktGuildRelation::SERVER_ERROR;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case PktGuildRelation::GR_REQUEST:
|
||||
{
|
||||
CGuildDB* lpHostilityGuild = static_cast<CGuildDB*>(CGuildDBMgr::GetInstance().GetGuild(dwValue));
|
||||
if (NULL == lpHostilityGuild)
|
||||
{
|
||||
wError = PktGuildRelation::SERVER_ERROR;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!CGuildDBMgr::GetInstance().SetRelation(dwGID, dwValue, Guild::NEUTRALITY))
|
||||
{
|
||||
wError = PktGuildRelation::SERVER_ERROR;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!CGuildDBMgr::GetInstance().SetRelation(dwGID, dwTargetGID, Guild::HOSTILITY))
|
||||
{
|
||||
wError = PktGuildRelation::SERVER_ERROR;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PktGuildRelation pktGuildRelation;
|
||||
memset(&pktGuildRelation, 0, sizeof(PktGuildRelation));
|
||||
|
||||
pktGuildRelation.m_dwCID = dwCID;
|
||||
pktGuildRelation.m_dwGID = dwGID;
|
||||
pktGuildRelation.m_dwTargetGID = dwTargetGID;
|
||||
pktGuildRelation.m_dwValue = dwValue;
|
||||
pktGuildRelation.m_cSubCmd = cSubCmd;
|
||||
|
||||
if(PacketWrap::WrapHeader(reinterpret_cast<char*>(&pktGuildRelation),
|
||||
sizeof(PktGuildRelation), CmdGuildRelation, 0, wError))
|
||||
{
|
||||
if (PktBase::NO_SERVER_ERR == wError)
|
||||
{
|
||||
DBAgent::CGameDispatch::GetDispatchTable().Process(CSendPacketAllServer(
|
||||
reinterpret_cast<char*>(&pktGuildRelation),
|
||||
sizeof(PktGuildRelation), CmdGuildRelation));
|
||||
}
|
||||
else
|
||||
{
|
||||
SendStream.PutBuffer(reinterpret_cast<char*>(&pktGuildRelation),
|
||||
sizeof(PktGuildRelation), CmdGuildRelation);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool GuildInclination(CSendStream& SendStream, PktBase* lpPktBase)
|
||||
{
|
||||
// 더이상 길드 국적은 변경할 수 없습니다. (2004-11-22 by 로딘)
|
||||
/*
|
||||
PktGuildInclination* lpPktInclination = static_cast<PktGuildInclination*>(lpPktBase);
|
||||
|
||||
unsigned short wError = PktBase::NO_SERVER_ERR;
|
||||
|
||||
unsigned long dwGID = lpPktInclination->m_dwUID;
|
||||
unsigned char cInclination = lpPktInclination->m_cInclination;
|
||||
|
||||
CGuildDB* lpGuild = static_cast<CGuildDB*>(CGuildDBMgr::GetInstance().GetGuild(dwGID));
|
||||
if (NULL == lpGuild)
|
||||
{
|
||||
wError = PktBase::SERVER_ERROR;
|
||||
}
|
||||
else
|
||||
{
|
||||
lpGuild->SetInclination(cInclination);
|
||||
}
|
||||
|
||||
PktGuildInclination pktGuildInclination;
|
||||
memset(&pktGuildInclination, 0, sizeof(PktGuildInclination));
|
||||
|
||||
pktGuildInclination.m_dwUID = dwGID;
|
||||
pktGuildInclination.m_cInclination = cInclination;
|
||||
|
||||
if(PacketWrap::WrapHeader(reinterpret_cast<char*>(&pktGuildInclination),
|
||||
sizeof(PktGuildInclination), CmdGuildInclination, 0, wError))
|
||||
{
|
||||
if (PktBase::NO_SERVER_ERR == wError)
|
||||
{
|
||||
DBAgent::CGameDispatch::GetDispatchTable().Process(CSendPacketAllServer(
|
||||
reinterpret_cast<char*>(&pktGuildInclination),
|
||||
sizeof(PktGuildInclination), CmdGuildInclination));
|
||||
}
|
||||
else
|
||||
{
|
||||
SendStream.PutBuffer(reinterpret_cast<char*>(&pktGuildInclination),
|
||||
sizeof(PktGuildInclination), CmdGuildInclination);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
*/
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool SetGuildRight(CSendStream& SendStream, PktBase* lpPktBase)
|
||||
{
|
||||
using namespace Guild;
|
||||
|
||||
PktGuildRight* lpPktGuildRight = static_cast<PktGuildRight *>(lpPktBase);
|
||||
|
||||
unsigned short wError = PktBase::NO_SERVER_ERR;
|
||||
|
||||
unsigned long dwGID = lpPktGuildRight->m_dwUID;
|
||||
GuildRight guildRight = lpPktGuildRight->m_GuildRight;
|
||||
|
||||
CGuildDB* lpGuild = static_cast<CGuildDB*>(CGuildDBMgr::GetInstance().GetGuild(dwGID));
|
||||
if (NULL == lpGuild)
|
||||
{
|
||||
wError = PktBase::SERVER_ERROR;
|
||||
}
|
||||
else
|
||||
{
|
||||
lpGuild->SetRight(guildRight);
|
||||
}
|
||||
|
||||
PktGuildRight pktGuildRight;
|
||||
memset(&pktGuildRight, 0, sizeof(PktGuildRight));
|
||||
|
||||
pktGuildRight.m_dwUID = dwGID;
|
||||
pktGuildRight.m_GuildRight = guildRight;
|
||||
|
||||
if(PacketWrap::WrapHeader(reinterpret_cast<char*>(&pktGuildRight),
|
||||
sizeof(PktGuildRight), CmdGuildRight, 0, wError))
|
||||
{
|
||||
if (PktBase::NO_SERVER_ERR == wError)
|
||||
{
|
||||
DBAgent::CGameDispatch::GetDispatchTable().Process(CSendPacketAllServer(
|
||||
reinterpret_cast<char*>(&pktGuildRight), sizeof(PktGuildRight), CmdGuildRight));
|
||||
}
|
||||
else
|
||||
{
|
||||
SendStream.PutBuffer(reinterpret_cast<char*>(&pktGuildRight),
|
||||
sizeof(PktGuildRight), CmdGuildRight);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool GuildSafe(CSendStream& SendStream, PktBase* lpPktBase)
|
||||
{
|
||||
PktGuildSafeAck* lpPktGuildSafe = reinterpret_cast<PktGuildSafeAck *>(lpPktBase);
|
||||
|
||||
unsigned wError = PktBase::NO_SERVER_ERR;
|
||||
|
||||
unsigned long dwCID = lpPktGuildSafe->m_dwCID;
|
||||
unsigned long dwGID = lpPktGuildSafe->m_dwGID;
|
||||
|
||||
unsigned long dwSafeGold = lpPktGuildSafe->m_dwSafeGold;
|
||||
unsigned long dwCharGold = lpPktGuildSafe->m_dwCharGold;
|
||||
|
||||
unsigned char cCmd = lpPktGuildSafe->m_cCmd;
|
||||
|
||||
using namespace DBAgent::DataStorage;
|
||||
CSessionData* lpSessionData = CSessionDataMgr::GetInstance().GetCharLoadedSession(dwCID);
|
||||
CCharacterData* lpCharacterData = NULL;
|
||||
|
||||
if(lpSessionData)
|
||||
lpCharacterData = lpSessionData->GetCharacterData();
|
||||
|
||||
CGuildDB* lpGuild = static_cast<CGuildDB*>(CGuildDBMgr::GetInstance().GetGuild(dwGID));
|
||||
if (NULL == lpGuild)
|
||||
{
|
||||
wError = PktBase::SERVER_ERROR;
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (cCmd)
|
||||
{
|
||||
// 출금
|
||||
case PktGuildSafe::SC_WITHDRAWAL:
|
||||
{
|
||||
if (false == lpGuild->DeductGold(dwCharGold))
|
||||
{
|
||||
wError = PktGuildSafe::FAIL_NOT_ENOUGH_MONEY;
|
||||
}
|
||||
dwSafeGold = dwCharGold;
|
||||
break;
|
||||
}
|
||||
|
||||
// 입금
|
||||
case PktGuildSafe::SC_DEPOSIT:
|
||||
{
|
||||
// edith 2008.03.15 캐릭터의 골드를 뺀다.
|
||||
if(false == lpCharacterData->DeductGold(dwCharGold))
|
||||
{
|
||||
wError = PktGuildSafe::FAIL_NOT_CHAR_MONEY;
|
||||
}
|
||||
else if (false == lpGuild->AddGold(dwCharGold))
|
||||
{
|
||||
// 되돌린다 금액을
|
||||
lpCharacterData->AddGold(dwCharGold);
|
||||
|
||||
wError = PktGuildSafe::FAIL_NOT_GUILD_DEPOSIT;
|
||||
}
|
||||
dwSafeGold = dwCharGold;
|
||||
break;
|
||||
}
|
||||
|
||||
// 길드 보너스
|
||||
case PktGuildSafe::SC_BONUS:
|
||||
{
|
||||
if (false == lpGuild->AddGold(dwCharGold))
|
||||
{
|
||||
wError = PktGuildSafe::FAIL_NOT_GUILD_DEPOSIT;
|
||||
}
|
||||
dwSafeGold = dwCharGold;
|
||||
}
|
||||
break;
|
||||
|
||||
// 분배
|
||||
case PktGuildSafe::SC_RELEASE:
|
||||
{
|
||||
unsigned long dwPreSafeGold = lpGuild->GetGold();
|
||||
dwCharGold = lpGuild->ReleaseGold(dwCharGold);
|
||||
if (0 == dwCharGold)
|
||||
{
|
||||
wError = PktGuildSafe::FAIL_NOT_ENOUGH_MONEY;
|
||||
break;
|
||||
}
|
||||
dwSafeGold = dwPreSafeGold - lpGuild->GetGold();
|
||||
break;
|
||||
}
|
||||
default:
|
||||
wError = PktBase::SERVER_ERROR;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
PktGuildSafeAck pktGuildSafeAck;
|
||||
memset(&pktGuildSafeAck, 0, sizeof(PktGuildSafeAck));
|
||||
|
||||
pktGuildSafeAck.m_dwCID = dwCID;
|
||||
pktGuildSafeAck.m_dwGID = dwGID;
|
||||
pktGuildSafeAck.m_dwSafeGold = dwSafeGold;
|
||||
pktGuildSafeAck.m_dwCharGold = dwCharGold;
|
||||
pktGuildSafeAck.m_cCmd = cCmd;
|
||||
|
||||
strncpy(pktGuildSafeAck.m_szCharName,
|
||||
lpPktGuildSafe->m_szCharName, Guild::MAX_MEMBER_NAME_LEN);
|
||||
|
||||
if (!DBComponent::GuildDB::UpdateGuildGold(
|
||||
CDBSingleObject::GetInstance(), lpGuild->GetGID(), lpGuild->GetGold()))
|
||||
{
|
||||
wError = PktGuildSafe::FAIL_NOT_GUILD_UPDATE;
|
||||
}
|
||||
|
||||
if(PacketWrap::WrapHeader(reinterpret_cast<char*>(&pktGuildSafeAck),
|
||||
sizeof(PktGuildSafeAck), CmdGuildSafe, 0, wError))
|
||||
{
|
||||
if (PktBase::NO_SERVER_ERR == wError)
|
||||
{
|
||||
DBAgent::CGameDispatch::GetDispatchTable().Process(CSendPacketAllServer(
|
||||
reinterpret_cast<char*>(&pktGuildSafeAck), sizeof(PktGuildSafeAck), CmdGuildSafe));
|
||||
}
|
||||
else
|
||||
{
|
||||
SendStream.PutBuffer(reinterpret_cast<char*>(&pktGuildSafeAck),
|
||||
sizeof(PktGuildSafeAck), CmdGuildSafe);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool GuildMemberInfoUpdate(CSendStream& SendStream, PktBase* lpPktBase)
|
||||
{
|
||||
PktGuildMemberInfoUpdate* lpPktGMIU = static_cast<PktGuildMemberInfoUpdate*>(lpPktBase);
|
||||
|
||||
unsigned short wError = PktBase::NO_SERVER_ERR;
|
||||
|
||||
unsigned long dwGID = lpPktGMIU->m_dwGID;
|
||||
unsigned long dwCID = lpPktGMIU->m_dwCID;
|
||||
|
||||
CGuildDB* lpGuild = static_cast<CGuildDB*>(CGuildDBMgr::GetInstance().GetGuild(dwGID));
|
||||
if (NULL == lpGuild)
|
||||
{
|
||||
wError = PktBase::SERVER_ERROR;
|
||||
}
|
||||
else
|
||||
{
|
||||
lpGuild->UpdateMemberInfo(dwCID,
|
||||
lpPktGMIU->m_MemberListInfo, lpPktGMIU->m_MemberDetailInfo);
|
||||
}
|
||||
|
||||
PktGuildMemberInfoUpdate pktGMIUAck;
|
||||
memset(&pktGMIUAck, 0, sizeof(PktGuildMemberInfoUpdate));
|
||||
|
||||
pktGMIUAck.m_dwGID = dwGID;
|
||||
pktGMIUAck.m_dwCID = dwCID;
|
||||
|
||||
pktGMIUAck.m_MemberListInfo = lpPktGMIU->m_MemberListInfo;
|
||||
pktGMIUAck.m_MemberDetailInfo = lpPktGMIU->m_MemberDetailInfo;
|
||||
|
||||
if(PacketWrap::WrapHeader(reinterpret_cast<char*>(&pktGMIUAck),
|
||||
sizeof(PktGuildMemberInfoUpdate), CmdGuildMemberInfoUpdate, 0, wError))
|
||||
{
|
||||
if (PktBase::NO_SERVER_ERR == wError)
|
||||
{
|
||||
DBAgent::CGameDispatch::GetDispatchTable().Process(CSendPacketAllServer(
|
||||
reinterpret_cast<char*>(&pktGMIUAck),
|
||||
sizeof(PktGuildMemberInfoUpdate), CmdGuildMemberInfoUpdate));
|
||||
}
|
||||
else
|
||||
{
|
||||
SendStream.PutBuffer(reinterpret_cast<char*>(&pktGMIUAck),
|
||||
sizeof(PktGuildMemberInfoUpdate), CmdGuildMemberInfoUpdate);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
#ifndef _DBAGENT_SERVER_PARSE_GUILD_H_
|
||||
#define _DBAGENT_SERVER_PARSE_GUILD_H_
|
||||
|
||||
// forward delc.
|
||||
class CSendStream;
|
||||
struct PktBase;
|
||||
|
||||
namespace DBAgent
|
||||
{
|
||||
namespace ParseGuild
|
||||
{
|
||||
bool CreateGuild(CSendStream& SendStream, PktBase* lpPktBase);
|
||||
bool GuildCmd(CSendStream& SendStream, PktBase* lpPktBase);
|
||||
bool GuildMark(CSendStream& SendStream, PktBase* lpPktBase);
|
||||
bool GuildLevel(CSendStream& SendStream, PktBase* lpPktBase);
|
||||
bool GuildRelation(CSendStream& SendStream, PktBase* lpPktBase);
|
||||
bool GuildInclination(CSendStream& SendStream, PktBase* lpPktBase);
|
||||
bool SetGuildRight(CSendStream& SendStream, PktBase* lpPktBase);
|
||||
bool GuildSafe(CSendStream& SendStream, PktBase* lpPktBase);
|
||||
bool GuildMemberInfoUpdate(CSendStream& SendStream, PktBase* lpPktBase);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,345 @@
|
||||
#include "stdafx.h"
|
||||
#include "ParseMoveZone.h"
|
||||
|
||||
#include <Creature/CreatureManager.h>
|
||||
#include <Network/Dispatch/GameDispatch.h>
|
||||
#include <Network/SendPacket/SendMoveZone.h>
|
||||
|
||||
#include <Network/Packet/PacketStruct/ServerInfo.h>
|
||||
#include <Network/Packet/PacketStruct/ServerPacket.h>
|
||||
|
||||
#include <DataStorage/CharacterData.h>
|
||||
#include <DataStorage/SessionData.h>
|
||||
#include <DataStorage/SessionDataMgr.h>
|
||||
|
||||
#include <Log/ServerLog.h>
|
||||
#include <Utility/Setup/ServerSetup.h>
|
||||
|
||||
#include <GameTime/GameTimeDBMgr.h>
|
||||
|
||||
namespace DBAgent
|
||||
{
|
||||
namespace ParseMoveZone
|
||||
{
|
||||
|
||||
bool CharMoveZone(CSendStream& SendStream, PktSZMvD* lpPktSZMvD);
|
||||
bool ServerZone(CSendStream& SendStream, PktSA* lpPktSA);
|
||||
bool ServerZoneEnd(CSendStream& SendStream, PktDD* lpPktDD);
|
||||
|
||||
|
||||
bool Parse(CSendStream& SendStream, PktBase* lpPktBase)
|
||||
{
|
||||
bool bResult = false;
|
||||
|
||||
PktDD* lpPktDD = static_cast<PktDD*>(lpPktBase);
|
||||
|
||||
switch (lpPktDD->m_wCmd)
|
||||
{
|
||||
case PktDD::SCmdCharMoveZone:
|
||||
bResult = CharMoveZone(SendStream, static_cast<PktSZMvD*>(lpPktDD));
|
||||
break;
|
||||
|
||||
case PktDD::SCmdServerZone:
|
||||
bResult = ServerZone(SendStream, static_cast<PktSA*>(lpPktDD));
|
||||
break;
|
||||
|
||||
case PktDD::SCmdServerZoneEnd:
|
||||
bResult = ServerZoneEnd(SendStream, lpPktDD);
|
||||
break;
|
||||
|
||||
default:
|
||||
ERRLOG1(g_Log, "ZoneMove 패킷 처리 에러 : 알 수 없는 패킷 CMD:0x%02X를 받았습니다.",
|
||||
lpPktDD->m_wCmd);
|
||||
|
||||
bResult = true;
|
||||
break;
|
||||
}
|
||||
|
||||
return bResult;
|
||||
}
|
||||
|
||||
|
||||
class CFindGameServerDispatch
|
||||
{
|
||||
public:
|
||||
|
||||
CFindGameServerDispatch(CGameDispatch*& lpGameDispatch, SERVER_ID serverID)
|
||||
: m_lpGameDispatch(lpGameDispatch), m_serverID(serverID)
|
||||
{
|
||||
m_lpGameDispatch = 0;
|
||||
}
|
||||
|
||||
bool operator() (unsigned long dwServerID, CPacketDispatch& packetDispatch)
|
||||
{
|
||||
if(0 == m_lpGameDispatch)
|
||||
{
|
||||
SERVER_ID serverID;
|
||||
serverID.dwID = dwServerID;
|
||||
|
||||
// 서버 ID가 같으면 선택, 다르더라도, 채널만 -1이고 다른게 같으면 선택.
|
||||
if ((serverID.dwID == m_serverID.dwID) ||
|
||||
|
||||
(-1 == m_serverID.GetChannel() &&
|
||||
serverID.GetZone() == m_serverID.GetZone() &&
|
||||
serverID.GetGroup() == m_serverID.GetGroup() &&
|
||||
serverID.GetType() == m_serverID.GetType()))
|
||||
{
|
||||
m_lpGameDispatch = &static_cast<CGameDispatch&>(packetDispatch);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
CGameDispatch*& m_lpGameDispatch;
|
||||
SERVER_ID m_serverID;
|
||||
};
|
||||
|
||||
|
||||
bool CharMoveZone(CSendStream& SendStream, PktSZMvD* lpPktSZMvD)
|
||||
{
|
||||
unsigned long dwRequestKey = lpPktSZMvD->m_dwRequestKey;
|
||||
unsigned long dwUID = lpPktSZMvD->m_dwUserID;
|
||||
|
||||
const POS& Pos = lpPktSZMvD->m_NewPos;
|
||||
char cZone = lpPktSZMvD->m_cZone;
|
||||
char cChannel = lpPktSZMvD->m_cChannel;
|
||||
|
||||
#ifdef ENABLE_PACKET_LOG
|
||||
DETLOG4(g_PacketLog, "ParseMoveZone::CharMoveZone : UID:%10u / CID:%10u / SessionID:%10u / ServerID:0x%08X / ",
|
||||
dwUID, 0, 0, 0);
|
||||
#endif
|
||||
|
||||
unsigned short usError = 0;
|
||||
|
||||
using namespace DataStorage;
|
||||
|
||||
CSessionData* lpSessionData = CSessionDataMgr::GetInstance().GetOpenSession(dwUID);
|
||||
CCharacterData* lpCharacterData = 0;
|
||||
|
||||
SERVER_ID serverID;
|
||||
serverID.sID.Type = CServerSetup::GameServer;
|
||||
serverID.sID.Group = CServerSetup::GetInstance().GetServerGroup();
|
||||
serverID.sID.Channel = cChannel;
|
||||
serverID.sID.ID = cZone;
|
||||
|
||||
CGameDispatch* lpGameDispatch = 0;
|
||||
|
||||
CGameDispatch::GetDispatchTable().Process(
|
||||
CFindGameServerDispatch(lpGameDispatch, serverID));
|
||||
|
||||
if (0 == lpSessionData)
|
||||
{
|
||||
ERRLOG1(g_Log, "UID:%10u / 캐릭터 이동 실패 : 세션이 열려 있지 않습니다.", dwUID);
|
||||
usError = PktSZMvDAck::FAIL_INVALID_CHAR;
|
||||
}
|
||||
else if (0 == (lpCharacterData = lpSessionData->GetCharacterData()))
|
||||
{
|
||||
ERRLOG1(g_Log, "UID:%10u / 캐릭터 이동 실패 : 캐릭터 데이터가 로드되지 않았습니다.", dwUID);
|
||||
usError = PktSZMvDAck::FAIL_INVALID_CHAR;
|
||||
}
|
||||
else if (0 == lpGameDispatch)
|
||||
{
|
||||
ERRLOG2(g_Log, "UID:%10u / ServerID:0x%08X / 캐릭터 이동 실패 : 서버가 없습니다.",
|
||||
dwUID, serverID.dwID);
|
||||
|
||||
usError = PktSZMvDAck::FAIL_INVALID_ZONE;
|
||||
}
|
||||
else if (0 == lpSessionData->GetAdminLevel())
|
||||
{
|
||||
// edith 2009.06.13 석상전 유저 수 체크
|
||||
if(SERVER_ID::STONE_WAR1 <= cZone && cZone <= SERVER_ID::STONE_WAR3)
|
||||
{
|
||||
if (CServerSetup::GetInstance().GetBattleLimit() < lpGameDispatch->GetCharNum())
|
||||
{
|
||||
// 사람이 너무 많다.
|
||||
ERRLOG2(g_Log, "UID:%10u / ServerID:0x%08X / 캐릭터 이동 실패 : 사람이 너무 많습니다.",
|
||||
dwUID, serverID.dwID);
|
||||
|
||||
usError = PktSZMvDAck::FAIL_PERSONNEL_OVER;
|
||||
}
|
||||
else
|
||||
{
|
||||
int maxDefaultUser = 10;
|
||||
float limitPer = (float)CServerSetup::GetInstance().GetBattleLimitPer()/100.f;
|
||||
if(limitPer < 1.0f)
|
||||
limitPer = 1.0f;
|
||||
|
||||
int akhanUser = lpGameDispatch->GetCharNum(CClass::AKHAN);
|
||||
int humanUser = lpGameDispatch->GetCharNum(CClass::HUMAN);
|
||||
|
||||
// 내가 인간이고, 인간이 아칸보다 1.5배 많은 상황이면 입장 불가.
|
||||
if (CClass::HUMAN == lpCharacterData->GetRace())
|
||||
{
|
||||
int overCount = (int)((float)akhanUser * limitPer) - akhanUser;
|
||||
if(overCount < maxDefaultUser)
|
||||
overCount = maxDefaultUser;
|
||||
|
||||
int overUser = akhanUser + overCount;
|
||||
|
||||
if(overUser < lpGameDispatch->GetCharNum(CClass::HUMAN))
|
||||
{
|
||||
ERRLOG2(g_Log, "UID:%10u / ServerID:0x%08X / 캐릭터 이동 실패 : 인간종족 불균형.",
|
||||
dwUID, serverID.dwID);
|
||||
|
||||
usError = PktSZMvDAck::FAIL_PERSONNEL_OVER;
|
||||
}
|
||||
}
|
||||
// 내가 아칸이고, 아칸이 인간보다 1.5배 많은 상황이면 입장 불가.
|
||||
else if (CClass::AKHAN == lpCharacterData->GetRace())
|
||||
{
|
||||
int overCount = (int)((float)humanUser * limitPer) - humanUser;
|
||||
if(overCount < maxDefaultUser)
|
||||
overCount = maxDefaultUser;
|
||||
|
||||
int overUser = humanUser + overCount;
|
||||
|
||||
if(overUser < lpGameDispatch->GetCharNum(CClass::AKHAN))
|
||||
{
|
||||
ERRLOG2(g_Log, "UID:%10u / ServerID:0x%08X / 캐릭터 이동 실패 : 아칸종족 불균형.",
|
||||
dwUID, serverID.dwID);
|
||||
|
||||
usError = PktSZMvDAck::FAIL_PERSONNEL_OVER;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (SERVER_ID::ZONE3 == cZone)
|
||||
{
|
||||
// 배틀그라운드의 경우 인원 제한 체크
|
||||
// 2008.10.12 ZONE3번 유저 설정 제거.
|
||||
ERRLOG3(g_Log, "UID:%10u / 3번 존 접속 시도 : Zone(%d,%d)", dwUID, cZone, cChannel);
|
||||
usError = PktSZMvDAck::FAIL_INVALID_CHAR;
|
||||
|
||||
/*
|
||||
SYSTEMTIME systemTime;
|
||||
GetSystemTime(&systemTime);
|
||||
|
||||
// 배틀 그라운드 휴식 시간동안에는 각 종족의 초기 존으로 이동 시켜준다.
|
||||
if ((systemTime.wMinute >= STATUE_REST_TIME_1ST_START && systemTime.wMinute <= STATUE_REST_TIME_1ST_END) ||
|
||||
(systemTime.wMinute >= STATUE_REST_TIME_2ND_START && systemTime.wMinute <= STATUE_REST_TIME_2ND_END))
|
||||
{
|
||||
cZone = lpDataSession->GetCharDataSession().GetCharStartZone(lpCharacterData->GetRace());
|
||||
}
|
||||
*/
|
||||
/* SERVER_ID serverID;
|
||||
serverID.sID.Type = CServerSetup::GameServer;
|
||||
serverID.sID.Group = CServerSetup::GetInstance().GetServerGroup();
|
||||
serverID.sID.Channel = cChannel;
|
||||
serverID.sID.ID = cZone;
|
||||
|
||||
CGameDispatch* lpGameDispatch = 0;
|
||||
|
||||
CGameDispatch::GetDispatchTable().Process(
|
||||
CFindGameServerDispatch(lpGameDispatch, serverID));
|
||||
|
||||
if (0 == lpGameDispatch)
|
||||
{
|
||||
ERRLOG2(g_Log, "UID:%10u / ServerID:0x%08X / 캐릭터 이동 실패 : 서버가 없습니다.",
|
||||
dwUID, serverID.dwID);
|
||||
|
||||
usError = PktSZMvDAck::FAIL_INVALID_ZONE;
|
||||
}
|
||||
else if (CServerSetup::GetInstance().GetBattleLimit() > lpGameDispatch->GetCharNum())
|
||||
{
|
||||
// 내가 인간이고, 인간이 아칸보다 1.5배 많은 상황이면 입장 불가.
|
||||
if (CClass::HUMAN == lpCharacterData->GetRace() &&
|
||||
lpGameDispatch->GetCharNum(CClass::AKHAN) * 1.5 < lpGameDispatch->GetCharNum(CClass::HUMAN))
|
||||
{
|
||||
usError = PktSZMvDAck::FAIL_PERSONNEL_OVER;
|
||||
}
|
||||
// 내가 아칸이고, 아칸이 인간보다 1.5배 많은 상황이면 입장 불가.
|
||||
else if (CClass::AKHAN == lpCharacterData->GetRace() &&
|
||||
lpGameDispatch->GetCharNum(CClass::HUMAN ) * 1.5 < lpGameDispatch->GetCharNum(CClass::AKHAN))
|
||||
{
|
||||
usError = PktSZMvDAck::FAIL_PERSONNEL_OVER;
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
// if(SERVER_ID::STONE_WAR1 <= cZone && cZone <= SERVER_ID::STONE_WAR3)
|
||||
// usError = PktSZMvDAck::FAIL_PERSONNEL_OVER;
|
||||
|
||||
if(0 == usError && 0 != lpSessionData)
|
||||
{
|
||||
// 미리 갈 존 설정
|
||||
if (!lpSessionData->SetMoveZone(cZone, Pos))
|
||||
{
|
||||
/*
|
||||
if(SERVER_ID::ZONE5 == cZone && !CGameTimeDBMgr::GetInstance().IsEnterTime())
|
||||
{
|
||||
// 테섭용 신규존 진입제한에 걸렸음.
|
||||
DETLOG5(g_Log, "UID:%10u / Zone:%2u / X:%f / Y:%f / Z:%f / 캐릭터 이동 실패 : 신규존 진입제한.",
|
||||
dwUID, cZone, Pos.fPointX, Pos.fPointY, Pos.fPointZ);
|
||||
}
|
||||
else
|
||||
{
|
||||
ERRLOG5(g_Log, "UID:%10u / Zone:%2u / X:%f / Y:%f / Z:%f / 캐릭터 이동 실패 : 잘못된 존으로 이동 시도.",
|
||||
dwUID, cZone, Pos.fPointX, Pos.fPointY, Pos.fPointZ);
|
||||
}
|
||||
*/
|
||||
ERRLOG5(g_Log, "UID:%10u / Zone:%2u / X:%f / Y:%f / Z:%f / 캐릭터 이동 실패 : 잘못된 존으로 이동 시도.",
|
||||
dwUID, cZone, Pos.fPointX, Pos.fPointY, Pos.fPointZ);
|
||||
|
||||
usError = PktSZMvDAck::FAIL_INVALID_ZONE;
|
||||
}
|
||||
}
|
||||
|
||||
// edith 2009.06.28 존이동실패시 전쟁 플래그를 꺼준다.
|
||||
// gameserver에서 dbagnet로 패킷 전달하게 소스 수정함.
|
||||
if(0 != usError)
|
||||
{
|
||||
if(SERVER_ID::STONE_WAR1 <= cZone && cZone <= SERVER_ID::STONE_WAR3)
|
||||
lpCharacterData->SetRealmWarFlag(Creature::WAR_OFF);
|
||||
else if(SERVER_ID::CAPITAL == cZone)
|
||||
lpCharacterData->SetGuildWarFlag(Creature::WAR_OFF);
|
||||
}
|
||||
|
||||
return (-1 == cChannel || 0 != usError) ?
|
||||
// 채널이 -1이거나, 에러가 있는 경우 이 패킷을 보냄.
|
||||
SendPacket::CharMoveZone(SendStream, dwRequestKey, cZone, usError)
|
||||
: SendPacket::ServerZone(SendStream, dwRequestKey, cZone, cChannel);
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool ServerZone(CSendStream& SendStream, PktSA* lpPktSA)
|
||||
{
|
||||
unsigned long dwUID = lpPktSA->m_dwUserID;
|
||||
unsigned short usError = 0;
|
||||
|
||||
#ifdef ENABLE_PACKET_LOG
|
||||
DETLOG4(g_PacketLog, "ParseMoveZone::ServerZone : UID:%10u / CID:%10u / SessionID:%10u / ServerID:0x%08X / ",
|
||||
dwUID, 0, 0, 0);
|
||||
#endif
|
||||
|
||||
using namespace DataStorage;
|
||||
CSessionData* lpSessionData = CSessionDataMgr::GetInstance().GetOpenSession(dwUID);
|
||||
if (0 == lpSessionData)
|
||||
{
|
||||
ERRLOG1(g_Log, "UID:%10u / ServerZone 실패 : 세션이 열려 있지 않습니다.", dwUID);
|
||||
usError = PktSAAck::SERVER_ERROR;
|
||||
}
|
||||
|
||||
return SendPacket::ServerZone(SendStream,
|
||||
lpPktSA->m_dwRequestKey, lpPktSA->m_cZone, lpPktSA->m_cChannel, usError);
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool ServerZoneEnd(CSendStream& SendStream, PktDD* lpPktDD)
|
||||
{
|
||||
#ifdef ENABLE_PACKET_LOG
|
||||
DETLOG4(g_PacketLog, "ParseMoveZone::ServerZoneEnd : UID:%10u / CID:%10u / SessionID:%10u / ServerID:0x%08X / ",
|
||||
0, 0, 0, 0);
|
||||
#endif
|
||||
|
||||
return SendPacket::ServerZoneEnd(SendStream, lpPktDD->m_dwRequestKey);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
#ifndef _DBAGENT_SERVER_PARSE_MOVE_ZONE_H_
|
||||
#define _DBAGENT_SERVER_PARSE_MOVE_ZONE_H_
|
||||
|
||||
// forward delc.
|
||||
class CSendStream;
|
||||
struct PktBase;
|
||||
|
||||
namespace DBAgent
|
||||
{
|
||||
namespace ParseMoveZone
|
||||
{
|
||||
bool Parse(CSendStream& SendStream, PktBase* lpPktBase);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,386 @@
|
||||
#include "stdafx.h"
|
||||
#include "ParseParty.h"
|
||||
|
||||
#include <Community/Party/PartyDBInfo.h>
|
||||
#include <Community/Party/PartyDBMgr.h>
|
||||
#include <Community/Guild/Guild.h>
|
||||
#include <Community/Guild/GuildMgr.h>
|
||||
|
||||
#include <Network/Stream/SendStream.h>
|
||||
#include <Network/Packet/PacketCommand.h>
|
||||
#include <Network/Packet/WrapPacket.h>
|
||||
#include <Network/Packet/PacketStruct/PartyPacket.h>
|
||||
#include <Network/Dispatch/GameDispatch.h>
|
||||
#include <Network/SendPacket/SendParty.h>
|
||||
|
||||
#include <Log/ServerLog.h>
|
||||
#include <DB/DBComponent.h>
|
||||
|
||||
#include <DataStorage/SessionData.h>
|
||||
#include <DataStorage/CharacterData.h>
|
||||
#include <DataStorage/SessionDataMgr.h>
|
||||
|
||||
#include <Community/Guild/Guild.h>
|
||||
|
||||
namespace DBAgent
|
||||
{
|
||||
namespace ParseParty
|
||||
{
|
||||
|
||||
bool CreateParty(CSendStream& SendStream, PktCPD* lpPktCPD);
|
||||
bool DeleteParty(CSendStream& SendStream, PktDPD* lpPktDPD);
|
||||
bool GetPartyInfo(CSendStream& SendStream, PktPID* lpPktPID);
|
||||
bool TransferLeader(CSendStream& SendStream, PktPMD* lpPktPMD);
|
||||
bool InsertPartyMember(CSendStream& SendStream, PktPMD* lpPktPMD);
|
||||
bool DeletePartyMember(CSendStream& SendStream, PktPMD* lpPktPMD);
|
||||
bool AutoRoutingOn(CSendStream& SendStream, PktPMD* lpPktPMD);
|
||||
bool AutoRoutingOff(CSendStream& SendStream, PktPMD* lpPktPMD);
|
||||
bool RelayPacket(CSendStream& SendStream, PktDD* lpPktDD);
|
||||
|
||||
bool Parse(CSendStream& SendStream, PktBase* lpPktBase)
|
||||
{
|
||||
bool bResult = false;
|
||||
|
||||
PktDD* lpPktDD = static_cast<PktDD*>(lpPktBase);
|
||||
|
||||
switch (lpPktDD->m_wCmd)
|
||||
{
|
||||
case PktDD::SCmdCreateParty: bResult = CreateParty(SendStream, static_cast<PktCPD*>(lpPktDD)); break; // 파티 생성
|
||||
case PktDD::SCmdDeleteParty: bResult = DeleteParty(SendStream, static_cast<PktDPD*>(lpPktDD)); break; // 파티 삭제
|
||||
case PktDD::SCmdGetPartyInfo: bResult = GetPartyInfo(SendStream, static_cast<PktPID*>(lpPktDD)); break; // 파티 정보 얻기
|
||||
case PktDD::SCmdTransferLeader: bResult = TransferLeader(SendStream, static_cast<PktPMD*>(lpPktDD)); break; // 파피 리더 양도
|
||||
case PktDD::SCmdInsertPartyMem: bResult = InsertPartyMember(SendStream, static_cast<PktPMD*>(lpPktDD)); break; // 파티 멤버 추가
|
||||
case PktDD::SCmdDeletePartyMem: bResult = DeletePartyMember(SendStream, static_cast<PktPMD*>(lpPktDD)); break; // 파티 멤버 삭제
|
||||
|
||||
case PktDD::SCmdDeadPartyMem:
|
||||
case PktDD::SCmdMoveZonePartyMem:
|
||||
case PktDD::SCmdLevelUpPartyMem:
|
||||
case PktDD::SCmdChangeClassPartyMem:
|
||||
case PktDD::SCmdChangeGuildPartyMem:
|
||||
bResult = RelayPacket(SendStream, lpPktDD);
|
||||
break;
|
||||
|
||||
case PktDD::SCmdAutoRoutingOn: bResult = AutoRoutingOn(SendStream, static_cast<PktPMD*>(lpPktDD)); break; // 파티 오토루팅 켜기
|
||||
case PktDD::SCmdAutoRoutingOff: bResult = AutoRoutingOff(SendStream, static_cast<PktPMD*>(lpPktDD)); break; // 파티 오토루팅 끄기
|
||||
|
||||
default:
|
||||
bResult = true;
|
||||
ERRLOG1(g_Log, "파티 로그 : Cmd:0x%02x 알 수 없는 파티 명령임", lpPktDD->m_wCmd);
|
||||
break;
|
||||
}
|
||||
|
||||
if(!bResult)
|
||||
{
|
||||
ERRLOG1(g_Log, "파티 로그 : Cmd:0x%02x 명령 처리 실패.", lpPktDD->m_wCmd);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CreateParty(CSendStream& SendStream, PktCPD* lpPktCPD)
|
||||
{
|
||||
// 파티 생성
|
||||
CPartyDBInfo* lpParty = CPartyDBMgr::GetInstance().CreateParty(CDBSingleObject::GetInstance(), lpPktCPD->m_dwLeaderID, lpPktCPD->m_cLeaderLevel,
|
||||
lpPktCPD->m_wLeaderClass, lpPktCPD->m_dwLeaderGID, lpPktCPD->m_dwMemberID, lpPktCPD->m_cMemberLevel, lpPktCPD->m_wMemberClass, lpPktCPD->m_dwMemberGID);
|
||||
|
||||
char* lpBuffer = 0;
|
||||
|
||||
if (0 == lpParty)
|
||||
{
|
||||
ERRLOG2(g_Log, "파티 로그 : LeaderCID:%10u / MemberCID:%10u / 파티 생성 실패 : 파티 생성 실패",
|
||||
lpPktCPD->m_dwLeaderID, lpPktCPD->m_dwMemberID);
|
||||
}
|
||||
else
|
||||
{
|
||||
PktCPDAck sPktCPDAck;
|
||||
memset(&sPktCPDAck, 0, sizeof(PktCPDAck));
|
||||
sPktCPDAck.m_wCmd = lpPktCPD->m_wCmd;
|
||||
sPktCPDAck.m_Party = lpParty->GetParty();
|
||||
|
||||
sPktCPDAck.m_dwLeaderID = lpPktCPD->m_dwLeaderID;
|
||||
sPktCPDAck.m_dwMemberID = lpPktCPD->m_dwMemberID;
|
||||
sPktCPDAck.m_dwLeaderGID = lpPktCPD->m_dwLeaderGID;
|
||||
sPktCPDAck.m_wLeaderClass = lpPktCPD->m_wLeaderClass;
|
||||
sPktCPDAck.m_cLeaderLevel = lpPktCPD->m_cLeaderLevel;
|
||||
sPktCPDAck.m_dwMemberGID = lpPktCPD->m_dwMemberGID;
|
||||
sPktCPDAck.m_wMemberClass = lpPktCPD->m_wMemberClass;
|
||||
sPktCPDAck.m_cMemberLevel = lpPktCPD->m_cMemberLevel;
|
||||
|
||||
// 캐릭터 정보 업데이트 //
|
||||
lpParty->SetUserInfoLevel(lpPktCPD->m_dwLeaderID, lpPktCPD->m_cLeaderLevel);
|
||||
lpParty->SetUserInfoClass(lpPktCPD->m_dwLeaderID, lpPktCPD->m_wLeaderClass);
|
||||
lpParty->SetUserInfoGID(lpPktCPD->m_dwLeaderID, lpPktCPD->m_dwLeaderGID);
|
||||
|
||||
lpParty->SetUserInfoLevel(lpPktCPD->m_dwMemberID, lpPktCPD->m_cMemberLevel);
|
||||
lpParty->SetUserInfoClass(lpPktCPD->m_dwMemberID, lpPktCPD->m_wMemberClass);
|
||||
lpParty->SetUserInfoGID(lpPktCPD->m_dwMemberID, lpPktCPD->m_dwMemberGID);
|
||||
|
||||
if(PacketWrap::WrapHeader(reinterpret_cast<char*>(&sPktCPDAck), sizeof(PktCPDAck), CmdAgentParty, 0, 0))
|
||||
{
|
||||
// 게임 서버로 브로드캐스팅 //
|
||||
DBAgent::CGameDispatch::GetDispatchTable().Process(CSendPacketAllServer(
|
||||
reinterpret_cast<char*>(&sPktCPDAck), sizeof(PktCPDAck), CmdAgentParty));
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool DeleteParty(CSendStream& SendStream, PktDPD* lpPktDPD)
|
||||
{
|
||||
// 파티 삭제
|
||||
if (!CPartyDBMgr::GetInstance().DestoryParty(
|
||||
CDBSingleObject::GetInstance(), lpPktDPD->m_dwPartyID))
|
||||
{
|
||||
ERRLOG1(g_Log, "파티 로그 : PID:%10u / 파티 삭제 실패", lpPktDPD->m_dwPartyID);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool GetPartyInfo(CSendStream& SendStream, PktPID* lpPktPID)
|
||||
{
|
||||
unsigned long dwPID = lpPktPID->m_dwPartyID;
|
||||
unsigned long dwCID = lpPktPID->m_dwCharID;
|
||||
|
||||
// 파티 열기
|
||||
CPartyDBInfo* lpParty = CPartyDBMgr::GetInstance().OpenParty(
|
||||
CDBSingleObject::GetInstance(), dwPID);
|
||||
|
||||
if (0 == lpParty)
|
||||
{
|
||||
ERRLOG2(g_Log, "파티 로그 : PID:%10u / CID:%10u / 파티 정보 얻기 실패 : 파티 얻기 실패",
|
||||
dwPID, dwCID);
|
||||
}
|
||||
else
|
||||
{
|
||||
unsigned long dwServerID = 0;
|
||||
|
||||
using namespace DataStorage;
|
||||
CSessionData* lpSessionData = CSessionDataMgr::GetInstance().GetCharLoadedSession(dwCID);
|
||||
if(0 != lpSessionData)
|
||||
{
|
||||
dwServerID = lpSessionData->GetServerID();
|
||||
}
|
||||
|
||||
// lpParty->PartyMemAllLogout();
|
||||
// lpParty->PartyMemLogin(dwCID, dwSID);
|
||||
// lpParty->SetLeader(dwCID);
|
||||
|
||||
DETLOG2(g_Log, "파티 로그 : PID:%10u / CID:%10u / 파티 정보 얻기", dwPID, dwCID);
|
||||
|
||||
// 패킷 보내기
|
||||
PktPIDAck pktPIDAck;
|
||||
memset(&pktPIDAck, 0, sizeof(PktPIDAck));
|
||||
|
||||
pktPIDAck.m_wCmd = lpPktPID->m_wCmd;
|
||||
pktPIDAck.m_Party = lpParty->GetParty();
|
||||
pktPIDAck.m_dwCharID = lpPktPID->m_dwCharID;
|
||||
pktPIDAck.m_dwGID = lpPktPID->m_dwGID;
|
||||
pktPIDAck.m_wClass = lpPktPID->m_wClass;
|
||||
pktPIDAck.m_cLevel = lpPktPID->m_cLevel;
|
||||
pktPIDAck.m_dwServerID = lpPktPID->m_dwServerID;
|
||||
|
||||
if(PacketWrap::WrapHeader(reinterpret_cast<char*>(&pktPIDAck),
|
||||
sizeof(PktPIDAck), CmdAgentParty, 0, 0))
|
||||
{
|
||||
// 게임 서버로 브로드캐스팅 //
|
||||
CGameDispatch::GetDispatchTable().Process(CSendPacketAllServer(
|
||||
reinterpret_cast<char*>(&pktPIDAck), sizeof(PktPIDAck), CmdAgentParty));
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool TransferLeader(CSendStream& SendStream, PktPMD* lpPktPMD)
|
||||
{
|
||||
unsigned long dwPartyID = lpPktPMD->m_dwPartyID;
|
||||
unsigned long dwSenderID = lpPktPMD->m_dwSenderID;
|
||||
unsigned long dwReferenceID = lpPktPMD->m_dwGID;
|
||||
|
||||
using namespace DataStorage;
|
||||
CSessionData* lpSessionData = CSessionDataMgr::GetInstance().GetCharLoadedSession(dwSenderID);
|
||||
CCharacterData* lpCharacterData = 0;
|
||||
CPartyDBInfo* lpParty = 0;
|
||||
|
||||
if(0 == lpSessionData)
|
||||
{
|
||||
ERRLOG2(g_Log, "파티 로그 : PID:%10u / CID:%10u / 리더 이양 실패 : 캐릭터 찾기 실패",
|
||||
dwPartyID, dwSenderID);
|
||||
}
|
||||
else if(0 == (lpCharacterData = lpSessionData->GetCharacterData()))
|
||||
{
|
||||
ERRLOG2(g_Log, "파티 로그 : PID:%10u / CID:%10u / 리더 이양 실패 : 캐릭터 데이터 없음",
|
||||
dwPartyID, dwSenderID);
|
||||
}
|
||||
else if(0 == (lpParty = CPartyDBMgr::GetInstance().FindPartyMap(dwPartyID)))
|
||||
{
|
||||
ERRLOG2(g_Log, "파티 로그 : PID:%10u / CID:%10u / 리더 이양 실패 : 파티 찾기 실패",
|
||||
dwPartyID, dwSenderID);
|
||||
}
|
||||
else if(!lpParty->TransferLeader(dwReferenceID, dwSenderID))
|
||||
{
|
||||
ERRLOG3(g_Log, "파티 로그 : PID:%10u / OldLeaderCID:%10u / NewLeaderCID:%10u / 리더 이양 실패",
|
||||
dwPartyID, dwReferenceID, dwSenderID);
|
||||
}
|
||||
else
|
||||
{
|
||||
DETLOG3(g_Log, "파티 로그 : PID:%10u / OldLeaderCID:%10u / NewLeaderCID:%10u / 리더 이양 성공",
|
||||
dwPartyID, dwReferenceID, dwSenderID);
|
||||
|
||||
SendPacket::PartyCmd(PktDD::SCmdTransferLeader, lpParty->GetPID(), dwSenderID, 0, 0,
|
||||
lpSessionData->GetServerID(), 0, lpCharacterData->GetName());
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool InsertPartyMember(CSendStream& SendStream, PktPMD* lpPktPMD)
|
||||
{
|
||||
unsigned long dwPartyID = lpPktPMD->m_dwPartyID;
|
||||
unsigned long dwSenderID = lpPktPMD->m_dwSenderID;
|
||||
unsigned long dwGID = lpPktPMD->m_dwGID;
|
||||
unsigned short wClass = lpPktPMD->m_wClass;
|
||||
char cLevel = lpPktPMD->m_cLevel;
|
||||
|
||||
// 파티원 추가
|
||||
if (!CPartyDBMgr::GetInstance().InsertPartyMember(
|
||||
CDBSingleObject::GetInstance(), dwPartyID, dwSenderID, dwGID, wClass, cLevel))
|
||||
{
|
||||
ERRLOG2(g_Log, "파티 로그 : PID:%10u / CID:%10u / 파티 멤버 추가 실패", dwPartyID, dwSenderID);
|
||||
}
|
||||
|
||||
CPartyDBInfo* lpParty = CPartyDBMgr::GetInstance().OpenParty(CDBSingleObject::GetInstance(), dwPartyID);
|
||||
|
||||
if(lpParty)
|
||||
{
|
||||
// 캐릭터 정보 업데이트 //
|
||||
lpParty->SetUserInfoLevel(dwSenderID, cLevel);
|
||||
lpParty->SetUserInfoClass(dwSenderID, wClass);
|
||||
lpParty->SetUserInfoGID(dwSenderID, dwGID);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool DeletePartyMember(CSendStream& SendStream, PktPMD* lpPktPMD)
|
||||
{
|
||||
unsigned long dwPartyID = lpPktPMD->m_dwPartyID;
|
||||
unsigned long dwSenderID = lpPktPMD->m_dwSenderID;
|
||||
unsigned long dwReferenceID = lpPktPMD->m_dwGID;
|
||||
|
||||
// 킥의 경우
|
||||
if (dwSenderID != dwReferenceID)
|
||||
{
|
||||
dwReferenceID = 0;
|
||||
}
|
||||
|
||||
CPartyDBInfo* lpParty = CPartyDBMgr::GetInstance().OpenParty(CDBSingleObject::GetInstance(), dwPartyID);
|
||||
|
||||
if(lpParty)
|
||||
{
|
||||
// 캐릭터 정보 업데이트 //
|
||||
lpParty->SetUserInfoLevel(dwSenderID, 0);
|
||||
lpParty->SetUserInfoClass(dwSenderID, 0);
|
||||
lpParty->SetUserInfoGID(dwSenderID, 0);
|
||||
}
|
||||
|
||||
// 파티원 삭제
|
||||
if (!CPartyDBMgr::GetInstance().DeletePartyMember(
|
||||
CDBSingleObject::GetInstance(), dwPartyID, dwSenderID, dwReferenceID))
|
||||
{
|
||||
ERRLOG2(g_Log, "파티 로그 : PID:%10u / CID:%10u / 파티 멤버 삭제 실패", dwPartyID, dwSenderID);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool AutoRoutingOn(CSendStream& SendStream, PktPMD* lpPktPMD)
|
||||
{
|
||||
unsigned long dwPartyID = lpPktPMD->m_dwPartyID;
|
||||
unsigned long dwSenderID = lpPktPMD->m_dwSenderID;
|
||||
unsigned long dwReferenceID = lpPktPMD->m_dwGID;
|
||||
|
||||
// 오토루팅 켜기
|
||||
if (!CPartyDBMgr::GetInstance().AutoRoutingOn(
|
||||
CDBSingleObject::GetInstance(), dwPartyID, dwSenderID))
|
||||
{
|
||||
ERRLOG2(g_Log, "파티 로그 : PID:%10u / CID:%10u / 캐릭터의 오토루팅 켜기 실패 (CID 가 0이면 ALL)",
|
||||
dwPartyID, dwSenderID);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool AutoRoutingOff(CSendStream& SendStream, PktPMD* lpPktPMD)
|
||||
{
|
||||
unsigned long dwPartyID = lpPktPMD->m_dwPartyID;
|
||||
unsigned long dwSenderID = lpPktPMD->m_dwSenderID;
|
||||
unsigned long dwReferenceID = lpPktPMD->m_dwGID;
|
||||
|
||||
// 오토루팅 끄기
|
||||
if (!CPartyDBMgr::GetInstance().AutoRoutingOff(
|
||||
CDBSingleObject::GetInstance(), dwPartyID, dwSenderID))
|
||||
{
|
||||
ERRLOG2(g_Log, "파티 로그 : PID:%10u / CID:%10u / 캐릭터의 오토루팅 끄기 실패 (CID 가 0이면 ALL)",
|
||||
dwPartyID, dwSenderID);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool RelayPacket(CSendStream& SendStream, PktDD* lpPktDD)
|
||||
{
|
||||
unsigned short usPacketSize = lpPktDD->GetLen();
|
||||
|
||||
switch(lpPktDD->m_wCmd)
|
||||
{
|
||||
case PktDD::SCmdLevelUpPartyMem:
|
||||
case PktDD::SCmdChangeClassPartyMem:
|
||||
case PktDD::SCmdChangeGuildPartyMem:
|
||||
{
|
||||
PktPMD* lpPktPMD = static_cast<PktPMD*>(lpPktDD);
|
||||
|
||||
CPartyDBInfo* lpParty = CPartyDBMgr::GetInstance().OpenParty(CDBSingleObject::GetInstance(), lpPktPMD->m_dwPartyID);
|
||||
|
||||
if(lpParty)
|
||||
{
|
||||
// 캐릭터 정보 업데이트 //
|
||||
if(PktDD::SCmdLevelUpPartyMem)
|
||||
{
|
||||
lpParty->SetUserInfoLevel(lpPktPMD->m_dwSenderID, lpPktPMD->m_cLevel);
|
||||
}
|
||||
if(PktDD::SCmdChangeClassPartyMem)
|
||||
{
|
||||
lpParty->SetUserInfoClass(lpPktPMD->m_dwSenderID, lpPktPMD->m_wClass);
|
||||
}
|
||||
if(PktDD::SCmdChangeGuildPartyMem)
|
||||
{
|
||||
lpParty->SetUserInfoGID(lpPktPMD->m_dwSenderID, lpPktPMD->m_dwGID);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if(PacketWrap::WrapHeader(reinterpret_cast<char*>(lpPktDD),
|
||||
usPacketSize, CmdAgentParty, 0, 0))
|
||||
{
|
||||
CGameDispatch::GetDispatchTable().Process(CSendPacketAllServer(
|
||||
reinterpret_cast<char*>(lpPktDD), usPacketSize, CmdAgentParty));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
#ifndef _DBAGENT_SERVER_PARSE_PARTY_H_
|
||||
#define _DBAGENT_SERVER_PARSE_PARTY_H_
|
||||
|
||||
// forward delc.
|
||||
class CSendStream;
|
||||
struct PktBase;
|
||||
|
||||
namespace DBAgent
|
||||
{
|
||||
namespace ParseParty
|
||||
{
|
||||
bool Parse(CSendStream& SendStream, PktBase* lpPktBase);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,244 @@
|
||||
#include "stdafx.h"
|
||||
#include "SendAdminTool.h"
|
||||
|
||||
#include <Network/Packet/PacketStruct/CharAdminPacket.h>
|
||||
#include <Network/Packet/PacketStruct/GameEventPacket.h>
|
||||
#include <Network/Packet/PacketStruct/CharLoginOutPacketStruct.h>
|
||||
#include <Network/Dispatch/AdminToolDispatch.h>
|
||||
|
||||
#include <Network/Packet/WrapPacket.h>
|
||||
#include <Network/Packet/PacketCommand.h>
|
||||
|
||||
#include <Utility/Setup/ServerSetup.h>
|
||||
|
||||
#include <DataStorage/StoreData.h>
|
||||
#include <DataStorage/CharacterData.h>
|
||||
|
||||
#include <Log/ServerLog.h>
|
||||
|
||||
namespace DBAgent
|
||||
{
|
||||
namespace SendPacket
|
||||
{
|
||||
|
||||
bool ItemQtyCheck(unsigned long dwItemTypeID, unsigned long dwItemQty,
|
||||
unsigned long dwCurrentItemQty, time_t tStartTime, time_t tEndTime,
|
||||
unsigned char cType, unsigned short usError)
|
||||
{
|
||||
PktItemQtyControl pktItemQtyControl;
|
||||
memset(&pktItemQtyControl, 0, sizeof(PktItemQtyControl));
|
||||
|
||||
pktItemQtyControl.m_dwItemTypeID = dwItemTypeID;
|
||||
pktItemQtyControl.m_dwItemQty = dwItemQty;
|
||||
pktItemQtyControl.m_dwCurrentItemQty = dwCurrentItemQty;
|
||||
pktItemQtyControl.m_tStartTime = tStartTime;
|
||||
pktItemQtyControl.m_tEndTime = tEndTime;
|
||||
|
||||
pktItemQtyControl.m_cType = cType;
|
||||
pktItemQtyControl.m_cGroup = CServerSetup::GetInstance().GetServerGroup();
|
||||
|
||||
if(PacketWrap::WrapHeader(reinterpret_cast<char*>(&pktItemQtyControl),
|
||||
sizeof(PktItemQtyControl), CmdItemQtyCheck, 0, usError))
|
||||
{
|
||||
DBAgent::CAdminToolDispatch::GetDispatchTable().Process(
|
||||
CSendPacketAllServer(reinterpret_cast<char*>(&pktItemQtyControl),
|
||||
sizeof(PktItemQtyControl), CmdItemQtyCheck));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool AdminToolGetDataAck(CSendStream& SendStream, PktAdminToolGetData::GetDataType dataType,
|
||||
unsigned long dwRequestKey, unsigned long dwUID, unsigned long dwCID,
|
||||
const char* lpData, unsigned long dwDataSize, unsigned short usError,
|
||||
unsigned char cOldServerGroupID)
|
||||
{
|
||||
// 최대 패킷 크기보다 크면 에러
|
||||
if(sizeof(PktAdminToolGetDataAck) + dwDataSize <= MAX_PACKET_LEN)
|
||||
{
|
||||
char szPacket[PktMaxLen];
|
||||
|
||||
PktAdminToolGetDataAck* lpPktAdminToolGetDataAck =
|
||||
reinterpret_cast<PktAdminToolGetDataAck*>(szPacket);
|
||||
|
||||
lpPktAdminToolGetDataAck->m_dwRequestKey = dwRequestKey;
|
||||
lpPktAdminToolGetDataAck->m_dwUID = dwUID;
|
||||
lpPktAdminToolGetDataAck->m_dwCID = dwCID;
|
||||
lpPktAdminToolGetDataAck->m_cType = dataType;
|
||||
lpPktAdminToolGetDataAck->m_cOldServerGroupID = cOldServerGroupID; // Part2Selectable 타입에서 필요.
|
||||
|
||||
if(0 != lpData && 0 < dwDataSize)
|
||||
{
|
||||
memcpy(lpPktAdminToolGetDataAck + 1, lpData, dwDataSize);
|
||||
}
|
||||
else
|
||||
{
|
||||
dwDataSize = 0;
|
||||
}
|
||||
|
||||
return SendStream.WrapCompress(szPacket,
|
||||
static_cast<unsigned short>(sizeof(PktAdminToolGetDataAck) + dwDataSize),
|
||||
CmdAdminToolGetData, 0, usError);
|
||||
}
|
||||
|
||||
ERRLOG4(g_Log, "UID:%10u / CID:%10u / dwSize:%u / DataType:%d "
|
||||
"운영툴에 데이터 전송 실패 : 데이터 + 헤더 크기가 최대 패킷 크기 이상입니다",
|
||||
dwUID, dwCID, dwDataSize, dataType);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool AdminToolSetDataAck(CSendStream& SendStream, unsigned long dwRequestKey,
|
||||
unsigned long dwUID, unsigned long dwCID,
|
||||
unsigned char cType, unsigned short eErrorCode)
|
||||
{
|
||||
PktNewAdminToolSetDataAck* lpSetDataAck = reinterpret_cast<PktNewAdminToolSetDataAck*>(
|
||||
SendStream.GetBuffer(sizeof(PktNewAdminToolSetDataAck)));
|
||||
|
||||
if(0 != lpSetDataAck)
|
||||
{
|
||||
lpSetDataAck->m_dwRequestKey = dwRequestKey;
|
||||
lpSetDataAck->m_dwUID = dwUID;
|
||||
lpSetDataAck->m_dwCID = dwCID;
|
||||
lpSetDataAck->m_cType = cType;
|
||||
|
||||
return SendStream.WrapHeader(sizeof(PktNewAdminToolSetDataAck),
|
||||
CmdAdminToolSetData, 0, eErrorCode);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
inline void CopyAndAdvanceDst(char*& lpWritePos, const void* lpData, unsigned long dwSize)
|
||||
{
|
||||
memcpy(lpWritePos, lpData, dwSize);
|
||||
lpWritePos += dwSize;
|
||||
}
|
||||
|
||||
|
||||
// 캐릭터 데이터를 운영툴로 전송한다.
|
||||
bool TotalDataToAdminTool(CSendStream& SendStream, unsigned long dwRequestKey, IN_ADDR peerAddr,
|
||||
DataStorage::CStoreData& storeData, DataStorage::CCharacterData& characterData)
|
||||
{
|
||||
unsigned long dwUID = storeData.GetUID();
|
||||
unsigned long dwCID = characterData.GetCID();
|
||||
|
||||
const unsigned long MAX_CHAR_DATA_SIZE = DBUpdateData::MAX_DBUPDATE_SIZE +
|
||||
sizeof(unsigned short) * DBUpdateData::MAX_UPDATE_DB;
|
||||
|
||||
const unsigned long MAX_CHAR_EXTRA_DATA_SIZE = sizeof(CHAR_INFOEX) +
|
||||
sizeof(QUEST) + sizeof(HISTORY) + sizeof(CONFIG) + sizeof(STORE_INFO);
|
||||
|
||||
const unsigned long MAX_FRIEND_BAN_DATA_SIZE =
|
||||
std::max(CFriendList::MAX_FRIENDS_NUM * sizeof(FriendInfo),
|
||||
CBanList::MAX_BAN_NUM * sizeof(BanInfo));
|
||||
|
||||
const unsigned long MAX_ADMIN_TOOL_DATA_SIZE = std::max(
|
||||
std::max(MAX_CHAR_DATA_SIZE, MAX_CHAR_EXTRA_DATA_SIZE), MAX_FRIEND_BAN_DATA_SIZE);
|
||||
|
||||
char* szDataBuffer = new char[MAX_ADMIN_TOOL_DATA_SIZE];
|
||||
|
||||
if(0 == szDataBuffer)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
const int MAX_ADDR_LEN = 32;
|
||||
char szAdminToolAddr[MAX_ADDR_LEN];
|
||||
_snprintf(szAdminToolAddr, MAX_ADDR_LEN - 1, "%s", inet_ntoa(peerAddr));
|
||||
szAdminToolAddr[MAX_ADDR_LEN - 1] = 0;
|
||||
|
||||
// ------------------------------------------------------------------------------------------
|
||||
// CHAR_BASIC_DATA 전송
|
||||
|
||||
unsigned long dwCharDataWritten = MAX_ADMIN_TOOL_DATA_SIZE -
|
||||
sizeof(unsigned short) * DBUpdateData::MAX_UPDATE_DB;
|
||||
|
||||
char* szCharData = szDataBuffer + sizeof(unsigned short) * DBUpdateData::MAX_UPDATE_DB;
|
||||
unsigned short* usSizeArray = reinterpret_cast<unsigned short*>(szDataBuffer);
|
||||
|
||||
if(characterData.SerializeOut(szCharData, usSizeArray,
|
||||
dwCharDataWritten, DBUpdateData::MAX_UPDATE_DB))
|
||||
{
|
||||
dwCharDataWritten += sizeof(unsigned short) * DBUpdateData::MAX_UPDATE_DB;
|
||||
|
||||
if(SendPacket::AdminToolGetDataAck(SendStream, PktAdminToolGetData::CHAR_BASIC_DATA,
|
||||
dwRequestKey, dwUID, dwCID, szDataBuffer, dwCharDataWritten, 0))
|
||||
{
|
||||
INFLOG3(g_Log, "UID:%10u / CID:%10u / IP:%15s / 운영툴로 CHAR_BASIC_DATA 전송 성공", dwUID, dwCID, szAdminToolAddr);
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------
|
||||
// CHAR_EXTRA_DATA 전송
|
||||
|
||||
char* szExtraDataPos = szDataBuffer;
|
||||
|
||||
CopyAndAdvanceDst(szExtraDataPos, &characterData.GetInfoEx(), sizeof(CHAR_INFOEX));
|
||||
CopyAndAdvanceDst(szExtraDataPos, &characterData.GetQuest(), sizeof(QUEST));
|
||||
CopyAndAdvanceDst(szExtraDataPos, &characterData.GetHistory(), sizeof(HISTORY));
|
||||
CopyAndAdvanceDst(szExtraDataPos, &characterData.GetConfig(), sizeof(CONFIG));
|
||||
CopyAndAdvanceDst(szExtraDataPos, &storeData.GetStoreInfo(), sizeof(STORE_INFO));
|
||||
|
||||
if(SendPacket::AdminToolGetDataAck(SendStream,
|
||||
PktAdminToolGetData::CHAR_EXTRA_DATA, dwRequestKey, dwUID, dwCID, szDataBuffer,
|
||||
static_cast<unsigned long>(szExtraDataPos - szDataBuffer), 0))
|
||||
{
|
||||
INFLOG3(g_Log, "UID:%10u / CID:%10u / IP:%15s / 운영툴로 CHAR_EXTRA_DATA 전송 성공", dwUID, dwCID, szAdminToolAddr);
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------------------------
|
||||
// CHAR_FRIEND_DATA
|
||||
// CHAR_BAN_DATA
|
||||
|
||||
unsigned long dwFriendBanWritten = MAX_FRIEND_BAN_DATA_SIZE;
|
||||
|
||||
if(characterData.GetFriendList().SerializeOut(szDataBuffer, dwFriendBanWritten))
|
||||
{
|
||||
if(SendPacket::AdminToolGetDataAck(SendStream, PktAdminToolGetData::CHAR_FRIEND_DATA,
|
||||
dwRequestKey, dwUID, dwCID, szDataBuffer, dwFriendBanWritten, 0))
|
||||
{
|
||||
INFLOG3(g_Log, "UID:%10u / CID:%10u / IP:%15s / 운영툴로 CHAR_FRIEND_DATA 전송 성공", dwUID, dwCID, szAdminToolAddr);
|
||||
}
|
||||
}
|
||||
|
||||
dwFriendBanWritten = MAX_FRIEND_BAN_DATA_SIZE;
|
||||
if(characterData.GetBanList().SerializeOut(szDataBuffer, dwFriendBanWritten))
|
||||
{
|
||||
if(SendPacket::AdminToolGetDataAck(SendStream, PktAdminToolGetData::CHAR_BAN_DATA,
|
||||
dwRequestKey, dwUID, dwCID, szDataBuffer, dwFriendBanWritten, 0))
|
||||
{
|
||||
INFLOG3(g_Log, "UID:%10u / CID:%10u / IP:%15s / 운영툴로 CHAR_BAN_DATA 전송 성공", dwUID, dwCID, szAdminToolAddr);
|
||||
}
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------------------------
|
||||
// STORE_12_DATA
|
||||
|
||||
if(SendPacket::AdminToolGetDataAck(SendStream, PktAdminToolGetData::STORE_12_DATA,
|
||||
dwRequestKey, dwUID, dwCID, reinterpret_cast<const char*>(&storeData.GetStore1()), sizeof(STORE), 0))
|
||||
{
|
||||
INFLOG3(g_Log, "UID:%10u / CID:%10u / IP:%15s / 운영툴로 STORE_12_DATA 전송 성공", dwUID, dwCID, szAdminToolAddr);
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------------------------
|
||||
// STORE_34_DATA
|
||||
|
||||
if(SendPacket::AdminToolGetDataAck(SendStream, PktAdminToolGetData::STORE_34_DATA,
|
||||
dwRequestKey, dwUID, dwCID, reinterpret_cast<const char*>(&storeData.GetStore2()), sizeof(STORE), 0))
|
||||
{
|
||||
INFLOG3(g_Log, "UID:%10u / CID:%10u / IP:%15s / 운영툴로 STORE_34_DATA 전송 성공", dwUID, dwCID, szAdminToolAddr);
|
||||
}
|
||||
|
||||
delete [] szDataBuffer;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
#ifndef _DBAGENT_SERVER_SEND_ADMIN_TOOL_H_
|
||||
#define _DBAGENT_SERVER_SEND_ADMIN_TOOL_H_
|
||||
|
||||
#include <ctime>
|
||||
#include <Network/Packet/PacketStruct/CharAdminPacket.h>
|
||||
|
||||
// forward decl.
|
||||
class CSendStream;
|
||||
|
||||
|
||||
namespace DBAgent
|
||||
{
|
||||
|
||||
namespace DataStorage
|
||||
{
|
||||
// forward decl.
|
||||
class CStoreData;
|
||||
class CCharacterData;
|
||||
}
|
||||
|
||||
namespace SendPacket
|
||||
{
|
||||
|
||||
bool ItemQtyCheck(unsigned long dwItemTypeID, unsigned long dwItemQty,
|
||||
unsigned long dwCurrentItemQty, time_t tStartTime, time_t tEndTime,
|
||||
unsigned char cType, unsigned short usError = 0);
|
||||
|
||||
bool AdminToolGetDataAck(CSendStream& SendStream, PktAdminToolGetData::GetDataType dataType,
|
||||
unsigned long dwRequestKey, unsigned long dwUID, unsigned long dwCID,
|
||||
const char* lpData, unsigned long dwDataSize, unsigned short usError,
|
||||
unsigned char cOldServerGroupID = 0);
|
||||
|
||||
bool AdminToolSetDataAck(CSendStream& SendStream, unsigned long dwRequestKey,
|
||||
unsigned long dwUID, unsigned long dwCID, unsigned char cType, unsigned short eErrorCode);
|
||||
|
||||
bool TotalDataToAdminTool(CSendStream& SendStream, unsigned long dwRequestKey, IN_ADDR peerAddr,
|
||||
DataStorage::CStoreData& storeData, DataStorage::CCharacterData& characterData);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,331 @@
|
||||
#include "stdafx.h"
|
||||
#include "SendCharManage.h"
|
||||
|
||||
#include <Network/Stream/SendStream.h>
|
||||
#include <Network/Packet/PacketCommand.h>
|
||||
#include <Network/Packet/PacketStruct/AuthServerToDBAgentServer.h>
|
||||
#include <Network/Packet/PacketStruct/UnifiedCharPacket.h>
|
||||
#include <Network/Packet/PacketStruct/CharItemPacket.h>
|
||||
#include <Network/Packet/PacketStruct/CharStatusPacket.h>
|
||||
#include <Network/Dispatch/GameDispatch.h>
|
||||
|
||||
#include <Utility/Setup/ServerSetup.h>
|
||||
|
||||
#include <DB/DBdefine.h>
|
||||
|
||||
namespace DBAgent
|
||||
{
|
||||
namespace SendPacket
|
||||
{
|
||||
|
||||
// WORK_LIST 2.1 계정 국적 추가
|
||||
// 캐릭터 뷰 얻어오기
|
||||
bool UserLogin(CSendStream& SendStream, unsigned long dwRequestKey, unsigned long dwUID,
|
||||
const CHAR_VIEW* lpCharView, const sGuildData* lpGuildData, const STORE_INFO* pStoreInfo, unsigned long dwCharViewNum,
|
||||
unsigned char cAccountNation, int nPlayTime, unsigned char cAdminLevel, unsigned char cBillingUser,
|
||||
unsigned char cBillingType, unsigned char cLoginType, unsigned short usError)
|
||||
{
|
||||
char* lpBuffer = SendStream.GetBuffer(sizeof(PktULDAck));
|
||||
if(0 != lpBuffer)
|
||||
{
|
||||
PktULDAck* lpPktULDAck = reinterpret_cast<PktULDAck*>(lpBuffer);
|
||||
|
||||
lpPktULDAck->m_dwRequestKey = dwRequestKey;
|
||||
lpPktULDAck->m_wCmd = PktDD::SCmdUserLogin;
|
||||
|
||||
lpPktULDAck->m_nPlayTime = nPlayTime;
|
||||
lpPktULDAck->m_usAdminLevel = cAdminLevel;
|
||||
lpPktULDAck->m_cBillingUser = cBillingUser;
|
||||
lpPktULDAck->m_cBillingType = cBillingType;
|
||||
|
||||
lpPktULDAck->m_cLoginType = cLoginType;
|
||||
|
||||
lpPktULDAck->m_dwUserID = dwUID;
|
||||
|
||||
// WORK_LIST 2.1 계정 국적 추가
|
||||
lpPktULDAck->m_cAccountNation = cAccountNation;
|
||||
|
||||
memset(lpPktULDAck->m_CharView, 0, sizeof(CHAR_VIEW) * PktULDAck::MAX_CHAR_VIEW);
|
||||
memset(lpPktULDAck->m_GuildData, 0, sizeof(sGuildData) * PktULDAck::MAX_CHAR_VIEW);
|
||||
memset(&lpPktULDAck->m_sStoreInfo, 0, sizeof(STORE_INFO));
|
||||
|
||||
if(0 != lpCharView && 0 != dwCharViewNum)
|
||||
{
|
||||
memcpy(lpPktULDAck->m_CharView, lpCharView,
|
||||
sizeof(CHAR_VIEW) * std::min(unsigned long(PktULDAck::MAX_CHAR_VIEW), dwCharViewNum));
|
||||
|
||||
memcpy(lpPktULDAck->m_GuildData, lpGuildData, sizeof(sGuildData) * PktULDAck::MAX_CHAR_VIEW);
|
||||
|
||||
memcpy(&lpPktULDAck->m_sStoreInfo, pStoreInfo, sizeof(STORE_INFO));
|
||||
}
|
||||
|
||||
return SendStream.WrapHeader(sizeof(PktULDAck), CmdDBGetData, 0, usError);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// 캐릭터 선택.
|
||||
bool CharSelect(CSendStream& SendStream, unsigned long dwRequestKey,
|
||||
unsigned char cZone, unsigned short usError)
|
||||
{
|
||||
char* lpBuffer = SendStream.GetBuffer(sizeof(PktCSDAck));
|
||||
|
||||
if(0 != lpBuffer)
|
||||
{
|
||||
PktCSDAck* lpPktCSDAck = reinterpret_cast<PktCSDAck*>(lpBuffer);
|
||||
|
||||
lpPktCSDAck->m_dwRequestKey = dwRequestKey;
|
||||
lpPktCSDAck->m_wCmd = PktDD::SCmdCharSelect;
|
||||
lpPktCSDAck->m_cZone = cZone;
|
||||
|
||||
CUserPercentageInZone userPercentageInZone(
|
||||
lpPktCSDAck->m_wChannelNum, cZone, PktCSDAck::MAX_CHANNEL_NUM);
|
||||
|
||||
CGameDispatch::GetDispatchTable().Process(userPercentageInZone);
|
||||
|
||||
return SendStream.WrapHeader(sizeof(PktCSDAck), CmdDBGetData, 0, usError);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CharCreate(CSendStream& SendStream, unsigned long dwRequestKey,
|
||||
unsigned long dwCID, unsigned long dwSlot,
|
||||
const CHAR_VIEW& CharView, unsigned short usError)
|
||||
{
|
||||
char* lpBuffer = SendStream.GetBuffer(sizeof(PktCCDAck));
|
||||
|
||||
if(0 != lpBuffer)
|
||||
{
|
||||
PktCCDAck* lpPktCCDAck = reinterpret_cast<PktCCDAck*>(lpBuffer);
|
||||
|
||||
lpPktCCDAck->m_dwRequestKey = dwRequestKey;
|
||||
lpPktCCDAck->m_wCmd = PktDD::SCmdCharCreate;
|
||||
|
||||
lpPktCCDAck->m_dwCharID = dwCID;
|
||||
lpPktCCDAck->m_dwSlot = dwSlot;
|
||||
lpPktCCDAck->m_CharView = CharView;
|
||||
|
||||
return SendStream.WrapHeader(sizeof(PktCCDAck), CmdDBGetData, 0, usError);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CharDelete(CSendStream& SendStream, unsigned long dwRequestKey,
|
||||
unsigned long dwUID, unsigned long dwSlot,
|
||||
unsigned long dwCID, unsigned short usError)
|
||||
{
|
||||
char* lpBuffer = SendStream.GetBuffer(sizeof(PktCDD));
|
||||
|
||||
if(0 != lpBuffer)
|
||||
{
|
||||
PktCDD* lpPktCDDAck = reinterpret_cast<PktCDD*>(lpBuffer);
|
||||
|
||||
lpPktCDDAck->m_dwRequestKey = dwRequestKey;
|
||||
lpPktCDDAck->m_wCmd = PktDD::SCmdCharDelete;
|
||||
|
||||
lpPktCDDAck->m_dwUserID = dwUID;
|
||||
lpPktCDDAck->m_dwSlotNum = dwSlot;
|
||||
lpPktCDDAck->m_dwCharID = dwCID;
|
||||
|
||||
return SendStream.WrapHeader(sizeof(PktCDD), CmdDBGetData, 0, usError);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// WORK_LIST 2.1 계정 국적 추가
|
||||
bool SelectAccountNation(CSendStream& SendStream, unsigned long dwRequestKey, unsigned long dwUID,
|
||||
unsigned char cType, unsigned char cAccountNation, unsigned short usError)
|
||||
{
|
||||
char* lpBuffer = SendStream.GetBuffer(sizeof(PktSAND));
|
||||
|
||||
if (0 != lpBuffer)
|
||||
{
|
||||
PktSAND* lpPktSANDAck = reinterpret_cast<PktSAND*>(lpBuffer);
|
||||
|
||||
lpPktSANDAck->m_dwRequestKey = dwRequestKey;
|
||||
lpPktSANDAck->m_wCmd = PktDD::SCmdSelectNation;
|
||||
|
||||
lpPktSANDAck->m_dwUserID = dwUID;
|
||||
lpPktSANDAck->m_cType = cType;
|
||||
lpPktSANDAck->m_cAccountNation = cAccountNation;
|
||||
|
||||
return SendStream.WrapHeader(sizeof(PktSAND), CmdDBGetData, 0, usError);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// WORK_LIST 2.3 계정 국적 변경 기능 구현
|
||||
bool NationChangeResult(CSendStream& SendStream, unsigned long dwRequestKey, unsigned long dwUID,
|
||||
unsigned long* aryGID, unsigned long* aryFame)
|
||||
{
|
||||
char* lpBuffer = SendStream.GetBuffer(sizeof(PktANCAck));
|
||||
|
||||
if (0 != lpBuffer)
|
||||
{
|
||||
PktANCAck* lpPktANCAck = reinterpret_cast<PktANCAck*>(lpBuffer);
|
||||
|
||||
lpPktANCAck->m_dwRequestKey = dwRequestKey;
|
||||
lpPktANCAck->m_wCmd = PktDD::SCmdNationChangeResult;
|
||||
|
||||
lpPktANCAck->m_dwUserID = dwUID;
|
||||
::memcpy(lpPktANCAck->m_dwGID, aryGID, sizeof(unsigned long) * PktANCAck::MAX_CHAR_VIEW);
|
||||
::memcpy(lpPktANCAck->m_dwFame, aryFame, sizeof(unsigned long) * PktANCAck::MAX_CHAR_VIEW);
|
||||
|
||||
return SendStream.WrapHeader(sizeof(PktANCAck), CmdDBGetData, 0, 0);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool UnifiedCharInfo(CSendStream& SendStream, unsigned long dwUID,
|
||||
unsigned char cTransferedCharCount, const USER_INFO& userInfo,
|
||||
const UnifiedStoreInfo* lpUnifiedStoreInfo, unsigned long dwUnifiedStoreNum,
|
||||
const UnifiedCharData* lpUnifiedCharData, unsigned long dwUnifiedCharNum)
|
||||
{
|
||||
char* lpBuffer = SendStream.GetBuffer(sizeof(PktUnifiedCharInfo));
|
||||
|
||||
if (0 != lpBuffer)
|
||||
{
|
||||
PktUnifiedCharInfo* lpPktUnifiedCharInfo =
|
||||
reinterpret_cast<PktUnifiedCharInfo*>(lpBuffer);
|
||||
|
||||
lpPktUnifiedCharInfo->dwUID = dwUID;
|
||||
|
||||
unsigned long dwMinUnifiedStoreNum =
|
||||
std::min(unsigned long(PktUnifiedCharInfo::MAX_STORE_INFO), dwUnifiedStoreNum);
|
||||
|
||||
unsigned long dwMinUnifiedCharNum =
|
||||
std::min(unsigned long(PktUnifiedCharInfo::MAX_CHAR_DATA), dwUnifiedCharNum);
|
||||
|
||||
lpPktUnifiedCharInfo->cRestrictedPart1ToPart2Level =
|
||||
CServerSetup::GetInstance().GetRestrictedPart1ToPart2Level();
|
||||
|
||||
unsigned char cMaxTransferCount = CServerSetup::GetInstance().GetMaxTransferPart1ToPart2Count();
|
||||
|
||||
if (cTransferedCharCount <= cMaxTransferCount)
|
||||
{
|
||||
lpPktUnifiedCharInfo->cRemainCharTransferCount = cMaxTransferCount - cTransferedCharCount;
|
||||
}
|
||||
else
|
||||
{
|
||||
lpPktUnifiedCharInfo->cRemainCharTransferCount = 0;
|
||||
}
|
||||
|
||||
lpPktUnifiedCharInfo->userInfo = userInfo;
|
||||
|
||||
memcpy(lpPktUnifiedCharInfo->unifiedStoreInfo, lpUnifiedStoreInfo,
|
||||
sizeof(UnifiedStoreInfo) * dwMinUnifiedStoreNum);
|
||||
|
||||
memcpy(lpPktUnifiedCharInfo->unifiedCharData, lpUnifiedCharData,
|
||||
sizeof(UnifiedCharData) * dwMinUnifiedCharNum);
|
||||
|
||||
lpPktUnifiedCharInfo->cStoreInfoNum = static_cast<unsigned char>(dwMinUnifiedStoreNum);
|
||||
lpPktUnifiedCharInfo->cCharDataNum = static_cast<unsigned char>(dwMinUnifiedCharNum);
|
||||
|
||||
return SendStream.WrapHeader(sizeof(PktUnifiedCharInfo), CmdUnifiedCharInfo, 0, 0);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool UnifiedCharSelectReq(CSendStream& SendStream, unsigned long dwUID,
|
||||
unsigned long dwRequestKey, unsigned long* lpdwCID, unsigned long dwCIDNum,
|
||||
unsigned char cSelectedStoreServerGroup, unsigned char cSelectedNation)
|
||||
{
|
||||
char* lpBuffer = SendStream.GetBuffer(sizeof(PktUnifiedCharSelectReq));
|
||||
|
||||
if (0 != lpBuffer)
|
||||
{
|
||||
PktUnifiedCharSelectReq* lpPktUnifiedCharSelectReq =
|
||||
reinterpret_cast<PktUnifiedCharSelectReq*>(lpBuffer);
|
||||
|
||||
memset(lpPktUnifiedCharSelectReq->szPassword,
|
||||
0, sizeof(char) * PktUnifiedCharSelectReq::MAX_PASSWORD_LEN);
|
||||
|
||||
lpPktUnifiedCharSelectReq->dwUID= dwUID;
|
||||
lpPktUnifiedCharSelectReq->dwRequestKey = dwRequestKey;
|
||||
|
||||
memcpy(lpPktUnifiedCharSelectReq->dwCID, lpdwCID,
|
||||
sizeof(unsigned long) * min(long(USER_INFO::MAX_CHAR_NUM), long(dwCIDNum)));
|
||||
|
||||
lpPktUnifiedCharSelectReq->cSelectedServerGroupID = cSelectedStoreServerGroup;
|
||||
lpPktUnifiedCharSelectReq->cSelectedNation = cSelectedNation;
|
||||
|
||||
return SendStream.WrapHeader(sizeof(PktUnifiedCharSelectReq), CmdUnifiedCharSelect, 0, 0);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool UnifiedCharSelectAck(CSendStream& SendStream, unsigned long dwUID,
|
||||
unsigned long dwRequestKey, unsigned short usError)
|
||||
{
|
||||
char* lpBuffer = SendStream.GetBuffer(sizeof(PktUnifiedCharSelectAck));
|
||||
|
||||
if (0 != lpBuffer)
|
||||
{
|
||||
PktUnifiedCharSelectAck* lpPktUnifiedCharSelectAck =
|
||||
reinterpret_cast<PktUnifiedCharSelectAck*>(lpBuffer);
|
||||
|
||||
lpPktUnifiedCharSelectAck->dwUID = dwUID;
|
||||
lpPktUnifiedCharSelectAck->dwRequestKey = dwRequestKey;
|
||||
|
||||
return SendStream.WrapHeader(sizeof(PktUnifiedCharSelectAck),
|
||||
CmdUnifiedCharSelect, 0, usError);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CharUseCashItem(CSendStream& SendStream, unsigned long dwSender, unsigned long dwReceiver,
|
||||
Item::ItemPos itemPos, unsigned char cRemainItemNum, unsigned short usError)
|
||||
{
|
||||
char* lpBuffer = SendStream.GetBuffer(sizeof(PktUI));
|
||||
|
||||
if (NULL != lpBuffer)
|
||||
{
|
||||
PktUI* lpPktUI = reinterpret_cast<PktUI*>(lpBuffer);
|
||||
|
||||
lpPktUI->m_dwSender = dwSender;
|
||||
lpPktUI->m_dwRecver = dwReceiver;
|
||||
lpPktUI->m_itemPos = itemPos;
|
||||
lpPktUI->m_cRemainItemNum = cRemainItemNum;
|
||||
|
||||
return SendStream.WrapCrypt(sizeof(PktUI), CmdCharUseCashItem, 0, usError);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CharExtraEvent(CSendStream& SendStream, unsigned long dwUID, unsigned long dwCID,
|
||||
unsigned long dwEventID, unsigned long dwValue1, unsigned long dwValue2, unsigned short usError)
|
||||
{
|
||||
// edith 2009.09.05 신규 이벤트 제작부분
|
||||
|
||||
char* lpBuffer = SendStream.GetBuffer(sizeof(PktExtraEvent));
|
||||
|
||||
if (NULL != lpBuffer)
|
||||
{
|
||||
PktExtraEvent* lpPktEE = reinterpret_cast<PktExtraEvent*>(lpBuffer);
|
||||
|
||||
lpPktEE->m_dwUserID = dwUID;
|
||||
lpPktEE->m_dwCharID = dwCID;
|
||||
lpPktEE->m_dwEventID = dwEventID;
|
||||
lpPktEE->m_dwValue1 = dwValue1;
|
||||
lpPktEE->m_dwValue2 = dwValue2;
|
||||
|
||||
return SendStream.WrapCrypt(sizeof(PktExtraEvent), CmdExtraEvent, 0, usError);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
#ifndef _DBAGENT_SERVER_SEND_CHAR_MANAGE_H_
|
||||
#define _DBAGENT_SERVER_SEND_CHAR_MANAGE_H_
|
||||
|
||||
#include <DB/DBdefine.h>
|
||||
#include <Item/Item.h>
|
||||
|
||||
// forward decl.
|
||||
class CSendStream;
|
||||
struct USER_INFO;
|
||||
struct CHAR_VIEW;
|
||||
struct sGuildData;
|
||||
struct UnifiedStoreInfo;
|
||||
struct UnifiedCharData;
|
||||
|
||||
namespace DBAgent
|
||||
{
|
||||
namespace DataStorage
|
||||
{
|
||||
// forward delc.
|
||||
class CSessionData;
|
||||
}
|
||||
|
||||
namespace SendPacket
|
||||
{
|
||||
// WORK_LIST 2.1 계정 국적 추가
|
||||
// 캐릭터 뷰 얻어 오기
|
||||
bool UserLogin(CSendStream& SendStream, unsigned long dwRequestKey, unsigned long dwUID,
|
||||
const CHAR_VIEW* lpCharView, const sGuildData* lpGuildData, const STORE_INFO* pStoreInfo, unsigned long dwCharViewNum,
|
||||
unsigned char cAccountNation, int nPlayTime, unsigned char cAdminLevel, unsigned char cBillingUser,
|
||||
unsigned char cBillingType, unsigned char cLoginType, unsigned short usError);
|
||||
|
||||
// 캐릭터 선택
|
||||
bool CharSelect(CSendStream& SendStream, unsigned long dwRequestKey,
|
||||
unsigned char cZone, unsigned short usError);
|
||||
|
||||
// 캐릭터 생성
|
||||
bool CharCreate(CSendStream& SendStream, unsigned long dwRequestKey,
|
||||
unsigned long dwCID, unsigned long dwSlot, const CHAR_VIEW& CharView, unsigned short usError);
|
||||
|
||||
// 캐릭터 삭제
|
||||
bool CharDelete(CSendStream& SendStream, unsigned long dwRequestKey,
|
||||
unsigned long dwUID, unsigned long dwSlot, unsigned long dwCID, unsigned short usError);
|
||||
|
||||
// 아이템 생성
|
||||
bool CharCreateItem(CSendStream& SendStream, unsigned long dwRequestKey,
|
||||
unsigned char cZone, unsigned short usError);
|
||||
|
||||
// WORK_LIST 2.1 계정 국적 추가
|
||||
// 계정 국적 설정 및 변경
|
||||
bool SelectAccountNation(CSendStream& SendStream, unsigned long dwRequestKey, unsigned long dwUID,
|
||||
unsigned char cType, unsigned char cAccountNation, unsigned short usError);
|
||||
|
||||
// WORK_LIST 2.3 계정 국적 변경 기능 구현
|
||||
bool NationChangeResult(CSendStream& SendStream, unsigned long dwRequestKey, unsigned long dwUID,
|
||||
unsigned long* aryGID, unsigned long* aryFame);
|
||||
|
||||
// 서버통합 캐릭터 정보 전달. 모든 캐릭터를 선택할 수 있는 통합시에는 데이터를 전달하지 않는다.
|
||||
bool UnifiedCharInfo(CSendStream& SendStream,
|
||||
unsigned long dwUID, unsigned char cTransferedCharCount, const USER_INFO& userInfo,
|
||||
const UnifiedStoreInfo* lpUnifiedStoreInfo, unsigned long dwUnifiedStoreNum,
|
||||
const UnifiedCharData* lpUnifiedCharData, unsigned long dwUnifiedCharNum);
|
||||
|
||||
// Part1 DB중계서버로 데이터를 전송한다.
|
||||
bool UnifiedCharSelectReq(CSendStream& SendStream, unsigned long dwUID,
|
||||
unsigned long dwRequestKey, unsigned long* lpdwCID, unsigned long dwCIDNum,
|
||||
unsigned char cSelectedStoreServerGroup, unsigned char cSelectedNation);
|
||||
|
||||
// 인증서버로 캐릭터 선택 성공/실패를 준다.
|
||||
bool UnifiedCharSelectAck(CSendStream& SendStream, unsigned long dwUID,
|
||||
unsigned long dwRequestKey, unsigned short usError);
|
||||
|
||||
// 캐쉬아이템을 사용
|
||||
bool CharUseCashItem(CSendStream& SendStream, unsigned long dwSender, unsigned long dwReceiver,
|
||||
Item::ItemPos itemPos, unsigned char cRemainItemNum, unsigned short usError);
|
||||
|
||||
// 엑스트라 이벤트 전송
|
||||
bool CharExtraEvent(CSendStream& SendStream, unsigned long dwUID, unsigned long dwCID,
|
||||
unsigned long dwEventID, unsigned long dwValue1, unsigned long dwValue2, unsigned short usError);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,114 @@
|
||||
#include "stdafx.h"
|
||||
#include "SendGuild.h"
|
||||
|
||||
#include <Network/Packet/WrapPacket.h>
|
||||
#include <Network/Packet/PacketCommand.h>
|
||||
#include <Network/Packet/PacketStruct/GuildPacket.h>
|
||||
|
||||
#include <Network/Stream/SendStream.h>
|
||||
#include <Network/Dispatch/GameDispatch.h>
|
||||
|
||||
namespace DBAgent
|
||||
{
|
||||
namespace SendPacket
|
||||
{
|
||||
|
||||
|
||||
bool GuildCmd(CSendStream* lpSendStream,
|
||||
unsigned long dwGID, unsigned long dwSenderID, unsigned long dwReferenceID,
|
||||
unsigned short wCmd, const char* szSenderName, const char* szGuildName, unsigned short wError)
|
||||
{
|
||||
PktGuildCmd pktGuildCmd;
|
||||
memset(&pktGuildCmd, 0, sizeof(PktGuildCmd));
|
||||
|
||||
pktGuildCmd.m_dwGID = dwGID;
|
||||
pktGuildCmd.m_dwSenderID = dwSenderID;
|
||||
pktGuildCmd.m_dwReferenceID = dwReferenceID;
|
||||
pktGuildCmd.m_wCmd = wCmd;
|
||||
|
||||
if(szSenderName)
|
||||
strncpy(pktGuildCmd.m_szSenderName, szSenderName, MAX_MEMBER_NAME_LEN);
|
||||
|
||||
if(szGuildName)
|
||||
strncpy(pktGuildCmd.m_szGuildName, szGuildName, MAX_GUILD_NAME_LEN);
|
||||
|
||||
|
||||
if (PktBase::NO_SERVER_ERR == wError)
|
||||
{
|
||||
// 서버 에러가 아닌 경우 전 서버에 보낸다.
|
||||
if(PacketWrap::WrapHeader(reinterpret_cast<char*>(&pktGuildCmd),
|
||||
sizeof(PktGuildCmd), CmdGuildCmd, 0, wError))
|
||||
{
|
||||
DBAgent::CGameDispatch::GetDispatchTable().Process(CSendPacketAllServer(
|
||||
reinterpret_cast<char*>(&pktGuildCmd), sizeof(PktGuildCmd), CmdGuildCmd));
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if(0 != lpSendStream)
|
||||
{
|
||||
// 서버 에러인경우, 해당 서버에만 보낸다.
|
||||
return lpSendStream->WrapCompress(reinterpret_cast<char*>(&pktGuildCmd),
|
||||
sizeof(PktGuildCmd), CmdGuildCmd, 0, wError);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool GuildMemberFameUpdate(unsigned long dwCID, unsigned long dwOurGID, unsigned char cType, int nAddFame, unsigned char cZone, unsigned long dwEnemyGID)
|
||||
{
|
||||
PktGuildMemberFameUpdate pktGuildMemberFameUpdate;
|
||||
memset(&pktGuildMemberFameUpdate, 0, sizeof(PktGuildMemberFameUpdate));
|
||||
|
||||
pktGuildMemberFameUpdate.m_dwCID = dwCID;
|
||||
pktGuildMemberFameUpdate.m_dwOurGID = dwOurGID;
|
||||
pktGuildMemberFameUpdate.m_dwEnemyGID = dwEnemyGID;
|
||||
pktGuildMemberFameUpdate.m_cType = cType;
|
||||
pktGuildMemberFameUpdate.m_nAddFame = nAddFame;
|
||||
|
||||
if(PacketWrap::WrapHeader(reinterpret_cast<char*>(&pktGuildMemberFameUpdate),
|
||||
sizeof(PktGuildMemberFameUpdate), CmdGuildMemberFameUpdate, 0, 0))
|
||||
{
|
||||
DBAgent::CGameDispatch::GetDispatchTable().Process(CSendPacketToZone(
|
||||
reinterpret_cast<char*>(&pktGuildMemberFameUpdate),
|
||||
sizeof(PktGuildMemberFameUpdate), CmdGuildMemberFameUpdate, cZone));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool GuildMemberGoldUpdate(unsigned long dwCID, unsigned long dwGID, unsigned long dwGold, unsigned char cZone)
|
||||
{
|
||||
PktGuildMemberGoldUpdate pktGuildMemberGoldUpdate;
|
||||
memset(&pktGuildMemberGoldUpdate, 0, sizeof(PktGuildMemberGoldUpdate));
|
||||
|
||||
pktGuildMemberGoldUpdate.m_dwCID = dwCID;
|
||||
pktGuildMemberGoldUpdate.m_dwGID = dwGID;
|
||||
pktGuildMemberGoldUpdate.m_dwGold = dwGold;
|
||||
|
||||
if (PacketWrap::WrapHeader(reinterpret_cast<char*>(&pktGuildMemberGoldUpdate),
|
||||
sizeof(PktGuildMemberGoldUpdate), CmdGuildMemberGoldUpdate, 0, 0))
|
||||
{
|
||||
DBAgent::CGameDispatch::GetDispatchTable().Process(CSendPacketToZone(
|
||||
reinterpret_cast<char*>(&pktGuildMemberGoldUpdate),
|
||||
sizeof(PktGuildMemberGoldUpdate), CmdGuildMemberGoldUpdate, cZone));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/*bool KeyInfo(unsigned long dwCID)
|
||||
{
|
||||
PktGuildMemberGoldUpdate pktGuildMemberGoldUpdate;
|
||||
memset(&pktGuildMemberGoldUpdate, 0, sizeof(PktGuildMemberGoldUpdate));
|
||||
|
||||
return false;
|
||||
}*/
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
#ifndef _DBAGENT_SERVER_SEND_GUILD_H_
|
||||
#define _DBAGENT_SERVER_SEND_GUILD_H_
|
||||
|
||||
// forward decl.
|
||||
class CSendStream;
|
||||
|
||||
namespace DBAgent
|
||||
{
|
||||
namespace SendPacket
|
||||
{
|
||||
bool GuildCmd(CSendStream* lpSendStream,
|
||||
unsigned long dwGID, unsigned long dwSenderID, unsigned long dwReferenceID,
|
||||
unsigned short wCmd, const char* szSenderName, const char* szGuildName, unsigned short wError);
|
||||
|
||||
bool GuildMemberFameUpdate(unsigned long dwCID, unsigned long dwOurGID,
|
||||
unsigned char cType, int nAddFame, unsigned char cZone, unsigned long dwEnemyGID = 0);
|
||||
|
||||
bool GuildMemberGoldUpdate(unsigned long dwCID,
|
||||
unsigned long dwGID, unsigned long dwGold, unsigned char cZone);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,653 @@
|
||||
#include "stdafx.h"
|
||||
#include "SendLoginout.h"
|
||||
|
||||
#include <Network/Stream/SendStream.h>
|
||||
#include <Network/Packet/PacketStruct/CharLoginOutPacket.h>
|
||||
#include <Network/Packet/PacketStruct/CharLoginOutPacketStruct.h>
|
||||
#include <Network/Packet/PacketStruct/CharItemPacket.h>
|
||||
#include <Network/Packet/PacketStruct/CharQuestPacket.h>
|
||||
#include <Network/Packet/PacketStruct/CharConfigPacket.h>
|
||||
#include <Network/Packet/PacketStruct/AuthServerToDBAgentServer.h>
|
||||
|
||||
#include <DataStorage/StoreData.h>
|
||||
#include <DataStorage/CharacterData.h>
|
||||
#include <DataStorage/SessionData.h>
|
||||
|
||||
#include <Log/ServerLog.h>
|
||||
#include <Network/Packet/PacketCommand.h>
|
||||
|
||||
#include <Community/Party/PartyDBInfo.h>
|
||||
#include <Community/Party/PartyDBMgr.h>
|
||||
|
||||
#include <Community/Guild/GuildDB.h>
|
||||
#include <Community/Guild/GuildDBMgr.h>
|
||||
|
||||
#include <DB/DBComponent.h>
|
||||
#include <DB/GameDBComponent.h>
|
||||
|
||||
#include <Utility/Setup/ServerSetup.h>
|
||||
|
||||
#include <DataStorage/SessionDataMgr.h>
|
||||
|
||||
#include <GameTime/GameTimeConstants.h>
|
||||
#include <GameTime/GameTimeDBMgr.h>
|
||||
|
||||
#include <Network/Packet/PacketStruct/CharCommunityPacket.h>
|
||||
|
||||
namespace DBAgent
|
||||
{
|
||||
namespace SendPacket
|
||||
{
|
||||
|
||||
// 친구 / 거부 데이터 전송
|
||||
bool Friend(CSendStream& SendStream, unsigned char cCmd, unsigned long dwRequestKey, unsigned long dwUID, unsigned long dwCID,
|
||||
unsigned long dwGID, unsigned short wClass, char cLevel, unsigned long dwServerID, const char* lpData, unsigned long dwDataLen);
|
||||
|
||||
// 퀘스트 / 히스토리 데이터 전송
|
||||
bool Quest(CSendStream& SendStream, unsigned long dwRequestKey,
|
||||
unsigned long dwUID, unsigned long dwCID,
|
||||
const char* lpQuestBuffer, unsigned long dwQuestSize,
|
||||
const char* lpHistoryBuffer, unsigned long dwHistorySize);
|
||||
|
||||
// 설정 정보 전송
|
||||
bool ConfigInfo(CSendStream& SendStream, unsigned long dwRequestKey,
|
||||
unsigned long dwUID, unsigned long dwCID,
|
||||
const char* lpConfigBuffer, unsigned long dwConfigSize);
|
||||
|
||||
// 창고 정보 전송
|
||||
bool DepositData(CSendStream& SendStream, unsigned char cCmd,
|
||||
unsigned long dwRequestKey, unsigned long dwCID, const STORE_INFO& storeInfo);
|
||||
|
||||
// 창고 데이터 전송
|
||||
bool DepositDBUpdate(CSendStream& SendStream, unsigned long dwRequestKey,
|
||||
unsigned long dwUID, unsigned long dwCID,
|
||||
unsigned char cTabNum, bool bComplete,
|
||||
const STORE_INFO& storeInfo, const STORE& store);
|
||||
|
||||
|
||||
// 세션 시작
|
||||
bool StartSession(CSendStream& SendStream, unsigned long dwRequestKey,
|
||||
unsigned long dwUID, unsigned long dwSessionID,
|
||||
unsigned char cFirstLogin, unsigned short usError)
|
||||
{
|
||||
char* lpBuffer = SendStream.GetBuffer(sizeof(PktSSD));
|
||||
if(0 != lpBuffer)
|
||||
{
|
||||
PktSSD* lpPktSSDAck = reinterpret_cast<PktSSD*>(lpBuffer);
|
||||
|
||||
lpPktSSDAck->m_dwRequestKey = dwRequestKey;
|
||||
lpPktSSDAck->m_wCmd = PktDD::SCmdStartSession;
|
||||
|
||||
lpPktSSDAck->m_dwUserID = dwUID;
|
||||
lpPktSSDAck->m_dwSessionID = dwSessionID;
|
||||
|
||||
lpPktSSDAck->m_cAgentServerType =
|
||||
static_cast<unsigned char>(CServerSetup::GetInstance().GetAgentServerType());
|
||||
|
||||
lpPktSSDAck->m_cFirstLogin =
|
||||
(UnifiedConst::Part2Selectable != lpPktSSDAck->m_cAgentServerType)
|
||||
? cFirstLogin : static_cast<unsigned char>(CServerSetup::GetInstance().GetSelectableUnifiedServerNum());
|
||||
|
||||
ZeroMemory(lpPktSSDAck->m_AccountName, sizeof(char)*PktSSD::MaxName);
|
||||
ZeroMemory(lpPktSSDAck->m_Password, sizeof(char)*PktSSD::MaxPass);
|
||||
|
||||
return SendStream.WrapHeader(sizeof(PktSSD), CmdDBGetData, 0, usError);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// 캐릭터 로그인
|
||||
bool CharLogin(CSendStream& SendStream, DataStorage::CSessionData& SessionData,
|
||||
unsigned long dwRequestKey)
|
||||
{
|
||||
// DBAgent에 캐릭터 로그인 결과가 날아왔다.
|
||||
// DB에서 정보를 읽어와 DataStorage::CCharacterData 에 정보를 저정한다.
|
||||
|
||||
|
||||
const unsigned long MAX_BUFFER_SIZE = sizeof(PktDBUpdate) + DBUpdateData::MAX_DBUPDATE_SIZE;
|
||||
|
||||
char szBuffer[MAX_BUFFER_SIZE] = {0,};
|
||||
unsigned long dwBufferSize = MAX_BUFFER_SIZE;
|
||||
|
||||
DataStorage::CCharacterData* lpCharacterData = SessionData.GetCharacterData();
|
||||
DataStorage::CStoreData* lpStoreData = SessionData.GetStoreData();
|
||||
|
||||
if(0 == lpCharacterData || 0 == lpStoreData)
|
||||
{
|
||||
ERRLOG4(g_Log, "UID:%10u / CID:%10u / CCharacterData:%p / CStoreData:%p / "
|
||||
"캐릭터 로그인 전송 실패 : 데이터가 없습니다.",
|
||||
SessionData.GetUID(), SessionData.GetCID(), lpCharacterData, lpStoreData);
|
||||
}
|
||||
else
|
||||
{
|
||||
unsigned long dwUID = SessionData.GetUID();
|
||||
unsigned long dwCID = lpCharacterData->GetCID();
|
||||
|
||||
PktDBUpdate* lpPktDBUpdate = reinterpret_cast<PktDBUpdate*>(szBuffer);
|
||||
char* lpDataPos = szBuffer + sizeof(PktDBUpdate);
|
||||
|
||||
unsigned long dwDataSize = MAX_BUFFER_SIZE - sizeof(PktDBUpdate);
|
||||
|
||||
memset(lpPktDBUpdate, 0, sizeof(PktDBUpdate));
|
||||
|
||||
if(!lpCharacterData->SerializeOut(lpDataPos, lpPktDBUpdate->m_usUpdate,
|
||||
dwDataSize, DBUpdateData::MAX_UPDATE_DB))
|
||||
{
|
||||
ERRLOG2(g_Log, "UID:%10u / CID:%10u / 캐릭터 로그인 전송 실패 : 캐릭터 데이터 SerializeOut에 실패했습니다.",
|
||||
SessionData.GetUID(), SessionData.GetCID());
|
||||
}
|
||||
else
|
||||
{
|
||||
// 플레이어 타음을 업데이트 해준다.
|
||||
// 로그인 한다.
|
||||
if (GameRYL::CHINA == CServerSetup::GetInstance().GetNationType())
|
||||
{
|
||||
DBComponent::GameDB::UpdatePlayTime(CDBSingleObject::GetInstance(), dwUID, 0);
|
||||
SessionData.GetPlayTimeFromDB(CDBSingleObject::GetInstance());
|
||||
}
|
||||
|
||||
// 프리미엄 서비스 타임 설정
|
||||
DBComponent::GameDB::UpdatePremiumService(CDBSingleObject::GetInstance(), dwUID, 0);
|
||||
SessionData.GetPremiumServiceFromDB(CDBSingleObject::GetInstance());
|
||||
|
||||
|
||||
unsigned char cAdminLevel = SessionData.GetAdminLevel();
|
||||
DBUpdateData::UpdateType eUpdateType =
|
||||
(0 != cAdminLevel) ? DBUpdateData::ADMIN_LOGIN : DBUpdateData::LOGIN;
|
||||
|
||||
// 용병 정보.
|
||||
CGuildDB* lpGuild = static_cast<CGuildDB*>(
|
||||
CGuildDBMgr::GetInstance().GetGuild(lpCharacterData->GetGID()));
|
||||
|
||||
unsigned char cTacticsFlag = 0;
|
||||
|
||||
if(lpGuild)
|
||||
{
|
||||
cTacticsFlag = lpGuild->GetTacticsMember(dwCID);
|
||||
}
|
||||
|
||||
lpPktDBUpdate->m_dlItemSerial = 0;
|
||||
lpPktDBUpdate->m_dwSessionID = SessionData.GetSessionID();
|
||||
lpPktDBUpdate->m_dwUserID = dwUID;
|
||||
lpPktDBUpdate->m_dwCharID = dwCID;
|
||||
lpPktDBUpdate->m_dwRequestKey = dwRequestKey;
|
||||
lpPktDBUpdate->m_Address = SessionData.GetRemoteAddress();
|
||||
lpPktDBUpdate->m_cAdminLevel = cAdminLevel;
|
||||
lpPktDBUpdate->m_cAdminFlag = lpCharacterData->GetAdminFlag();
|
||||
lpPktDBUpdate->m_cTacticsFlag = cTacticsFlag;
|
||||
|
||||
strncpy(lpPktDBUpdate->m_szAccountName,
|
||||
SessionData.GetAccountName(), CHAR_INFOST::MAX_ACCOUNT_LEN);
|
||||
|
||||
lpPktDBUpdate->m_szAccountName[CHAR_INFOST::MAX_ACCOUNT_LEN - 1] = 0;
|
||||
|
||||
// WORK_LIST 2.4 계정 국적을 게임서버의 캐릭터가 가지도록 구현
|
||||
lpPktDBUpdate->m_cAccountNation = SessionData.GetAccountNation();
|
||||
lpPktDBUpdate->m_cNameChangeCount = lpCharacterData->GetInfoEx().cNameChangeCount;
|
||||
|
||||
// 인스턴스 전쟁 참여 플래그인데 전쟁 시간이 아니면 OFF 로 바꿔준다.
|
||||
if (lpCharacterData->GetInfoEx().GuildWarFlag == Creature::WAR_INSTANCE &&
|
||||
!CGameTimeDBMgr::GetInstance().IsGuildWarTime())
|
||||
{
|
||||
lpCharacterData->SetGuildWarFlag(Creature::WAR_OFF);
|
||||
}
|
||||
|
||||
if (lpCharacterData->GetInfoEx().RealmWarFlag == Creature::WAR_INSTANCE &&
|
||||
!CGameTimeDBMgr::GetInstance().IsRealmWarReadyTime() &&
|
||||
!CGameTimeDBMgr::GetInstance().IsRealmWarTime())
|
||||
{
|
||||
lpCharacterData->SetRealmWarFlag(Creature::WAR_OFF);
|
||||
}
|
||||
|
||||
|
||||
lpPktDBUpdate->m_cGuildWarFlag = lpCharacterData->GetInfoEx().GuildWarFlag;
|
||||
lpPktDBUpdate->m_cRealmWarFlag = lpCharacterData->GetInfoEx().RealmWarFlag;
|
||||
lpPktDBUpdate->m_cRealmPoint = lpCharacterData->GetInfoEx().RealmPoint;
|
||||
|
||||
lpPktDBUpdate->m_TypeCode = static_cast<unsigned short>(eUpdateType);
|
||||
lpPktDBUpdate->m_PlayTime = SessionData.GetPlayTime();
|
||||
lpPktDBUpdate->m_PremiumTime = SessionData.GetPremiumTime();
|
||||
lpPktDBUpdate->m_PremiumType = SessionData.GetPremiumType();
|
||||
|
||||
if(!SendStream.WrapCompress(szBuffer,
|
||||
static_cast<unsigned short>(sizeof(PktDBUpdate) + dwDataSize), CmdDBUpdateData, 0, 0))
|
||||
{
|
||||
// 캐릭터 로그인 전송 실패
|
||||
return false;
|
||||
}
|
||||
|
||||
// 일단 캐릭터 로그인이 전송 완료된 이후는,
|
||||
|
||||
unsigned long dwGID = lpCharacterData->GetGID();
|
||||
unsigned short wClass = lpCharacterData->GetClass();
|
||||
char cLevel = lpCharacterData->GetLevel();
|
||||
|
||||
// Friend 정보 설정 (시간이 생기면 수정하겠음) //
|
||||
unsigned long dwMemberCID[CFriendList::MAX_FRIENDS_NUM] = {0,};
|
||||
|
||||
// 친구리스트에 CID 만 가지고 온다. //
|
||||
CFriendList friendList = lpCharacterData->GetFriendList();
|
||||
|
||||
friendList.GetCIDList(dwMemberCID);
|
||||
|
||||
for(unsigned char cIndex = 0; cIndex < friendList.GetFriendNum(); cIndex++)
|
||||
{
|
||||
DataStorage::CSessionData* lpTargetSessionData = DataStorage::CSessionDataMgr::GetInstance().GetCharLoadedSession(dwMemberCID[cIndex]);
|
||||
|
||||
CFriendList::Rebind* lpRebind = friendList.GetFriend(dwMemberCID[cIndex]);
|
||||
|
||||
if(lpRebind)
|
||||
{
|
||||
if(lpTargetSessionData)
|
||||
{
|
||||
DataStorage::CCharacterData* lpTargetCharacterData = lpTargetSessionData->GetCharacterData();
|
||||
|
||||
if(lpTargetCharacterData)
|
||||
{
|
||||
if (DataStorage::CSessionData::SE_USER_ENABLED != lpTargetSessionData->GetSessionState() &&
|
||||
DataStorage::CSessionData::SE_CHAR_ENABLED != lpTargetSessionData->GetSessionState())
|
||||
{
|
||||
lpRebind->UpdateServerID(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Frind 초기화 //
|
||||
lpRebind->InitializeFriendInfo(lpTargetCharacterData->GetServerID(), lpTargetCharacterData->GetGID(),
|
||||
lpTargetCharacterData->GetClass(), lpTargetCharacterData->GetLevel());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
lpRebind->UpdateServerID(0);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
lpRebind->UpdateServerID(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 친구 리스트 전송
|
||||
dwBufferSize = MAX_BUFFER_SIZE;
|
||||
if(friendList.SerializeOut(szBuffer, dwBufferSize))
|
||||
{
|
||||
SendPacket::Friend(SendStream, PktFriendDB::CMD::FRIEND_LIST, dwRequestKey, dwUID, dwCID,
|
||||
dwGID, wClass, cLevel, SessionData.GetServerID(), szBuffer, dwBufferSize);
|
||||
}
|
||||
|
||||
// Ban 정보 설정 (시간이 생기면 여기도 수정하겠음) //
|
||||
|
||||
CBanList banList = lpCharacterData->GetBanList();
|
||||
|
||||
// 거부리스트에 CID 만 가지고 온다. //
|
||||
banList.GetCIDList(dwMemberCID);
|
||||
|
||||
for(unsigned char cIndex = 0; cIndex < banList.GetBanNum(); cIndex++)
|
||||
{
|
||||
DataStorage::CSessionData* lpTargetSessionData = DataStorage::CSessionDataMgr::GetInstance().GetCharLoadedSession(dwMemberCID[cIndex]);
|
||||
|
||||
CBanList::Rebind* lpRebind = banList.GetBan(dwMemberCID[cIndex]);
|
||||
|
||||
if(lpRebind)
|
||||
{
|
||||
if(lpTargetSessionData)
|
||||
{
|
||||
DataStorage::CCharacterData* lpTargetCharacterData = lpTargetSessionData->GetCharacterData();
|
||||
|
||||
if(lpTargetCharacterData)
|
||||
{
|
||||
if (DataStorage::CSessionData::SE_USER_ENABLED != lpTargetSessionData->GetSessionState() &&
|
||||
DataStorage::CSessionData::SE_CHAR_ENABLED != lpTargetSessionData->GetSessionState())
|
||||
{
|
||||
lpRebind->UpdateServerID(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Frind 초기화 //
|
||||
lpRebind->InitializeBanInfo(lpTargetCharacterData->GetServerID(), lpTargetCharacterData->GetGID(),
|
||||
lpTargetCharacterData->GetClass(), lpTargetCharacterData->GetLevel());
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
lpRebind->UpdateServerID(0);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
lpRebind->UpdateServerID(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 거부 리스트 전송
|
||||
dwBufferSize = MAX_BUFFER_SIZE;
|
||||
if(banList.SerializeOut(szBuffer, dwBufferSize))
|
||||
{
|
||||
SendPacket::Friend(SendStream, PktFriendDB::CMD::BAN_LIST, dwRequestKey, dwUID, dwCID,
|
||||
dwGID, wClass, cLevel, SessionData.GetServerID(), szBuffer, dwBufferSize);
|
||||
}
|
||||
|
||||
// 퀘스트 전송
|
||||
const QUEST& quest = lpCharacterData->GetQuest();
|
||||
const HISTORY& history = lpCharacterData->GetHistory();
|
||||
|
||||
SendPacket::Quest(SendStream, dwRequestKey, dwUID, dwCID,
|
||||
quest.Data, quest.dwSize, history.Data, history.dwSize);
|
||||
|
||||
// 설정 전송
|
||||
const CONFIG& config = lpCharacterData->GetConfig();
|
||||
SendPacket::ConfigInfo(SendStream, dwRequestKey, dwUID, dwCID, config.Data, config.dwSize);
|
||||
|
||||
const STORE_INFO& storeInfo = lpStoreData->GetStoreInfo();
|
||||
|
||||
// 창고 패스워드 및 창고 금액 전송. 반드시 DepositDBUpdate보다 먼저 보내야 한다.
|
||||
SendPacket::DepositData(SendStream, PktDeposit::CMD::PASSWORD, dwRequestKey, dwCID, storeInfo);
|
||||
SendPacket::DepositData(SendStream, PktDeposit::CMD::GOLD, dwRequestKey, dwCID, storeInfo);
|
||||
|
||||
// 창고 전송
|
||||
const STORE& store1 = lpStoreData->GetStore1();
|
||||
const STORE& store2 = lpStoreData->GetStore2();
|
||||
|
||||
if (0 == store2.dwSize)
|
||||
{
|
||||
SendPacket::DepositDBUpdate(SendStream, dwRequestKey, dwUID, dwCID,
|
||||
PktDepositUpdateDB::TabNum::TAB_12, true, storeInfo, store1);
|
||||
}
|
||||
else
|
||||
{
|
||||
SendPacket::DepositDBUpdate(SendStream, dwRequestKey, dwUID, dwCID,
|
||||
PktDepositUpdateDB::TabNum::TAB_12, false, storeInfo, store1);
|
||||
|
||||
SendPacket::DepositDBUpdate(SendStream, dwRequestKey, dwUID, dwCID,
|
||||
PktDepositUpdateDB::TabNum::TAB_34, true, storeInfo, store2);
|
||||
}
|
||||
|
||||
// 파티 로그인 처리
|
||||
CPartyDBInfo* lpParty = CPartyDBMgr::GetInstance().OpenParty(
|
||||
CDBSingleObject::GetInstance(), lpCharacterData->GetPID());
|
||||
|
||||
if (0 != lpParty)
|
||||
{
|
||||
CPartyDBMgr::GetInstance().LoginPartyMember(
|
||||
lpParty, dwUID, dwCID, dwGID, wClass, SessionData.GetServerID(), cLevel);
|
||||
}
|
||||
|
||||
// 길드 로그인 처리
|
||||
if (0 != lpGuild)
|
||||
{
|
||||
lpGuild->SendLoginOutMember(dwCID, SessionData.GetServerID());
|
||||
}
|
||||
|
||||
// 듀얼시 연사 방지 패킷.
|
||||
DataStorage::CSessionData::SaveEnemy* lpSaveEnemyInfo = SessionData.GetSaveEnemy();
|
||||
|
||||
unsigned long dwSaveEnemySize = sizeof(PktSaveEnemy) + sizeof(DataStorage::CSessionData::SaveEnemy)*4;
|
||||
|
||||
char* szSaveEnemyBuffer = SendStream.GetBuffer(dwSaveEnemySize);
|
||||
|
||||
PktSaveEnemy* lpPktSaveEnemy = reinterpret_cast<PktSaveEnemy*>(szSaveEnemyBuffer);
|
||||
lpPktSaveEnemy->m_dwCID = SessionData.GetCID();
|
||||
|
||||
DataStorage::CSessionData::SaveEnemy* lpPktSaveEnemyInfo = NULL;
|
||||
|
||||
unsigned long dwTick = ::GetTickCount();
|
||||
|
||||
for(unsigned char cIndex = 0; cIndex < DataStorage::CSessionData::SaveEnemy::MAX_SAVING_ENEMY; cIndex++)
|
||||
{
|
||||
if(!cIndex)
|
||||
{
|
||||
lpPktSaveEnemy->m_dwAttackedCID = lpSaveEnemyInfo[cIndex].m_dwCID;
|
||||
lpPktSaveEnemy->m_dwTick = dwTick - lpSaveEnemyInfo[cIndex].m_dwTick;
|
||||
lpPktSaveEnemyInfo = reinterpret_cast<DataStorage::CSessionData::SaveEnemy*>(szSaveEnemyBuffer+sizeof(PktSaveEnemy));
|
||||
}
|
||||
else
|
||||
{
|
||||
lpPktSaveEnemyInfo[cIndex-1].m_dwCID = lpSaveEnemyInfo[cIndex].m_dwCID;
|
||||
lpPktSaveEnemyInfo[cIndex-1].m_dwTick = 0;
|
||||
|
||||
if(lpSaveEnemyInfo[cIndex].m_dwCID)
|
||||
{
|
||||
lpPktSaveEnemyInfo[cIndex-1].m_dwTick = dwTick - lpSaveEnemyInfo[cIndex].m_dwTick;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(!SendStream.WrapHeader((unsigned short)dwSaveEnemySize, CmdSaveEnemy, 0, 0))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// 조이스틱 키 정보.
|
||||
KeyInfo* pKeyInfo = SessionData.GetKeyInfo();
|
||||
|
||||
if (pKeyInfo && pKeyInfo->m_cUsed)
|
||||
{
|
||||
char* lpBuffer = SendStream.GetBuffer(sizeof(PktKeyInfo));
|
||||
|
||||
if(0 != lpBuffer)
|
||||
{
|
||||
PktKeyInfo* pPktKeyInfo = reinterpret_cast<PktKeyInfo*>(lpBuffer);;
|
||||
pPktKeyInfo->m_dwCID = dwCID;
|
||||
memcpy(pPktKeyInfo->m_dwKeyInfo, pKeyInfo->m_dwKeyInfo, sizeof(unsigned long)*PktKeyInfo::MAX_KEY_INFO);
|
||||
|
||||
SendStream.WrapCrypt(sizeof(PktKeyInfo), CmdKeyInfo, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
// 로그 출력
|
||||
SessionData.LogCharData("캐릭터 로그인");
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// 캐릭터 로그인 실패.
|
||||
bool CharLoginError(CSendStream& SendStream, unsigned long dwRequestKey,
|
||||
DBUpdateData::UpdateType eUpdateType,
|
||||
unsigned long dwUID, unsigned long dwCID, unsigned short usError)
|
||||
{
|
||||
if(0 != usError)
|
||||
{
|
||||
char* lpBuffer = SendStream.GetBuffer(sizeof(PktDBUpdate));
|
||||
|
||||
if(0 != lpBuffer)
|
||||
{
|
||||
PktDBUpdate* lpPktDBUpdate = reinterpret_cast<PktDBUpdate*>(lpBuffer);
|
||||
memset(lpPktDBUpdate, 0, sizeof(PktDBUpdate));
|
||||
|
||||
lpPktDBUpdate->m_dlItemSerial = 0;
|
||||
lpPktDBUpdate->m_dwSessionID = 0;
|
||||
lpPktDBUpdate->m_dwUserID = dwUID;
|
||||
lpPktDBUpdate->m_dwCharID = dwCID;
|
||||
lpPktDBUpdate->m_dwRequestKey = dwRequestKey;
|
||||
|
||||
lpPktDBUpdate->m_Address.S_un.S_addr = 0;
|
||||
|
||||
lpPktDBUpdate->m_cAdminLevel = 0;
|
||||
|
||||
// WORK_LIST 2.4 계정 국적을 게임서버의 캐릭터가 가지도록 구현
|
||||
lpPktDBUpdate->m_cAccountNation = 0;
|
||||
lpPktDBUpdate->m_cNameChangeCount = 0;
|
||||
lpPktDBUpdate->m_cGuildWarFlag = 0;
|
||||
lpPktDBUpdate->m_cRealmWarFlag = 0;
|
||||
lpPktDBUpdate->m_cTacticsFlag = 0;
|
||||
|
||||
lpPktDBUpdate->m_TypeCode = static_cast<unsigned short>(eUpdateType);
|
||||
|
||||
memset(lpPktDBUpdate->m_usUpdate, 0,
|
||||
sizeof(unsigned short) * DBUpdateData::MAX_UPDATE_DB);
|
||||
|
||||
return SendStream.WrapCrypt(sizeof(PktDBUpdate), CmdDBUpdateData, 0, usError);
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool Friend(CSendStream& SendStream, unsigned char cCmd, unsigned long dwRequestKey, unsigned long dwUID, unsigned long dwCID,
|
||||
unsigned long dwGID, unsigned short wClass, char cLevel, unsigned long dwServerID, const char* lpData, unsigned long dwDataLen)
|
||||
{
|
||||
char* lpBuffer = SendStream.GetBuffer(sizeof(PktFriendDB) + dwDataLen);
|
||||
if(0 != lpBuffer)
|
||||
{
|
||||
PktFriendDB* lpFriendDB = reinterpret_cast<PktFriendDB*>(lpBuffer);
|
||||
|
||||
lpFriendDB->m_cCmd = cCmd;
|
||||
lpFriendDB->m_dwRequestKey = dwRequestKey;
|
||||
lpFriendDB->m_wCmd = 0;
|
||||
|
||||
lpFriendDB->m_dwOwnerUID = dwUID;
|
||||
lpFriendDB->m_dwOwnerCID = dwCID;
|
||||
lpFriendDB->m_dwReferenceCID = 0;
|
||||
lpFriendDB->m_dwData = dwDataLen;
|
||||
|
||||
lpFriendDB->m_dwGID = dwGID;
|
||||
lpFriendDB->m_wClass = wClass;
|
||||
lpFriendDB->m_cLevel = cLevel;
|
||||
lpFriendDB->m_dwServerID = dwServerID;
|
||||
|
||||
memcpy(lpFriendDB + 1, lpData, dwDataLen);
|
||||
|
||||
return SendStream.WrapHeader(
|
||||
static_cast<unsigned short>(sizeof(PktFriendDB) + dwDataLen), CmdFriendDB, 0, 0);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Quest(CSendStream& SendStream, unsigned long dwRequestKey,
|
||||
unsigned long dwUID, unsigned long dwCID,
|
||||
const char* lpQuestBuffer, unsigned long dwQuestSize,
|
||||
const char* lpHistoryBuffer, unsigned long dwHistorySize)
|
||||
{
|
||||
char* lpBuffer = SendStream.GetBuffer(sizeof(PktQuestDB) + dwQuestSize + dwHistorySize);
|
||||
|
||||
if(0 != lpBuffer)
|
||||
{
|
||||
PktQuestDB* lpPktQuestDB = reinterpret_cast<PktQuestDB*>(lpBuffer);
|
||||
|
||||
lpPktQuestDB->m_dwRequestKey = dwRequestKey;
|
||||
lpPktQuestDB->m_wCmd = 0;
|
||||
|
||||
lpPktQuestDB->m_dwUID = dwUID;
|
||||
lpPktQuestDB->m_dwCID = dwCID;
|
||||
|
||||
lpPktQuestDB->m_wExecuteQuestSize = static_cast<unsigned short>(dwQuestSize);
|
||||
lpPktQuestDB->m_wHistoryQuestSize = static_cast<unsigned short>(dwHistorySize);
|
||||
|
||||
memcpy(lpBuffer + sizeof(PktQuestDB), lpQuestBuffer, dwQuestSize);
|
||||
memcpy(lpBuffer + sizeof(PktQuestDB) + dwQuestSize, lpHistoryBuffer, dwHistorySize);
|
||||
|
||||
return SendStream.WrapHeader(
|
||||
static_cast<unsigned short>(sizeof(PktQuestDB) + dwQuestSize + dwHistorySize),
|
||||
CmdQuestDB, 0, 0);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ConfigInfo(CSendStream& SendStream, unsigned long dwRequestKey,
|
||||
unsigned long dwUID, unsigned long dwCID,
|
||||
const char* lpConfigBuffer, unsigned long dwConfigSize)
|
||||
{
|
||||
char* lpBuffer = SendStream.GetBuffer(sizeof(PktConfigInfo) + dwConfigSize);
|
||||
|
||||
if(0 != lpBuffer)
|
||||
{
|
||||
PktConfigInfo* lpConfigInfo = reinterpret_cast<PktConfigInfo*>(lpBuffer);
|
||||
|
||||
lpConfigInfo->m_dwRequestKey = dwRequestKey;
|
||||
lpConfigInfo->m_wCmd = 0;
|
||||
|
||||
lpConfigInfo->m_dwUserID = dwUID;
|
||||
lpConfigInfo->m_dwCharID = dwCID;
|
||||
lpConfigInfo->m_wSize = static_cast<unsigned short>(dwConfigSize);
|
||||
|
||||
memcpy(lpBuffer + sizeof(PktConfigInfo), lpConfigBuffer, dwConfigSize);
|
||||
|
||||
return SendStream.WrapHeader(
|
||||
static_cast<unsigned short>(sizeof(PktConfigInfo) + dwConfigSize), CmdConfigInfoDB, 0, 0);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool DepositData(CSendStream& SendStream, unsigned char cCmd, unsigned long dwRequestKey,
|
||||
unsigned long dwCID, const STORE_INFO& storeInfo)
|
||||
{
|
||||
char* lpBuffer = SendStream.GetBuffer(sizeof(PktDeposit));
|
||||
|
||||
if(0 != lpBuffer)
|
||||
{
|
||||
PktDeposit* lpPktDeposit = reinterpret_cast<PktDeposit*>(lpBuffer);
|
||||
|
||||
lpPktDeposit->m_cCmd = cCmd;
|
||||
lpPktDeposit->m_wCmd = 0;
|
||||
lpPktDeposit->m_dwRequestKey = dwRequestKey;
|
||||
|
||||
if (PktDeposit::CMD::PASSWORD == cCmd)
|
||||
{
|
||||
memcpy(&lpPktDeposit->m_szData[0], &dwCID, sizeof(unsigned long));
|
||||
memcpy(&lpPktDeposit->m_szData[4], storeInfo.Password, Deposit::PASSWORD_LENGTH);
|
||||
}
|
||||
else if (PktDeposit::CMD::GOLD == cCmd)
|
||||
{
|
||||
memcpy(&lpPktDeposit->m_szData[0], &dwCID, sizeof(unsigned long));
|
||||
memcpy(&lpPktDeposit->m_szData[4], &storeInfo.Gold, sizeof(unsigned long));
|
||||
}
|
||||
|
||||
return SendStream.WrapHeader(sizeof(PktDeposit), CmdDeposit, 0, 0);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool DepositDBUpdate(CSendStream& SendStream, unsigned long dwRequestKey,
|
||||
unsigned long dwUID, unsigned long dwCID,
|
||||
unsigned char cTabNum, bool bComplete,
|
||||
const STORE_INFO& storeInfo, const STORE& store)
|
||||
{
|
||||
char* lpBuffer = SendStream.GetBuffer(sizeof(PktDepositUpdateDB) + store.dwSize);
|
||||
|
||||
if(0 != lpBuffer)
|
||||
{
|
||||
PktDepositUpdateDB* lpPktDepositUpdateDB =
|
||||
reinterpret_cast<PktDepositUpdateDB*>(lpBuffer);
|
||||
|
||||
lpPktDepositUpdateDB->m_dwRequestKey = dwRequestKey;
|
||||
lpPktDepositUpdateDB->m_wCmd = 0;
|
||||
|
||||
lpPktDepositUpdateDB->m_dwUID = dwUID;
|
||||
lpPktDepositUpdateDB->m_dwCID = dwCID;
|
||||
lpPktDepositUpdateDB->m_dwTabFlag = storeInfo.Flag;
|
||||
lpPktDepositUpdateDB->m_usDataSize = static_cast<unsigned short>(store.dwSize);
|
||||
lpPktDepositUpdateDB->m_cTabNum = cTabNum;
|
||||
lpPktDepositUpdateDB->m_bUpdateComplete = bComplete;
|
||||
|
||||
memcpy(lpBuffer + sizeof(PktDepositUpdateDB), store.Data, store.dwSize);
|
||||
|
||||
return SendStream.WrapHeader(
|
||||
static_cast<unsigned short>(sizeof(PktDepositUpdateDB) + store.dwSize), CmdDepositUpdate, 0, 0);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
#ifndef _DBAGENT_SERVER_SEND_LOGIN_OUT_H_
|
||||
#define _DBAGENT_SERVER_SEND_LOGIN_OUT_H_
|
||||
|
||||
#include <Network/Packet/PacketStruct/CharLoginOutPacketStruct.h>
|
||||
|
||||
// forward decl.
|
||||
class CSendStream;
|
||||
|
||||
namespace DBAgent
|
||||
{
|
||||
namespace DataStorage
|
||||
{
|
||||
// forward delc.
|
||||
class CSessionData;
|
||||
}
|
||||
|
||||
namespace SendPacket
|
||||
{
|
||||
// 세션 시작
|
||||
bool StartSession(CSendStream& SendStream, unsigned long dwRequestKey,
|
||||
unsigned long dwUID, unsigned long dwSessionID,
|
||||
unsigned char cFirstLogin, unsigned short usError);
|
||||
|
||||
// 캐릭터 로그인
|
||||
bool CharLogin(CSendStream& SendStream,
|
||||
DataStorage::CSessionData& SessionData, unsigned long dwRequestKey);
|
||||
|
||||
// 캐릭터 로그아웃
|
||||
bool CharLoginError(CSendStream& SendStream, unsigned long dwRequestKey,
|
||||
DBUpdateData::UpdateType eUpdateType,
|
||||
unsigned long dwUID, unsigned long dwCID, unsigned short usError);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,111 @@
|
||||
#include "stdafx.h"
|
||||
#include "SendMoveZone.h"
|
||||
|
||||
#include <Network/Stream/SendStream.h>
|
||||
|
||||
#include <Network/Packet/PacketCommand.h>
|
||||
#include <Network/Packet/PacketStruct/ServerInfo.h>
|
||||
#include <Network/Packet/PacketStruct/ServerPacket.h>
|
||||
#include <Network/Dispatch/GameDispatch.h>
|
||||
|
||||
#include <Utility/Setup/ServerSetup.h>
|
||||
|
||||
namespace DBAgent
|
||||
{
|
||||
namespace SendPacket
|
||||
{
|
||||
|
||||
bool CharMoveZone(CSendStream& SendStream, unsigned long dwRequestKey,
|
||||
unsigned char cZone, unsigned short usError)
|
||||
{
|
||||
char* lpBuffer = SendStream.GetBuffer(sizeof(PktSZMvDAck));
|
||||
if(0 != lpBuffer)
|
||||
{
|
||||
PktSZMvDAck* lpPktSZMvDAck = reinterpret_cast<PktSZMvDAck*>(lpBuffer);
|
||||
|
||||
lpPktSZMvDAck->m_dwRequestKey = dwRequestKey;
|
||||
lpPktSZMvDAck->m_wCmd = PktDD::SCmdCharMoveZone;
|
||||
|
||||
lpPktSZMvDAck->m_cZone = cZone;
|
||||
|
||||
CUserPercentageInZone getUserPercentage(
|
||||
lpPktSZMvDAck->m_wChannelNum, cZone, PktSZMvDAck::MAX_CHANNEL_NUM);
|
||||
|
||||
CGameDispatch::GetDispatchTable().Process(getUserPercentage);
|
||||
|
||||
return SendStream.WrapHeader(sizeof(PktSZMvDAck), CmdAgentZone, 0, usError);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ServerZone(CSendStream& SendStream, unsigned long dwRequestKey,
|
||||
unsigned char cZone, unsigned char cChannel, unsigned short usError)
|
||||
{
|
||||
char* lpBuffer = SendStream.GetBuffer(sizeof(PktSAAck));
|
||||
if(0 != lpBuffer)
|
||||
{
|
||||
unsigned short usError = 0;
|
||||
|
||||
PktSAAck* lpPktSAAck = reinterpret_cast<PktSAAck*>(lpBuffer);
|
||||
|
||||
lpPktSAAck->m_dwRequestKey = dwRequestKey;
|
||||
lpPktSAAck->m_wCmd = PktDD::SCmdServerZone;
|
||||
|
||||
lpPktSAAck->m_dwServerID = 0;
|
||||
lpPktSAAck->m_GameAddress.S_un.S_addr = 0;
|
||||
|
||||
if(0 == usError)
|
||||
{
|
||||
SERVER_ID serverID;
|
||||
serverID.sID.Type = CServerSetup::GameServer;
|
||||
serverID.sID.Group = CServerSetup::GetInstance().GetServerGroup();
|
||||
serverID.sID.Channel = cChannel;
|
||||
serverID.sID.ID = cZone;
|
||||
|
||||
GET_MULTI_DISPATCH(lpGameDispatch, serverID.dwID,
|
||||
CGameDispatch, CGameDispatch::GetDispatchTable());
|
||||
|
||||
int nUserLimit = static_cast<int>(CServerSetup::GetInstance().GetUserLimit());
|
||||
|
||||
if(0 == lpGameDispatch)
|
||||
{
|
||||
usError = PktSAAck::SERVER_ERROR;
|
||||
}
|
||||
else if(nUserLimit < lpGameDispatch->GetCharNum())
|
||||
{
|
||||
usError = PktSAAck::FAIL_USER_LIMIT;
|
||||
}
|
||||
else
|
||||
{
|
||||
lpPktSAAck->m_dwServerID = lpGameDispatch->GetServerID();
|
||||
lpPktSAAck->m_GameAddress = lpGameDispatch->GetRemoteAddr().get_addr_in().sin_addr;
|
||||
}
|
||||
}
|
||||
|
||||
return SendStream.WrapHeader(sizeof(PktSAAck), CmdAgentZone, 0, usError);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ServerZoneEnd(CSendStream& SendStream, unsigned long dwRequestKey)
|
||||
{
|
||||
char* lpBuffer = SendStream.GetBuffer(sizeof(PktDD));
|
||||
|
||||
if(0 != lpBuffer)
|
||||
{
|
||||
PktDD* lpPktDD = reinterpret_cast<PktDD*>(lpBuffer);
|
||||
|
||||
lpPktDD->m_dwRequestKey = dwRequestKey;
|
||||
lpPktDD->m_wCmd = PktDD::SCmdServerZoneEnd;
|
||||
|
||||
return SendStream.WrapHeader(sizeof(PktDD), CmdAgentZone, 0, 0);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
#ifndef _DBAGENT_SERVER_SEND_MOVE_ZONE_H_
|
||||
#define _DBAGENT_SERVER_SEND_MOVE_ZONE_H_
|
||||
|
||||
|
||||
// forward decl.
|
||||
class CSendStream;
|
||||
|
||||
namespace DBAgent
|
||||
{
|
||||
namespace SendPacket
|
||||
{
|
||||
bool CharMoveZone(CSendStream& SendStream, unsigned long dwRequestKey,
|
||||
unsigned char cZone, unsigned short usError);
|
||||
|
||||
bool ServerZone(CSendStream& SendStream, unsigned long dwRequestKey,
|
||||
unsigned char cZone, unsigned char cChannel, unsigned short usError = 0);
|
||||
|
||||
bool ServerZoneEnd(CSendStream& SendStream, unsigned long dwRequestKey);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,111 @@
|
||||
#include "stdafx.h"
|
||||
#include "SendParty.h"
|
||||
#include <Community/Party/PartyDBInfo.h>
|
||||
#include <Network/Packet/WrapPacket.h>
|
||||
#include <Network/Packet/PacketCommand.h>
|
||||
#include <Network/Packet/PacketStruct/DataPacket.h>
|
||||
#include <Network/Packet/PacketStruct/PartyPacket.h>
|
||||
#include <Network/Dispatch/GameDispatch.h>
|
||||
|
||||
namespace DBAgent
|
||||
{
|
||||
namespace SendPacket
|
||||
{
|
||||
|
||||
bool DeleteParty(CPartyDBInfo* lpParty)
|
||||
{
|
||||
if(0 != lpParty)
|
||||
{
|
||||
PktDPD pktDPD;
|
||||
memset(&pktDPD, 0, sizeof(PktDPD));
|
||||
|
||||
pktDPD.m_wCmd = PktDD::SCmdDeleteParty;
|
||||
pktDPD.m_dwPartyID = lpParty->GetPID();
|
||||
|
||||
if(PacketWrap::WrapHeader(reinterpret_cast<char*>(&pktDPD),
|
||||
sizeof(PktDPD), CmdAgentParty, 0, 0))
|
||||
{
|
||||
CGameDispatch::GetDispatchTable().Process(CSendPacketAllServer(
|
||||
reinterpret_cast<char*>(&pktDPD), sizeof(PktDPD), CmdAgentParty));
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool PartyCmd(CSendStream& SendStream, unsigned short cSubCmd, unsigned long dwPID, unsigned long dwSenderID, unsigned long dwGID,
|
||||
unsigned short wClass, unsigned long dwServerID, char cLevel, const char* szSenderName, unsigned short usError)
|
||||
{
|
||||
char* lpBuffer = SendStream.GetBuffer(sizeof(PktPMD));
|
||||
|
||||
if(0 != lpBuffer)
|
||||
{
|
||||
PktPMD* lpPktPMD = reinterpret_cast<PktPMD*>(lpBuffer);
|
||||
|
||||
lpPktPMD->m_wCmd = cSubCmd;
|
||||
lpPktPMD->m_dwPartyID = dwPID;
|
||||
lpPktPMD->m_dwSenderID = dwSenderID;
|
||||
lpPktPMD->m_dwGID = dwGID;
|
||||
lpPktPMD->m_wClass = wClass;
|
||||
lpPktPMD->m_dwServerID = dwServerID;
|
||||
lpPktPMD->m_cLevel = cLevel;
|
||||
|
||||
if(0 != szSenderName)
|
||||
{
|
||||
strncpy(lpPktPMD->m_strSenderName, szSenderName, CHAR_INFOST::MAX_NAME_LEN);
|
||||
lpPktPMD->m_strSenderName[CHAR_INFOST::MAX_NAME_LEN - 1] = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
memset(lpPktPMD->m_strSenderName, 0, sizeof(char) * CHAR_INFOST::MAX_NAME_LEN);
|
||||
}
|
||||
|
||||
return SendStream.WrapHeader(sizeof(PktPMD), CmdAgentParty, 0, usError);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool PartyCmd(unsigned short cSubCmd, unsigned long dwPID, unsigned long dwSenderID, unsigned long dwGID,
|
||||
unsigned short wClass, unsigned long dwServerID, char cLevel, const char* szSenderName)
|
||||
{
|
||||
PktPMD pktPMD;
|
||||
memset(&pktPMD, 0, sizeof(PktPMD));
|
||||
|
||||
pktPMD.m_wCmd = cSubCmd;
|
||||
pktPMD.m_dwPartyID = dwPID;
|
||||
pktPMD.m_dwSenderID = dwSenderID;
|
||||
pktPMD.m_dwGID = dwGID;
|
||||
pktPMD.m_wClass = wClass;
|
||||
pktPMD.m_dwServerID = dwServerID;
|
||||
pktPMD.m_cLevel = cLevel;
|
||||
|
||||
if (0 != szSenderName)
|
||||
{
|
||||
strncpy(pktPMD.m_strSenderName, szSenderName, CHAR_INFOST::MAX_NAME_LEN);
|
||||
pktPMD.m_strSenderName[CHAR_INFOST::MAX_NAME_LEN - 1];
|
||||
}
|
||||
else
|
||||
{
|
||||
memset(pktPMD.m_strSenderName, 0, sizeof(char) * CHAR_INFOST::MAX_NAME_LEN);
|
||||
}
|
||||
|
||||
if(PacketWrap::WrapHeader(reinterpret_cast<char*>(&pktPMD),
|
||||
sizeof(PktPMD), CmdAgentParty, 0, 0))
|
||||
{
|
||||
// 게임 서버로 브로드캐스팅 //
|
||||
CGameDispatch::GetDispatchTable().Process(CSendPacketAllServer(
|
||||
reinterpret_cast<char*>(&pktPMD), sizeof(PktPMD), CmdAgentParty));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
#ifndef _DBAGENT_SERVER_SEND_PARTY_H_
|
||||
#define _DBAGENT_SERVER_SEND_PARTY_H_
|
||||
|
||||
// forward decl.
|
||||
class CSendStream;
|
||||
class CPartyDBInfo;
|
||||
|
||||
namespace DBAgent
|
||||
{
|
||||
namespace SendPacket
|
||||
{
|
||||
bool DeleteParty(CPartyDBInfo* lpParty);
|
||||
|
||||
bool PartyCmd(CSendStream& SendStream, unsigned short cSubCmd, unsigned long dwPID, unsigned long dwSenderID, unsigned long dwGID,
|
||||
unsigned short wClass, unsigned long dwServerID, char cLevel, const char* szSenderName, unsigned short usError);
|
||||
|
||||
bool PartyCmd(unsigned short cSubCmd, unsigned long dwPID, unsigned long dwSenderID, unsigned long dwGID,
|
||||
unsigned short wClass, unsigned long dwServerID, char cLevel, const char* szSenderName);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,422 @@
|
||||
#include "stdafx.h"
|
||||
#include "SendServerInfo.h"
|
||||
|
||||
#include <Network/Stream/SendStream.h>
|
||||
#include <Network/Winsock/SocketFactory.h>
|
||||
#include <Network/Packet/PacketCommand.h>
|
||||
#include <Network/Packet/PacketStruct/ServerInfo.h>
|
||||
#include <Network/Packet/PacketStruct/ServerPacket.h>
|
||||
|
||||
#include <Network/Dispatch/LoginDispatch.h>
|
||||
#include <Network/Dispatch/AuthDispatch.h>
|
||||
#include <Network/Dispatch/GameDispatch.h>
|
||||
#include <Network/Dispatch/UIDDispatch.h>
|
||||
|
||||
#include <DataStorage/SessionData.h>
|
||||
#include <Utility/Setup/ServerSetup.h>
|
||||
|
||||
#include <Log/ServerLog.h>
|
||||
|
||||
namespace DBAgent
|
||||
{
|
||||
namespace SendPacket
|
||||
{
|
||||
|
||||
class CSendUpdateServerVersionAllGameServer
|
||||
{
|
||||
public:
|
||||
bool operator () (unsigned long dwServer, CPacketDispatch& packetDispatch)
|
||||
{
|
||||
return DBAgent::SendPacket::UpdateServerVersion(
|
||||
static_cast<DBAgent::CGameDispatch&>(packetDispatch).GetSendStream());
|
||||
}
|
||||
};
|
||||
|
||||
bool ServerLogin(CSendStream& SendStream, unsigned long dwServerID)
|
||||
{
|
||||
char* lpBuffer = SendStream.GetBuffer(sizeof(PktSL));
|
||||
if(0 != lpBuffer)
|
||||
{
|
||||
const int MAX_ADDRESS = 64;
|
||||
char szAddress[MAX_ADDRESS];
|
||||
|
||||
CTCPFactory tcpFactory;
|
||||
tcpFactory.GetNetworkInfo(szAddress, MAX_ADDRESS);
|
||||
|
||||
PktSL* lpPktSL = reinterpret_cast<PktSL*>(lpBuffer);
|
||||
|
||||
lpPktSL->m_dwServerID = dwServerID;
|
||||
lpPktSL->m_Address.S_un.S_addr = inet_addr(szAddress);
|
||||
|
||||
return SendStream.WrapHeader(sizeof(PktSL), CmdSysServerLogin, 0, 0);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ServerLoginAck(CSendStream& SendStream, unsigned long dwServerID,
|
||||
unsigned __int64 dwItemSerial)
|
||||
{
|
||||
char* lpBuffer = SendStream.GetBuffer(sizeof(PktSLAck));
|
||||
|
||||
if(0 != lpBuffer)
|
||||
{
|
||||
PktSLAck* lpPktSLAck = reinterpret_cast<PktSLAck*>(lpBuffer);
|
||||
|
||||
CServerSetup& serverSetup = CServerSetup::GetInstance();
|
||||
|
||||
lpPktSLAck->m_dlItemUID = dwItemSerial;
|
||||
lpPktSLAck->m_dwServerID = dwServerID;
|
||||
|
||||
lpPktSLAck->m_dwClientVer = serverSetup.GetClientVer();
|
||||
lpPktSLAck->m_dwCheckSum = serverSetup.GetCheckSum();
|
||||
|
||||
strncpy(lpPktSLAck->m_PatchAddress,
|
||||
serverSetup.GetPatchAddress(), PktSLAck::PATCH_ADDRESS_LENGTH - 1);
|
||||
|
||||
lpPktSLAck->m_PatchAddress[PktSLAck::PATCH_ADDRESS_LENGTH - 1] = 0;
|
||||
|
||||
return SendStream.WrapHeader(sizeof(PktSLAck), CmdSysServerLogin, 0, 0);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool UpdateChannel(CSendStream& SendStream, unsigned long dwServerID)
|
||||
{
|
||||
char* lpBuffer = SendStream.GetBuffer(sizeof(PktSCInfo));
|
||||
if(0 != lpBuffer)
|
||||
{
|
||||
PktSCInfo* lpPktSCInfo = reinterpret_cast<PktSCInfo*>(lpBuffer);
|
||||
|
||||
lpPktSCInfo->m_dwServerID = dwServerID;
|
||||
|
||||
CGetTotalCount getCount(
|
||||
lpPktSCInfo->m_usChannelClientNum[0],
|
||||
lpPktSCInfo->m_usChannelClientNum[1],
|
||||
lpPktSCInfo->m_cChannelNum);
|
||||
|
||||
CGameDispatch::GetDispatchTable().Process(getCount);
|
||||
|
||||
if(0 < lpPktSCInfo->m_cChannelNum)
|
||||
{
|
||||
if(lpPktSCInfo->m_cChannelNum <= lpPktSCInfo->m_usChannelClientNum[0])
|
||||
{
|
||||
lpPktSCInfo->m_usChannelClientNum[0] -= lpPktSCInfo->m_cChannelNum;
|
||||
++lpPktSCInfo->m_usChannelClientNum[0];
|
||||
}
|
||||
|
||||
if(lpPktSCInfo->m_cChannelNum <= lpPktSCInfo->m_usChannelClientNum[1])
|
||||
{
|
||||
lpPktSCInfo->m_usChannelClientNum[1] -= lpPktSCInfo->m_cChannelNum;
|
||||
++lpPktSCInfo->m_usChannelClientNum[1];
|
||||
}
|
||||
|
||||
lpPktSCInfo->m_cChannelNum = 2;
|
||||
}
|
||||
|
||||
return SendStream.WrapCrypt(sizeof(PktSCInfo), CmdSysChannelUpdate, 0, 0);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool UpdateServerVersion(CSendStream& SendStream)
|
||||
{
|
||||
char* lpBuffer = SendStream.GetBuffer(sizeof(PktSVU));
|
||||
if(0 != lpBuffer)
|
||||
{
|
||||
PktSVU* lpPktSVU = reinterpret_cast<PktSVU*>(lpBuffer);
|
||||
|
||||
CServerSetup& serverSetup = CServerSetup::GetInstance();
|
||||
|
||||
lpPktSVU->m_dwClientVer = serverSetup.GetClientVer();
|
||||
lpPktSVU->m_dwCheckSum = serverSetup.GetCheckSum();
|
||||
strncpy(lpPktSVU->m_PatchAddress, serverSetup.GetPatchAddress(),
|
||||
PktSVU::PATCH_ADDRESS_LENGTH - 1);
|
||||
|
||||
lpPktSVU->m_PatchAddress[PktSVU::PATCH_ADDRESS_LENGTH - 1] = 0;
|
||||
|
||||
GET_SINGLE_DISPATCH(lpAuthDispatch,
|
||||
CAuthDispatch, CAuthDispatch::GetDispatchTable());
|
||||
|
||||
if(0 != lpAuthDispatch)
|
||||
{
|
||||
lpPktSVU->m_ServerAddr = lpAuthDispatch->GetRemoteAddr().get_addr_in().sin_addr;
|
||||
}
|
||||
else
|
||||
{
|
||||
lpPktSVU->m_ServerAddr.S_un.S_addr = 0;
|
||||
}
|
||||
|
||||
return SendStream.WrapCrypt(sizeof(PktSVU), CmdSysServerVerUpdate, 0, 0);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void UpdateChannelAllServer()
|
||||
{
|
||||
// 로그인 서버로 서버 버전 업데이트 보냄
|
||||
GET_SINGLE_DISPATCH(lpLoginDispatch, DBAgent::CLoginDispatch,
|
||||
DBAgent::CLoginDispatch::GetDispatchTable());
|
||||
|
||||
if(0 != lpLoginDispatch)
|
||||
{
|
||||
DBAgent::SendPacket::UpdateServerVersion(lpLoginDispatch->GetSendStream());
|
||||
}
|
||||
|
||||
// 인증 서버로 서버 버전 업데이트 보냄
|
||||
GET_SINGLE_DISPATCH(lpAuthDispatch, DBAgent::CAuthDispatch,
|
||||
DBAgent::CAuthDispatch::GetDispatchTable());
|
||||
|
||||
if(0 != lpAuthDispatch)
|
||||
{
|
||||
DBAgent::SendPacket::UpdateServerVersion(lpAuthDispatch->GetSendStream());
|
||||
}
|
||||
|
||||
// 게임 서버로 서버 버전 업데이트 보냄
|
||||
DBAgent::CGameDispatch::GetDispatchTable().Process(
|
||||
CSendUpdateServerVersionAllGameServer());
|
||||
}
|
||||
|
||||
|
||||
bool UpdateUIDTable(PktUUT::UpdateType eUpdateType, const char* szAccountName, const char* szPassword,
|
||||
unsigned long dwUID, unsigned long dwCID, unsigned long dwSessionID,
|
||||
unsigned long dwServerID, IN_ADDR peerAddr, unsigned short usError)
|
||||
{
|
||||
const char* szErrorReason = 0;
|
||||
|
||||
GET_SINGLE_DISPATCH(lpUIDDispatch, CUIDDispatch, CUIDDispatch::GetDispatchTable());
|
||||
|
||||
if(0 != lpUIDDispatch)
|
||||
{
|
||||
// edith 2008.01.15 UID 서버로 캐릭터 로그인 메시지를 전달한다.
|
||||
// 이유는 캐릭터 로그인을 전달해 빌링서버에서 인증을 하기위함이다.
|
||||
CSendStream& uidSendStream = lpUIDDispatch->GetSendStream();
|
||||
|
||||
char* lpBuffer = uidSendStream.GetBuffer(sizeof(PktUUT));
|
||||
if(0 != lpBuffer)
|
||||
{
|
||||
PktUUT* lpPktUUT = reinterpret_cast<PktUUT*>(lpBuffer);
|
||||
|
||||
lpPktUUT->m_cCmd = static_cast<unsigned char>(eUpdateType);
|
||||
|
||||
ZeroMemory(lpPktUUT->m_strAccount, PktUUT::MaxAccountLen);
|
||||
ZeroMemory(lpPktUUT->m_strPassword, PktUUT::MaxPasswordLen);
|
||||
|
||||
if(szAccountName && strlen(szAccountName) > 0)
|
||||
{
|
||||
strcpy(lpPktUUT->m_strAccount, szAccountName);
|
||||
}
|
||||
|
||||
// edith 2008.01.15 패스워드 추가작업
|
||||
if(szPassword && strlen(szPassword) > 0)
|
||||
{
|
||||
strcpy(lpPktUUT->m_strPassword, szPassword);
|
||||
// strncpy(lpPktUUT->m_strPassword, szPassword, PktUUT::MaxPasswordLen - 1);
|
||||
// lpPktUUT->m_strPassword[PktUUT::MaxPasswordLen - 1] = 0;
|
||||
}
|
||||
|
||||
lpPktUUT->m_IPAddress = peerAddr;
|
||||
|
||||
lpPktUUT->m_dwSessionID = dwSessionID;
|
||||
lpPktUUT->m_dwServerID = dwServerID;
|
||||
lpPktUUT->m_dwUserID = dwUID;
|
||||
lpPktUUT->m_dwCharID = dwCID;
|
||||
|
||||
if(uidSendStream.WrapHeader(sizeof(PktUUT), CmdUpdateUIDTable, 0, usError))
|
||||
{
|
||||
INFLOG3(g_Log, "UID:%10u / CID:%10u / ST:%s / UpdateUIDTable 전송 성공",
|
||||
dwUID, dwCID, g_szPktUUTString[eUpdateType]);
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
szErrorReason = "WrapHeader 실패";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
szErrorReason = "버퍼 할당 실패";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
szErrorReason = "UID서버와 연결 끊어짐";
|
||||
}
|
||||
|
||||
if(0 != szErrorReason)
|
||||
{
|
||||
ERRLOG4(g_Log, "UID:%10u / CID:%10u / ST:%s / UpdateUIDTable 전송 실패 : %s",
|
||||
dwUID, dwCID, g_szPktUUTString[eUpdateType], szErrorReason);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool UserKill(const DataStorage::CSessionData& SessionData)
|
||||
{
|
||||
SERVER_ID serverID;
|
||||
serverID.dwID = SessionData.GetServerID();
|
||||
|
||||
CSendStream* lpSendStream = 0;
|
||||
|
||||
if(serverID.GetType() == CServerSetup::AuthServer)
|
||||
{
|
||||
GET_SINGLE_DISPATCH(lpAuthDispatch, CAuthDispatch,
|
||||
CAuthDispatch::GetDispatchTable());
|
||||
|
||||
if(0 != lpAuthDispatch)
|
||||
{
|
||||
lpSendStream = &lpAuthDispatch->GetSendStream();
|
||||
}
|
||||
}
|
||||
else if(serverID.GetType() == CServerSetup::GameServer)
|
||||
{
|
||||
GET_MULTI_DISPATCH(lpGameDispatch, serverID.dwID,
|
||||
CGameDispatch, CGameDispatch::GetDispatchTable());
|
||||
|
||||
if(0 != lpGameDispatch)
|
||||
{
|
||||
lpSendStream = &lpGameDispatch->GetSendStream();
|
||||
}
|
||||
}
|
||||
|
||||
const char* szErrorReason = 0;
|
||||
|
||||
if(0 == lpSendStream)
|
||||
{
|
||||
szErrorReason = "해당 서버가 없습니다";
|
||||
}
|
||||
else
|
||||
{
|
||||
char* lpBuffer = lpSendStream->GetBuffer(sizeof(PktUK));
|
||||
if(0 == lpBuffer)
|
||||
{
|
||||
szErrorReason = "버퍼 할당 실패";
|
||||
}
|
||||
else
|
||||
{
|
||||
PktUK* lpPktUK = reinterpret_cast<PktUK*>(lpBuffer);
|
||||
|
||||
lpPktUK->m_dwUserID = SessionData.GetUID();
|
||||
lpPktUK->m_dwCharID = SessionData.GetCID();
|
||||
lpPktUK->m_dwServerID = SessionData.GetServerID();
|
||||
|
||||
if(!lpSendStream->WrapHeader(sizeof(PktUK), CmdUserKill, 0, 0))
|
||||
{
|
||||
szErrorReason = "전송 실패";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(0 != szErrorReason)
|
||||
{
|
||||
ERRLOG4(g_Log, "UID:%10u / CID:%10u / ServerID:0x%08X / 유저 죽이기 전송 실패 : %s",
|
||||
SessionData.GetUID(), SessionData.GetCID(), SessionData.GetServerID(), szErrorReason);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
INFLOG3(g_Log, "UID:%10u / CID:%10u / ServerID:0x%08X / 유저 죽이기 전송 성공",
|
||||
SessionData.GetUID(), SessionData.GetCID(), SessionData.GetServerID());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool BillingNotify(const DataStorage::CSessionData& SessionData,
|
||||
unsigned char cRemainMinute, char cBillingType)
|
||||
{
|
||||
GET_MULTI_DISPATCH(lpGameDispatch, SessionData.GetServerID(),
|
||||
CGameDispatch, CGameDispatch::GetDispatchTable());
|
||||
|
||||
if(0 != lpGameDispatch)
|
||||
{
|
||||
CSendStream& SendStream = lpGameDispatch->GetSendStream();
|
||||
|
||||
char* lpBuffer = SendStream.GetBuffer(sizeof(PktBTN));
|
||||
if(0 != lpBuffer)
|
||||
{
|
||||
PktBTN* lpPktBTN = reinterpret_cast<PktBTN*>(lpBuffer);
|
||||
|
||||
lpPktBTN->m_dwUserID = SessionData.GetUID();
|
||||
lpPktBTN->m_dwCharID = SessionData.GetCID();
|
||||
lpPktBTN->m_dwServerID = SessionData.GetServerID();
|
||||
lpPktBTN->m_cRemainMinute = cRemainMinute;
|
||||
lpPktBTN->m_cBillingType = cBillingType;
|
||||
|
||||
return SendStream.WrapHeader(sizeof(PktBTN), CmdBillingTimeoutNotify, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool BillingCheckNotify(const DataStorage::CSessionData& SessionData,
|
||||
unsigned char cRemainMinute, char cBillingType)
|
||||
{
|
||||
|
||||
SERVER_ID serverID;
|
||||
serverID.dwID = SessionData.GetServerID();
|
||||
|
||||
if (CServerSetup::AuthServer == serverID.GetType())
|
||||
{
|
||||
GET_SINGLE_DISPATCH(lpAuthDispatch,
|
||||
CAuthDispatch, CAuthDispatch::GetDispatchTable());
|
||||
|
||||
CSendStream& SendStream = lpAuthDispatch->GetSendStream();
|
||||
|
||||
char* lpBuffer = SendStream.GetBuffer(sizeof(PktBTN));
|
||||
if(0 != lpBuffer)
|
||||
{
|
||||
PktBTN* lpPktBTN = reinterpret_cast<PktBTN*>(lpBuffer);
|
||||
|
||||
lpPktBTN->m_dwUserID = SessionData.GetUID();
|
||||
lpPktBTN->m_dwCharID = SessionData.GetCID();
|
||||
lpPktBTN->m_dwServerID = SessionData.GetServerID();
|
||||
lpPktBTN->m_cRemainMinute = cRemainMinute;
|
||||
lpPktBTN->m_cBillingType = cBillingType;
|
||||
|
||||
return SendStream.WrapHeader(sizeof(PktBTN), CmdBillingTimeCheckNotify, 0, 0);
|
||||
}
|
||||
}
|
||||
else if(CServerSetup::GameServer == serverID.GetType())
|
||||
{
|
||||
GET_MULTI_DISPATCH(lpGameDispatch, SessionData.GetServerID(),
|
||||
CGameDispatch, CGameDispatch::GetDispatchTable());
|
||||
|
||||
if(0 != lpGameDispatch)
|
||||
{
|
||||
CSendStream& SendStream = lpGameDispatch->GetSendStream();
|
||||
|
||||
char* lpBuffer = SendStream.GetBuffer(sizeof(PktBTN));
|
||||
if(0 != lpBuffer)
|
||||
{
|
||||
PktBTN* lpPktBTN = reinterpret_cast<PktBTN*>(lpBuffer);
|
||||
|
||||
lpPktBTN->m_dwUserID = SessionData.GetUID();
|
||||
lpPktBTN->m_dwCharID = SessionData.GetCID();
|
||||
lpPktBTN->m_dwServerID = SessionData.GetServerID();
|
||||
lpPktBTN->m_cRemainMinute = cRemainMinute;
|
||||
lpPktBTN->m_cBillingType = cBillingType;
|
||||
|
||||
return SendStream.WrapHeader(sizeof(PktBTN), CmdBillingTimeCheckNotify, 0, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
#ifndef _DBAGENT_SERVER_SEND_SERVER_INFO_H_
|
||||
#define _DBAGENT_SERVER_SEND_SERVER_INFO_H_
|
||||
|
||||
#include <Network/Packet/PacketStruct/ServerPacket.h>
|
||||
|
||||
// forward decl.
|
||||
class CSendStream;
|
||||
class CPacketDispatch;
|
||||
|
||||
namespace DBAgent
|
||||
{
|
||||
namespace DataStorage
|
||||
{
|
||||
// forward delc.
|
||||
class CSessionData;
|
||||
}
|
||||
|
||||
namespace SendPacket
|
||||
{
|
||||
bool ServerLogin(CSendStream& SendStream, unsigned long dwServerID);
|
||||
bool ServerLoginAck(CSendStream& SendStream, unsigned long dwServerID,
|
||||
unsigned __int64 dwItemSerial);
|
||||
|
||||
bool UpdateChannel(CSendStream& SendStream, unsigned long dwServerID);
|
||||
bool UpdateServerVersion(CSendStream& SendStream);
|
||||
|
||||
void UpdateChannelAllServer();
|
||||
|
||||
bool UpdateUIDTable(PktUUT::UpdateType eUpdateType, const char* szAccountName, const char* szPassword,
|
||||
unsigned long dwUID, unsigned long dwCID, unsigned long dwSessionID,
|
||||
unsigned long dwServerID, IN_ADDR peerAddr, unsigned short usError = 0);
|
||||
|
||||
bool UserKill(const DataStorage::CSessionData& SessionData);
|
||||
|
||||
bool BillingNotify(const DataStorage::CSessionData& SessionData,
|
||||
unsigned char cRemainMinute, char cBillingType);
|
||||
|
||||
// ´ë¸¸ÂÊ ºô¸µ üũ Notify
|
||||
bool BillingCheckNotify(const DataStorage::CSessionData& SessionData,
|
||||
unsigned char cRemainMinute, char cBillingType);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user