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:
2025-11-29 20:17:20 +09:00
parent 5d3cd64a25
commit dd97ddec92
11602 changed files with 1446576 additions and 0 deletions

View File

@@ -0,0 +1,140 @@
#ifndef _CHAT_TOOL_PACKET_COMMAND_H_
#define _CHAT_TOOL_PACKET_COMMAND_H_
#include <Network/Packet/PacketBase.h>
#include <Network/Packet/PacketCommand.h>
#include <DB/DBDefine.h>
//! 채팅 모니터링 툴 패킷 및 패킷 커맨드를 정의하는 파일이다.
namespace ChatToolCMD
{
enum CMD
{
Authorize = 1,
ChangeOption = 2,
ChatSend = 3,
ChatRequest = 4,
ChatAdminStatus = 5,
ChatPing = CmdSysPing
};
};
#pragma pack(1)
namespace ChatToolPkt
{
enum Const
{
MAX_USER_ID = 16,
MAX_PASSWORD = 16,
MAX_CHAR_NAME = 16,
TARGET_UID = 0,
TARGET_CHARNAME = 1,
TARGET_ACCOUNTNAME = 2
};
//! Request : fill UserID/Passsword
//! Result : fill m_cResult( 1 : success / 0 : failed )
struct Authorize : public PktBase
{
char m_szUserID[MAX_USER_ID];
char m_szPassword[MAX_PASSWORD];
unsigned char m_cResult;
};
//! ChatServer -> ChatTool : fill all data + chatting message;
struct ChatDataSend : public PktBase
{
unsigned long m_dwUID;
unsigned long m_dwCID;
unsigned long m_dwServerID; // 서버 ID가 0인 경우는 모니터링 툴에서 보냈을때이다.
// 이때는 UID/CID가 툴에서 보낸 메시지를 받은 사람의 UID/CID값이 된다.
char m_szSenderName[CHAR_INFOST::MAX_NAME_LEN];
char m_szTargetName[CHAR_INFOST::MAX_NAME_LEN];
unsigned short m_usXPos;
unsigned short m_usZPos;
unsigned short m_usLang;
unsigned char m_cChatType;
unsigned char m_cChatMsgLen;
unsigned char m_cRace; // 종족이 머냐
};
//! ChatTool -> ChatServer : 채팅을 보낼 때 사용
struct ChatRequest : public PktBase
{
enum ERR
{
PACKET_ERROR = 1,
NONE_CHARACTER = 2, // 캐릭터 없음
};
char m_szAdminName[MAX_CHAR_NAME]; // 보내는 운영자 이름.
char m_szTargetName[MAX_CHAR_NAME]; // 귓속말을 보내는 경우, 누구에게 보낼지 세팅. (캐릭명 혹은 계정명)
unsigned long m_dwUID; // 대상 캐릭터 UID (TargetName이 없을 경우 사용)
unsigned long m_dwCID; // 대상 캐릭터 CID
unsigned long m_dwMessageID; // 메시지 ID. 그대로 돌려준다.
unsigned char m_cTargetType; // UID / CharName / AccountName 중 하나
unsigned char m_cChatType;
unsigned char m_cChatMsgLen;
};
//! Request : fill m_cChatOption
//! Result : none
struct ChatOption : public PktBase
{
enum Options
{
DO_LISTEN = 0, // 들을거면 무조건 1로 세팅.
LISTEN_NORMAL_CHAT = 1,
LISTEN_PARTY_CHAT = 2,
LISTEN_FRIEND_CHAT = 3,
LISTEN_GUILD_CHAT = 4,
LISTEN_STALL_CHAT = 5,
LISTEN_SHOUT_CHAT = 6,
LISTEN_ADMIN_NORMAL_CHAT = 7, // 운영자 통상 채팅 (Ack로만 사용)
LISTEN_ADMIN_SHOUT = 8, // 운영자 외치기 (Ack로만 사용)
LISTEN_WHISPER_CHAT = 9,
LISTEN_NOTICE = 10,
LISTEN_TRADE_CHAT = 11,
LISTEN_DICE_CHAT = 12,
MAX_OPTION = 20
};
unsigned char m_cChatOption[MAX_OPTION];
};
struct ChatAdminStatus : public PktBase
{
enum Status
{
LOGIN = 0,
LOGOUT = 1
};
char m_szChatAdminName[MAX_USER_ID];
unsigned char m_cChangeStatus;
};
};
#pragma pack()
#endif

View File

@@ -0,0 +1,329 @@
#ifndef _MANAGE_PACKET_COMMAND_H_
#define _MANAGE_PACKET_COMMAND_H_
#include <winsock2.h>
#include <windows.h>
#include <tchar.h>
#include <psapi.h>
#include <Network/Packet/PacketBase.h>
#include <Network/Packet/PacketCommand.h>
#include <ctime>
namespace ServerManage
{
namespace CMD
{
enum CMDType
{
// ManageClient, ManageServer, ManageTool 전부 사용하는 패킷 커맨드.
UpdateRunList = 0x00, // 실행 목룍을 준다 (ManageServer -> ManageClient, ManageTool), Ack없음.
RunProcess = 0x01, // 실행한다. (ManageTool -> ManageServer -> ManageClient), Ack는 반대 순서로 전송
QuitProcess = 0x02, // 종료한다. (ManageTool -> ManageServer -> ManageClient), Ack는 반대 순서로 전송
ForceTerminate = 0x03, // 강제 종료한다. (ManageTool -> ManageServer -> ManageClient), Ack는 반대 순서로 전송
ProcessStatus = 0x04, // 프로세스 상태 전송 (ManageClient -> ManageServer -> ManageTool), Ack없음.
RelayCommand = 0x05, // 패킷 커맨드를 윈도우 메시지를 써서 중계해서 넘긴다.
AutoPatch = 0x06, // 자기 자신을 패치한다
ChangeSetup = 0x07, // 설정을 바꾸고 저장한다.
ReloadSetup = 0x08, // 설정을 재로드한다.
ExecuteCommand = 0x09, // 콘솔 커맨드를 문자열로 전달한다.
// ManageServer <-> ManageTool
AuthUser = 0x10, // 유저 인증
AddUser = 0x11, // 유저 추가
DelUser = 0x12, // 유저 삭제
ModUser = 0x13, // 유저 정보 변경
RequestUserReaction = 0x14, // 유저에게 어떤 판단에 대해서 동의를 얻음.(usSubCommand 활용)
RequestPromote = 0x15, // 스스로 관리자가 되겠다고 선언
ManagerInfo = 0x16, // 현재 관리자 정보를 줌
// ManageServer -> ManageTool
UserList = 0x20, // 유저 리스트(유저 정보)
UserLogin = 0x21, // 서버에서 툴로 유저 정보를 준다. (유저가 로그인했음)
UserLogout = 0x22, // 서버에서 툴로 유저 정보를 준다. (유저가 로그아웃했음)
StatServerStatus= 0x23, // 관리서버, 통계서버간 연결 상태를 준다.
// ManageClient <-> Each Server
IPC_ManagePing = 0x30, // Each Server -> ManageClient (Alive여부 및 Window Name을 준다)
// ManageTool <-> ManageServer
Ping = CmdSysPing
};
enum RelaySubCmd
{
// UserInfo
SubCmd_ServerUserNum = 0x01
};
enum UserReactionSubCmd
{
// Promote
REQUEST_TAKEBACK_PROMOTE = 0x01,
ACK_TAKEBACK_PROMOTE = 0x02,
NAK_TAKEBACK_PROMOTE = 0x03
};
enum UserStatCMD
{
UPDATE_USER_STATUS = 0x01
};
};
#pragma pack(1)
// 패킷 뒤에 윈도우 이름, 추가 데이터가 붙어 온다.
// 사용 패킷 : ExecuteFile, RelayCommand, AutoPatch,
// ChangeSetup, ReloadSetup
//
struct ManageCommand : public PktBase
{
enum AutoPatchFlag
{
AUTOPATCH_OPENFILE = 1,
AUTOPATCH_DATA = 2
};
unsigned int nMessage; // 메시지 번호
WPARAM wParam; // 파라미터1
LPARAM lParam; // 파라미터2
unsigned long dwRunID; // 타겟 RunID
unsigned short usFlags; // 추가 데이터 플래그
unsigned short usDataLen; // 추가 데이터 길이
};
enum ManageCommandError
{
INVALID_MANAGE_PACKET_ERROR = 0,
CANNOT_FIND_CLIENT_DISPATCH = 1,
SEND_MANAGE_COMMAND_ERROR = 2,
UNKNOWN_RUN_INFO = 3,
INVALID_MANAGE_RIGHTS = 4
};
enum UpdateRunInfoFlags
{
SEND_RUNINFO_START = 0,
SEND_RUNINFO_NOW = 1,
SEND_RUNINFO_FINISH = 2
};
enum ProcessStatusFlags
{
PROCESS_RUNNING = (1 << 0)
};
struct ProcessStatus
{
unsigned long m_dwRunID;
unsigned long m_dwStatusFlags;
unsigned long m_dwCustomStatus;
unsigned long m_dwLastSetWindowHandleTime;
unsigned long m_dwCurrentTime;
FILETIME m_CreationTIme;
FILETIME m_ExitTime;
FILETIME m_KernelTime;
FILETIME m_UserTime;
PROCESS_MEMORY_COUNTERS m_ProcessMemoryCounters;
};
/*
사용 패킷 : AuthUser, AddUser, DelUser, ModUser, PromoteUser
AuthUser : 툴 -> 서버 (szID, szPassword),
서버 -> 툴 (szID, szPassword, szFullName, dwIP, usAdminLevel)
다른 툴들에게 전부 자신의 UserInfo 패킷을 보낸다.
로그인 된 사용자 전부의 정보를 받는다.
기능 : 유저 인증을 한다.
에러 코드 : INVALID_PACKET_ERROR,
AUTHORIZE_FAILED
AddUser : 툴 -> 서버 (szID, szPassword, szFullName, dwIP, usAdminLevel)
서버 -> 툴 (szID, szPassword, szFullName, dwIP, usAdminLevel)
기능 : 유저를 추가한다.
에러 코드 :
DelUser : 툴 -> 서버 (szID, szPassword, szFullName, dwIP, usAdminLevel)
서버 -> 툴 (szID, szPassword, szFullName, dwIP, usAdminLevel)
기능 : 유저를 삭제한다.
에러 코드 :
ModUser : 툴 -> 서버 (szID, szPassword, szFullName, dwIP, usAdminLevel)
서버 -> 툴 (szID, szPassword, szFullName, dwIP, usAdminLevel)
기능 : 유저 정보를 변경한다.
에러 코드 :
UserInfo : 툴 -> 서버
현재 로그인된 유저 정보를 요청한다. 데이터는 없다.
서버 -> 툴
현재 로그인된 유저 수만큼 UserInfo구조체가 뒤에 붙어 온다.
기능 : 사용자 정보를 전송한다.
에러 코드 :
Promote의 과정
0. 인증 성공시, 현재 Promote된 유저의 ID를 준다.
1. Manager가 없거나 Master의 Promote
서버로 Promote패킷을 보냄 -> 서버는 Master거나 Manager가 없음을 확인.
-> 확인 성공시 이 id에 Promote 권한을 준다.
-> 각 유저들에게 누가 Promote유저인지를 가르쳐 준다.
2. General의 Promote
서버로 Promote패킷을 보냄 -> 서버는 General인지 확인
-> 확인 성공시, 현재 Promote 권한이 있는 유저가 있는지 살피고 확인 패킷 보냄
-> 확인 패킷에서, ok가 오면, 권한을 넘기고, 각 유저들에게 Promote유저임을 준다.
-> 확인 패킷에서, no가 오면, Promote요청자에게 실패 메시지를 준다.
필요 패킷
1. ManageUserInfo (ManageServer -> ManageTool) ManagerID및 정보
2. Request Promote (ManageTool -> ManageServer) 정보 없음
3. Request Promote Ack (ManageServer -> ManageTool) 정보 없음
4. Request User Reaction (ManageServer -> ManageTool) 요구자 정보, 요구 타입(usSubCommand)
5. Request User Reaction Ack (ManageTool -> ManageServer) 요구자 정보, 요구 결과(usSubCommand)
*/
enum UserCommandError
{
NO_USER_COMMAND_ERROR = 0,
INVALID_USER_PACKET_ERROR = 1,
AUTHORIZE_FAILED = 2,
CANNOT_AUTHORIZE_NOT_USER = 3,
CANNOT_AUTHORIZE_INVALID_PASSWORD = 4,
CANNOT_AUTHORIZE_INVALID_IPADDRESS = 5,
ALREADY_LOGINED = 6,
ADD_USER_FAILED = 7,
DELETE_USER_FAILED = 8,
MODIFY_USER_FAILED = 9,
PROMOTE_USER_FAILED = 10,
PROMOTE_TAKEBACK_FAILED = 11,
REJECTED_PROMOTE_USER = 12,
SEND_USER_LIST_FAILED = 13,
INVALID_USERMANAGE_RIGHTS = 14
};
struct UserInfo
{
enum Const
{
// edith 2008.03.17 ID,PASS 길이조정
ID_LEN = 16,
PASS_LEN = 16,
NAME_LEN = 32
};
TCHAR szFullName[NAME_LEN];
TCHAR szID[ID_LEN];
TCHAR szPassword[PASS_LEN];
unsigned long dwIP;
unsigned short usAdminLevel;
unsigned short usSubCommand;
};
struct UserCommand : public PktBase
{
unsigned char cUserInfoNum;
// 뒤에 UserInfo구조체가 cUserInfoNum개 만큼 붙는다.
};
/*
Relay Command로 오는 커맨드
서버 정보
*/
struct RunInfo
{
enum Const
{
MAX_SERVER_NAME = 64,
MAX_PATH_LEN = 260,
MAX_OPT_LEN = 260
};
unsigned long m_dwRunID; // RunID(primary key)
unsigned long m_dwServerIP; // (network order ip)
unsigned long m_dwPathID; // PathID
unsigned long m_dwOptionID; // OptionID
char m_szServerName[MAX_SERVER_NAME];
char m_szPath[MAX_PATH_LEN];
char m_szOption[MAX_OPT_LEN];
};
struct PktManagePacket : public PktBase
{
unsigned long m_dwPID;
unsigned long m_dwStatusFlag;
unsigned long m_dwSubCommand;
PktManagePacket() : m_dwPID(GetCurrentProcessId()), m_dwStatusFlag(0), m_dwSubCommand(0) { }
};
struct PktManagePing : public PktManagePacket
{
char m_szAppFullPathName[MAX_PATH];
char m_szWindowName[MAX_PATH];
char m_szCommandLine[MAX_PATH * 2];
};
struct UserNumPair
{
unsigned long m_dwServerID;
int m_nUserNum;
};
struct PktManageUserNum : public PktManagePacket
{
unsigned long m_dwUserInfoNum;
};
struct PktUserStat : public PktBase
{
enum SIZE
{
MAX_DATE = 20
};
//time_t m_nTime;
char m_szSendingTime[MAX_DATE];
unsigned short m_usUserStatDataNum;
};
struct UserStatData
{
unsigned int m_nNation; // 국가 코드(AdminToolServer.ini 참조)
unsigned long m_dwServerID; // 정보를 전송해온 서버 ID
unsigned int m_nUserNum; // 접속 유저 수
};
struct StatServerStatus : public PktBase
{
bool m_bGlobalStatServerOK; // 글로번 통계서버와 관리서버 연결 상태
bool m_bLocalStatServerOK; // 로컬 통계서버와 관리서버 연결 상태
};
#pragma pack()
};
#endif

View File

@@ -0,0 +1,3 @@
#include "stdafx.h"
#include "PacketBase.h"
#include "GMMemory.h"

View File

@@ -0,0 +1,177 @@
#ifndef _PACKET_BASE
#define _PACKET_BASE
////////////////////////////////////////////////////////////////////////////////////////////////////
//
// 서버의 버퍼링 상태
//
// SS_SMOOTH : 원활한 소통 중임.
// SS_LOADED : 약간의 부하가 있슴. (50 % of bufferring)
// SS_BUSY : 과중한 부하가 있슴. (70 % of bufferring)
// SS_VERYBUSY : 극심한 과부하 상태임 (패킷 손실을 초래할 수 있슴.)
//
////////////////////////////////////////////////////////////////////////////////////////////////////
union ServerInfo
{
enum ServerState
{
SS_SMOOTH, SS_LOADED, SS_BUSY, SS_VERYBUSY
};
struct sSrvState
{
unsigned short wError; // 에러 코드
unsigned short wSrvState; // 서버 상태
};
sSrvState SrvState;
unsigned long dwServerInfo;
};
////////////////////////////////////////////////////////////////////////////////////////////////////
// 기본 패킷
#pragma pack(1)
struct PktBase
{
enum PktBaseErr
{
NO_SERVER_ERR = 0,
SERVER_ERROR = 1
};
typedef unsigned char StartType;
typedef unsigned char CMDType;
typedef unsigned short LengthType;
protected:
StartType m_StartBit;
CMDType m_Cmd;
LengthType m_Len; // 헤더 길이를 포함한 패킷 길이
unsigned long m_CodePage;
ServerInfo m_SrvInfo;
public:
inline void InitPtHead(unsigned short Len_In, unsigned char Cmd_In,
unsigned short State_In, unsigned short Error_In);
inline void InitPtHead(unsigned short Len_In, unsigned char Cmd_In, unsigned long Tick_In);
inline void SetError(unsigned short Error) { m_SrvInfo.SrvState.wError = Error; }
inline unsigned short GetError(void) { return m_SrvInfo.SrvState.wError; }
inline unsigned short GetState(void) { return m_SrvInfo.SrvState.wSrvState; }
inline StartType GetStartBit(void) { return m_StartBit; }
inline void SetCodePage(unsigned long Code) { m_CodePage = Code; }
inline unsigned long GetCodePage(void) { return m_CodePage; }
inline void SetServerInfo(unsigned long Info) { m_SrvInfo.dwServerInfo = Info; }
inline unsigned long GetServerInfo(void) { return m_SrvInfo.dwServerInfo; }
inline CMDType GetCmd(void) const { return m_Cmd; }
inline bool IsCrypt(void);
inline void SetCrypt(void);
inline bool IsCompress(void);
inline void SetCompress(void);
inline LengthType GetUncompressLen(void);
inline void SetLen(LengthType Len);
inline LengthType GetLen(void);
};
typedef PktBase* LPPktBase;
// 여러개를 압축해서 보낼 때 사용하는 패킷 헤더.
struct PktBlockCompressedBase
{
public:
unsigned short GetLength() const { return m_usLength; }
unsigned char GetCmd() const { return m_cCommand; }
unsigned char GetExtra() const { return m_cExtra; }
void InitPtHead(unsigned short usLength, unsigned char cCmd, unsigned char cExtra)
{
m_usLength = usLength;
m_cCommand = cCmd;
m_cExtra = cExtra;
}
protected:
unsigned short m_usLength;
unsigned char m_cCommand;
unsigned char m_cExtra;
};
#pragma pack()
const unsigned int PktBaseSize = sizeof(PktBase);
const PktBase::StartType StartBit = 0xFF; // 시작 비트
const PktBase::LengthType Crypt = 0x8000; // 암호화 여부 - 1000B
const PktBase::LengthType Compress = 0x4000; // 압축 여부 - 0100B
const PktBase::LengthType LengthHdr = 0xC000; // 1100B
const PktBase::LengthType LengthMask = 0x3FFF; // 실제 길이 얻어내느 마스크 값. 전부 14비트. 최대 16383byte.
const PktBase::LengthType PktMinLen = sizeof(PktBase);
const PktBase::LengthType PktMaxLen = 16383;
const PktBase::LengthType MIN_PACKET_LEN = sizeof(PktBase);
const PktBase::LengthType MAX_PACKET_LEN = 16383;
inline bool PktBase::IsCrypt(void) { return ((m_Len & Crypt) == Crypt) ? true : false; }
inline void PktBase::SetCrypt(void) { m_Len |= Crypt; }
inline bool PktBase::IsCompress(void) { return ((m_Len & Compress) == Compress) ? true : false; }
inline void PktBase::SetCompress(void) { m_Len |= Compress; }
inline PktBase::LengthType PktBase::GetUncompressLen(void) { return PktMaxLen; }
inline void PktBase::SetLen(PktBase::LengthType Len) { m_Len = (m_Len & LengthHdr) | Len; }
inline PktBase::LengthType PktBase::GetLen(void) { return m_Len & LengthMask; }
//Interface/////////////////////////////////////////////////////////////////////////////////////
//
// 패킷 해더 초기화
//
// Parameter :
// 1st : 길이[In]
// 2st : 커맨드[In]
// 3st : 서버 상태[In]
// 4st : 에러[In]
//
// Return :
//
///////////////////////////////////////////////////////////////////////////////////////////////
inline void PktBase::InitPtHead(unsigned short Len_In, unsigned char Cmd_In,
unsigned short State_In, unsigned short Error_In)
{
m_StartBit = StartBit;
m_Cmd = Cmd_In;
m_Len = Len_In;
m_CodePage = 0;
m_SrvInfo.SrvState.wSrvState = State_In;
m_SrvInfo.SrvState.wError = Error_In;
}
inline void PktBase::InitPtHead(unsigned short Len_In, unsigned char Cmd_In, unsigned long Tick_In)
{
m_StartBit = StartBit;
m_Cmd = Cmd_In;
m_Len = Len_In;
m_CodePage = 0;
m_SrvInfo.dwServerInfo = Tick_In;
}
#endif

View File

@@ -0,0 +1,299 @@
////////////////////////////////////////////////////////////////////////////////////////////////////
//
// 패킷 커맨드
//
////////////////////////////////////////////////////////////////////////////////////////////////////
#ifndef _PACKET_COMMAND_H_
#define _PACKET_COMMAND_H_
#include <Network/Packet/PacketBase.h>
////////////////////////////////////////////////////////////////////////////////////////////////////
//
// 커맨드
//
////////////////////////////////////////////////////////////////////////////////////////////////////
const PktBase::CMDType CmdNull = 0x00;
const PktBase::CMDType CmdAuthAccount = 0x01; // 계정 인증
const PktBase::CMDType CmdServerGroup = 0x02; // 서버군 선택
const PktBase::CMDType CmdUserLogin = 0x03; // 유저 로그인
const PktBase::CMDType CmdUserKill = 0x04; // 유저 제거
const PktBase::CMDType CmdCharSelect = 0x05; // 캐릭터 선택
const PktBase::CMDType CmdCharCreate = 0x06; // 캐릭터 생성
const PktBase::CMDType CmdCharDelete = 0x07; // 캐릭터 삭제
const PktBase::CMDType CmdCharLogin = 0x08; // 캐릭터 로그인
const PktBase::CMDType CmdCharSuicide = 0x09; // 캐릭터 자살
const PktBase::CMDType CmdCharRespawn = 0x0A; // 캐릭터 부활
const PktBase::CMDType CmdCharMove = 0x0B; // 캐릭터 이동 (P2P)
const PktBase::CMDType CmdCharMoveUpdate = 0x0C; // 캐릭터 이동 업데이트
const PktBase::CMDType CmdCharChat = 0x0D; // 캐릭터 채팅
const PktBase::CMDType CmdCharAttack = 0x0E; // 캐릭터 공격
const PktBase::CMDType CmdCharCastObject = 0x0F; // 캐릭터 오브젝트 던지기
const PktBase::CMDType CmdCharUseSkill = 0x10; // 캐릭터 스킬 사용
const PktBase::CMDType CmdCharTakeItem = 0x11; // 캐릭터 아이템 집기
const PktBase::CMDType CmdCharSwapItem = 0x12; // 캐릭터 아이템 스왑
const PktBase::CMDType CmdCharRepairItem = 0x13; // 캐릭터 아이템 수리
const PktBase::CMDType CmdCharUseItem = 0x14; // 캐릭터 아이템 사용
const PktBase::CMDType CmdCharTradeItem = 0x15; // 캐릭터 아이템 거래
const PktBase::CMDType CmdCharSkillLock = 0x16; // 캐릭터 스킬 락
const PktBase::CMDType CmdCharSkillCreate = 0x17; // 캐릭터 스킬 생성
const PktBase::CMDType CmdCharSkillErase = 0x18; // 캐릭터 스킬 지우기
const PktBase::CMDType CmdCharClassUpgrade = 0x19; // 캐릭터 클래스 업그레이드
const PktBase::CMDType CmdCharShapeInfo = 0x1A; // 캐릭터 정보 (P2P)
const PktBase::CMDType CmdCharIncreasePoint = 0x1B; // 캐릭터 능력 포인트 증가
const PktBase::CMDType CmdCharBindPosition = 0x1C; // 캐릭터 바인드 포지션
const PktBase::CMDType CmdCharRequireInfo = 0x1D; // 캐릭터 해당 정보 요청
const PktBase::CMDType CmdCharUpdateAddress = 0x1E; // 캐릭터 UDP 주소 업데이트
const PktBase::CMDType CmdCharPartyCmd = 0x1F; // 캐릭터 파티 명령
const PktBase::CMDType CmdCharPartyMemInfo = 0x20; // 캐릭터 파티 맴버 정보 전달
const PktBase::CMDType CmdCharExchangeCmd = 0x21; // 캐릭터 아이템 교환 명령
const PktBase::CMDType CmdSysConnectAgent = 0x22; // 시스템 중계 접속 (UDP 중계) # 사용 안함
const PktBase::CMDType CmdSysPacketTransmit = 0x23; // 시스템 패킷 전달 (UDP 중계) # 사용 안함
const PktBase::CMDType CmdCharLogout = 0x24; // 캐릭터 로그 아웃
const PktBase::CMDType CmdDBGetData = 0x25; // DB 데이터 얻기
const PktBase::CMDType CmdDBUpdateData = 0x26; // 업데이트 DB 데이터
const PktBase::CMDType CmdAgentParty = 0x27; // DB 에이전트 파티
const PktBase::CMDType CmdSysServerLogin = 0x28; // 시스템 서버 로그인
const PktBase::CMDType CmdServerZone = 0x29; // 서버존 선택
const PktBase::CMDType CmdGameCellInfo = 0x2A; // 게임 셀 정보 (오브젝트 정보)
const PktBase::CMDType CmdCharInfo = 0x2B; // 캐릭터 정보 (서버군 통합에 사용함)
const PktBase::CMDType CmdCharAddressInfo = 0x2C; // 캐릭터 UDP 주소 정보
const PktBase::CMDType CmdCharCellLogin = 0x2D; // 캐릭터 셀 로그인
const PktBase::CMDType CmdCharCellLogout = 0x2E; // 캐릭터 셀 로그아웃
const PktBase::CMDType CmdMonMove = 0x2F; // 몬스터 이동
const PktBase::CMDType CmdCharAttackInfo = 0x30; // 캐릭터 공격 정보 (P2P)
const PktBase::CMDType CmdCharAttacked = 0x31; // 캐릭터 공격 얻음
const PktBase::CMDType CmdCharAward = 0x32; // 캐릭터 어워드
const PktBase::CMDType CmdCharItemInfo = 0x33; // 캐릭터 아이템 정보
const PktBase::CMDType CmdCharPickUp = 0x34; // 캐릭터 집기
const PktBase::CMDType CmdCharPullDown = 0x35; // 캐릭터 떨구기
const PktBase::CMDType CmdCharPickUpInfo = 0x36; // 캐릭터 집기 정보
const PktBase::CMDType CmdCharPullDownInfo = 0x37; // 캐릭터 떨구기 정보
const PktBase::CMDType CmdCharCastObjectInfo = 0x38; // 캐릭터 던지기 오브젝트 정보
const PktBase::CMDType CmdCharInstallSocket = 0x39; // 캐릭터 아이템 소켓 설치
const PktBase::CMDType CmdCharLevelUp = 0x3A; // 캐릭터 레벨 업
const PktBase::CMDType CmdCharPartyInfo = 0x3B; // 캐릭터 파티 정보
const PktBase::CMDType CmdCharUpgradeItem = 0x3C; // 캐릭터 아이템 업그레이드
const PktBase::CMDType CmdCharHPRegen = 0x3D; // 캐릭터 HP 리젠
const PktBase::CMDType CmdCharLevelUpInfo = 0x3E; // 캐릭터 레벨업 정보
const PktBase::CMDType CmdCharSplitItem = 0x3F; // 캐릭터 스플릿 아이템 (개수 있는 아이템을 두개로 쪼갤 때 쓰임)
const PktBase::CMDType CmdUpdateUIDTable = 0x40; // UID 테이블 업데이트
const PktBase::CMDType CmdCharQuickSlotMove = 0x41; // 캐릭터 퀵슬롯 이동
const PktBase::CMDType CmdCharSwitchEQ = 0x42; // 장비 바꾸기
const PktBase::CMDType CmdSysMngerRegistry = 0x43; // 서버 관리자 등록
const PktBase::CMDType CmdSysMngerRequest = 0x44; // 서버 관리자의 요청
const PktBase::CMDType CmdSysMngerResponse = 0x45; // 서버 관리자로 응답
const PktBase::CMDType CmdCharTakeItems = 0x46; // 캐릭터 아이템 집기 (복수)
const PktBase::CMDType CmdCharTakeGold = 0x47; // 캐릭터 돈 집기
const PktBase::CMDType CmdCharExchangeItem = 0x48; // 캐릭터 아이템 교환
const PktBase::CMDType CmdCellBroadCasting = 0x49; // 셀 브로드 캐스팅
const PktBase::CMDType CmdSysPatchAddress = 0x4A; // 패치 주소
const PktBase::CMDType CmdCharPartyCmdInfo = 0x4B; // 파티 명령 정보
const PktBase::CMDType CmdServerLog = 0x4C; // 로그 정보 (???)
const PktBase::CMDType CmdCharWhisper = 0x4D; // 캐릭터 귓속말
const PktBase::CMDType CmdSysServerVerUpdate = 0x4E; // 서버 버젼 업데이트
const PktBase::CMDType CmdSysMng = 0x4F; // 서버 관리 서버, 클라이언트가 사용하는 패킷 (임시) (???)
const PktBase::CMDType CmdSysChannelUpdate = 0x50; // 서버 채널 업데이트
const PktBase::CMDType CmdCharPartyFind = 0x51; // 파티 찾기
const PktBase::CMDType CmdCharPartyMemData = 0x52; // 파티 멤버 데이터
const PktBase::CMDType CmdCharControlOption = 0x53; // 캐릭터 옵션 조정
const PktBase::CMDType CmdCharDuelCmd = 0x54; // 캐릭터 듀얼 명령
const PktBase::CMDType CmdCharFameInfo = 0x55; // 캐릭터 명성 정보
const PktBase::CMDType CmdLoginServerList = 0x56; // 서버 리스트 #!! 번호 수정 불가 !!#
const PktBase::CMDType CmdCharSpellInfo = 0x57; // 캐릭터 챈트&인챈트 정보
const PktBase::CMDType CmdCharSkillUnLock = 0x58; // 캐릭터 스킬 락 해제
const PktBase::CMDType CmdSysPing = 0x59; // 서버 핑 패킷
const PktBase::CMDType CmdCharMoveZone = 0x5A; // 존 이동
const PktBase::CMDType CmdAgentZone = 0x5B; // 존 관리
const PktBase::CMDType CmdDeposit = 0x5C; // 창고 처리 패킷 (Client <--> GameServer)
const PktBase::CMDType CmdDepositUpdate = 0x5D; // 창고 업데이트 패킷 (GameServer <--> DBAgent)
const PktBase::CMDType CmdCharStallOpen = 0x5E; // 캐릭터 노점상 개설
const PktBase::CMDType CmdCharStallRegisterItem = 0x5F; // 캐릭터 노점상 아이템 등록
const PktBase::CMDType CmdCharStallEnter = 0x60; // 캐릭터 노점상 입장
const PktBase::CMDType CmdCharStallItemInfo = 0x61; // 캐릭터 노점상 아이템 정보
const PktBase::CMDType CmdCharAdminCmd = 0x62; // 캐릭터 어드민
const PktBase::CMDType CmdCharTeamBattleInfo = 0x63; // 팀배틀 정보
const PktBase::CMDType CmdFriendAddRequest = 0x64; // 친구 추가
const PktBase::CMDType CmdFriendRemoveRequest = 0x65; // 친구 삭제
const PktBase::CMDType CmdFriendEtcRequest = 0x66; // 친구 기타
const PktBase::CMDType CmdFriendAck = 0x67; // 친구 Ack
const PktBase::CMDType CmdFriendDB = 0x68; // 친구 데이터 (및 친구 리스트 정보)
const PktBase::CMDType CmdEliteBonus = 0x69; // 엘리트 보너스
const PktBase::CMDType CmdCharStartQuest = 0x6A; // 퀘스트 시작
const PktBase::CMDType CmdCharOperateTrigger = 0x6B; // 트리거 발동
const PktBase::CMDType CmdQuestDB = 0x6C; // 퀘스트 정보 (DB에 세이브/로드, 캐릭터 로긴시)
const PktBase::CMDType CmdCharEndQuest = 0x6D; // 퀘스트 종료
const PktBase::CMDType CmdCharDisappearItem = 0x6E; // 캐릭터 아이템 사라지기
const PktBase::CMDType CmdCharAuthorizePanel = 0x6F; // 캐릭터 인증 판넬
const PktBase::CMDType CmdCharPeaceMode = 0x70; // 캐릭터 반전 모드
const PktBase::CMDType CmdConfigInfoDB = 0x71; // 설정 정보
const PktBase::CMDType CmdCharAutoRouting = 0x72; // 캐릭터 오토 루팅
const PktBase::CMDType CmdRankingInfo = 0x73; // 랭킹 정보
const PktBase::CMDType CmdCharStateRedistribution = 0x74; // 스탯 재분배 (클래스 처음 상태로)
const PktBase::CMDType CmdBillingTimeoutNotify = 0x75; // 빌링 타임아웃 Notify정보
const PktBase::CMDType CmdAdminToolGetData = 0x76; // 운영툴에서 DBAgent의 데이터 얻어 오기.
const PktBase::CMDType CmdAdminToolSetData = 0x77; // 운영툴에서 DBAgent로 데이터 쓰기.
const PktBase::CMDType CmdEventDropItem = 0x78; // 아이템 떨구기 이벤트
const PktBase::CMDType CmdCharCancelQuest = 0x79; // 퀘스트 취소
const PktBase::CMDType CmdBillingTimeCheckNotify = 0x7A; // 빌링 타임 체크
const PktBase::CMDType CmdCharLotteryResult = 0x7B; // 복권 결과
const PktBase::CMDType CmdCharSummonCmd = 0x7C; // 소환수 명령
const PktBase::CMDType CmdChatClientLogin = 0x7D; // 클라이언트에서 채팅서버에 붙을 때 정보 줌
const PktBase::CMDType CmdChatLogin = 0x7E; // 중계서버가 채팅서버로 클라이언트 로그인 줌.
const PktBase::CMDType CmdChatLogout = 0x7F; // 중계서버가 채팅서버로 클라이언트 로그아웃 줌.
const PktBase::CMDType CmdChatInfoChanged = 0x80; // 중계서버가 채팅서버로 클라이언트 정보 변경 줌.
const PktBase::CMDType CmdCharSummon = 0x81; // 소환
const PktBase::CMDType CmdJapanAuthAccount = 0x82; // 일본쪽 계정 인증 (ID, Password대신, 인증된 코드가 온다.)
const PktBase::CMDType CmdCharBattleGroundRespawn = 0x83; // 리스폰 (배틀그라운드 대기중)
const PktBase::CMDType CmdCharRespawnWaitQueue = 0x84; // 리스폰 큐 대기인 정보 (배틀그라운드용)
const PktBase::CMDType CmdStatueInfo = 0x85; // 석상 정보
const PktBase::CMDType CmdCameraScript = 0x86; // 카메라 스크립트
const PktBase::CMDType CmdCharEquipDurability = 0x87; // 캐릭터 장비 내구도
const PktBase::CMDType CmdCreateGuild = 0x88; // 길드 생성
const PktBase::CMDType CmdGuildCmd = 0x89; // 길드 멤버 관련 명령
const PktBase::CMDType CmdGuildMark = 0x8A; // 길드 마크 변경
const PktBase::CMDType CmdGuildLevel = 0x8B; // 길드 레벨 변경
const PktBase::CMDType CmdGuildRelation = 0x8C; // 길드 관계 변경
const PktBase::CMDType CmdGuildList = 0x8D; // 길드 리스트
const PktBase::CMDType CmdGuildDB = 0x8E; // 길드 데이터
const PktBase::CMDType CmdGuildRight = 0x8F; // 길드 권한 설정
const PktBase::CMDType CmdGuildMemberList = 0x90; // 길드 멤버 리스트
const PktBase::CMDType CmdMyGuildInfo = 0x91; // 자기 길드 정보
const PktBase::CMDType CmdGuildSafe = 0x92; // 길드 금고
const PktBase::CMDType CmdGuildMemberInfoUpdate = 0x93; // 길드 멤버 정보 업데이트
const PktBase::CMDType CmdCharStatusRetrain = 0x94; // 스테이터스 재훈련 (일정량 다시 돌려받음)
const PktBase::CMDType CmdSysServerLogout = 0x95; // 서버 로그아웃
const PktBase::CMDType CmdCharUseCashItem = 0x96; // 캐릭터 캐쉬 아이템 사용
const PktBase::CMDType CmdExtraEvent = 0x97; // 엑스트라 이벤트 관련
//const PktBase::CMDType CmdCharPartyAddress = 0x96; // 파티원 UDP 주소 정보
//const PktBase::CMDType CmdCharPartyMemAddress = 0x97; // 파티원 UDP 주소 정보 (P2P)
const PktBase::CMDType CmdBGServerMapList = 0x98; // 배틀 그라운드 서버 맵(방) 정보 리스트 요청
const PktBase::CMDType CmdBGServerResultList = 0x99; // 배틀 그라운드 서버 맵(방) 결과 리스트 요청
const PktBase::CMDType CmdBGServerMoveZone = 0x9A; // 배틀 그라운드 서버 맵(방) 이동 (존 이동)
const PktBase::CMDType CmdBGServerMileageChange = 0x9B; // 배틀 그라운드 서버 환전소 명령
const PktBase::CMDType CmdBGServerCharSlot = 0x9C; // 배틀 그라운드 서버 정섭 캐릭터 정보 요청
const PktBase::CMDType CmdHanBTNWarning = 0x9D; // 한게임 통합빌링 접속 끊기전 경고 메시지
const PktBase::CMDType CmdHanBTNUserKill = 0x9E; // 한게임 통합빌링 접속 끊기 메시지
const PktBase::CMDType CmdCharRepairAllItem = 0x9F; // 장비 아이템 모두 수리
const PktBase::CMDType CmdCSAuth = 0xA0; // 인증 코드 (게임 가드)
const PktBase::CMDType CmdCharItemChemical = 0xA1; // 아이템 합성
const PktBase::CMDType CmdItemQtyCheck = 0xA2; // 아이템 수량 제어
const PktBase::CMDType CmdGuildInclination = 0xA3; // 길드 성향
const PktBase::CMDType CmdGuildMemberFameUpdate = 0xA4; // 길드 멤버 명성 업데이트
const PktBase::CMDType CmdCastleInfo = 0xA5; // 성 정보 보내기 (DBAgentServer -> GameServer)
const PktBase::CMDType CmdCampInfo = 0xA6; // 길드 요새 정보 보내기 (DBAgentServer -> GameServer)
const PktBase::CMDType CmdCreateCastle = 0xA7; // 성 생성 (GameServer -> Client)
const PktBase::CMDType CmdCreateCamp = 0xA8; // 길드 요새 생성 (Client <- GameServer -> DBAgentServer)
const PktBase::CMDType CmdCreateSiegeArms = 0xA9; // 공성 병기 생성 (Client <- GameServer -> DBAgentServer)
const PktBase::CMDType CmdCastleCmd = 0xAA; // 성 관련 명령 패킷 (Client <-> GameServer <-> DBAgentServer)
const PktBase::CMDType CmdCampCmd = 0xAB; // 길드 요새 관련 명령 패킷 (Client <-> GameServer <-> DBAgentServer)
const PktBase::CMDType CmdSiegeArmsCmd = 0xAC; // 공성 병기 관련 명령 패킷 (Client <-> GameServer <-> DBAgentServer)
const PktBase::CMDType CmdCastleRight = 0xAD; // 성 관리 권한 패킷 (Client <-> GameServer <-> DBAgentServer)
const PktBase::CMDType CmdCampRight = 0xAE; // 길드 요새 관리 권한 패킷
const PktBase::CMDType CmdSiegeBroadCast = 0xAF; // 공성 오브젝트 브로드 캐스트
const PktBase::CMDType CmdGameTimeInfo = 0xB0; // 게임 시간 정보
const PktBase::CMDType CmdStealthInfo = 0xB1; // 스텔스 사용가능 정보
//const PktBase::CMDType CmdCastleUpdate = 0xB2; // 성 정보 업데이트 (DBAgentServer -> GameServer -> Client)
const PktBase::CMDType CmdCellBroadCast2nd = 0xB3; // 셀 브로드캐스트 수정된 패킷
const PktBase::CMDType CmdCharRespawnInfo = 0xB4; // 리스폰 정보 (리스폰 지역 리스트 정보)
const PktBase::CMDType CmdCharRespawnAreaInfo = 0xB5; // 선택한 리스폰 지역의 세부 정보
const PktBase::CMDType CmdCharEquipShopInfo = 0xB6; // NPC 장비 상점 정보
const PktBase::CMDType CmdSiegeBroadCast2nd = 0xB7; // 공성 오브젝트 브로드 캐스트 다른 버젼
const PktBase::CMDType CmdCharItemOptionGraft = 0xB8; // 아이템 옵션 이식
const PktBase::CMDType CmdCharItemCompensation = 0xB9; // 아이템 보상 판매
const PktBase::CMDType CmdGuildMemberGoldUpdate = 0xBA; // 길드 멤버 돈 업데이트
const PktBase::CMDType CmdCampMessage = 0xBB; // 길드 요새 관련 메시지 패킷
const PktBase::CMDType CmdCharDeadInfo = 0xBC; // 캐릭터 사망 정보
const PktBase::CMDType CmdNewSiegeBroadCast = 0xBD; // 공성 오브젝트 브로드 캐스트 최신 버젼 (스피어 트리 사용)
const PktBase::CMDType CmdSelectAccountNation = 0xBE; // 계정 국적 변경 패킷
const PktBase::CMDType CmdNationChangeResult = 0xBF; // 계정 국적 변경으로 인한 변경된 캐릭터 정보 패킷
const PktBase::CMDType CmdUnifiedCharInfo = 0xC0; // 서버통합시 캐릭터 정보 보내기
const PktBase::CMDType CmdUnifiedCharSelect = 0xC1; // 서버통합시 캐릭터 / 창고 선택
const PktBase::CMDType CmdChatBan = 0xC2; // 채팅 금지
const PktBase::CMDType CmdGiveItemToTempInven = 0xC3; // 임시 인벤으로 아이템 지급
const PktBase::CMDType CmdCharNameChange = 0xC4; // 캐릭터 이릅 바꾸기
const PktBase::CMDType CmdFertilityInfo = 0xC5; // 지력 정보 전송 (DBAgentServer -> GameServer)
const PktBase::CMDType CmdMiningCampMineralInfo = 0xC6; // 채굴기 누적 광물 정보 전송 (GameServer -> Client)
const PktBase::CMDType CmdProcessMining = 0xC7; // 채굴기 프로세스 실행
const PktBase::CMDType CmdWorldWeaponInfo = 0xC8; // 월드 웨폰 정보 전송 (DBAgentServer -> GameServer)
const PktBase::CMDType CmdCampShopInfo = 0xC9; // 길드 요새 상점 정보 전송 (GameServer -> DBAgentServer)
const PktBase::CMDType CmdCharInstallRuneSocket = 0xCA; // 룬 아이템 설치/제거정보.
const PktBase::CMDType CmdTakeMaterial = 0xCB; // 길드 요새 공성 자재 넣기/빼기
const PktBase::CMDType CmdCastleTaxMove = 0xCC; // 성의 임시 세금이 누적 세금으로 옮겨지는 정보 전송
const PktBase::CMDType CmdCastleSiegeCount = 0xCD; // 공성 시간후 남은 공성 횟수 정보 전송
const PktBase::CMDType CmdCompressedPacket = 0xCE; // 패킷 여러개를 압축해서 보낼 때 사용
const PktBase::CMDType CmdTakeCastleJewel = 0xCF; // 성 상징물 보석 아이템 넣기/빼기
const PktBase::CMDType CmdCastleMineralInfo = 0xD0; // 성의 임시 광물 세금 업데이트, 성의 누적 광물 세금 정보 전송
// (GS -> DBAS), (GS -> Client)
const PktBase::CMDType CmdWarOnOff = 0xD1; // 길드, 국가 전쟁 참가 패킷 (Client <-> GS).
const PktBase::CMDType CmdRealmPoint = 0xD2; // 국가 전쟁 공헌 훈장 포인트 전송 (DBAgentServer -> GameServer -> Client).
const PktBase::CMDType CmdStatueCmd = 0xD3; // 국가 전쟁 석상 커맨드 패킷
const PktBase::CMDType CmdSaveEnemy = 0xD4; // 듀얼시 연사 방지 패킷 (DBAgentServer <-> GameServer).
const PktBase::CMDType CmdGuildHostilityList = 0xD5; // 적대 관계 현황 리스트 요청 패킷
const PktBase::CMDType CmdGuildRelationInfo = 0xD6; // 길드 가입시 자기 길드의 관계 리스트 요청 패킷
const PktBase::CMDType CmdGuildPosition = 0xD7; // 운영툴에서 길드 포지션 설정.
const PktBase::CMDType CmdAdminCommandLog = 0xD8; // 운영자 명령어 로그 패킷.
const PktBase::CMDType CmdChatBanInfo = 0xD9; // 채팅금지 정보 (GameServer <-> ChatServer).
const PktBase::CMDType CmdKeyInfo = 0xDA; // 조이스틱 키 정보.
const PktBase::CMDType CmdFinalPacketNum = 0xDB; // 마지막 패킷 번호
#endif

View File

@@ -0,0 +1,93 @@
#ifndef _RYL_SERVERLIB_PACKET_DISPATHCH_TABLE_H_
#define _RYL_SERVERLIB_PACKET_DISPATHCH_TABLE_H_
#include <vector>
#include <utility>
template<typename FunctionType>
class CPacketDispatchTable
{
public:
typedef std::pair<unsigned long, FunctionType> DispatchType;
typedef std::vector<DispatchType> DispatchMap;
FunctionType GetDispatch(unsigned long dwCmd);
protected:
struct PredFirstPairOnly
{
template<typename Ty1, typename Ty2>
bool operator () (const std::pair<Ty1, Ty2>& lhs, const std::pair<Ty1, Ty2>& rhs)
{
return lhs.first < rhs.first;
}
};
CPacketDispatchTable(size_t nReservedSize) { m_DispatchMap.reserve(nReservedSize); }
bool AddDispatch(unsigned long dwCmd, FunctionType fnDispatch);
void RemoveDispatch(unsigned long dwCmd);
private:
DispatchMap m_DispatchMap;
PredFirstPairOnly m_PredFirstPairOnly;
};
template<typename FunctionType>
FunctionType CPacketDispatchTable<FunctionType>::GetDispatch(unsigned long dwCmd)
{
DispatchType findVal(dwCmd, FunctionType());
DispatchMap::iterator end = m_DispatchMap.end();
DispatchMap::iterator pos = std::lower_bound(m_DispatchMap.begin(),
end, findVal, m_PredFirstPairOnly);
return (pos != end && !m_PredFirstPairOnly(findVal, *pos)) ? pos->second : findVal.second;
}
template<typename FunctionType>
bool CPacketDispatchTable<FunctionType>::AddDispatch(unsigned long dwCmd, FunctionType lpDispatch)
{
DispatchType addVal(dwCmd, lpDispatch);
DispatchMap::iterator end = m_DispatchMap.end();
DispatchMap::iterator pos = std::lower_bound(m_DispatchMap.begin(),
end, addVal, m_PredFirstPairOnly);
if(pos == end || m_PredFirstPairOnly(addVal, *pos))
{
// 똑같은 커맨드로 삽입 시도. 그냥 넣는다.
m_DispatchMap.insert(pos, addVal);
return true;
}
return false;
}
template<typename FunctionType>
void CPacketDispatchTable<FunctionType>::RemoveDispatch(unsigned long dwCmd)
{
DispatchType removeVal(dwCmd, FunctionType());
DispatchMap::iterator end = m_DispatchMap.end();
DispatchMap::iterator pos = std::lower_bound(m_DispatchMap.begin(),
end, removeVal, m_PredFirstPairOnly);
if(pos != end && !m_PredFirstPairOnly(removeVal, *pos))
{
// 맵에서 제거한다.
m_DispatchMap.erase(pos);
}
}
#endif

View File

@@ -0,0 +1,274 @@
#include "stdafx.h"
#include "PacketStatistics.h"
#include <algorithm>
#include <functional>
#include <Utility/Debug/DebugUtils.h>
void MakeBytesToString(char* szString, unsigned long dwStringLen, double fBytes)
{
_snprintf(szString, dwStringLen - 1, "%16.4fMb/%16.4fKb/%16.4fBytes",
fBytes / 1024 / 1024, fBytes / 1024, fBytes);
szString[dwStringLen - 1] = 0;
}
void LogPacketStatData(FILE* logFile, const char* szTotalSummeryHeader, time_t tDiffTime,
CPacketStatistics::PacketData* lpPos, CPacketStatistics::PacketData* lpEnd)
{
const int MAX_BUFFER = 128;
char szTotalBytes[MAX_BUFFER];
CPacketStatistics::PacketData totalData;
for(unsigned char cCmd = 0; lpPos != lpEnd; ++lpPos, ++cCmd)
{
if (0.0f != lpPos->m_Count)
{
MakeBytesToString(szTotalBytes, MAX_BUFFER, lpPos->m_Bytes);
fprintf(logFile, "\t %3d(0x%02X) : %16.4f : (%s) : %16.4fBytes/Sec\n",
cCmd, cCmd, lpPos->m_Count, szTotalBytes,
lpPos->m_Bytes / tDiffTime);
totalData.m_Bytes += lpPos->m_Bytes;
totalData.m_Count += lpPos->m_Count;
}
}
MakeBytesToString(szTotalBytes, MAX_BUFFER, totalData.m_Bytes);
fprintf(logFile,
"\n %s"
"\n Total Data : %s/%16.4fBytes/Sec"
"\n Total Count : %16.4f/%16.4f(Count/Sec)\n\n",
szTotalSummeryHeader, szTotalBytes, totalData.m_Bytes / tDiffTime,
totalData.m_Count, totalData.m_Count / tDiffTime);
}
CPacketStatistics::PacketData::PacketData()
: m_Bytes(0.0f)
, m_Count(0.0f)
{
}
void CPacketStatistics::PacketData::Clear()
{
m_Bytes = m_Count = 0.0f;
}
CPacketStatistics::CompressData::CompressData()
: m_CompressCount(0.0f)
, m_FailedCount(0.0f)
, m_TotalBytes(0.0f)
, m_TotalCompressed(0.0f)
{
}
void CPacketStatistics::CompressData::Clear()
{
m_CompressCount = m_FailedCount =
m_TotalBytes = m_TotalCompressed = 0.0f;
}
CPacketStatistics::CPacketStatistics()
: m_StartTime(time(0)), m_fnPrefix(0), m_fnPostfix(0)
{
}
CPacketStatistics::~CPacketStatistics()
{
Log();
}
CPacketStatistics& CPacketStatistics::GetInstance()
{
static CPacketStatistics packetStatistics;
return packetStatistics;
}
void CPacketStatistics::Recv(unsigned char cCmd, unsigned long dwPacketSize)
{
PacketData& packetData = m_RecvData[cCmd];
packetData.m_Bytes += dwPacketSize;
++packetData.m_Count;
}
void CPacketStatistics::Send(unsigned char cCmd, unsigned long dwPacketSize)
{
PacketData& packetData = m_SendData[cCmd];
packetData.m_Bytes += dwPacketSize;
++packetData.m_Count;
}
// 압축관련 통계 작성
void CPacketStatistics::CheckCompression(unsigned char cCmd,
unsigned long dwSrcSize, unsigned long dwDstSize)
{
CompressData& compressData = m_CompressionData[cCmd];
compressData.m_TotalBytes += dwSrcSize;
compressData.m_TotalCompressed += dwDstSize;
++compressData.m_CompressCount;
if (dwSrcSize < dwDstSize) { ++compressData.m_FailedCount; }
}
void CPacketStatistics::Clear()
{
std::for_each(m_RecvData, m_RecvData + UCHAR_MAX, std::mem_fun_ref(&PacketData::Clear));
std::for_each(m_SendData, m_SendData + UCHAR_MAX, std::mem_fun_ref(&PacketData::Clear));
std::for_each(m_CompressionData, m_CompressionData + UCHAR_MAX, std::mem_fun_ref(&CompressData::Clear));
m_StartTime = time(0);
}
void CPacketStatistics::SetUserMessageFunc(FnPrintUserMessage fnPreFix, FnPrintUserMessage fnPostFix)
{
m_fnPrefix = fnPreFix;
m_fnPostfix = fnPostFix;
}
bool CPacketStatistics::Log()
{
char strLogPath[MAX_PATH];
char strLogFileName[MAX_PATH];
DbgUtils::SetProgramName(strLogPath, MAX_PATH, 0);
// create the directory if it doesn't exist
if (INVALID_FILE_ATTRIBUTES == GetFileAttributes(strLogPath) &&
!CreateDirectory(strLogPath, 0))
{
return false;
}
unsigned long dwSpinCount = 0;
unsigned long dwMaxFileSize = 50 * 1024 * 1024;
while (true)
{
_sntprintf(strLogFileName, MAX_PATH, "%s/Statistics-%s-%05d.log",
strLogPath, strLogPath, dwSpinCount);
HANDLE hLogFile = CreateFile(strLogFileName, GENERIC_WRITE,
FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0 );
if(INVALID_HANDLE_VALUE == hLogFile)
{
break;
}
else
{
unsigned long dwHighValue = 0;
unsigned long dwFileSize = GetFileSize(hLogFile, &dwHighValue);
CloseHandle(hLogFile);
if(dwHighValue == 0 && dwFileSize < dwMaxFileSize)
{
break;
}
}
++dwSpinCount;
}
FILE* logFile = fopen(strLogFileName, "at");
if(0 != logFile)
{
// Prefix
if(0 != m_fnPrefix)
{
m_fnPrefix(logFile);
}
// 실제 로그
time_t tCurrent = time(0);
time_t tDiffTime = tCurrent - m_StartTime;
time_t tDiffHour = tDiffTime / 3600;
time_t tDiffMinute = (tDiffTime % 3600) / 60;
time_t tDiffSecond = (tDiffTime % 3600) % 60;
struct tm tmServerStart = *localtime(&m_StartTime);
struct tm tmCurrent = *localtime(&tCurrent);
fprintf(logFile, "\t-- Server Packet Statistics -- \n"
"\tLog Start Time : %04dyear %02dmon %02dday %02dhour %02dmin %02dsec\n"
"\tCurrent Log Time : %04dyear %02dmon %02dday %02dhour %02dmin %02dsec\n"
"\tLog Duration : %02dhour %02dmin %02dsec\n\n",
tmServerStart.tm_year + 1900, tmServerStart.tm_mon + 1, tmServerStart.tm_mday,
tmServerStart.tm_hour, tmServerStart.tm_min, tmServerStart.tm_sec,
tmCurrent.tm_year + 1900, tmCurrent.tm_mon + 1, tmCurrent.tm_mday,
tmCurrent.tm_hour, tmCurrent.tm_min, tmCurrent.tm_sec,
tDiffHour, tDiffMinute, tDiffSecond);
const int MAX_BUFFER = 128;
char szTotalBytes[MAX_BUFFER];
char szCompressedBytes[MAX_BUFFER];
// 받은 데이터 로그
LogPacketStatData(logFile, "Recv Packet", tDiffTime, m_RecvData, m_RecvData + UCHAR_MAX);
// 보낸 데이터 로그
LogPacketStatData(logFile, "Send Packet", tDiffTime, m_SendData, m_SendData + UCHAR_MAX);
// 압축 데이터 로그
CompressData* lpCompressPos = m_CompressionData;
CompressData* lpCompressEnd = m_CompressionData + UCHAR_MAX;
CompressData totalCount;
for(unsigned char cCmd = 0; lpCompressPos != lpCompressEnd; ++lpCompressPos, ++cCmd)
{
if (0.0f != lpCompressPos->m_CompressCount)
{
MakeBytesToString(szTotalBytes, MAX_BUFFER, lpCompressPos->m_TotalBytes);
MakeBytesToString(szCompressedBytes, MAX_BUFFER, lpCompressPos->m_TotalCompressed);
fprintf (logFile, "\t %3d(0x%02X) : %16.4f(Failed %16.4f) : Total(%16s) : Compressed(%16s)\n",
cCmd, cCmd, lpCompressPos->m_CompressCount, lpCompressPos->m_FailedCount,
szTotalBytes, szCompressedBytes);
totalCount.m_CompressCount += lpCompressPos->m_CompressCount;
totalCount.m_FailedCount += lpCompressPos->m_FailedCount;
totalCount.m_TotalBytes += lpCompressPos->m_TotalBytes;
totalCount.m_TotalCompressed += lpCompressPos->m_TotalCompressed;
}
}
MakeBytesToString(szTotalBytes, MAX_BUFFER, totalCount.m_TotalBytes);
MakeBytesToString(szCompressedBytes, MAX_BUFFER, totalCount.m_TotalCompressed);
fprintf(logFile,
"\n Check compression status - not actually sent"
"\n Total Data : %s"
"\n Total Data Compressed : %s"
"\n Total Count : %16.4f/Failed(%16.4f)\n\n\n",
szTotalBytes, szCompressedBytes, totalCount.m_CompressCount, totalCount.m_FailedCount);
// Postfix
if(0 != m_fnPostfix)
{
m_fnPostfix(logFile);
}
fclose(logFile);
}
return true;
}

View File

@@ -0,0 +1,64 @@
#ifndef _GAMA_PACKET_STATISTICS_H_
#define _GAMA_PACKET_STATISTICS_H_
#include <climits>
#include <ctime>
class CPacketStatistics
{
public:
struct PacketData
{
double m_Bytes;
double m_Count;
PacketData();
void Clear();
};
struct CompressData
{
double m_CompressCount;
double m_FailedCount;
double m_TotalBytes;
double m_TotalCompressed;
CompressData();
void Clear();
};
typedef void (*FnPrintUserMessage) (FILE* fDescriptor);
static CPacketStatistics& GetInstance();
void Recv(unsigned char cCmd, unsigned long dwPacketSize); // 받은 패킷 통계 (압축된 패킷)
void Send(unsigned char cCmd, unsigned long dwPacketSize); // 전송한 패킷 통계 (압축된 패킷)
// 압축관련 통계 작성
void CheckCompression(unsigned char cCmd, unsigned long dwSrcSize, unsigned long dwDstSize);
void Clear();
bool Log();
void SetUserMessageFunc(FnPrintUserMessage fnPreFix = 0, FnPrintUserMessage fnPostFix = 0);
private:
CPacketStatistics();
~CPacketStatistics();
time_t m_StartTime;
FnPrintUserMessage m_fnPrefix;
FnPrintUserMessage m_fnPostfix;
PacketData m_RecvData[UCHAR_MAX];
PacketData m_SendData[UCHAR_MAX];
CompressData m_CompressionData[UCHAR_MAX];
};
#endif

View File

@@ -0,0 +1,237 @@
#ifndef _AUTHSERVER_TO_DBAGENT_SERVER_PACKET_H_
#define _AUTHSERVER_TO_DBAGENT_SERVER_PACKET_H_
#include <winsock2.h>
#include <windows.h>
#include <DB/DBDefine.h>
#include "DataPacket.h"
#pragma pack(1)
// ---------------------------------------------------------
// 유저 로그인 요청 AuthServer -> DBAgentServer
typedef struct PktULD* LPPktULD;
struct PktULD : public PktDD
{
unsigned long m_dwSessionID;
unsigned long m_dwUserID;
IN_ADDR m_Address;
unsigned char m_cLoginType;
};
// 유저 로그인 응답 DBAgentServer -> AuthServer
typedef struct PktULDAck* LPPktULDAck;
struct PktULDAck : public PktDD
{
enum Const
{
MAX_CHAR_VIEW = 5
};
unsigned long m_dwUserID;
sGuildData m_GuildData[MAX_CHAR_VIEW];
CHAR_VIEW m_CharView[MAX_CHAR_VIEW];
STORE_INFO m_sStoreInfo;
// WORK_LIST 2.1 계정 국적 추가
unsigned char m_cAccountNation; // 계정 국적
int m_nPlayTime; // BillingType이 정액인 경우는 남은 날짜. 정량인 경우는 남은 시간(분)
unsigned short m_usAdminLevel;
unsigned char m_cBillingType; // D : 정액 T : 정량 N : 무료
unsigned char m_cBillingUser; // 0 : 개인 1 : 피시방
unsigned char m_cLoginType;
};
// 유저 로그아웃 AuthServer -> DBAgentServer
typedef struct PktULoD *LPPktULoD;
struct PktULoD : public PktDD
{
unsigned long m_dwSessionID;
unsigned long m_dwUserID;
};
// 유저 이동
typedef struct PktUMvD *LPPktUMvD;
struct PktUMvD : public PktDD
{
unsigned long m_dwSessionID;
unsigned long m_dwUserID;
};
// 세션 시작 DBAgentServer -> AuthServer
typedef struct PktSSD *LPPktSSD;
struct PktSSD : public PktDD
{
enum
{
// edith 2008.03.17 ID,PASS 길이조정
MaxName = 24,
MaxPass = 36,
};
unsigned long m_dwSessionID;
unsigned long m_dwUserID;
char m_AccountName[MaxName];
// edith 2008.01.15 패스워드 추가작업
char m_Password[MaxPass];
unsigned char m_cAgentServerType;
unsigned char m_cFirstLogin;
IN_ADDR m_Address;
};
/*
* cAgentServerType 멤버
CServerSetup::AgentServerType 의 값을 참고할 것.
Part1 = 20,
Part1Unified = 21,
Part2 = 22,
Part2Unified = 23,
Part2Selectable = 24,
* cFirstLogin 멤버
에러값이 0 이상이면 무시한다.
cAgentServerType값이 Part2Unified/Part2Selectable일 경우만 유의미한 값이다.
Part2Unified
창고 가져온 적 없다 : 0
Part1 통합에서 창고 가져온 적 있다 : 1
Part2 통합에서 창고 가져온 적 있다 : 2
Part2Selectable
로그인한 적이 없다 : 0
로그인한 적이 있다 : 2
*/
// ---------------------------------------------------------
// ---------------------------------------------------------
// 캐릭터 생성 요청 AuthServer -> DBAgentServer
typedef struct PktCCD* LPPktCCD;
struct PktCCD : public PktDD
{
unsigned long m_dwUserID;
unsigned long m_dwSlot;
unsigned long m_dwGold;
POS m_Pos;
CHAR_CREATE m_CharCreate;
unsigned short m_wSkill;
};
// 캐릭터 생성 응답 DBAgentServer -> AuthServer
typedef struct PktCCDAck* LPPktCCDAck;
struct PktCCDAck : public PktDD
{
unsigned long m_dwCharID;
unsigned long m_dwSlot;
CHAR_VIEW m_CharView;
};
// ---------------------------------------------------------
// ---------------------------------------------------------
// 캐릭터 선택 관련 (데이터)
typedef struct PktCSD* LPPktCSD;
struct PktCSD : public PktDD
{
unsigned long m_dwUserID;
unsigned long m_dwCharID;
};
typedef struct PktCSDAck* LPPktCSDAck;
struct PktCSDAck : public PktDD
{
enum { MAX_CHANNEL_NUM = 5 };
unsigned char m_cZone;
unsigned short m_wChannelNum[MAX_CHANNEL_NUM];
};
// ---------------------------------------------------------
// ---------------------------------------------------------
// 캐릭터 삭제 관련 (데이터)
typedef struct PktCDD* LPPktCDD;
struct PktCDD : public PktDD
{
unsigned long m_dwUserID;
unsigned long m_dwSlotNum;
unsigned long m_dwCharID;
};
// ---------------------------------------------------------
// WORK_LIST 2.1 계정 국적 추가
// ---------------------------------------------------------
// 계정 국적 변경 관련 (데이터)
typedef struct PktSAND* LPPktSAND;
struct PktSAND : public PktDD
{
enum eType { TYPE_SET = 1, TYPE_CHANGE = 2 };
unsigned long m_dwUserID;
unsigned char m_cType;
unsigned char m_cAccountNation;
};
// 계정 국적 변경에 따른 결과 패킷
typedef struct PktANCAck* LPPktANCAck;
struct PktANCAck : public PktDD
{
enum
{
MAX_CHAR_VIEW = 5
};
unsigned long m_dwUserID;
unsigned long m_dwGID[ MAX_CHAR_VIEW ];
unsigned long m_dwFame[ MAX_CHAR_VIEW ];
};
// ---------------------------------------------------------
// ---------------------------------------------------------
// 캐릭터 생성 아이템 관련 (데이터)
typedef struct PktCCID* LPPktCCID;
struct PktCCID : public PktDD
{
unsigned __int64 m_dwItemSerial;
unsigned long m_dwCharID;
unsigned long m_dwSize;
};
// ---------------------------------------------------------
// ---------------------------------------------------------
// 캐릭터 로그인 관련 (데이터)
typedef struct PktCLiD* LPPktCLiD;
struct PktCLiD : public PktDD
{
unsigned long m_dwUserID;
unsigned long m_dwCharID;
unsigned long m_dwSerial;
};
// ---------------------------------------------------------
#pragma pack()
#endif

View File

@@ -0,0 +1,157 @@
#ifndef _BATTLEGROUND_SERVER_PACKET_H_
#define _BATTLEGROUND_SERVER_PACKET_H_
#include <Network/Packet/PacketBase.h>
#include <Creature/Character/CharacterClass.h>
#pragma pack(1)
// 방 리스트 (가변 길이) + 방 정보
typedef struct PktBGServerMapList* LPPktBGServerMapList;
struct PktBGServerMapList : public PktBase
{
enum Const
{
MAX_MAP_NUM = 10
};
bool m_bAll; // true 이면 모든 맵 리스트, false 이면 자신의 맵 정보
unsigned char m_cMapInfoNodeNum; // 노드 수
};
// 방 정보
struct BGServerMapInfoNode
{
enum MapType
{
FRAG = 0, // 스코어 경쟁 게임 방
STATUE = 1, // 석상 점령 게임 방
MAX_MAP_TYPE
};
// 배틀 그라운드 하나의 가상 맵이 가져야 하는 변수
bool m_bPlaying; // 게임 중인지 여부
unsigned char m_cMapType; // 게임 방식
unsigned char m_cMaxCharNumOfNation; // 한 진영 최대 인원
unsigned char m_cRemainMin; // 남은 시간 (경기시간 혹은 쉬는시간) (분)
unsigned short m_wTargetScore; // 목표 점수
unsigned char m_cCurrentCharNum[CClass::MAX_RACE]; // 현재 인원
unsigned short m_wScore[CClass::MAX_RACE]; // 점수
};
// 방 결과 리스트 (가변 길이) + 방 결과 정보
typedef struct PktBGServerResultList* LPPktBGServerResultList;
struct PktBGServerResultList : public PktBase
{
enum Const
{
MAX_MAP_NUM = 10
};
bool m_bAll; // true 이면 모든 방 리스트, false 이면 자신의 방 정보
unsigned char m_cResultInfoNodeNum; // 노드 수
};
// 방 결과 정보
struct BGServerResultInfoNode
{
unsigned char m_cWinRace; // 승자 (CClass::MAX_RACE 이면 무승부)
unsigned char m_cPlayMin; // 실제 플레이한 시간
unsigned char m_cKill; // 상대방을 죽인 수
unsigned char m_cKilled; // 죽은 수
unsigned short m_wAward; // 보상으로 받은 마일리지
unsigned short m_wScore[CClass::MAX_RACE]; // 점수
};
// BATTLEGROUND_SERVER 존 이동
typedef struct PktBGServerMoveZone* LPPktBGServerMoveZone;
struct PktBGServerMoveZone : public PktBase
{
enum MoveType
{
TYPE_PLAYER = 0, // 게임 참전자
TYPE_SPECTATOR = 1, // 게임 관전자
MAX_TYPE_NUM
};
enum Error
{
FAIL_FULL_MAP = 2, // 방 정원 초과
FAIL_FIX_RATE = 3 // 각 팀의 균형을 맞추기 위한 비율 제한
};
unsigned short m_wMapNumber; // 해당 방 번호 (0은 대기실)
unsigned char m_cMoveType; // 방에 들어가는 타입
unsigned char m_cZone; // 해당 방의 존 번호 (Ack)
};
// 정섭 캐릭터 정보
typedef struct PktBGServerCharSlot* LPPktBGServerCharSlot;
struct PktBGServerCharSlot : public PktBase
{
unsigned long m_dwCID; // 캐릭터 아이디 (Client <-> Game)
unsigned long m_dwUID; // 유저 아이디 (Game <-> DBAgent)
unsigned char m_cGroup; // 서버 그룹
};
// 정섭 캐릭터 정보 Ack
typedef struct PktBGServerCharSlotAck* LPPktBGServerCharSlotAck;
struct PktBGServerCharSlotAck : public PktBase
{
enum PktCharSlotAckErr
{
FAIL_NOT_USER = 2, // DB에서 유저 정보 얻기 실패
FAIL_NOT_CHAR = 3 // DB에서 캐릭터 정보 얻기 실패
};
unsigned long m_dwCID; // 캐릭터 아이디
unsigned char m_cGroup; // 서버 그룹
unsigned long m_dwSlotCID[USER_INFO::MAX_CHAR_NUM]; // 정섭 캐릭터 ID
char m_szSlotName[USER_INFO::MAX_CHAR_NUM][CHAR_INFOST::MAX_NAME_LEN]; // 정섭 캐릭터 이름
};
// 환전소 이용
typedef struct PktBGServerMileageChange* LPPktBGServerMileageChange;
struct PktBGServerMileageChange : public PktBase
{
enum PktBGSMCCmd
{
MC_REQUEST = 0, // 정보 요청 (선택한 정섭의...)
MC_INFO = 1, // 정보 Ack
MC_CHANGE = 2, // 교환 요청 (BG의 공헌메달 -> 정섭의 돈)
MC_RESULT = 3 // 교환 Ack
};
enum PktErr
{
SERVER_ERROR = 1,
NOT_USED_STORE = 2, // 창고 사용한적이 없는 경우 - MC_RESULT (메시지 처리 필요)
NOT_ENOUGH_MEDAL = 3, // 공헌 메달 부족 - MC_RESULT (메시지 처리 필요)
MONEY_OVERFLOW = 4, // 돈 오버플로우 발생(입금 불가) - MC_RESULT ( 메시지 처리 필요)
DATA_REQUESTING = 5, // 서버 데이터 요청중임 - MC_RESULT (메시지 처리 필요 없음)
NONE_CHARACTER = 6 // 캐릭터가 없는 경우 - MC_INFO (메시지 처리 필요)
};
unsigned long m_dwCID; // 캐릭터 ID
unsigned char m_cGroup; // 서버 그룹
unsigned char m_cCmd; // 명령
unsigned long m_dwGold; // 돈
unsigned long m_dwMileage; // 공헌 메달
};
#pragma pack()
#endif

View File

@@ -0,0 +1,326 @@
#ifndef _CLIENT_TO_AUTH_SERVER_PACKET_H_
#define _CLIENT_TO_AUTH_SERVER_PACKET_H_
#include <DB/DBDefine.h>
#include <Network/Packet/PacketBase.h>
#pragma pack(1)
////////////////////////////////////////////////////////////////////////////////////////////////////
//
// 사용자 인증 요청 (Client to AuthServer)
// - 계정 이름
// - 계정 패스워드
// - 클라이언트 버젼
//
// : 사용자 계정으로 로그인하여 유저 아이디와 로그인 가능한 서버 리스트드을 얻는다.
//
////////////////////////////////////////////////////////////////////////////////////////////////////
typedef struct PktAU* LPPktAU;
struct PktAU : public PktBase
{
enum
{
// edith 2008.03.17 ID,PASS 길이조정
ID_LEN = 24,
PASS_LEN = 36
};
char m_UserAccount[ID_LEN];
char m_UserPassword[PASS_LEN];
unsigned long m_dwSessionID;
unsigned long m_dwClientVer;
unsigned long m_dwCheckSum;
unsigned short m_usFlag;
};
////////////////////////////////////////////////////////////////////////////////////////////////////
//
// 일본쪽 사용자 인증 요청 (Client to AuthServer)
//
// : 사용자 계정으로 로그인하여 유저 아이디와 로그인 가능한 서버 리스트드을 얻는다.
//
////////////////////////////////////////////////////////////////////////////////////////////////////
typedef struct PktJPAU* LPPktJPAU;
struct PktJPAU : public PktBase
{
enum { NAME_LEN = 16 };
char m_szUserAccount[NAME_LEN];
unsigned long m_dwUserID;
unsigned long m_dwSessionID;
unsigned long m_dwClientVer;
unsigned long m_dwCheckSum;
unsigned short m_usFlag;
};
////////////////////////////////////////////////////////////////////////////////////////////////////
//
// 사용자 인증 응답 (AuthServer to Client)
// - 유저 아이디
//
// : 사용자 계정으로 로그인하여 유저 아이디를 얻는다.
//
////////////////////////////////////////////////////////////////////////////////////////////////////
typedef struct PktAUAck* LPPktAUAck;
struct PktAUAck : public PktBase
{
unsigned long m_dwUserID;
unsigned char m_cAgentServerType;
unsigned char m_cFirstLogin;
};
////////////////////////////////////////////////////////////////////////////////////////////////////
//
// 유저 로그인 (Client to AuthServer)
// - 유저 아이디
// - 체크섬
// - 명령
//
// : 유저 로그인 후에 캐릭터 셀렉트 관련 정보를 얻어온다.
//
////////////////////////////////////////////////////////////////////////////////////////////////////
typedef struct PktULi* LPPktULi;
struct PktULi : public PktBase
{
enum LoginType
{
USERLOGIN_FIRST = 0, // 최초 로긴
USERLOGIN_CHAR_SELECT = 1 // 캐릭터 선택화면으로 이동
};
unsigned long m_dwUserID;
unsigned long m_dwCheckSum;
unsigned char m_cLoginType;
};
////////////////////////////////////////////////////////////////////////////////////////////////////
//
// 유저 로그인 Ack (AuthServer to Client)
// - 유저 아이디
// - 캐릭터 정보
//
// (1 = 서버 에러, 2 = 데이터 얻기 실패)
//
////////////////////////////////////////////////////////////////////////////////////////////////////
typedef struct PktULiAck* LPPktULiAck;
struct PktULiAck : public PktBase
{
enum Const
{
MAX_CHAR_VIEW = 5
};
enum PktULiAckErr
{
FAIL_GET_DATA = 2
};
unsigned long m_dwSessionID;
unsigned long m_dwUserID;
CHAR_VIEW m_CharView[MAX_CHAR_VIEW];
sGuildData m_GuildData[MAX_CHAR_VIEW];
unsigned long m_dwTabFlag;
// WORK_LIST 2.1 계정 국적 추가
unsigned char m_cAccountNation; // 계정 국적
time_t m_dwCurrentTime; // 현재 시간
int m_nPlayTime; // BillingType이 정액이나 무료인 경우는 남은 날짜. 정량인 경우는 남은 시간(분)
unsigned short m_usAdminLevel; // 운영자 레벨.
unsigned char m_cBillingType; // D : 정액 T : 정량 N : 무료
unsigned char m_cBillingUser; // 0 : 개인 1 : 피시방
unsigned char m_cLoginType;
};
////////////////////////////////////////////////////////////////////////////////////////////////////
//
// 캐릭터 선택 ( Char Select )
// - 유저 아이디
// - 캐릭터 아이디
//
// : 캐릭터 선택 후 해당 캐릭터의 서버의 예약 포인터와 주소를 넘겨 받는다.
//
////////////////////////////////////////////////////////////////////////////////////////////////////
typedef struct PktCS* LPPktCS;
struct PktCS : public PktBase
{
unsigned long m_dwUserID;
unsigned long m_dwCharID;
};
// 캐릭터 선택 Ack
typedef struct PktCSAck* LPPktCSAck;
struct PktCSAck : public PktBase
{
enum { MAX_CHANNEL_NUM = 5 };
unsigned char m_cZone; // 존
unsigned short m_wChannelNum[MAX_CHANNEL_NUM]; // 채널
};
////////////////////////////////////////////////////////////////////////////////////////////////////
//
// 캐릭터 생성 ( Char Create )
// - 유저 아이디
// - 슬롯 번호
// - 캐릭터 생성 데이터
// - 복장 (셔츠, 부츠, 무기)
//
////////////////////////////////////////////////////////////////////////////////////////////////////
typedef struct PktCC* LPPktCC;
struct PktCC : public PktBase
{
unsigned long m_dwUserID;
unsigned long m_dwSlotNum;
CHAR_CREATE m_CreateChar;
};
////////////////////////////////////////////////////////////////////////////////////////////////////
//
// 캐릭터 생성 Ack
// - 캐릭터 아이디
// - 슬롯 번호
// - 캐릭터 데이터
//
// (1 = 서버 에러, 2 = 데이터 생성 실패, 3 = 존재하는 캐릭터 이름, 4 = 비어 있지 않은 슬롯,
// 5 = 적당하지 않은 이름, 6 = 잘못된 생성 데이터)
//
////////////////////////////////////////////////////////////////////////////////////////////////////
typedef struct PktCCAck* LPPktCCAck;
struct PktCCAck : public PktBase
{
unsigned long m_dwCharID;
unsigned long m_dwSlotNum;
CHAR_VIEW m_CharView;
enum
{
SERVER_ERROR = 1,
FAIL_INSERT_DATA = 2,
EXIST_CHAR_NAME = 3,
EXIST_SLOT = 4,
WRONG_CHAR_NAME = 5,
WRONG_CHAR_DATA = 6,
SLANG_FILTERED = 7,
NULL_SESSION = 8,
VIEW_RELOAD_FAILED = 9,
SUPRESSED_CHAR_CREATE = 10
};
};
////////////////////////////////////////////////////////////////////////////////////////////////////
//
// 캐릭터 삭제 ( Char Delete )
// - 유저 아이디
// - 캐릭터 아이디
// - 슬롯 번호
// - 파티 아이디
// - 길드 아이디
//
////////////////////////////////////////////////////////////////////////////////////////////////////
typedef struct PktCD* LPPktCD;
struct PktCD : public PktBase
{
unsigned long m_dwUserID;
unsigned long m_dwCharID;
unsigned long m_dwSlotNum;
unsigned char m_szPassword[STORE_INFO::MAX_PASS_LEN];
};
////////////////////////////////////////////////////////////////////////////////////////////////////
//
// 캐릭터 삭제 Ack
// - 유저 아이디
// - 슬롯 번호
//
// (1 = 서버 에러, 2 = 데이터 삭제 실패)
//
////////////////////////////////////////////////////////////////////////////////////////////////////
typedef struct PktCDAck* LPPktCDAck;
struct PktCDAck : public PktBase
{
unsigned long m_dwUserID;
unsigned long m_dwSlotNum;
enum
{
SERVER_ERROR = 1,
FAIL_DELETE_DATA = 2,
BLOCKED_DELETE_DATA = 6,
FAIL_PASSWORD = 7
};
};
// WORK_LIST 2.1 계정 국적 추가
////////////////////////////////////////////////////////////////////////////////////////////////////
//
// 계정 국적 변경 ( Select Account Nation )
// - 유저 아이디
// - 계정 국적
//
// (1 = 서버 에러, 2 = 설정 실패)
//
////////////////////////////////////////////////////////////////////////////////////////////////////
typedef struct PktSelectAccountNation* LPPktSelectAccountNation;
struct PktSelectAccountNation : public PktBase
{
unsigned long m_dwUserID;
unsigned char m_cType;
unsigned char m_cAccountNation;
enum eType
{
TYPE_SET = 1, // 값 셋팅
TYPE_CHANGE = 2 // 계정 국적 변경
};
enum { SERVER_ERROR = 1, FAIL_SET_NATION = 2 };
};
// WORK_LIST 2.3 계정 국적 변경 기능 구현
////////////////////////////////////////////////////////////////////////////////////////////////////
//
// 계정 국적 변경으로 인한 캐릭터들 결과 정보
// - 유저 아이디
// - CID, GID, Fame
//
// (1 = 서버 에러 )
//
////////////////////////////////////////////////////////////////////////////////////////////////////
typedef struct PktNationChangeResult* LPPktNationChangeResult;
struct PktNationChangeResult : public PktBase
{
enum
{
MAX_CHAR_VIEW = 5
};
unsigned long m_dwUserID;
unsigned long m_dwGID[ MAX_CHAR_VIEW ];
unsigned long m_dwFame[ MAX_CHAR_VIEW ];
};
#pragma pack()
#endif

View File

@@ -0,0 +1,85 @@
#ifndef _CLIENT_TO_LOGIN_SERVER_PACKET_H_
#define _CLIENT_TO_LOGIN_SERVER_PACKET_H_
#include "ServerInfo.h"
#include <Network/Packet/PacketBase.h>
#pragma pack(1)
// -----------------------------------------------------------------------------
// 로그인 클라이언트 패킷.
// -----------------------------------------------------------------------------
// 서버 리스트 요청 패킷 : Launcher to LoginServer
typedef struct PktSvL* LPPktSvL;
struct PktSvL : public PktBase
{
unsigned long m_dwClientVer;
};
// 서버 리스트 응답 패킷 : LoginServer to Launcher
typedef struct PktSvLAck* LPPktSvLAck;
struct PktSvLAck : public PktBase
{
enum { PATCH_ADDRESS_LENGTH = 100 };
unsigned long m_dwClientVer;
char m_PatchAddress[PATCH_ADDRESS_LENGTH];
SERVER_LIST m_ServerList; // 서버 리스트
};
// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
// 서버군 선택 요청 패킷 : Launcher to LoginServer
typedef struct PktSG* LPPktSG;
struct PktSG : public PktBase
{
char m_cGroup;
};
// 서버군 선택 응답 패킷 : LoginServer to Launcher
typedef struct PktSGAck* LPPktSGAck;
struct PktSGAck : public PktBase
{
unsigned long m_dwServerID;
IN_ADDR m_AuthAddress;
};
// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
// 사용자 인증 요청 패킷(OLD) : Launcher to LoginServer
typedef struct PktAUO* LPPktAUO;
struct PktAUO : public PktBase
{
enum
{
// edith 2008.03.17 ID,PASS 길이조정
NAME_LEN = 24,
PASS_LEN = 36
};
char m_UserAccount[NAME_LEN];
char m_UserPassword[PASS_LEN];
unsigned long m_ClientVerInfo;
unsigned short m_cFlag;
};
// 사용자 인증 응답 패킷 : LoginServer to Launcher
typedef struct PktAUOAck* LPPktAUOAck;
struct PktAUOAck : public PktBase
{
unsigned long m_dwUserID; // 유저 아이디
SERVER_LIST m_ServerList; // 서버 리스트
};
// -----------------------------------------------------------------------------
#pragma pack()
#endif

View File

@@ -0,0 +1,63 @@
#ifndef _DATA_PACKET_H_
#define _DATA_PACKET_H_
#include <Network/Packet/PacketBase.h>
#pragma pack(1)
typedef struct PktDD* LPPktDD;
struct PktDD : public PktBase
{
unsigned long m_dwRequestKey;
unsigned short m_wCmd;
enum SubCommands
{
SCmdUserLogin = 0x0001, // 유저 로그인
SCmdUserLogout = 0x0002, // 유저 로그인
SCmdUserMove = 0x0003, // 유저 존 이동
// WORK_LIST 2.1 계정 국적 추가
SCmdSelectNation = 0x0004, // 유저 계정 국적
// WORK_LIST 2.3 계정 국적 변경 기능 구현
SCmdNationChangeResult = 0x0005,
SCmdCharCreate = 0x0021, // 캐릭터 생성
SCmdCharDelete = 0x0022, // 캐릭터 삭제
SCmdCharCreateItem = 0x0023, // 캐릭터 생성 아이템
SCmdCharSelect = 0x0024, // 캐릭터 선택
SCmdCreateParty = 0x0031, // 파티 생성
SCmdDeleteParty = 0x0032, // 파티 삭제
SCmdGetPartyInfo = 0x0033, // 파티 정보 얻기
SCmdInsertPartyMem = 0x0034, // 파티 멤버 추가
SCmdDeletePartyMem = 0x0035, // 파티 멤버 삭제
SCmdLoginPartyMem = 0x0036, // 파티 멤버 로그인
SCmdLogoutPartyMem = 0x0037, // 파티 멤버 로그아웃
SCmdTransferLeader = 0x0038, // 파티 리더 양도
SCmdAutoRoutingOn = 0x0039, // 파티 오토루팅 켜기
SCmdAutoRoutingOff = 0x003A, // 파티 오토루팅 끄기
//SCmdPartyAddress = 0x003B, // 파티원 UDP 주소 업데이트
SCmdDeadPartyMem = 0x003C, // 파티원 사망
SCmdMoveZonePartyMem = 0x003D, // 파티원 존이동 : RefID = 이동할 존 ID
SCmdLevelUpPartyMem = 0x003E, // 파티원 레벨업 : RefID = 레벨업한 레벨
SCmdChangeClassPartyMem = 0x003F, // 파티원 클래스변경 : RefID = 바뀐 클래스
SCmdChangeGuildPartyMem = 0x0040, // 파티원 길드 변경시 : RefID = 바뀐 길드 ID
SCmdStartSession = 0x0050, // 세션 시작
SCmdServerZone = 0x0051, // 서버 존
SCmdCharMoveZone = 0x0052, // 캐릭터 존이동
SCmdServerZoneEnd = 0x0053 // 서버 존 끝
};
inline void InitPtSubCmd(unsigned long dwRequestKey, unsigned short Cmd_In);
};
inline void PktDD::InitPtSubCmd(unsigned long dwRequestKey, unsigned short Cmd_In)
{
m_dwRequestKey = dwRequestKey;
m_wCmd = Cmd_In;
}
#pragma pack()
#endif

View File

@@ -0,0 +1,364 @@
#ifndef _CHAR_FRIEND_PACKET_H_
#define _CHAR_FRIEND_PACKET_H_
// CharFriendPacket.h
#include <Network/Packet/PacketBase.h>
#include <Network/Packet/PacketStruct/DataPacket.h>
#pragma pack(1)
/*
struct PktFriendAddReq : public PktBase CMD : 0x64
struct PktFriendRemoveReq : public PktBase CMD : 0x65
struct PktFriendEtc : public PktBase CMD : 0x66
struct PktFriendAck : public PktBase CMD : 0x67
struct PktFriendDB : public PktBase CMD : 0x68
친구 관련 Operations
<Client->GameServer>
친구 등록 : PktFriendAddReq
거부 등록 : PktFriendAddReq
친구 삭제 : PktFriendRemoveReq
거부 삭제 : PktFriendRemoveReq
그룹 설정 : PktFriendEtc(Ack없음)
<GameServer->Client>
친구 리스트 주기 : PktFriendDB
거부 리스트 추기 : PktFriendDB
친구 등록 Ack : PktFriendAck
친구 삭제 Ack : PktFriendAck
거부 등록 Ack : PktFriendAck
거부 삭제 Ack : PktFriendAck
친구 로그인 : PktFriendAck
친구 로그아웃 : PktFriendAck
친구 등록당함 : PktFriendAddReq
<GameServer->DBAgent>
친구 등록 : PktFriendDB
거부 등록 : PktFriendDB
친구 제거 : PktFriendDB
거부 제거 : PktFriendDB
그룹 세팅 : PktFriendDB
<DBAgent->GameServer>
친구 리스트 주기 : PktFriendDB
거부 리스트 주기 : PktFriendDB
*/
struct DBFriend
{
enum { MAX_NAME = 16 };
unsigned long m_dwCID;
unsigned long m_dwStatusFlag;
char m_szName[MAX_NAME];
};
struct DBFriendInfo
{
unsigned long m_dwGID; // 길드정보.
unsigned short m_wClass; // 클래스정보.
char m_cLevel; // 레벨정보.
};
struct FriendInfo
{
private:
enum StatusMask
{
IS_LOGINED = 0x00000001,
GROUP = 0x000000F0,
};
public:
enum
{
MAX_NAME = 16,
MOVE_ZONE = 0x00000100,
};
unsigned long m_dwCID;
unsigned long m_dwStatusFlag;
char m_szName[MAX_NAME];
unsigned long m_dwGID; // 길드정보.
unsigned short m_wClass; // 클래스정보.
char m_cLevel; // 레벨정보.
unsigned long m_dwServerID; // 서버 정보.
FriendInfo() : m_dwCID(0), m_dwStatusFlag(0), m_dwGID(0), m_wClass(0), m_cLevel(0), m_dwServerID(0) { }
bool IsLogined() { return (0 != (m_dwStatusFlag & IS_LOGINED)); }
void SetLoginStatus(bool bLogined)
{
unsigned long dwMoveZone = 0;
if(!bLogined)
{
if(m_dwStatusFlag&MOVE_ZONE )
dwMoveZone = MOVE_ZONE;
}
m_dwStatusFlag = bLogined ? (m_dwStatusFlag | IS_LOGINED) : (m_dwStatusFlag & (~IS_LOGINED));
m_dwStatusFlag = (m_dwStatusFlag - dwMoveZone);
}
unsigned long GetGroup() { return ((m_dwStatusFlag & GROUP) >> 4); }
bool IsMoveZone() { if(m_dwStatusFlag & MOVE_ZONE) return true; return false; }
void SetMoveZone(unsigned long dwMoveZone) { m_dwStatusFlag = (m_dwStatusFlag | MOVE_ZONE); }
bool SetGroup(unsigned long dwGroup)
{
if(dwGroup <= 0xF) { m_dwStatusFlag = (m_dwStatusFlag & (~GROUP)) | (dwGroup << 4); return true; }
return false;
}
};
struct DBBan
{
enum { MAX_NAME = 16 };
unsigned long m_dwCID;
char m_szName[MAX_NAME];
};
struct DBBanInfo
{
unsigned long m_dwGID; // 길드정보.
unsigned short m_wClass; // 클래스정보.
char m_cLevel; // 레벨정보.
};
struct BanInfo
{
enum { MAX_NAME = 16 };
unsigned long m_dwCID;
char m_szName[MAX_NAME];
unsigned long m_dwGID;
unsigned short m_wClass;
char m_cLevel;
unsigned long m_dwServerID;
BanInfo() : m_dwCID(0) { }
};
// 추가 패킷
struct PktFriendAddReq : public PktBase
{
enum { MAX_NAME = 16 };
enum CMD
{
ADD_FRIEND_REQ = 0, // 친구 등록 (Client->GameServer), m_szName는 등록할 사람의 이름.
BAN_FRIEND_REQ = 1, // 거부 등록 (Client->GameServer), m_szName은 등록할 사람의 이름.
ADDED_INFO = 2 // 친구가 등록됨 (GameServer->Client), m_szName은 나를 등록한 사람의 이름.
};
char m_szName[MAX_NAME]; // 등록한 사람 이름.
unsigned long m_dwCID; // ADDED_INFO일때만 CID를 넣어 준다.
unsigned char m_cCmd;
};
// 제거 패킷
struct PktFriendRemoveReq : public PktBase
{
enum { MAX_NAME = 16 };
enum CMD
{
REMOVE_FRIEND_REQ = 0, // 친구 제거 (Client->GameServer), m_dwCID는 제거할 사람의 CID.
REMOVE_BAN_REQ = 1, // 거부 등록 제거 (Client->GameServer), m_dwCID는 제거할 사람의 CID.
NOFRIEND_REQ = 2, // 상대친구 리스트에서 자신을 삭제
};
char m_szName[MAX_NAME]; // 삭제할 사람 이름.
unsigned long m_dwCID; // 대상자 CID;
unsigned char m_cCmd;
};
// 기타 패킷
struct PktFriendEtc : public PktBase
{
enum CMD
{
SETGROUP = 0, // 그룹 등록 (Client->GameServer),
// m_dwCID는 그룹 세팅할 사람의 CID, m_dwData는 바뀔 그룹 번호
};
unsigned long m_dwCID;
unsigned long m_dwData;
unsigned char m_cCmd;
};
// 친구 관련 패킷 ( Client <--> GameServer )
struct PktFriendAck : public PktBase
{
enum CMD
{
UNKNOWN_ERROR_ACK = 0, // 알 수 없는 커맨드 에러 (Ack)
ADD_FRIEND_ACK = 1, // 친구 등록 Ack (GameServer->Client)
// 가능한 에러 : SERVER_ERROR (서버 에러)
// CLIENT_ERROR (클라이언트가 잘못된 커맨드를 주는 경우)
// NOT_LOGINED (로그인되지 않은 캐릭터를 등록하려 함)
// LIST_FULL (친구 리스트가 꽉 차 있음)
// REJECTED (상대의 거부 리스트에 속해 있음)
// m_dwCID : 등록 성공시 : 등록한 사람의 CID, 실패시 : 0
MOVE_BAN_TO_FRIEND = 2, // 친구 등록 Ack (GameServer->Client) 거부 리스트에서 삭제하고 친구를 추가함.
// 가능한 에러 : SERVER_ERROR (서버 에러)
// CLIENT_ERROR (클라이언트가 잘못된 커맨드를 주는 경우)
// NOT_LOGINED (로그인되지 않은 캐릭터를 등록하려 함)
// LIST_FULL (친구 리스트가 꽉 차 있음)
// REJECTED (상대의 거부 리스트에 속해 있음)
// m_dwCID : 등록 성공시 : 등록한 사람의 CID, 실패시 : 0
REMOVE_FRIEND_ACK = 3, // 친구 제거 Ack (GameServer->Client)
// 가능한 에러 : SERVER_ERROR (서버 에러)
// CLIENT_ERROR (클라이언트가 잘못된 커맨드를 주는 경우)
// NOT_IN_LIST (요청하는 캐릭터가 리스트에 없어서 삭제할 수 없음)
// m_dwCID : 0
ADD_BAN_ACK = 4, // 거부 등록 Ack (GameServer->Client)
// 가능한 에러 : SERVER_ERROR (서버 에러)
// CLIENT_ERROR (클라이언트가 잘못된 커맨드를 주는 경우)
// NOT_LOGINED (로그인되지 않은 캐릭터를 등록하려 함)
// LIST_FULL (친구 리스트가 꽉 차 있음)
// m_dwCID : 등록 성공시 : 등록한 사람의 CID, 실패시 : 0
MOVE_FRIEND_TO_BAN = 5, // 친구 둥록 Ack (GameServer->Client) 친구 리스트에서 삭제하고 거부를 추가함.
// 가능한 에러 : SERVER_ERROR (서버 에러)
// CLIENT_ERROR (클라이언트가 잘못된 커맨드를 주는 경우)
// NOT_LOGINED (로그인되지 않은 캐릭터를 등록하려 함)
// LIST_FULL (친구 리스트가 꽉 차 있음)
// REJECTED (상대의 거부 리스트에 속해 있음)
// m_dwCID : 등록 성공시 : 등록한 사람의 CID, 실패시 : 0
REMOVE_BAN_ACK = 6, // 거부 제거 Ack (GameServer->Client)
// 가능한 에러 : SERVER_ERROR (서버 에러)
// CLIENT_ERROR (클라이언트가 잘못된 커맨드를 주는 경우)
// NOT_IN_LIST (요청하는 캐릭터가 리스트에 없어서 삭제할 수 없음)
// m_dwCID : 0
FRIEND_LOGIN = 7, // 친구 로그인 (GameServer->Client), m_dwCID는 로그인한 친구의 CID, m_szName은 로그인한 친구의 이름
FRIEND_LOGOUT = 8, // 친구 로그아웃 (GameServer->Client), m_dwCID는 로그아웃한 친구의 CID, m_szName은 로그인한 친구의 이름
FRIEND_LOGIN_TO_GAME = 9, // 친구 로그인 (Chat->GameServer)
// m_dwCID는 로그인한 친구의 CID, m_szName은 로그인한 친구의 이름
// 패킷 뒤에 캐릭터 CID개수(2byte unsigned long)
// 캐릭터 CID가 CID개수만큼 따라온다. 해당 캐릭터들에게 패킷을 전송하면 된다.
FRIEND_LOGOUT_TO_GAME = 10, // 친구 로그아웃 (Chat->GameServer)
// m_dwCID는 로그아웃한 친구의 CID, m_szName은 로그인한 친구의 이름
// 패킷 뒤에 캐릭터 CID개수(2byte unsigned long)
// 캐릭터 CID가 CID개수만큼 따라온다. 해당 캐릭터들에게 패킷을 전송하면 된다.
FRIEND_INFO_UPDATE = 11, // 친구 정보 업데이트.
BAN_INFO_UPDATE = 12, // 거부 정보 업데이트.
BAN_LOGIN = 13, // 거부 로그인. (GameServer->Client)
BAN_LOGOUT = 14, // 거부 로그아웃. (GameServer->Client)
BAN_LOGIN_TO_GAME = 15, // 거부 로그인. (Chat->GameServer)
BAN_LOGOUT_TO_GAME = 16, // 거부 로그아웃. (Chat->GameServer)
// edith 2009.08.28 NoFriend 추가
NOFRIEND_ACK = 17, // 친구 제거 Ack (GameServer->Client)
// 가능한 에러 : SERVER_ERROR (서버 에러)
// CLIENT_ERROR (클라이언트가 잘못된 커맨드를 주는 경우)
// NOT_IN_LIST (요청하는 캐릭터가 리스트에 없어서 삭제할 수 없음)
// m_dwCID : 0
};
enum FriendERROR
{
SERVER_ERROR = 1, // 서버 에러
CLIENT_ERROR = 2, // 클라이언트가 잘못된 커맨드를 주는 경우
NOT_LOGINED = 3, // 로그인하지 않았음
LIST_FULL = 4, // 리스트가 꽉 찼음
REJECTED = 5, // 거부당했음
NOT_IN_LIST = 6, // 요청하는 작업이 리스트에 없음
FAIL_ENEMY = 7 // 적군은 추가 불가능
};
enum { MAX_NAME = 16 };
unsigned long m_dwCID;
char m_szName[MAX_NAME];
unsigned long m_dwGID; // 길드 아이디.
unsigned short m_wClass; // 클래스.
char m_cLevel; // 레벨.
unsigned long m_dwServerID; // 서버 아이디.
unsigned char m_cCmd;
};
// 친구 관련 패킷
struct PktFriendDB : public PktDD
{
enum CMD
{
ADD_FRIEND = 0, // 친구 등록 (GameServer->DBAgent) Owner가 Reference를 등록.
REMOVE_FRIEND = 1, // 친구 제거 (GameServer->DBAgent) Owner가 Reference를 제거. 이때는 ReferenceUID = 0;
ADD_BAN = 2, // 거부 등록 (GameServer->DBAgent) Owner가 Reference를 등록.
REMOVE_BAN = 3, // 거부 제거 (GameServer->DBAgent) Owner가 Reference를 제거. 이때는 ReferenceUID = 0;
SETGROUP = 4, // 그룹 세팅 (GameServer->DBAgent)
// Owner가 Reference를 m_dwData에 들어 있는 그룹으로 세팅. 이때는 ReferenceUID = 0;
FRIEND_LIST = 5, // 친구 리스트 (DBAgent->GameServer, GameServer->Client)
// FriendList의 배열이 붙는다.
// Reference는 의미 없음. m_dwData는 뒤에 붙는 데이터의 크기.
BAN_LIST = 6, // 거부 리스트 (DBAgent->GameServer, GameServer->Client)
// BanInfo의 배열이 붙는다.
// Reference는 의미 없음. m_dwData는 뒤에 붙는 데이터의 크기.
FRIEND_INFO_UPDATE = 7, // 정보 업데이트.
FRIEND_INFO = 8, // 정보 업데이트.
BAN_INFO = 9, // 정보 업데이트.
};
unsigned long m_dwOwnerUID; // 등록 하는 사람 UID
unsigned long m_dwOwnerCID; // 등록 하는 사람 CID
unsigned long m_dwReferenceUID; // 등록 되는 사람 UID
unsigned long m_dwReferenceCID; // 등록 되는 사람 CID
unsigned long m_dwData; // Data
unsigned long m_dwGID; // 등록 되는 사람 길드 정보.
unsigned short m_wClass; // 등록 되는 사람 클래스 정보.
char m_cLevel; // 등록 되는 사람 레벨 정보.
unsigned long m_dwServerID; // 등록 되는 사람 서버 정보.
unsigned char m_cCmd;
};
#pragma pack()
#endif

View File

@@ -0,0 +1,43 @@
#ifndef _GAME_EVENT_PACKET_H_
#define _GAME_EVENT_PACKET_H_
#include <Network/Packet/PacketBase.h>
#pragma pack(1)
// ---------------------------------------------------------------------------
// °ÔÀÓ À̺¥Æ® °ü·Ã
typedef struct PktEventDropItem* LPPktEventDropItem;
struct PktEventDropItem : public PktBase
{
unsigned short m_usItemID;
};
struct PktItemQtyControl : public PktBase
{
enum TYPE
{
ADD = 0,
DEL = 1,
STATUS_REQUEST = 2,
STATUS_ACK = 3,
STATUS_ACK_END = 4
};
unsigned long m_dwItemTypeID;
unsigned long m_dwItemQty;
unsigned long m_dwCurrentItemQty;
time_t m_tStartTime;
time_t m_tEndTime;
unsigned char m_cType;
unsigned char m_cGroup;
};
#pragma pack()
#endif

View File

@@ -0,0 +1,119 @@
#ifndef _GAME_LOG_PACKET_H_
#define _GAME_LOG_PACKET_H_
#include <Network/Packet/PacketBase.h>
namespace GAMELOG
{
namespace CMD
{
enum Packet
{
DefaultInfo = 1,
ItemInfo = 2,
EquipInfo = 3,
};
enum LogType
{
CHAR_LOGIN = 1, // 로그인
CHAR_LOGOUT = 2, // 로그아웃
PICKUP = 3, // 아이템 집기 - 돈 포함
DROP = 4, // 아이템 버리기 - 돈 포함
BUY_ITEM = 5, // 아이템 사기 - 돈 포함
SELL_ITEM = 6, // 아이템 팔기 - 돈 포함
BEFORE_EXCHANGE = 7, // 아이템 교환 전의 교환창 아이템 - 돈 포함
AFTER_EXCHANGE = 8, // 아이템 교환 전의 교환창 아이템 - 돈 포함
USE_ITEM = 9, // 아이템 사용 - 돈 포함
UPGRADE_ITEM = 10, // 아이템 업그레이드 - 돈 포함
INSTALL_SOCKET = 11, // 아이템 소켓에 보석 박기
GET_QUEST_ITEM = 12, // 퀘스트 아이템 얻기
GET_QUEST_REWARD = 13, // 퀘스트 보상 얻기 - 돈 포함
REMOVE_QUEST_ITEM = 14, // 퀘스트 아이템 제거
REPAIR_ITEM = 15, // 아이템 수리 - 돈 포함
ADMIN_DROP = 16, // 운영자 명령으로 아이템 떨구기 - 돈 포함
CHAR_LOGIN_INVENTORY_GOLD = 17, // 캐릭터 로그인시 인벤토리 돈
CHAR_LOGIN_DEPOSIT_GOLD = 18, // 캐릭터 로그인시 창고 돈
CHAR_LOGOUT_INVENTORY_GOLD = 19, // 캐릭터 로그아웃시 인벤토리 돈
CHAR_LOGOUT_DEPOSIT_GOLD = 20, // 캐릭터 로그아웃시 창고 돈
DEPOSIT_RENT_GOLD = 21, // 창고 대여료
FAME_GET_BATTLE = 22, // 전투로 얻은 명성
FAME_LOSE_BATTLE = 23, // 전투로 잃은 명성
FAME_GET_CAMP = 24, // 요새로 얻은 명성
FAME_LOSE_CAMP = 25, // 요새로 잃은 명성
QUEST_GET_REWARD = 26, // 퀘스트 수행으로 얻은 보상
CHANGE_RIDE = 27, // 라이더 타기 로그
MAX_LOG_TYPE = 28
};
};
namespace PACKET
{
enum Flags
{
ITEM_INFO = (1 << 0),
EQUIP_INFO = (1 << 1)
};
enum
{
MAX_SOCKET_NUM = 8,
MAX_ATTRIBUTE_NUM = 35
};
#pragma pack(1)
struct DefaultInfo : public PktBase
{
time_t m_dwTime;
unsigned long m_dwFirstUID; // 행위자의 UID
unsigned long m_dwFirstCID; // 행위자의 CID
unsigned long m_dwGold; // 행위로 인해서 영향을 받게 된 금액
unsigned long m_dwSecondUID; // 대상자의 UID
unsigned long m_dwSecondCID; // 대상자의 CID
unsigned short m_usPosX; // 사건이 일어난 장소(X)
unsigned short m_usPosY; // 사건이 일어난 장소(Y)
unsigned short m_usPosZ; // 사건이 일어난 장소(Z)
unsigned char m_cCommand; // 사건 종류
unsigned char m_cFlags; // 기타 정보(아이템 정보인지.. 장비 정보가 따라 붙는지 등..)
};
struct ItemInfo : public DefaultInfo
{
unsigned __int64 m_dwItemUID;
unsigned short m_usItemProtoTypeID;
unsigned char m_cTakeType;
unsigned char m_cItemAmount;
unsigned char m_cItemPosX;
unsigned char m_cItemPosY;
unsigned char m_cItemPosZ;
unsigned char m_cItemExtra; // 추가 정보
};
struct EquipInfo : public ItemInfo
{
unsigned short m_usRuneSocket; // 룬 소켓 내용
unsigned char m_cUpgradeStep; // 업그레이드 단계
unsigned char m_cMaxSocket; // 현재 뚫려 있는 소켓 수
unsigned char m_cMaxDurability; // 최대 내구도
unsigned char m_cSocket[MAX_SOCKET_NUM]; // 소켓 내용
short m_usAttribute[MAX_ATTRIBUTE_NUM]; // 속성 내용
};
#pragma pack()
};
};
#endif

View File

@@ -0,0 +1,611 @@
#ifndef _GUILD_PACKET_H_
#define _GUILD_PACKET_H_
#include <Network/Packet/PacketBase.h>
#include <Creature/Character/CharacterClass.h>
#include <Creature/CreatureStructure.h>
#include <Community/Guild/GuildConstants.h>
#include <Community/Guild/GuildStructure.h>
#pragma pack(1)
using namespace Guild;
// 길드 생성
struct PktCreateGuild : public PktBase
{
enum PktCreateGuildErr
{
FAIL_ALREADY_NAME = 2, // 이미 존재하는 이름
FAIL_DISSOLVE_GUILD = 3, // 길드 해체
FAIL_INVALID_NAME = 4 // 부적절한 이름
};
enum DissolveReason
{
NONE_LOGIN = 1, // 오랫동안 아무도 로그인하지 않음
MIN_MEMBER_TIMEOUT = 2, // 길드원이 최소 인원 미만인 채 일정 시간 경과
NONE_NEXT_GUILDMASTER_BY_NONE_LOGIN = 3, // 일정기간 길드마스터가 로그인하지 않아, 권한 이양하려 할 시에 길마가 없을 경우
NONE_NEXT_GUILDMASTER_BY_GUILDMASTER_OUT = 4, // 길드마스터 탈퇴시에 권한 이양하려 할 시에 길마가 없을 경우
NONE_NEXT_GUILDMASTER_BY_GUILDMASTER_DELETED = 5 // 길드마스터 삭제시에 권한 이양하려 할 시에 길마가 없을 경우
};
unsigned long m_dwCID;
unsigned long m_dwGID;
unsigned char m_cInclination;
char m_szGuildName[MAX_GUILD_NAME_LEN];
};
// 길드 리스트 (가변 길이) + 길드 정보
struct PktGuildList : public PktBase
{
enum { MAX_NUM_PER_PAGE = 10 };
unsigned long m_dwCID; // 캐릭터 아이디
unsigned char m_cSortCmd; // 명령
unsigned char m_cPage; // 페이지
unsigned char m_cSmallNodeNum; // 노드 수 (C -> S : 체크섬 노드, S -> C : 간략 노드)
unsigned char m_cLargeNodeNum; // 노드 수 (전체 정보 노드)
};
// 길드 정보 (체크섬)
struct GuildCheckSumNode
{
unsigned long m_dwGID; // 길드 아이디
unsigned long m_dwCheckSum; // 체크섬
};
// 길드 정보 (종종 변하지만 간혹 요청되는 자잘한 것들)
struct GuildSmallInfoNode
{
// TODO : 국가, 레벨, 길드 이름은 GuildLargeInfoNode로 빼면 될 듯 합니다.
// (국가와 길드 이름은 변경되지 않습니다. 레벨은 마크나 관계처럼 변경시마다 브로드캐스팅하면 됩니다.)
// 더불어 길드 생성시 생성되는 길드의 GuildLargeInfoNode를 브로드캐스팅해야 합니다.
// (이 때 주의할 점은 길드 생성 패킷 전송 당시엔 마스터가 가입하지 않은 상태이므로 마스터 이름을 별도로 넣어줘야 합니다.)
unsigned long m_dwGID; // 길드 아이디
unsigned char m_cIndex; // 리스트상의 인덱스
unsigned char m_cInclination; // 길드 성향
unsigned short m_wRank; // 순위
unsigned long m_dwFame; // 명성
unsigned char m_cLevel; // 레벨
unsigned char m_cCurrentMemberNum; // 인원수
char m_szName[MAX_GUILD_NAME_LEN]; // 길드 이름
char m_szMasterName[MAX_MEMBER_NAME_LEN]; // 마스터 이름
GuildSmallInfoNode()
: m_dwGID(0), m_cIndex(0), m_cInclination(0), m_wRank(0), m_dwFame(0), m_cLevel(0), m_cCurrentMemberNum(0)
{
std::fill_n(m_szName, int(MAX_GUILD_NAME_LEN), 0);
std::fill_n(m_szMasterName, int(MAX_MEMBER_NAME_LEN), 0);
}
GuildSmallInfoNode(unsigned long dwGID, unsigned char cIndex, unsigned char cInclination,
unsigned short wRank, unsigned long dwFame, unsigned char cLevel,
unsigned char cCurrentMemberNum, const char* szGuildName, const char* szMasterName)
: m_dwGID(dwGID), m_cIndex(cIndex), m_cInclination(cInclination),
m_wRank(wRank), m_dwFame(dwFame), m_cLevel(cLevel), m_cCurrentMemberNum(cCurrentMemberNum)
{
if (NULL != szGuildName)
{
strncpy(m_szName, szGuildName, MAX_GUILD_NAME_LEN);
}
if (NULL != szMasterName)
{
strncpy(m_szMasterName, szMasterName, MAX_MEMBER_NAME_LEN);
}
}
};
// 길드 정보 (모두)
struct GuildLargeInfoNode : public GuildSmallInfoNode
{
char m_szMark[MAX_MARK_SIZE]; // 마크
unsigned char m_cRelationByMine; // 클라이언트(유저)가 이 길드에 맺은 길드 관계
unsigned char m_cRelationByTarget; // 이 길드가 클라이언트(유저)에게 맺은 길드 관계
GuildLargeInfoNode()
: GuildSmallInfoNode(), m_cRelationByMine(0), m_cRelationByTarget(0)
{
std::fill_n(m_szMark, int(MAX_MARK_SIZE), 0);
}
GuildLargeInfoNode(unsigned long dwGID, unsigned char cIndex, unsigned char cInclination,
unsigned short wRank, unsigned long dwFame, unsigned char cLevel,
unsigned char cCurrentMemberNum, const char* szMasterName, const char* szGuildName,
const char* szMark, unsigned char cRelationByMine, unsigned char cRelationByTarget)
: GuildSmallInfoNode(dwGID, cIndex, cInclination, wRank, dwFame, cLevel, cCurrentMemberNum, szGuildName, szMasterName),
m_cRelationByMine(cRelationByMine), m_cRelationByTarget(cRelationByTarget)
{
if (NULL != szMark)
{
memcpy(m_szMark, szMark, MAX_MARK_SIZE);
}
}
};
// 길드 멤버 관련 명령
struct PktGuildCmd : public PktBase
{
enum GuildCmd
{
GC_INVITE = 0, // 초대
GC_JOIN = 1, // 가입 (초대에 의한)
GC_REFUSE = 2, // 거절 (초대에 대한)
GC_ASK_ENTER = 3, // 가입 신청
GC_ASK_LEAVE = 4, // 탈퇴 신청
GC_KICK = 5, // 강제 탈퇴
GC_SETUP_TITLE = 6, // 직위 변경
GC_LOGINOUT = 7, // 로그인/아웃
GC_RANK_UP = 8, // 서열 위로
GC_RANK_DOWN = 9, // 서열 아래로
GC_TACTICS = 10, // 용병 가입 신청.
GC_TACTICS_JOIN = 11, // 용병 가입 초대.
GC_TACTICS_TITLE = 12, // 용병 허가.
GC_TACTICS_KICK = 13, // 용병 삭제.
GC_TACTICS_LEAVE = 14, // 용병 탈퇴.
GC_TACTICS_REQUEST = 15, // 길드 전쟁 중 용병 허가 시 캐릭터 확인 요청.
};
enum PktGuildCmdErr
{
FAIL_NOT_MEMBER = 2, // 길드원이 아님
FAIL_NOT_RIGHT = 3, // 권한이 없음
FAIL_ALREADY_MEMBER = 4, // 이미 길드원임
FAIL_OVER_MEMBER = 5, // 길드 정원 초과
FAIL_NATION = 6, // 다른 국가의 길드
FAIL_DIFFERENCE_TITLE = 7, // 다른 직위로의 서열 변경
FAIL_OVER_MEMBER_NUM = 8, // 길드원 수 범위를 초과하는 서열 변경
FAIL_GUILDWAR_TIME_KICK = 9, // 길드전쟁 시간에 탈퇴를 시도하는 경우
FAIL_TACTICS_LIMITLEVEL = 10, // 용병 신청 레벨이 안되는 캐릭터.
FAIL_TACTICS_NATION = 11, // 국적이 다른 캐릭터.
FAIL_TACTICS_GUILDJOIN = 12, // 길드나 용병에 가입되어있거나 신청중인 캐릭터.
FAIL_TACTICS_OVER_MEMBER = 13, // 길드 정원 초과.
FAIL_TACTICS_LOGOUT = 14 // 용병 허가 시 로그아웃 상태일때.
};
unsigned long m_dwGID; // 길드 아이디
unsigned long m_dwSenderID; // 캐릭터 아이디 (주체)
unsigned long m_dwReferenceID; // 참조 아이디 (대상 캐릭터/서버 아이디/권한 비트)
char m_szGuildName[MAX_GUILD_NAME_LEN]; // 길드 이름
char m_szSenderName[MAX_MEMBER_NAME_LEN]; // 캐릭터 이름 (주체)
unsigned short m_wCmd; // 명령
};
// 멤버 리스트 (가변 길이) + 멤버 정보
struct PktGuildMemberList : public PktBase
{
enum { MAX_NUM_PER_PAGE = 10 };
unsigned long m_dwCID; // 캐릭터 아이디
unsigned char m_cMemberType; // 멤버리스트, 용병리스트
unsigned char m_cSortCmd; // 명령 (Guild::MemberSort)
unsigned char m_cPage; // 페이지
unsigned char m_cTotalMemberNum; // 총 멤버 수
unsigned char m_cNodeNum; // 노드 수 (멤버 노드)
};
// 멤버 정보
struct GuildMemberInfoNode
{
unsigned long m_dwCID;
char m_szName[MAX_MEMBER_NAME_LEN];
unsigned char m_cTactics;
unsigned long m_dwFame;
unsigned long m_dwGold;
unsigned long m_dwServerID;
unsigned char m_cRank;
unsigned char m_cTitle;
unsigned char m_cLevel;
unsigned char m_cClass;
unsigned char m_cGuildWarFlag;
};
// 멤버 정보 업데이트 (Game <-> DBAgent)
struct PktGuildMemberInfoUpdate : public PktBase
{
unsigned long m_dwGID;
unsigned long m_dwCID;
MemberListInfo m_MemberListInfo;
MemberDetailInfo m_MemberDetailInfo;
};
// 멤버 명성 업데이트
struct PktGuildMemberFameUpdate : public PktBase
{
unsigned long m_dwOurGID;
unsigned long m_dwEnemyGID;
unsigned long m_dwCID;
unsigned char m_cType;
int m_nAddFame;
};
// 멤버 돈 업데이트
struct PktGuildMemberGoldUpdate : public PktBase
{
unsigned long m_dwGID;
unsigned long m_dwCID;
unsigned long m_dwGold;
};
// 길드 마크
struct PktGuildMark : public PktBase
{
enum eError
{
FAIL_INVALID_GUILD = 2, // 존재하지않는 길드
FAIL_INVALID_MARK = 3, // 변경할 마크가 없음
FAIL_INVALID_CHARACTER = 4, // 존재하지않는 캐릭터
FAIL_NOT_MASTER = 5, // 마스터가 아님
FAIL_NOT_ENOUGH_GOLD = 6, // 금액 부족
};
unsigned long m_dwCID; // 캐릭터 아이디
unsigned long m_dwGID; // 길드 아이디
char m_szMark[MAX_MARK_SIZE]; // 마크
unsigned long m_dwGold; // 금고 잔액
};
// 길드 레벨
struct PktGuildLevel : public PktBase
{
unsigned long m_dwUID; // 아이디 (C -> S : 캐릭터 아이디, S -> C : 길드 아이디)
unsigned char m_cLevel; // 레벨
unsigned long m_dwGold; // 금고 잔액
};
// 길드 관계
struct PktGuildRelation : public PktBase
{
enum eSubCmd
{
GR_HOSTILITY = 0, // 적대 선언
GR_PEACE = 1, // 평화 선언
GR_ALERT = 2, // 경계 적대 선언
GR_COUNTER = 3, // 카운터 적대 선언
GR_REQUEST = 4, // 이미 적대인 길드와 평화 선언후 대상 길드와 적대 선언
// 카운터 적대 선언을 할지 물어보는 대화창
GR_HOSTILITYDEL = 5 // A->B로 적대선언을 한후 A->B에게 평화선언을 해도 B의 Target에 존재하는
// 적대선언 리스트는 사라지지 않는다. B가 직접 5번 커맨드로 취소해줘야만
// 취소가 된다.
};
enum eError
{
FAIL_NOT_MEMBER = 2, // 해당 길드의 멤버가 아님
FAIL_NOT_HOSTILITY_TIME = 3, // 적대 선언을 할수 없는 시간
FAIL_NOT_ALERT_TIME = 4, // 경계 적대 선언을 할수 없는 시간
FAIL_NOT_COUNTER_TIME = 5, // 카운터 적대 선언을 할수 없는 시간
FAIL_NOT_MASTER = 6, // 길드의 마스터가 아님
FAIL_NOT_EXIST_GUILD = 7, // 길드 ID가 0 이거나 길드가 존재하지 않음
FAIL_SELF_GUILD = 8, // 자신의 길드에게 적대/평화/경계/카운터 선언
FAIL_ALREADY_HOSTILITY = 9, // 대상 길드와 이미 적대 관계입니다.
FAIL_ALREADY_COUNTER_HOSTILITY = 10, // 대상 길드와 이미 카운터 적대 관계입니다.
FAIL_ALREADY_ALERT_HOSTILITY = 11, // 데상 길드와 이미 경계 적대 관계입니다.
FAIL_ALREADY_NEUTRALITY = 12, // 대상 길드와 이미 중립 관계입니다.
FAIL_MAX_ALERT_NUM = 13, // 경계 적대 선언권 초과
FAIL_NOT_HAVE_DEVELOPING_CAMP = 14, // 구축중인 길드 요새가 없음
FAIL_NOT_HAVE_ALERT = 15, // 경계 적대 신청을 받지 않고 카운터 적대 신청을 하려함
FAIL_TARGET_HOSTILITY_FULL = 16, // 적대 선언 받을 수 있는 한계치 초과
FAIL_REQUEST_WINDOW = 100, // 적대 선언수 초과로 인해 평화 선언후 적대 선언을 하도록 인증
FAIL_REQUEST_COUNTER = 101, // 카운터 적대 선언을 하도록 인증
};
unsigned long m_dwCID; // 캐릭터 아이디
unsigned long m_dwGID; // 자신의 GID
unsigned long m_dwTargetGID; // 상대 길드 아이디
unsigned long m_dwValue; // 적대 선언중인 GID ( GR_REQUEST 일때만... )
char m_cSubCmd; // 길드 관계 변경 커맨드
char m_szGuildName[MAX_GUILD_NAME_LEN]; // 대상 길드명 / 선포 길드명
char m_szTempGuildName[MAX_GUILD_NAME_LEN]; // 이미 적대 선언중인 길드 이름
};
// 길드 성향
struct PktGuildInclination : public PktBase
{
enum PktGIErr
{
FAIL_SO_FAST = 2, // 일정 시간동안을 변경할 수 없다.
FAIL_WRONG_NATION_KARTERANT = 3, // 카르테란트 길드에는 인간만 속할 수 있다.
FAIL_WRONG_NATION_MERKADIA = 4 // 메르카디아 길드에는 아칸만 속할 수 있다.
};
unsigned long m_dwUID; // 아이디 (C -> S : 캐릭터 아이디, S -> C : 길드 아이디)
unsigned char m_cInclination; // 성향 (Guild::Inclination 참고)
};
// 길드 권한 정보
struct GuildRight
{
enum Index
{
PUT_STOREHOUSE = 0,
GET_STOREHOUSE = 1,
USE_SAFE = 2,
INVITE_MEMBER = 3,
PERMIT_JOIN = 4,
CHANGE_PASSWORD = 5,
REGULATE_TEX = 6,
KICK_MEMBER = 7,
BOARD_ADMIN = 8,
SETUP_MARK_N_LEVEL = 9,
SETUP_MIDDLE = 10,
DIVIDE_GOLD = 11,
SETUP_POLICY = 12,
MAX_USING_RIGHT = 13
};
unsigned char m_aryRight[MAX_RIGHT_SIZE];
GuildRight()
{
Init(false);
}
GuildRight(bool bMaxRight)
{
Init(bMaxRight);
}
void Init(bool bMaxRight)
{
std::fill_n(m_aryRight, int(MAX_RIGHT_SIZE), Guild::NONE);
m_aryRight[CHANGE_PASSWORD] = (true == bMaxRight) ? Guild::COMMON : Guild::MASTER;
m_aryRight[PUT_STOREHOUSE] = (true == bMaxRight) ? Guild::COMMON : Guild::MASTER;
m_aryRight[GET_STOREHOUSE] = (true == bMaxRight) ? Guild::COMMON : Guild::MASTER;
m_aryRight[USE_SAFE] = (true == bMaxRight) ? Guild::COMMON : Guild::MASTER;
m_aryRight[INVITE_MEMBER] = (true == bMaxRight) ? Guild::COMMON : Guild::MASTER;
m_aryRight[PERMIT_JOIN] = (true == bMaxRight) ? Guild::COMMON : Guild::MASTER;
m_aryRight[REGULATE_TEX] = (true == bMaxRight) ? Guild::MIDDLE_ADMIN : Guild::MASTER;
m_aryRight[KICK_MEMBER] = (true == bMaxRight) ? Guild::MIDDLE_ADMIN : Guild::MASTER;
m_aryRight[BOARD_ADMIN] = (true == bMaxRight) ? Guild::MIDDLE_ADMIN : Guild::MASTER;
m_aryRight[SETUP_MARK_N_LEVEL] = (true == bMaxRight) ? Guild::MASTER : Guild::MASTER;
m_aryRight[SETUP_MIDDLE] = (true == bMaxRight) ? Guild::MASTER : Guild::MASTER;
m_aryRight[DIVIDE_GOLD] = (true == bMaxRight) ? Guild::MASTER : Guild::MASTER;
m_aryRight[SETUP_POLICY] = (true == bMaxRight) ? Guild::MASTER : Guild::MASTER;
}
int IsValid(void)
{
GuildRight MaxRight(true);
int nIndex = 0;
for (; nIndex < MAX_RIGHT_SIZE; ++nIndex)
{
if (m_aryRight[nIndex] > MaxRight.m_aryRight[nIndex])
{
return nIndex;
}
}
return nIndex;
}
};
// 길드 권한
struct PktGuildRight : public PktBase
{
unsigned long m_dwUID; // 아이디 (C -> S : 캐릭터 아이디, S -> C : 길드 아이디)
GuildRight m_GuildRight; // 길드 권한
};
// 자기 길드 정보
struct PktMyGuildInfo : public PktBase
{
unsigned long m_dwGold; // 길드 금고
GuildRight m_GuildRight; // 길드 권한
unsigned char m_cTitle; // 직위
};
// 적대 현황 리스트 (가변 길이) + 적대 현황 정보
struct PktGuildHostilityList : public PktBase
{
enum { MAX_NUM_PER_PAGE = 5 };
enum PageState
{
PAGE_CURRENT = 0,
PAGE_PREV = 1,
PAGE_NEXT = 2
};
unsigned long m_dwCID; // 캐릭터 아이디
unsigned char m_cCurrentPage; // 현재 페이지
unsigned char m_cPageState; // 요청한 페이지의 상태
unsigned char m_cNodeNum; // 가변 노드수
unsigned short m_wTotalItemNum; // 적대 현황의 총 리스트 수
char m_szHostility[MAX_GUILD_NAME_LEN]; // 적대 선언 중인 길드명
char m_szAlert[MAX_GUILD_NAME_LEN]; // 경계 적대 선언중인 길드명
};
// 길드 적대 현황 정보
struct GuildHostilityInfoNode
{
char m_szName[MAX_GUILD_NAME_LEN]; // 적대 관계 길드 이름
unsigned char m_cRelationType; // 적대 관계 타입 (Guild::Relation)
};
// 자신의 길드의 관계 리스트 요청 패킷 (가변 길이) + 관계 정보
struct PktGuildRelationInfo : public PktBase
{
unsigned long m_dwCID; // 요청 캐릭터
unsigned long m_dwGID; // 자신의 길드 ID
unsigned short m_wNodeNum; // 가변 노드수
};
// 길드 관계 정보
struct GuildRelationInfoNode
{
// GuildLargeInfo 의 내용과 동일
unsigned long m_dwGID;
unsigned char m_cRelationByMine;
unsigned char m_cRelationByTarget;
};
// 길드 금고
struct PktGuildSafe : public PktBase
{
enum PktGuildSafeErr
{
FAIL_NOT_ENOUGH_MONEY = 2, // 금고에 돈이 충분치 않음
FAIL_NOT_CHAR_MONEY = 3, // 캐릭터에 돈이 충분치 않음
FAIL_NOT_GUILD_DEPOSIT = 4, // 금고 입금하는데 실패했습니다.
FAIL_NOT_GUILD_UPDATE = 5, // 금고 정보를 업데이트 하는데 실패했습니다.
FAIL_REQUEST_DATA = 6, // 정보를 요청중입니다.
};
enum SafeCmd
{
SC_WITHDRAWAL = 0, // 출금
SC_DEPOSIT = 1, // 입금
SC_RELEASE = 2, // 길드원에게 방출
SC_REFER = 3, // 사용 내역 조회
SC_CAMPSHOP = 4, // 길드 요새 상점의 수익금
SC_BONUS = 5, // 보너스 입금
};
unsigned long m_dwCID; // 캐릭터 아이디
unsigned long m_dwGold; // 입금/출금/방출하는 금액
unsigned char m_cCmd; // 명령
};
// 길드 금고 Ack
struct PktGuildSafeAck : public PktBase
{
unsigned long m_dwCID; // 캐릭터 아이디
unsigned long m_dwGID; // 길드 아이디
unsigned long m_dwSafeGold; // 금고 잔액
unsigned long m_dwCharGold; // 캐릭터 잔액 (C -> S : 입금/출금/방출하는 금액)
unsigned char m_cCmd; // 명령
char m_szCharName[Guild::MAX_MEMBER_NAME_LEN]; // 캐릭터 이름
};
// 길드 DB (가변 길이) + 길드 정보
struct PktGuildDB : public PktBase
{
bool m_bStartFlag; // 시작 패킷인가? (PktGuildDB는 길드 수만큼 보내므로 첫번째 길드를 받았을 때 리스트를 초기화 해주어야 한다.)
unsigned long m_dwGID; // 길드 아이디
unsigned char m_cTotalMemberNum; // 길드원 수
unsigned char m_cRelationByMineNum; // 내가 맺은 길드 관계수
unsigned char m_cRelationByTargetNum; // 다른 길드가 맺은 길드 관계수
unsigned short m_wSize; // 길드 정보 크기
};
// 길드 정보 (DB)
struct GuildInfoDB
{
unsigned long m_dwGID;
char m_strName[MAX_GUILD_NAME_FOR_DB];
unsigned char m_cLevel;
unsigned long m_dwFame;
unsigned long m_dwGold;
TIME m_tmLastLogout;
TIME m_tmCheckMember;
TIME m_tmGMLastLogout;
char m_szMark[MAX_MARK_SIZE];
char m_szRight[MAX_RIGHT_SIZE];
unsigned char m_cInclination;
TIME m_tmChangeInclination;
};
// 길드 멤버 (DB)
struct GuildMemberDB
{
unsigned long m_dwGID;
unsigned long m_dwCID;
unsigned long m_dwRank;
char m_strName[MAX_MEMBER_NAME_LEN];
unsigned long m_dwTitle;
unsigned char m_cLevel;
unsigned short m_wClass;
unsigned long m_dwFame;
unsigned long m_dwGold;
unsigned char m_cGuildWarFlag;
TIME m_LeaveGuildTime;
unsigned char m_cTactics;
};
// 길드 관계 (DB)
struct GuildRelationDB
{
unsigned long m_dwGID;
unsigned long m_dwTargetGID;
unsigned char m_cRelation;
};
// 길드 포지션 설정 패킷.
struct PktGuildPosition : public PktBase
{
enum PktErr
{
FAIL_GUILD = 1, // 길드가 없을때.
FAIL_CONNECT_CHAR = 2, // 캐릭터가 접속 중일때.
FAIL_DB_UPDATE = 3, // DB 업데이트 실패.
FAIL_MEMBER_DELETE = 4 // 길드 멤버 삭제 실패.
};
enum Const
{
TYPE_POSITION = 0, // 포지션 변경시.
TYPE_MEMBERDELETE = 1 // 길드 멤버 삭제시.
};
unsigned long m_dwGID;
unsigned long m_dwCID;
unsigned char m_cPosition;
unsigned char m_cType;
};
// 위치가 없어서 임시로(조이스틱 키 설정 관련).
struct PktKeyInfo : public PktBase
{
enum Const
{
MAX_KEY_INFO = 34
};
unsigned long m_dwCID;
unsigned long m_dwKeyInfo[MAX_KEY_INFO];
};
#pragma pack()
#endif

View File

@@ -0,0 +1,174 @@
#ifndef _PARTY_INFO_PACKET_H_
#define _PARTY_INFO_PACKET_H_
#include "DataPacket.h"
#include <DB/DBdefine.h>
#pragma pack(1)
////////////////////////////////////////////////////////////////////////////////////////////////////
//
// 파티 정보
//
////////////////////////////////////////////////////////////////////////////////////////////////////
typedef struct PktPID* LPPktPID;
struct PktPID : public PktDD
{
unsigned long m_dwCharID;
unsigned long m_dwPartyID;
unsigned long m_dwServerID;
unsigned long m_dwGID;
unsigned short m_wClass;
char m_cLevel;
};
typedef struct PktPIDAck* LPPktPIDAck;
struct PktPIDAck : public PktDD
{
PARTY m_Party;
unsigned long m_dwCharID;
unsigned long m_dwServerID;
unsigned long m_dwGID;
unsigned short m_wClass;
char m_cLevel;
};
////////////////////////////////////////////////////////////////////////////////////////////////////
//
// 파티 생성
//
////////////////////////////////////////////////////////////////////////////////////////////////////
typedef struct PktCPD* LPPktCPD;
struct PktCPD : public PktDD
{
unsigned long m_dwLeaderID;
unsigned long m_dwMemberID;
unsigned long m_dwLeaderGID;
unsigned short m_wLeaderClass;
char m_cLeaderLevel;
unsigned long m_dwMemberGID;
unsigned short m_wMemberClass;
char m_cMemberLevel;
};
typedef struct PktCPDAck* LPPktCPDAck;
struct PktCPDAck : public PktDD
{
PARTY m_Party;
unsigned long m_dwLeaderID;
unsigned long m_dwMemberID;
unsigned long m_dwLeaderGID;
unsigned short m_wLeaderClass;
char m_cLeaderLevel;
unsigned long m_dwMemberGID;
unsigned short m_wMemberClass;
char m_cMemberLevel;
unsigned char m_cZone;
};
////////////////////////////////////////////////////////////////////////////////////////////////////
//
// 파티 삭제
//
////////////////////////////////////////////////////////////////////////////////////////////////////
typedef struct PktDPD* LPPktDPD;
struct PktDPD : public PktDD
{
unsigned long m_dwPartyID;
};
////////////////////////////////////////////////////////////////////////////////////////////////////
//
// 파티 멤버 정보
//
//
// 멤버 로그인 : CID/CID 0/SID
// 멤버 로그아웃 : CID/CID 0/리더 아이디(0 일경우 리더 양도 없음)
// 멤버 가입 : CID/CID CID/CID
// 멤버 삭제 : CID/CID CID/리더 아이디(0 일 경우 리더 양도 없음)
//
////////////////////////////////////////////////////////////////////////////////////////////////////
typedef struct PktPMD* LPPktPMD;
struct PktPMD : public PktDD
{
enum PktPMDErr
{
NO_SERVER_ERR = 0,
SERVER_ERROR = 1,
FAIL_WRONG_PARTY = 2
};
unsigned long m_dwPartyID;
unsigned long m_dwSenderID;
unsigned long m_dwGID; // 길드 아이디(이전 Reference 도 사용).
unsigned long m_dwServerID; // 서버 아이디.
unsigned short m_wClass; // 클래스.
char m_cLevel; // 레벨.
char m_strSenderName[CHAR_INFOST::MAX_NAME_LEN];
};
struct PartyMemberData
{
// 인챈트 정보의 경우 CreatureStructure.h의 EnchantInfo에 변화가 생기면 수정이 필요합니다.
enum ChangedData
{
CHANGED_XPOS = ( 1 << 0 ),
CHANGED_YPOS = ( 1 << 1 ),
CHANGED_ZPOS = ( 1 << 2 ),
CHANGED_MAX_HP = ( 1 << 3 ),
CHANGED_MAX_MP = ( 1 << 4 ),
CHANGED_CUR_HP = ( 1 << 5 ),
CHANGED_CUR_MP = ( 1 << 6 ),
CHANGED_LEVEL = ( 1 << 7 ),
CHANGED_CLASS = ( 1 << 8 ),
CHANGED_ENCHANT_INFO_0 = ( 1 << 9 ),
CHANGED_ENCHANT_INFO_1 = ( 1 << 10 ),
CHANGED_ENCHANT_INFO_2 = ( 1 << 11 ),
CHANGED_ENCHANT_INFO_3 = ( 1 << 12 )
};
enum Const
{
MAX_ENCHANT_INFO_NUM = 4
};
unsigned long m_dwCID; // 캐릭터 CID
float m_fXPos; // X위치
float m_fYPos; // Y위치
float m_fZPos; // Z위치
unsigned short m_usMaxHP; // 최대 HP
unsigned short m_usMaxMP; // 최대 MP
unsigned short m_usCurHP; // 현재 HP
unsigned short m_usCurMP; // 현재 MP
unsigned char m_cLevel; // 캐릭터 레벨
unsigned char m_cClass; // 캐릭터 클래스
unsigned long m_dwEnchantInfo[MAX_ENCHANT_INFO_NUM]; // 인챈트 정보
unsigned short m_usDataChanged; // 데이터 변경 여부
};
#pragma pack()
#endif

View File

@@ -0,0 +1,79 @@
#ifndef _RANKING_PACKET_H_
#define _RANKING_PACKET_H_
#include <algorithm>
#include <Network/Packet/PacketBase.h>
#pragma pack(1)
// ---------------------------------------------------------------------------
// ·©Å· °ü·Ã
struct RankingNode
{
enum { MAX_NAME = 16 };
char m_szCharName[MAX_NAME];
unsigned long m_dwPoint;
unsigned char m_cLevel;
unsigned char m_cClass;
RankingNode()
: m_dwPoint(0), m_cLevel(0), m_cClass(0)
{
std::fill_n(m_szCharName, int(MAX_NAME), 0);
}
RankingNode(const char* szCharName, unsigned long dwPoint, unsigned char cLevel, unsigned char cClass)
: m_dwPoint(dwPoint), m_cLevel(cLevel), m_cClass(cClass)
{
strncpy(m_szCharName, szCharName, MAX_NAME);
m_szCharName[MAX_NAME - 1] = 0;
}
bool operator < (const RankingNode& rhs)
{
return (m_dwPoint < rhs.m_dwPoint);
}
bool operator > (const RankingNode& rhs)
{
return (m_dwPoint > rhs.m_dwPoint);
}
struct ComparePoint
{
int operator() (const RankingNode& node1, const RankingNode& node2)
{
return (node1.m_dwPoint > node2.m_dwPoint);
}
};
};
typedef struct PktRankingInfo* LPPktRankingInfo;
struct PktRankingInfo : public PktBase
{
enum Const
{
MAX_NUM_PER_PAGE = 18
};
enum PktRankingInfoErr
{
FAIL_INVALID_PAGE = 2
};
unsigned long m_dwCharID;
unsigned char m_cClass;
unsigned char m_cPage;
unsigned short m_wNum;
};
#pragma pack()
#endif

View File

@@ -0,0 +1,163 @@
#ifndef _LOGIN_SERVER_INFO_
#define _LOGIN_SERVER_INFO_
#include <winsock2.h>
#include <windows.h>
#include <algorithm>
#pragma pack(1)
// -----------------------------------------------------------------------------
// 서버 정보 관련 구조체들
typedef union SERVER_ID* LPSERVER_ID;
union SERVER_ID
{
// 서버군
enum Group
{
GROUP_TEST = 0, // 테스트
GROUP_OFFICIAL1 = 1, // Ichman
GROUP_OFFICIAL2 = 2, //
GROUP_OFFICIAL3 = 3, //
GROUP_OFFICIAL4 = 4, //
GROUP_OFFICIAL5 = 5, //
GROUP_OFFICIAL6 = 6, //
GROUP_OFFICIAL7 = 7, //
GROUP_OFFICIAL8 = 8, //
GROUP_BATTLE_SERVER = 9, // 배틀서버
// Rodin : MAX_GROUP_NUM을 8로 하면 로긴 서버가 릴리즈에서 죽습니다. 왜?!?!
MAX_GROUP_NUM = 10
};
enum Zone
{
NONE = 0,
ZONE1 = 1, // 그랜드 코스트
ZONE2 = 2, // 레한 스팟
ZONE3 = 3, // X 구 배틀그라운드 (현재 사용안함)
ZONE4 = 4, // 사이너 아일랜드
ZONE5 = 5, // 아일랜드 오브 페인
BATTLE_ZONE = 6, // X 배틀 존
ADMIN_TOOL_ZONE = 7, // X (클라이언트 사정으로 쓰이지 않음) - 운영툴이 사용하겠소.
CAPITAL = 8, // 카나번
ZONE9 = 9, // X 구 NEWZONE5 번인데 글로벌에서 사용해야하기 때문에 ZONE9로 이전후 제거
FRAG_ZONE = 10, // X 배틀 그라운드 전용 서버의 가상 존
BATTLE_SERVER = 11, // X 배틀 그라운드 전용 서버
ZONE12 = 12, // 신의 대지
STATUE_ZONE = 13, // X 배틀 그라운드 전용 서버의 가상 존
PRISON = 14, // 감옥 (감금 시스템)
CHAR_SELECT = 15, // X 캐릭터 선택 화면 존
STONE_WAR1 = 16, // 로우 40랩이하 석상전용
STONE_WAR2 = 17, // 로우 80랩이하 석상전용
STONE_WAR3 = 18, // 로우 80랩이상 석상전용
MAX_ZONE_NUM = 19
};
enum Channel
{
// sphawk : 채널 관련해서 고쳤습니다. 여기저기 복잡하게 흩어져 있으니 함부로 건들지 마세요.
// 고친 패킷은 다음과 같습니다.
// 1. 여기.
// 2. PktSCInfo (중계쪽에서도 사용하는 패킷입니다)
// 3. PktCSAck
// 4. PktSZMvAck
// 5. PktCSDAck (중계쪽에서도 사용하는 패킷입니다)
// 6. PktSZMvDAck (중계쪽에서도 사용하는 패킷입니다)
// SERVER_GROUP쪽은 채널이라고 써 있지만 실제로는 휴먼/아칸 의 인원수입니다.(중계 소스를 보면 압니다.)
// 착오 없으시길 바랍니다.
MAX_CHANNEL_NUM = 5
};
typedef struct SID* LPSID;
struct SID
{
char Type;
char Group;
char Channel;
char ID;
};
SID sID;
unsigned long dwID;
inline char GetType(void) { return sID.Type; }
inline char GetChannel(void) { return sID.Channel; }
inline char GetZone(void) { return sID.ID; }
inline char GetGroup(void) { return sID.Group; }
};
typedef struct SERVER* LPSERVER_GROUP;
struct SERVER_GROUP
{
enum { CHANNEL_NUM = 2, SERVER_NAME = 15 };
char m_Group; // 서버 그룹
char m_Name[SERVER_NAME]; // 서버 이름
long m_ClientNum[CHANNEL_NUM]; // 접속 자 수
IN_ADDR m_Address; // 서버 주소
};
typedef struct SERVER* LPSERVER_LIST;
struct SERVER_LIST
{
enum { SERVER_NUM = 10 };
unsigned short m_ServerNum; // 서버 숫자
SERVER_GROUP m_ServerGroup[SERVER_NUM]; // 서버 그룹
};
#pragma pack()
typedef struct RylServerInfo* LPRylServerInfo;
struct RylServerInfo
{
enum
{
GROUP_NAME_LENGTH = 120,
PATCH_ADDRESS_LENGTH = 100
};
SERVER_ID m_ServerUID;
IN_ADDR m_ServerAddress;
unsigned long m_dwClientVer;
unsigned long m_dwChecksum;
size_t m_nGroupNameLen;
size_t m_nPatchAddressLen;
char m_szGroupName[GROUP_NAME_LENGTH];
char m_szPatchAddress[PATCH_ADDRESS_LENGTH];
unsigned short m_usChannelClientNum[SERVER_GROUP::CHANNEL_NUM];
unsigned short m_usChannelNum;
RylServerInfo::RylServerInfo()
: m_dwClientVer(0), m_dwChecksum(0),
m_nPatchAddressLen(0), m_usChannelNum(0)
{
m_ServerUID.dwID = 0;
m_ServerAddress.S_un.S_addr = 0;
m_szPatchAddress[0] = '\0';
strncpy(m_szGroupName, "UnKnown", GROUP_NAME_LENGTH);
m_nGroupNameLen = strlen(m_szGroupName);
std::fill_n(m_usChannelClientNum, int(SERVER_GROUP::CHANNEL_NUM), 0);
}
};
#endif

View File

@@ -0,0 +1,34 @@
#ifndef _RYL_SERVER_NETWORK_SERVER_LOG_H_
#define _RYL_SERVER_NETWORK_SERVER_LOG_H_
#include <Network/Packet/PacketBase.h>
#pragma pack(1)
struct PktServerLog : public PktBase
{
enum LogType
{
ITEM_DUPLICATED_LOG = 0x01
};
unsigned char m_cLogCmd;
};
// ¾ÆÀÌÅÛ º¹»ç ·Î±×
struct PktItemDuplicated : public PktServerLog
{
enum { MAX_NAME = 16 };
char m_szName[MAX_NAME];
unsigned __int64 m_dwItemSerial;
unsigned long m_dwUID;
unsigned long m_dwCID;
unsigned long m_dwQty;
};
#pragma pack()
#endif

View File

@@ -0,0 +1,295 @@
#ifndef _DBAGENT_TO_LOGIN_
#define _DBAGENT_TO_LOGIN_
#include <DB/DBDefine.h>
#include <Network/Packet/PacketBase.h>
#include <Network/Packet/PacketStruct/DataPacket.h>
#pragma pack(1)
// 핑 패킷 ( 클라이언트 -> 서버로 5초마다.. 서버 - 서버간 통신도, 연결하는 쪽에서 Ping을 준다. )
typedef struct PktSyP* LPPktSyP;
struct PktSyP : public PktBase
{
unsigned long m_dwTickTime;
};
// 서비스 로그인 요청 패킷
typedef struct PktSL* LPPktSL;
struct PktSL : public PktBase
{
unsigned long m_dwServerID;
IN_ADDR m_Address;
};
// 서비스 로그인 응답 패킷
typedef struct PktSLAck* LPPktSLAck;
struct PktSLAck : public PktBase
{
enum { PATCH_ADDRESS_LENGTH = 100 };
unsigned __int64 m_dlItemUID;
unsigned long m_dwServerID;
unsigned long m_dwClientVer;
unsigned long m_dwCheckSum;
char m_PatchAddress[PATCH_ADDRESS_LENGTH];
};
// 서비스 버전 업데이트 정보
typedef struct PktSVU* LPPktSVU;
struct PktSVU : public PktBase
{
enum { PATCH_ADDRESS_LENGTH = 100 };
unsigned long m_dwServerID;
IN_ADDR m_ServerAddr;
unsigned long m_dwClientVer;
unsigned long m_dwCheckSum;
char m_PatchAddress[PATCH_ADDRESS_LENGTH];
};
// 채널 업데이트 정보
typedef struct PktSCInfo* LPPktSCInfo;
struct PktSCInfo : public PktBase
{
enum { MAX_CHANNEL_NUM = 5 };
unsigned long m_dwServerID;
unsigned char m_cChannelNum;
unsigned short m_usChannelClientNum[MAX_CHANNEL_NUM];
};
// ---------------------------------------------------------------------------
// 패치 정보 관련 패킷
// 패치 정보 요청 패킷
typedef struct PktSPI* LPPktSPI;
struct PktSPI : public PktBase
{
unsigned long m_dwServerID;
};
// 패치 서버 응답 패킷
typedef struct PktSPIAck* LPPktSPIAck;
struct PktSPIAck : public PktBase
{
enum { PATCH_ADDRESS_LENGTH = 100 };
unsigned long m_dwClientVer;
char m_PatchAddress[PATCH_ADDRESS_LENGTH];
};
// ---------------------------------------------------------------------------
// Zone 관련 패킷
// 서버존 선택
typedef struct PktSZ* LPPktSZ;
struct PktSZ : public PktBase
{
unsigned short m_cChannel;
unsigned char m_cZone;
};
// 서버존 선택 Ack
typedef struct PktSZAck* LPPktSZAck;
struct PktSZAck : public PktBase
{
unsigned long m_dwServerID;
sockaddr_in m_GameServerTCPAddr;
};
// 서버존 이동
typedef struct PktSZMv* LPPktSZMv;
struct PktSZMv : public PktBase
{
POS m_NewPos;
char m_cZone;
char m_cChannel;
};
// 서버존 선택 Ack
typedef struct PktSZMvAck* LPPktSZMvAck;
struct PktSZMvAck : public PktBase
{
enum { MAX_CHANNEL_NUM = 5 };
unsigned short m_wChannelNum[MAX_CHANNEL_NUM];
unsigned char m_cZone;
};
typedef struct PktSZMvD* LPPktSZMvD;
struct PktSZMvD : public PktDD
{
unsigned long m_dwUserID;
char m_cZone;
char m_cChannel;
POS m_NewPos;
};
typedef struct PktSZMvDAck* LPPktSZMvDAck;
struct PktSZMvDAck : public PktDD
{
enum
{
MAX_CHANNEL_NUM = 5
};
enum PktSZMvDAckErr
{
FAIL_INVALID_ZONE = 3,
FAIL_INVALID_CHAR = 5,
FAIL_PERSONNEL_OVER = 6,
FAIL_LIMIT_LEVEL = 7
};
unsigned char m_cZone;
unsigned short m_wChannelNum[MAX_CHANNEL_NUM];
};
// 서버 주소 얻기
typedef struct PktSA* LPPktSA;
struct PktSA : public PktDD
{
unsigned long m_dwUserID; // 유저 아이디
char m_cZone; // 존 번호
char m_cChannel; // 채널 번호
};
// 서버 주소 얻기 Ack
typedef struct PktSAAck* LPPktSAAck;
struct PktSAAck : public PktDD
{
enum PktSAAckErr
{
NO_SERVER_ERR = 0,
SERVER_ERROR = 1,
FAIL_USER_LIMIT = 4
};
unsigned long m_dwServerID;
IN_ADDR m_GameAddress;
};
// ---------------------------------------------------------------------------
// 유저 관련
// 유저 테이블 업데이트
typedef struct PktUUT *LPPktUUT;
struct PktUUT : public PktBase
{
enum UpdateType
{
UpdateUIDTableNone = 0, // 없음
UpdateUIDTableUserLogin = 1, // 유저 로그인
UpdateUIDTableUserLogout = 2, // 유저 로그아웃
UpdateUIDTableUserMove = 3, // 유저 이동
UpdateUIDTableCharLogin = 4, // 캐릭터 로그인
UpdateUIDTableCharLogout = 5, // 캐릭터 로그아웃
UpdateUIDTableCharMove = 6, // 캐릭터 이동
UpdateUIDTableBillingCheck = 7, // 빌링 체크
MAX_UPDATE_TYPE = 8
};
enum Err
{
DISCONNECT_USER = 1
};
enum
{
// edith 2008.03.17 ID,PASS 길이조정
MaxAccountLen = 24,
MaxPasswordLen = 36
};
unsigned char m_cCmd;
char m_strAccount[MaxAccountLen];
// edith 2008.01.15 패스워드 추가작업
char m_strPassword[MaxPasswordLen];
IN_ADDR m_IPAddress;
unsigned long m_dwSessionID;
unsigned long m_dwServerID;
unsigned long m_dwUserID;
unsigned long m_dwCharID;
};
typedef struct PktUUTAck *LPPktUUTAck;
struct PktUUTAck : public PktBase
{
unsigned char m_cCmd;
unsigned long m_dwUserID;
unsigned long m_dwFlag; // Success(=0)
int m_nPlayTime; // 현재 남은 시간 (일, 분)
unsigned long m_dwCRMIndex1; // 피시방 ID(0이면 개인유저)
char m_cstrBillingType; // D, T(N: 무료계정)
};
// 유저 죽이기.
typedef struct PktUK* LPPktUK;
struct PktUK : public PktBase
{
unsigned long m_dwUserID;
unsigned long m_dwCharID;
unsigned long m_dwServerID;
};
// 빌링 타임아웃 공지. (Billing Timeout Notify)
typedef struct PktBTN* LPPktBTN;
struct PktBTN : public PktBase
{
unsigned long m_dwUserID;
unsigned long m_dwCharID;
unsigned long m_dwServerID;
unsigned char m_cRemainMinute; // 남은 분..
unsigned char m_cBillingType; // 'D' 정액제 'T' 정량제
};
// 한게임 통합빌링 경고 메시지
typedef struct PktHanBTN* LPPktHanBTN;
struct PktHanBTN : public PktBase
{
enum
{
MAX_HAN_BTN = 70
};
unsigned long m_dwIP;
unsigned long m_dwUID;
unsigned long m_dwCID;
char m_szAccount[PktUUT::MaxAccountLen];
char m_szMsg[MAX_HAN_BTN];
};
// 한게임 통합빌링 접속 끊기 메시지(계정명 및, IP로)
typedef struct PktHanUserKill* LPPktHanUserKill;
struct PktHanUserKill : public PktBase
{
enum
{
DISCONN_ALL_IP = 0xFFFFFFFF
};
unsigned long m_dwIP;
char m_szAccount[PktUUT::MaxAccountLen];
};
#pragma pack()
#endif

View File

@@ -0,0 +1,99 @@
#ifndef _UNIFIED_CHAR_DATA_PACKET_H_
#define _UNIFIED_CHAR_DATA_PACKET_H_
#include <DB/DBdefine.h>
#include <Network/Packet/PacketBase.h>
namespace UnifiedConst
{
enum AgentServerType
{
// OldServerGroupID의 값으로도 사용한다. 0 ~ 10 은 예전 서버군 ID이다.
Part1 = 20,
Part1Unified = 21,
ROW = 22,
Part2Unified = 23,
Part2Selectable = 24,
};
enum StoreSelected
{
NONE_SELECTED = 0,
SELECTED_PART1 = (1 << 0),
SELECTED_PART2 = (1 << 1)
};
}
struct PktUnifiedCharInfo : public PktBase
{
enum
{
MAX_STORE_INFO = 10,
MAX_CHAR_DATA = 30
};
enum ErrorCode
{
STORE_READ_ERROR = 1,
CHARINFO_READ_ERROR = 2
};
unsigned long dwUID;
unsigned char cStoreInfoNum;
unsigned char cCharDataNum;
unsigned char cRestrictedPart1ToPart2Level; // Part1 에서 Part2 로 이전 가능한 캐릭터 레벨
unsigned char cRemainCharTransferCount; // Part1 에서 Part2 로 이전 가능한 횟수
USER_INFO userInfo;
UnifiedStoreInfo unifiedStoreInfo[MAX_STORE_INFO];
UnifiedCharData unifiedCharData[MAX_CHAR_DATA];
};
struct PktUnifiedCharSelectReq : public PktBase
{
enum
{
// edith 2008.03.17 ID,PASS 길이조정
MAX_PASSWORD_LEN = 36
};
char szPassword[MAX_PASSWORD_LEN]; // 계정 패스워드
unsigned char cSelectedServerGroupID; // 선택한 서버군 번호
unsigned char cSelectedNation; // 선택한 국적
unsigned long dwRequestKey; // RequestKey
unsigned long dwUID; // UID
unsigned long dwCID[USER_INFO::MAX_CHAR_NUM]; // 선택한 슬롯 번호에 CID를 채워 준다.
};
struct PktUnifiedCharSelectAck : public PktBase
{
enum ErrorCode
{
SERVER_ERROR = 1,
PACKET_ERROR = 2,
PASSWORD_FAILED = 3,
WRONG_STORE_SELECTED = 4, // 잘못된 창고 선택(내 소유 아닌것 선택)
WRONG_CHAR_SELECTED = 5, // 잘못된 캐릭터 선택(내 소유 아닌것 선택. 이미 선택한 것 선택)
UNIFIED_STORE_READ_ERROR = 6, // 선택한 창고 읽기 실패
UNIFIED_STORE_WRITE_ERROR = 7, // 선택한 창고 기록 실패
UNIFIED_CHAR_READ_ERROR = 8, // 캐릭터 선택 정보 읽기 실패
UNIFIED_CHAR_WRITE_ERROR = 9, // 캐릭터 선택 정보 기록 실패
CHAR_VIEW_RELOAD_ERROR = 10, // 캐릭터 뷰 리로드 실패
PART1_DB_LOGINED = 11, // Part1 DB에 로그인 해 있음
TRANSFER_COUNT_OVER = 12 // TransferCount가 일정 회수 이상 초과되어 있다.
};
unsigned long dwUID;
unsigned long dwRequestKey;
};
#endif

View File

@@ -0,0 +1,233 @@
#include "stdafx.h"
#include "WrapPacket.h"
#include "PacketStatistics.h"
#include <Log/ServerLog.h>
#include <Stream/Buffer/Buffer.h>
#include <Network/XORCrypt/XORCrypt.h>
#include <Utility/Compress/MiniLZO/MiniLZOWrapper.h>
bool PacketWrap::WrapHeader(CBuffer* lpBuffer_In, unsigned short usUsed_In, unsigned char cCMD_In,
unsigned short usState_In, unsigned short usError_In)
{
if (WrapHeader(lpBuffer_In->wr_ptr(), usUsed_In, cCMD_In, usState_In, usError_In))
{
lpBuffer_In->wr_ptr(usUsed_In);
return true;
}
return false;
}
bool PacketWrap::WrapCryptOld(CBuffer* lpBuffer_In, unsigned short usUsed_In, unsigned char cCMD_In,
unsigned short usState_In, unsigned short usError_In)
{
if (WrapCryptOld(lpBuffer_In->wr_ptr(), usUsed_In, cCMD_In, usState_In, usError_In))
{
lpBuffer_In->wr_ptr(usUsed_In);
return true;
}
return false;
}
bool PacketWrap::WrapCrypt(CBuffer* lpBuffer_In, unsigned short usUsed_In, unsigned char cCMD_In,
unsigned short usState_In, unsigned short usError_In)
{
if (WrapCrypt(lpBuffer_In->wr_ptr(), usUsed_In, cCMD_In, usState_In, usError_In))
{
lpBuffer_In->wr_ptr(usUsed_In);
return true;
}
return false;
}
bool PacketWrap::WrapCompress(CBuffer* lpDstBuffer, const char* lpSourceData, unsigned short usSourceLength,
unsigned char cCMD_In, unsigned short usState_In, unsigned short usError_In)
{
char* lpBuffer = lpDstBuffer->wr_ptr();
unsigned long dwDstBufferSize_InOut = static_cast<unsigned long>(lpDstBuffer->remain());
if (WrapCompress(lpBuffer, dwDstBufferSize_InOut,
lpSourceData, usSourceLength, cCMD_In, usState_In, usError_In))
{
// 압축된 길이를 알아야 하기 때문.
lpDstBuffer->wr_ptr(dwDstBufferSize_InOut);
return true;
}
return false;
}
bool PacketWrap::WrapHeader(char* lpBuffer_In, unsigned short usUsed_In,
unsigned char cCMD_In, unsigned short usState_In, unsigned short usError_In)
{
reinterpret_cast<PktBase*>(lpBuffer_In)->InitPtHead(usUsed_In, cCMD_In, usState_In, usError_In);
CXORCrypt::GetInstance().EncodeHeader(lpBuffer_In + 1, sizeof(PktBase) - 1, 0, 0);
return true;
}
bool PacketWrap::WrapCryptOld(char* lpBuffer_In, unsigned short usUsed_In,
unsigned char cCMD_In, unsigned short usState_In, unsigned short usError_In)
{
CXORCrypt& Crypt = CXORCrypt::GetInstance();
unsigned long dwCodePage = Crypt.GetCodePage(1);
if(Crypt.EncodePacket(lpBuffer_In + sizeof(PktBase), usUsed_In - sizeof(PktBase), dwCodePage))
{
PktBase* lpPktBase = reinterpret_cast<PktBase*>(lpBuffer_In);
lpPktBase->InitPtHead(usUsed_In, cCMD_In, usState_In, usError_In);
lpPktBase->SetCodePage(dwCodePage);
lpPktBase->SetCrypt();
// 헤더 인코딩
Crypt.EncodeHeader(lpBuffer_In + 1, sizeof(PktBase) - 1, 0, 0);
return true;
}
return false;
}
bool PacketWrap::WrapCryptOld(char* lpBuffer_In, unsigned short usUsed_In,
unsigned char cCMD_In, unsigned long dwTick)
{
CXORCrypt& Crypt = CXORCrypt::GetInstance();
unsigned long dwCodePage = Crypt.GetCodePage(1);
if(Crypt.EncodePacket(lpBuffer_In + sizeof(PktBase), usUsed_In - sizeof(PktBase), dwCodePage))
{
PktBase* lpPktBase = reinterpret_cast<PktBase*>(lpBuffer_In);
lpPktBase->InitPtHead(usUsed_In, cCMD_In, dwTick);
lpPktBase->SetCodePage(dwCodePage);
lpPktBase->SetCrypt();
// 헤더 인코딩
Crypt.EncodeHeader(lpBuffer_In + 1, sizeof(PktBase) - 1, 0, 0);
return true;
}
return false;
}
bool PacketWrap::WrapCrypt(char* lpBuffer_In, unsigned short usUsed_In,
unsigned char cCMD_In, unsigned short usState_In, unsigned short usError_In)
{
CXORCrypt& Crypt = CXORCrypt::GetInstance();
unsigned long dwCodePage = Crypt.GetCodePage();
if(Crypt.EncodePacket(lpBuffer_In + sizeof(PktBase), usUsed_In - sizeof(PktBase), dwCodePage))
{
PktBase* lpPktBase = reinterpret_cast<PktBase*>(lpBuffer_In);
lpPktBase->InitPtHead(usUsed_In, cCMD_In, usState_In, usError_In);
lpPktBase->SetCodePage(dwCodePage);
lpPktBase->SetCrypt();
// 헤더 인코딩
Crypt.EncodeHeader(lpBuffer_In + 1, sizeof(PktBase) - 1, 0, 0);
return true;
}
return false;
}
bool PacketWrap::WrapCrypt(char* lpBuffer_In, unsigned short usUsed_In,
unsigned char cCMD_In, unsigned long dwTick)
{
CXORCrypt& Crypt = CXORCrypt::GetInstance();
unsigned long dwCodePage = Crypt.GetCodePage();
if(Crypt.EncodePacket(lpBuffer_In + sizeof(PktBase), usUsed_In - sizeof(PktBase), dwCodePage))
{
PktBase* lpPktBase = reinterpret_cast<PktBase*>(lpBuffer_In);
lpPktBase->InitPtHead(usUsed_In, cCMD_In, dwTick);
lpPktBase->SetCodePage(dwCodePage);
lpPktBase->SetCrypt();
// 헤더 인코딩
Crypt.EncodeHeader(lpBuffer_In + 1, sizeof(PktBase) - 1, 0, 0);
return true;
}
return false;
}
bool PacketWrap::WrapCompress(char* lpDstBuffer, unsigned long& dwDstBufferSize_InOut,
const char* lpSourceData, unsigned short usSourceLength,
unsigned char cCMD_In, unsigned short usState_In, unsigned short usError_In)
{
if(usSourceLength < sizeof(PktBase) || PktMaxLen < usSourceLength)
{
// 패킷 크기가 헤더 크기보다 작거나, 소스 크기가 최대 패킷 길이보다 큰 경우
ERRLOG2(g_Log, "Cmd:0x%02x Invalid packet size, Can't compress now.",
reinterpret_cast<const PktBase*>(lpSourceData)->GetCmd(), usSourceLength);
}
else if(dwDstBufferSize_InOut < usSourceLength)
{
// 압축할 버퍼 크기가 소스 크기보다 작은 경우
SERLOG1(g_Log, "Cmd:0x%02x Insufficient buffer size, Can't compress now.",
reinterpret_cast<const PktBase*>(lpSourceData)->GetCmd());
}
else
{
unsigned long dwArchiveSrcLen = usSourceLength - sizeof(PktBase);
unsigned long dwArchiveDstLen = dwDstBufferSize_InOut - sizeof(PktBase);
bool bCompressResult =
CMiniLZO::Compress(lpSourceData + sizeof(PktBase), dwArchiveSrcLen,
lpDstBuffer + sizeof(PktBase), &dwArchiveDstLen);
// 전체 버퍼 크기를 맞춘다.
dwArchiveDstLen += sizeof(PktBase);
if (!bCompressResult)
{
// 압축 실패 로그를 남긴다.
SERLOG2(g_Log, "Cmd:0x%02x Packet compress failed. Packet length is %d.",
reinterpret_cast<const PktBase*>(lpSourceData)->GetCmd(), usSourceLength);
}
else
{
// 압축후 패킷 통계를 낸다. 패킷 커맨드, 원본 크기, 압축본 크기를 넘긴다.
CPacketStatistics::GetInstance().CheckCompression(cCMD_In,
usSourceLength, dwArchiveDstLen);
}
if (!bCompressResult || usSourceLength <= dwArchiveDstLen)
{
// 압축에 실패했거나, 압축한 후 크기가 같거나, 오히려 더 커진 경우이다
// 데이터를 복사한 후에, WrapCrypt로 다시 작업한다.
memcpy(lpDstBuffer, lpSourceData, usSourceLength);
dwDstBufferSize_InOut = usSourceLength;
return PacketWrap::WrapCrypt(lpDstBuffer, usSourceLength,
cCMD_In, usState_In, usError_In);
}
else
{
PktBase* lpPktDst = reinterpret_cast<PktBase*>(lpDstBuffer);
lpPktDst->InitPtHead(static_cast<PktBase::LengthType>(dwArchiveDstLen),
cCMD_In, usState_In, usError_In);
lpPktDst->SetCompress();
// 헤더 인코딩
CXORCrypt::GetInstance().EncodeHeader(lpDstBuffer + 1, sizeof(PktBase) - 1, 0, 0);
dwDstBufferSize_InOut = dwArchiveDstLen;
return true;
}
}
return false;
}

View File

@@ -0,0 +1,45 @@
#ifndef _WRAP_PACKET_
#define _WRAP_PACKET_
#include "PacketBase.h"
#include <Stream/Buffer/Buffer.h>
namespace PacketWrap
{
// WrapHeader
bool WrapHeader(CBuffer* lpBuffer_In, unsigned short usUsed_In,
unsigned char cCMD_In, unsigned short usState_In, unsigned short usError_In);
bool WrapHeader(char* lpBuffer_In, unsigned short usUsed_In,
unsigned char cCMD_In, unsigned short usState_In, unsigned short usError_In);
// WrapCrypt Old
bool WrapCryptOld(CBuffer* lpBuffer_In, unsigned short usUsed_In,
unsigned char cCMD_In, unsigned short usState_In, unsigned short usError_In);
bool WrapCryptOld(char* lpBuffer_In, unsigned short usUsed_In,
unsigned char cCMD_In, unsigned short usState_In, unsigned short usError_In);
bool WrapCryptOld(char* lpBuffer_In, unsigned short usUsed_In,
unsigned char cCMD_In, unsigned long dwTick);
// WrapCrypt
bool WrapCrypt(CBuffer* lpBuffer_In, unsigned short usUsed_In,
unsigned char cCMD_In, unsigned short usState_In, unsigned short usError_In);
bool WrapCrypt(char* lpBuffer_In, unsigned short usUsed_In,
unsigned char cCMD_In, unsigned short usState_In, unsigned short usError_In);
bool WrapCrypt(char* lpBuffer_In, unsigned short usUsed_In,
unsigned char cCMD_In, unsigned long dwTick);
// WrapCompress
bool WrapCompress(CBuffer* lpDstBuffer, const char* lpSourceData, unsigned short usSourceLength,
unsigned char cCMD_In, unsigned short usState_In, unsigned short usError_In);
bool WrapCompress(char* lpDstBuffer, unsigned long& dwDstBufferSize_InOut,
const char* lpSourceData, unsigned short usSourceLength,
unsigned char cCMD_In, unsigned short usState_In, unsigned short usError_In);
};
#endif