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

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,367 @@
///////////////////////////////////////////////////////////////////////////////////////////////
//
// ClientSocket Class
//
// Last Update : 2003-01-10
//
///////////////////////////////////////////////////////////////////////////////////////////////
#ifndef _ClientSocket
#define _ClientSocket
#include "NetBase.h"
#include "UDPList/UDPList.h" // 클라이언트 리스트
#include <Network/Packet/PacketStruct/FriendPacket.h>
#include <Network/Packet/PacketStruct/CharItemPacket.h>
#include <Network/Packet/PacketStruct/CharStatusPacket.h>
#include <Network/Packet/PacketStruct/CharAttackPacket.h>
#include <Network/Packet/PacketStruct/CharCommunityPacket.h>
#include <DB/DBDefine.h>
const unsigned long WM_CLIENT_SOCKET = RegisterWindowMessage("WM_CLIENT_SOCKET");
const unsigned long WM_UDP_SOCKET = RegisterWindowMessage("WM_UDP_SOCKET");
//////////////////////////////////////////////////////////////////////////////////////////////
//
// 클래스 정의
//
///////////////////////////////////////////////////////////////////////////////////////////////
class ClientSocket : public NetBase
{
public:
enum CO_SRV { CO_GAME = 0, CO_AUTH = 1 };
enum ListType { ListType_Client = 1, ListType_Party = 2 };
enum ListOper { ListOper_Update = 1, ListOper_Insert = 2 };
enum BindPos { Bind_SavePos = 1 };
enum Hand { Hand_Weapon1 = 1, Hand_Weapon2 = 2 };
enum FameInfoType { FameInfoType_Fame = 1, FameInfoType_Merits = 2 };
enum Require { Require_HPInfo = 0, Require_UDPInfo = 1, Require_Shape = 2 };
enum ChatType
{
ChatType_Normal = 0, ChatType_Party = 1, ChatType_Friend = 2,
ChatType_Guild = 3, ChatType_Notify = 4, ChatType_ClientLog = 5,
ChatType_Stall = 6
};
enum CellOper
{
CellOper_Move = 0, CellOper_Login = 1,
CellOper_Logout = 1, CellOper_Respawn = 2
};
enum ItemPos
{
ItemPos_None = 0, ItemPos_Equip = 1, ItemPos_Inven = 2,
ItemPos_QSlot = 3, ItemPos_SSlot = 4, ItemPos_Temp = 6,
ItemPos_Upgrade = 7, ItemPos_Exchange = 8, ItemPos_Deposit = 9,
ItemPos_Stall = 10
};
enum PartyCmd
{
PartyCmd_Invite = 0, PartyCmd_Accept = 1, PartyCmd_Refuse = 2,
PartyCmd_Banish = 3, PartyCmd_Secession = 4, PartyCmd_Transfer = 5,
PartyCmd_Destroy = 6, PartyCmd_Login = 7, PartyCmd_Logout = 8,
PartyCmd_Delete = 9, PartyCmd_ReLogin = 10, PartyCmd_FindParty = 11,
PartyCmd_FindMember = 12
};
enum StateType
{
StateType_STR = 1, StateType_DEX = 2, StateType_CON = 3,
StateType_INT = 4, StateType_WIS = 5
};
enum Judge
{
Judge_Front = 0, Judge_Side = 1, Judge_Back = 2,
Judge_Guard = 3, Judge_Critical = 4, Judge_Heal = 5,
Judge_ManaHeal = 6, Judge_Chant = 7, Judge_Enchant = 8,
Judge_Disenchant = 9, Judge_Evade = 10, Judge_Resist = 11,
Judge_ManaShell = 12, Judge_Poisoned = 13
};
enum ExchangeCmd
{
ExchangeCmd_Propose = 0, ExchangeCmd_Accept = 1, ExchangeCmd_Refuse = 2,
ExchangeCmd_OK = 3, ExchangeCmd_Cancel = 4, ExchangeCmd_Exchange = 5,
ExchangeCmd_Quit = 6, ExchangeCmd_Lock = 7, ExchangeCmd_UnLock = 8
};
enum DuelCmd
{
DuelCmd_Propose = 0, DuelCmd_Ready = 1, DuelCmd_Refuse = 2,
DuelCmd_Logout = 3, DuelCmd_Dead = 4, DuelCmd_PartyPropose = 5,
DuelCmd_PartyReady = 6, DuelCmd_RequestPartyInfo = 7, DuelCmd_Cancel = 8
};
enum SpellType
{
SpellType_None = 0,
// Chant
SpellType_BattleSong = 1,
SpellType_MaintenanceChant = 2,
SpellType_AccelerationChant = 3,
SpellType_LifeAura = 4,
// Enchant
SpellType_Stealth = 17, SpellType_ManaShell = 18,
SpellType_Encourage = 19, SpellType_EnchantWeapon = 20,
SpellType_BrightArmor = 21, SpellType_HardenSkin = 22,
SpellType_Flexibility = 23, SpellType_Guard = 24,
SpellType_Hold = 25, SpellType_Stun = 26,
SpellType_Frozen = 27, SpellType_Poisoned = 28,
SpellType_LowerStrength = 29,
// Other
SpellType_Invincible = 30
};
enum StallCmd
{
StallCmd_Register = 0, StallCmd_ChangePrice = 1, StallCmd_Cancel = 2
};
enum AdminCmd
{
MoveZoneChar = 1, MoveZoneParty = 2, MoveChar = 3, MoveParty = 4,
RespawnChar = 5, RespawnParty = 6, KillChar = 7, KillParty = 8,
DuelInit = 9, CreateItem = 10, CreateMon = 11, InfoChar = 12
};
private:
HWND m_hMainWnd;
IN_ADDR m_RegAddress;
void* m_RegPointer;
SOCKADDR_IN m_PubUDPAddress;
SOCKADDR_IN m_PriUDPAddress;
SOCKADDR_IN m_UDPAgentAddress;
DWORD m_UpdateCount;
int m_ConnectServer;
public:
SOCKADDR_IN m_GSSUDPAddress;
UDPList* m_ClientList;
UDPList* m_PartyList;
UDPList* m_InstanceClientList;
///////////////////////////////////////////////////////////////////////////////////////////////
//
// ClientSocket 기본 클래스 메소드
//
///////////////////////////////////////////////////////////////////////////////////////////////
public:
ClientSocket(HWND hWnd_In);
virtual ~ClientSocket(void);
inline IN_ADDR GetRegAddress(void) { return m_RegAddress; }
inline char* GetRegString(void) { return inet_ntoa(m_RegAddress); }
inline bool IsEmptyRegAddress(void) { return (0 == m_RegAddress.S_un.S_addr) ? true : false; }
inline void CrearRegAddress(void) { memset(&m_RegAddress, 0, sizeof(SOCKADDR_IN)); }
inline SOCKADDR_IN GetPubAddress(void) { return m_PubUDPAddress; }
inline SOCKADDR_IN GetPriAddress(void) { return m_PriUDPAddress; }
inline SOCKADDR_IN GetUDPAddress(void) { return m_UDPAgentAddress; }
inline int GetConnectServer() { return m_ConnectServer; }
DWORD InsertIntoAddressList(unsigned short List_In, DWORD CharID_In, SOCKADDR_IN PubAddress_In, SOCKADDR_IN PriAddress_In);
bool DeleteFromAddressList(unsigned short List_In, DWORD CharID_In);
bool DeleteFromAddressList(unsigned short List_In, SOCKADDR_IN Address_In);
bool IsExistToList(unsigned short List_In, DWORD CharID_In);
DWORD GetListCount(unsigned short List_In);
bool RegistInstanceUDPList(DWORD CharID_In);
void DeleteInstanceUDPList();
bool IsRealIP(void);
PEERTYPE GetPeerType(SOCKADDR_IN PubAddress_In, SOCKADDR_IN PriAddress_In);
bool UDPSendList(WSABUF &SendBuf_In, UDPList* lpList_In);
bool UDPSendList(WSABUF &SendBuf_In, UDPList* lpList_In, DWORD CharID_In);
bool UDPRecv(void);
bool ConnectToAuthServer(char *Address_In);
bool ConnectToGameServer(char *Address_In);
bool Disconnect(void);
bool SendSysPing(void);
bool CharMoveZone(char Zone_In, POS& NewPos_In);
DWORD HandleCharMoveZone(char *pBuffer_In, unsigned char *Zone_Out, unsigned short *lpChannelNum_Out);
bool ServerZone(char Zone_In, char Channel_In);
DWORD HandleServerZone(char *pBuffer_In, DWORD *ServerID_Out);
bool UserLogin(DWORD SessionID_In, DWORD UserID_In, DWORD ServerID_In, DWORD ClientVer_In);
bool CharSelect(DWORD UserID_In, DWORD CharID_In);
bool CharCreate(DWORD UserID_In, DWORD SlotNum_In, CHAR_CREATE &Create_In);
bool CharDelete(DWORD UserID_In, DWORD CharID_In, DWORD SlotNum_In);
DWORD HandleUserLogin(char *pBuffer_In, DWORD *UserID_Out, LPCHAR_VIEW CharRecode_Out);
DWORD HandleCharSelect(char *pBuffer_In, unsigned char *Zone_Out, unsigned short *lpChannelNum_Out);
DWORD HandleCharCreate(char *pBuffer_In, DWORD *CharID_Out, DWORD *SlotNum_Out, LPCHAR_VIEW lpCharView_Out);
DWORD HandleCharDelete(char *pBuffer_In, DWORD *UserID_Out, DWORD *SlotNum_Out);
bool CharLogin(DWORD UserID_In, DWORD CharID_In, DWORD SessionID_In);
bool CharLogout(DWORD CharID_In);
bool CharUpdateAddress(DWORD CharID_In);
bool CharAddressInfo(DWORD CharID_In, DWORD TargetID_In);
bool CharRequireInfo(DWORD SenderID_In, DWORD TargetID_In, unsigned char Cmd_In);
bool CharMove(DWORD CharID_In, LPPOS Pos_In, float Dir_In, unsigned short UAct_In, unsigned short LAct_In, char Level_In, DWORD ChantEf_In, DWORD EnchantEf_In);
bool CharMoveUpdate(DWORD CharID_In, bool SitMode_In, LPPOS Pos_In, float Dir_In);
bool CharChat(DWORD CharID_In, unsigned short Cmd_In, char* Message_In, int MessageSize_In);
bool CharWhisper(char* SenderName_In, char *RecverName_In, char* Message_In, int MessageSize_In);
bool CharAttack(DWORD CharID_In, LPPOS lpPos_In, float Dir_In, AtType &AtType_In, AtNode &AtNode_In);
bool CharAttackInfo(DWORD CharID_In, AtType &AtType_In, unsigned char DefenserNum_In, LPDefenserNode lpNode_In);
bool CharRespawn(DWORD CharID_In, unsigned char cCmd_In, POS& Pos_In);
bool CharShapeInfo(LPCHAR_VIEW lpCharView_In, unsigned char cSelectedHands_In, unsigned long dwStatusFlag_In, char *StallName_In);
bool CharShapeInfo(DWORD CharID_In, LPCHAR_VIEW lpCharView_In, unsigned char cSelectedHands_In, unsigned long dwStatusFlag_In, char *StallName_In);
bool CharPickUp(DWORD CharID_In, DWORD ObjectID_In, Item::ItemPos Index_In);
bool CharPullDown(DWORD CharID_In, Item::ItemPos Index_In, unsigned char cNum);
bool CharTakeItem(DWORD CharID_In, TakeType TakeType_In);
bool CharSwapItem(DWORD CharID_In, TakeType SrcType_In, TakeType DstType_In);
bool CharTradeItem(DWORD CharID_In, DWORD NPCID_In, unsigned short ItemID_In, TakeType TakeType_In);
bool CharRepairItem(DWORD NPCID_In, Item::ItemPos* lpIndex_In, DWORD Gold_In);
bool CharUseItem(DWORD SenderID_In, DWORD Recver_In, Item::ItemPos* lpIndex_In);
bool CharCastObject(DWORD SenderID_In, DWORD RecverID_In, CastObject &CastObject_In);
bool CharCastObjectInfo(DWORD SenderID_In, DWORD RecverID_In, CastObject &CastObject_In);
bool CharInstallSocket(DWORD CharID_In, Item::ItemPos* lpEquipIndex_In, Item::ItemPos* lpSocket_In);
bool CharSuicide(DWORD CharID_In);
bool CharBindPos(DWORD NPCID_In, unsigned char Cmd_In, LPPOS lpPos_In, char Zone_In);
bool CharIncreasePoint(DWORD CharID_In, unsigned char StateType_In);
bool CharClassUpgrade(DWORD CharID_In, unsigned char ClassID_In);
bool CharSkillLock(DWORD CharID_In, unsigned short SkillID_In, unsigned char Index_In);
bool CharSkillUnLock(DWORD CharID_In, unsigned short SkillID_In, unsigned char Index_In, Item::ItemPos* lpIndex_In);
bool CharSkillCreate(DWORD CharID_In, unsigned short SkillID_In, unsigned char Index_In);
bool CharSkillErase(DWORD CharID_In, unsigned short SkillID_In, unsigned char Index_In);
bool CharPartyCmd(DWORD SenderID_In, DWORD ReferenceID_In, DWORD PartyID_In, unsigned short Cmd_In);
bool CharPartyMemInfo(DWORD CharID_In, DWORD PartyID_In, unsigned char Class_In, char Level_In, unsigned short MaxHP_In, short CurHP_In, unsigned short MaxMP_In, short CurMP_In, DWORD Chant_In, DWORD Enchant_In);
bool CharPartyFind(DWORD CharID_In);
bool CharUpgradeItem(DWORD CharID_In, unsigned char MineralNum_In);
bool CharLevelUpInfo(DWORD CharID_In, unsigned char Level_In);
bool CharSplitItem(DWORD CharID_In, TakeType &TakeType_In);
bool CharQuickSlotMove(TakeType &TakeType_In);
bool CharSwitchHand(unsigned char SelectHand_In);
bool CharTakeItems(DWORD CharID_In, unsigned char TakeNum_In, LPTakeType lpTakeTypes_In);
bool CharTakeGold(DWORD CharID_In, unsigned char SrcPos_In, unsigned char DstPos_In, DWORD Gold_In);
bool CharExchangeCmd(DWORD SenderID_In, DWORD RecverID_In, unsigned char Cmd_In);
bool CharPartyData(DWORD CharID_In, unsigned short Cmd_In, unsigned short Len_In, void *Data_In);
bool CharControlOption(DWORD CharID_In, RejectOption &Reject_In);
bool CharDuelCmd(DWORD SenderID_In, DWORD RecverID_In, unsigned char Cmd_In);
bool CharFameInfo(DWORD CharID_In, unsigned char Cmd_In);
// 노점상
bool CharStallOpen(DWORD CharID_In, char* StallName_In);
bool CharStallRegisterItem(DWORD CharID_In, TakeType TakeType_In, unsigned long Price_In, unsigned char Cmd_In);
bool CharStallEnter(DWORD CustomerID_In, DWORD Owner_In);
// 친구 관련
bool CharFriendAddRequest(char* szName_In, PktFriendAddReq::CMD addType);
bool CharFriendRemoveRequest(unsigned long dwCID, PktFriendRemoveReq::CMD removeType);
bool CharFriendEtcRequest(unsigned long dwCID, unsigned long dwData, PktFriendEtc::CMD etcType);
bool StoreLogin(char *Password_In, char PassSave_In);
bool StoreLogout(void);
bool StoreBuyTab(char TabNum_In);
bool StoreChangePass(char *Password_In, char *NewPassword_In);
bool CharAdmin(unsigned short Cmd_In, char* Name_In, char Zone_In, char Channel_In, unsigned short ProtoTypeID, POS& Pos_In);
DWORD HandleDeposit(char *pBuffer_In, unsigned char *Cmd_Out, DWORD *Gold_Out, char *PassSave_Out);
DWORD HandleCharLogin(char *pBuffer_In, char *Admin_Out, LPCHAR_INFOST lpCharInfo_Out, LPSKILL lpSkill_Out, LPQUICK lpQuick_Out, LPCHAR_POS lpPos_Out, DWORD *ServerTime_Out,
unsigned short *EquipSize_Out, char **lppEquipBuff_Out, unsigned short *InvenSize_Out, char **lppInvenBuff_Out, unsigned short *ExtraSize_Out, char **lppExtraBuff_Out, unsigned short *ExchangeSize_Out, char **lppExchangeBuff_Out);
DWORD HandleCharLogout(char *pBuffer_In, DWORD *CharID_Out);
DWORD HandleDepositUpdate(char *pBuffer_In, DWORD *Flag_Out, unsigned char *TabNum_Out, bool *Complete_Out, unsigned short *StoreSize_Out, char **lppStoreBuff_Out);
DWORD HandleCharUpdateAddress(char *pBuffer_In);
DWORD HandleCharAddressInfo(char *pBuffer_In, DWORD *CharID_Out, SOCKADDR_IN* PubAddress_Out, SOCKADDR_IN* PriAddress_Out);
DWORD HandleCharRequireInfo(char *pBuffer_In, DWORD *CharID_Out, SOCKADDR_IN* PubAddress_Out, SOCKADDR_IN* PriAddress_Out, unsigned char *Cmd_Out);
DWORD HandleCharMove(char *pBuffer_In, DWORD *CharID_Out, LPPOS Pos_Out, float *Dir_Out, unsigned short *UAct_Out, unsigned short *LAct_Out, char *Level_Out, DWORD *ChantEf_Out, DWORD *EnchantEf_Out, DWORD *PtCount_Out);
DWORD HandleCharChat(char *pBuffer_In, DWORD *CharID_Out, unsigned short *Cmd_Out, char *Message_Out);
DWORD HandleCharWhisper(char *pBuffer_In, char *SenderName_Out, char *RecverName_Out, char *Message_Out);
DWORD HandleCharCellLogin(char *pBuffer_In, DWORD *CharID_Out, LPPOS Pos_Out, SOCKADDR_IN* PubAddress_Out, SOCKADDR_IN* PriAddress_Out, unsigned char *Cmd_Out);
DWORD HandleCharCellLogout(char *pBuffer_In, DWORD *CharID_Out, unsigned char *Cmd_Out);
DWORD HandleMonMove(char *pBuffer_In, DWORD *MonID_Out, LPPOS lpPos_Out, float *Dir_Out, float *Vec_Out, unsigned short *Act_Out, unsigned short *AniNum_Out);
DWORD HandleCharAttack(char *pBuffer_In, DWORD *CharID_Out, LPAtType lpAtType_Out, unsigned short *HP_Out, unsigned short *MP_Out, DWORD *RightIndex_Out, DWORD *RightValue_Out, DWORD *LeftIndex_Out, DWORD *LeftValue_Out, char *Judge_Out, unsigned char *DefenserNum_Out, LPDefenserNode *lppNode_Out);
DWORD HandleCharAttackInfo(char *pBuffer_In, DWORD *CharID_Out, LPAtType lpAtType_Out, unsigned char *DefenserNum_Out, LPDefenserNode *lppNode_Out);
DWORD HandleCharRespawn(char *pBuffer_In, DWORD *CharID_Out, unsigned short *HP_Out, unsigned short *MP_Out, LPPOS lpPos_Out, __int64 *Exp_Out);
DWORD HandleCharAttacked(char *pBuffer_In, DWORD *AtCharID_Out, AtType *AtType_Out, LPPOS lpAtPos_Out, float *AtDir_Out, unsigned short *Judge_Out, unsigned short *MyHP_Out, unsigned short *MyMP_Out, unsigned char *MyIndex_Out, unsigned char *MyValue_Out);
DWORD HandleCharAward(char *pBuffer_In, DWORD *CharID_Out, DWORD *Exp_Out);
DWORD HandleCharShapeInfo(char *pBuffer_In, LPCHAR_VIEW lpCharView_Out, unsigned char *cSelectedHands_Out, unsigned long *dwStatusFlag_Out, char *StallName_Out);
DWORD HandleCharPickUp(char *pBuffer_In, DWORD *CharID_Out, DWORD *ObjectID_Out, Item::ItemPos* lpIndex_Out, DWORD *Gold_Out, DWORD *Size_Out, unsigned char* cNum_Out, char **lppBuffer_Out);
DWORD HandleCharPickUpInfo(char *pBuffer_In, DWORD *CharID_Out, DWORD *ObjectID_Out);
DWORD HandleCharPullDown(char *pBuffer_In, DWORD *CharID_Out, Item::ItemPos* lpIndex_Out, LPFieldObject lpFieldObject_Out);
DWORD HandleCharPullDownInfo(char *pBuffer_In, DWORD *CharID_Out, LPFieldObject lpFieldObject_Out);
DWORD HandleGameCellInfo(char *pBuffer_In, unsigned char *ObjectNum_Out, LPFieldObject *lppFieldObject_Out);
DWORD HandleCharTakeItem(char *pBuffer_In, DWORD *CharID_Out, LPTakeType lpTakeType_Out);
DWORD HandleCharSwapItem(char *pBuffer_In, DWORD *CharID_Out, LPTakeType lpSrcType_Out, LPTakeType lpDstType_Out);
DWORD HandleCharTradeItem(char *pBuffer_In, DWORD *CharID_Out, DWORD *NPCID_Out, unsigned char *Pos_Out, Item::ItemPos* lpIndex_Out, unsigned char *Num_Out, DWORD *Gold_Out, unsigned short *Size_Out, char **lppBuffer_Out);
DWORD HandleCharRepairItem(char *pBuffer_In, DWORD *CharID_Out, Item::ItemPos* lpIndex_Out, DWORD *Gold_Out);
DWORD HandleCharUseItem(char *pBuffer_In, DWORD *SenderID_Out, DWORD *Recver_Out, Item::ItemPos* lpIndex_Out);
DWORD HandleCharCastObject(char *pBuffer_In, DWORD *SenderID_Out, DWORD *RecverID_Out, LPCastObject lpCastObject);
DWORD HandleCharCastObjectInfo(char *pBuffer_In, DWORD *SenderID_Out, DWORD *RecverID_Out, LPCastObject lpCastObject);
DWORD HandleCharInstallSocket(char *pBuffer_In, DWORD *CharID_Out, Item::ItemPos* lpEquipIndex_Out, Item::ItemPos* lpSocket_Out, unsigned short *Size_Out, char **lppBuffer_Out);
DWORD HandleCharSuicide(char *pBuffer_In, DWORD *CharID_Out, LPPOS lpPos_Out);
DWORD HandleCharBindPos(char *pBuffer_In, DWORD *NPCID_Out, unsigned char *Cmd_Out, LPPOS lpPos_Out, char *Zone_Out);
DWORD HandleCharLevelUp(char *pBuffer_In, DWORD *CharID_Out, unsigned char *Level_Out, LPChState lpChState_Out);
DWORD HandleCharIncreasePoint(char *pBuffer_In, DWORD *CharID_Out, LPChState lpChState_Out);
DWORD HandleCharClassUpgrade(char *pBuffer_In, DWORD *CharID_Out, unsigned short *ClassID_Out, LPChState lpState_Out, char *Index_Out, unsigned short *Skill_Out);
DWORD HandleCharSkillLock(char *pBuffer_In, DWORD *CharID_Out, unsigned short *SkillID_Out, unsigned char *Index_Out);
DWORD HandleCharSkillUnLock(char *pBuffer_In, DWORD *CharID_Out, unsigned short *SkillID_Out, unsigned char *Index_Out, Item::ItemPos* lpIndex_Out, unsigned long *Gold_Out);
DWORD HandleCharSkillCreate(char *pBuffer_In, DWORD *CharID_Out, unsigned short *SkillID_Out, unsigned char *Index_Out);
DWORD HandleCharSkillErase(char *pBuffer_In, DWORD *CharID_Out, unsigned short *SkillID_Out, unsigned char *Index_Out);
DWORD HandleCharPartyInfo(char *pBuffer_In, LPPARTY lpParty_Out);
DWORD HandleCharPartyCmd(char *pBuffer_In, LPAddressInfo SenderAddress_Out, char *SenderName_Out, DWORD *SenderID_Out, DWORD *ReferenceID_Out, DWORD *PartyID_Out, unsigned short *Cmd_Out);
DWORD HandleCharPartyCmdInfo(char *pBuffer_In, DWORD *MemberID_Out, DWORD *PartyID_Out, unsigned short *Cmd_Out);
DWORD HandleCharPartyMemInfo(char *pBuffer_In, DWORD *CharID_Out, DWORD *PartyID_Out, unsigned char *Class_Out, char *Level_Out, unsigned short *MaxHP_Out, unsigned short *CurHP_Out, unsigned short *MaxMP_Out, unsigned short *CurMP_Out, DWORD *Chant_Out, DWORD *Enchant_Out, SOCKADDR_IN* PubAddress_Out, SOCKADDR_IN* PriAddress_Out);
DWORD HandleCharPartyFind(char *pBuffer_In, DWORD *CharID_Out, unsigned char *MemberFindPartyNum_Out, unsigned char *PartyFindMemberNum_Out, LPMemberFindParty *lppMemberFindParty_Out, LPPartyFindMember *lppPartyFindMember_Out);
DWORD HandleCharHPRegen(char *pBuffer_In, DWORD *CharID_Out, unsigned short *HP_Out, unsigned short *MP_Out);
DWORD HandleCharUpgradeItem(char *pBuffer_In, DWORD *CharID_Out, unsigned char *Size_Out, char **lppBuffer_Out);
DWORD HandleCharLevelUpInfo(char *pBuffer_In, DWORD *CharID_Out, unsigned char *Level_Out);
DWORD HandleCharSplitItem(char *pBuffer_In, DWORD *CharID_Out, LPTakeType lpTakeType_Out, unsigned char *Size_Out, char **lppBuffer_Out);
DWORD HandleCharQuickSlotMove(char *pBuffer_In, LPTakeType lpTakeType_Out);
DWORD HandleCharSwitchHand(char *pBuffer_In, unsigned char *SelectHand_Out);
DWORD HandleCharTakeItems(char *pBuffer_In, DWORD *CharID_Out, unsigned char *TakeNum_Out, LPTakeType *lppTakeTypes_Out);
DWORD HandleCharTakeGold(char *pBuffer_In, DWORD *CharID_Out, unsigned char *SrcPos_Out, unsigned char *DstPos_Out, DWORD *Gold_Out);
DWORD HandleCharExchangeCmd(char *pBuffer_In, DWORD *SenderID_Out, DWORD *RecverID_Out, unsigned char *Cmd_Out);
DWORD HandleCharExchangeItem(char *pBuffer_In, DWORD *CharID_Out, DWORD *Size_Out, Item::ItemPos* lpIndex_Out, unsigned char *Type_Out, unsigned char *Num_Out, char **lppBuffer_Out);
DWORD HandleCellBroadCasting(char *pBuffer_In, unsigned short *CharNum_Out, LPAddressInfo *lppAddress_Out);
DWORD HandleControlOption(char *pBuffer_In, DWORD *CharID_Out, LPRejectOption Reject_Out);
DWORD HandleCharDuelCmd(char *pBuffer_In, DWORD *SenderID_Out, DWORD *RecverID_Out, unsigned char *Cmd_Out);
DWORD HandleCharTeamBattleInfo(char *pBuffer_In, unsigned long *CharID_Out, char *ChallengerName_Out, unsigned char *Cmd_Out, unsigned char *MemberNum_Out, unsigned long *MemberID_Out, unsigned char *MemberLevel_Out);
DWORD HandleCharFameInfo(char *pBuffer_In, DWORD *CharID_Out, unsigned char *Cmd_Out, unsigned long *FameOrMerits_Out, unsigned char *RankingByRace_Out, unsigned char *RankingByClass_Out);
DWORD HandleCharSpellInfo(char *pBuffer_In, DWORD *CharID_Out, unsigned char *SpellType_Out, unsigned short *EnchantLevel_Out, bool *OnOff_Out);
// 노점상
DWORD HandleCharStallOpen(char *pBuffer_In, DWORD *CharID_Out, char* StallName_Out);
DWORD HandleCharStallRegisterItem(char *pBuffer_In, DWORD *CharID_Out, TakeType *TakeType_Out, unsigned long *Price_Out, unsigned char *Cmd_Out);
DWORD HandleCharStallEnter(char *pBuffer_In, DWORD *CustomerID_Out, DWORD *Owner_Out);
DWORD HandleCharStallItemInfo(char *pBuffer_In, unsigned long *StallSize_Out, char **lppStallBuff_Out, unsigned short *ItemNum_Out, unsigned long **StallPrice_Out);
// 친구 관련
DWORD HandleCharFriendDB(char *pBuffer_In, unsigned char* cDataType_Out, char **ppFriendListData_Out, DWORD *dwDataSize_Out);
DWORD HandleCharFriendAck(char *pBuffer_In, unsigned char* cCmd_Out, DWORD *dwCID_Out);
DWORD HandleCharFriendRegistered(char *pBuffer_In, char* szName_Out);
DWORD HandleCharEliteBonus(char *pBuffer_In, char *Nation_Out, unsigned char *Level_Out);
};
#endif

View File

@@ -0,0 +1,343 @@
///////////////////////////////////////////////////////////////////////////////////////////////
//
// ClientSocket Class
//
///////////////////////////////////////////////////////////////////////////////////////////////
#include "LoginSocket.h"
#include <Network/Packet/PacketCommand.h>
#include <Network/Packet/PacketStruct/ServerInfo.h>
#include <Network/Packet/PacketStruct/ServerPacket.h>
#include <Network/Packet/PacketStruct/ClientToAuthServer.h>
#include <Network/Packet/PacketStruct/ClientToLoginServer.h>
LoginSocket::LoginSocket(HWND hWnd_In):
m_hMainWnd(hWnd_In), m_ConnectServer(0)
{
m_RegAddress.S_un.S_addr = 0;
}
LoginSocket::~LoginSocket(void)
{
Disconnect();
}
bool LoginSocket::ConnectToLoginServer(char* Address_In)
{
Disconnect();
if(!Socket::CreateTCPSocket(&m_TCPSocket, m_hMainWnd, WM_LOGIN_SOCKET))
return false;
m_ConnectServer = CO_SRV::CO_LOGIN;
return Socket::Connect(m_TCPSocket, Socket::MakeSockAddr(Address_In, DemonLoginTCPPort), &m_pRecvDataBuffer);
}
bool LoginSocket::ConnectToAuthServer(void)
{
Disconnect();
if(!Socket::CreateTCPSocket(&m_TCPSocket, m_hMainWnd, WM_LOGIN_SOCKET))
return false;
m_ConnectServer = CO_SRV::CO_AUTH;
return Socket::Connect(m_TCPSocket, Socket::MakeSockAddr(m_RegAddress, DemonAuthTCPPort), &m_pRecvDataBuffer);
}
bool LoginSocket::Disconnect(void)
{
if(m_TCPSocket)
Socket::DeleteSocket(&m_TCPSocket, m_hMainWnd);
return true;
}
//Interface/////////////////////////////////////////////////////////////////////////////////////
//
// 핑 패킷 [ public ]
//
// Parameter :
//
// Return :
// 패킷 생성 후 보내기 성공시 true, 실패시 false
//
///////////////////////////////////////////////////////////////////////////////////////////////
bool LoginSocket::SendSysPing(void)
{
if(m_TCPSocket == NULL)
return false;
CPacket* lpBuffer = new CPacket(sizeof(PktSyP), CmdSysPing, 0);
LPPktSyP lpSyPAckPt = reinterpret_cast<LPPktSyP>(lpBuffer->GetBuf());
lpSyPAckPt->m_dwTickTime = GetTickCount();
lpBuffer->WrapPacket(true);
if(!Send(m_TCPSocket, lpBuffer->GetWSABuf()))
{
lpBuffer->Release();
return false;
}
lpBuffer->Release();
return true;
}
//Interface/////////////////////////////////////////////////////////////////////////////////////
//
// GAS 유저 인증 [ public ]
// - GAS 서버로 유저 인증.
//
// Parameter :
// 1st : 유저 아이디 문자열[In] ex) "Bono"
// 2st : 유저 패스 워드 문자열[In] ex) "Bono"
// 3st : 클라이언트 버젼[In]
//
// Return :
// 패킷 생성 후 보내기 성공시 true, 실패시 false
//
///////////////////////////////////////////////////////////////////////////////////////////////
bool LoginSocket::AuthAccount(char* UserID_In, char* UserPW_In, DWORD ClientVer_In, unsigned short CnFlag_In, unsigned short Flag_In)
{
if(m_TCPSocket == NULL || UserID_In == NULL || UserPW_In == NULL)
return false;
CPacket* lpBuffer = new CPacket(sizeof(PktAU), CmdAuthAccount, 0, CnFlag_In);
LPPktAU lpAUPt = reinterpret_cast<LPPktAU>(lpBuffer->GetBuf());
strncpy(lpAUPt->m_UserAccount, UserID_In, 16);
strncpy(lpAUPt->m_UserPassword, UserPW_In, 16);
lpAUPt->m_dwSessionID = GetDiskSerial('C');
lpAUPt->m_ClientVerInfo = ClientVer_In;
lpAUPt->m_cFlag = Flag_In;
lpBuffer->WrapPacket(true);
if(!Send(m_TCPSocket, lpBuffer->GetWSABuf()))
{
lpBuffer->Release();
return false;
}
lpBuffer->Release();
return true;
}
//Interface/////////////////////////////////////////////////////////////////////////////////////
//
// 패킷 처리 [ public ]
// - AUAckPt 처리
//
// Parameter :
// 1st : 패킷 버퍼[In]
// 2st : 유저 고유 아이디 포인터[Out]
// 3st : 로그인 캐릭터 정보 구조체[Out]
//
// Return :
// 에러 코드
//
///////////////////////////////////////////////////////////////////////////////////////////////
DWORD LoginSocket::HandleAuthAccount(char *pBuffer_In, DWORD *SessionID_Out, DWORD *UserID_Out)
{
LPPktAUAck lpAUAckPt = (LPPktAUAck)pBuffer_In;
if(lpAUAckPt == NULL || UserID_Out == NULL)
return WrongParameter;
*SessionID_Out = lpAUAckPt->m_dwSessionID;
*UserID_Out = lpAUAckPt->m_dwUserID;
if(lpAUAckPt->Error() != NoError)
return lpAUAckPt->Error();
return NoError;
}
//Interface/////////////////////////////////////////////////////////////////////////////////////
//
// GAS 서버 선택 [ public ]
// - GAS 서버 선택.
//
// Parameter :
// 1st : 유저 아이디[In]
// 2st : 서버 아이디[In]
//
// Return :
// 패킷 생성 후 보내기 성공시 true, 실패시 false
//
///////////////////////////////////////////////////////////////////////////////////////////////
bool LoginSocket::ServerList(DWORD ClientVersion_In)
{
if(m_TCPSocket == NULL)
return false;
CPacket* lpBuffer = new CPacket(sizeof(PktSvL), CmdLoginServerList, 0, 0);
LPPktSvL lpSvLPt = reinterpret_cast<LPPktSvL>(lpBuffer->GetBuf());
lpSvLPt->m_ClientVerInfo = ClientVersion_In;
lpBuffer->WrapPacket(true);
if(!Send(m_TCPSocket, lpBuffer->GetWSABuf()))
{
lpBuffer->Release();
return false;
}
lpBuffer->Release();
return true;
}
//Interface/////////////////////////////////////////////////////////////////////////////////////
//
// 패킷 처리 [ public ]
// - AUAckPt 처리
//
// Parameter :
// 1st : 패킷 버퍼[In]
// 2st : 유저 고유 아이디 포인터[Out]
// 3st : 로그인 캐릭터 정보 구조체[Out]
//
// Return :
// 에러 코드
//
///////////////////////////////////////////////////////////////////////////////////////////////
DWORD LoginSocket::HandleServerList(char *pBuffer_In, DWORD *dwUserID_Out, SERVER_LIST* lpServerList_Out)
{
LPPktSvLAck lpSvLAckPt = (LPPktSvLAck)pBuffer_In;
if(lpSvLAckPt == NULL || dwUserID_Out == NULL)
return WrongParameter;
if(lpSvLAckPt->Error() != NoError)
return lpSvLAckPt->Error();
*dwUserID_Out = lpSvLAckPt->m_dwUserID;
CopyMemory(lpServerList_Out, &(lpSvLAckPt->m_ServerList), sizeof(SERVER_LIST));
return NoError;
}
//Interface/////////////////////////////////////////////////////////////////////////////////////
//
// GAS 서버 선택 [ public ]
// - GAS 서버 선택.
//
// Parameter :
// 1st : 유저 아이디[In]
// 2st : 서버 아이디[In]
//
// Return :
// 패킷 생성 후 보내기 성공시 true, 실패시 false
//
///////////////////////////////////////////////////////////////////////////////////////////////
bool LoginSocket::ServerGroup(unsigned char Group_In)
{
if(m_TCPSocket == NULL)
return false;
CPacket* lpBuffer = new CPacket(sizeof(PktSG), CmdServerGroup, 0, 0);
LPPktSG lpSGPt = reinterpret_cast<LPPktSG>(lpBuffer->GetBuf());
lpSGPt->m_cGroup = Group_In;
lpBuffer->WrapPacket(true);
if(!Send(m_TCPSocket, lpBuffer->GetWSABuf()))
{
lpBuffer->Release();
return false;
}
lpBuffer->Release();
return true;
}
//Interface/////////////////////////////////////////////////////////////////////////////////////
//
// 서버 선택 패킷 처리 [ public ]
// - AUTSAck 처리
//
// Parameter :
// 1st : 패킷 버퍼[In]
// 2st : 서버 아이디 포인터[Out]
//
// Return :
// 에러 코드
//
///////////////////////////////////////////////////////////////////////////////////////////////
DWORD LoginSocket::HandleServerGroup(char *pBuffer_In, DWORD *dwServerID_Out)
{
LPPktSGAck lpSGAckPt = (LPPktSGAck)pBuffer_In;
if(lpSGAckPt == NULL || dwServerID_Out == NULL)
return WrongParameter;
if(lpSGAckPt->Error() != NoError)
return lpSGAckPt->Error();
*dwServerID_Out = lpSGAckPt->m_dwServerID;
m_RegAddress = lpSGAckPt->m_AuthAddress;
return NoError;
}
//Interface/////////////////////////////////////////////////////////////////////////////////////
//
// 패치 주소 [ public ]
// - 패치 주소 얻기
//
// Parameter :
// 1st : 서버 아이디[In]
//
// Return :
// 패킷 생성 후 보내기 성공시 true, 실패시 false
//
///////////////////////////////////////////////////////////////////////////////////////////////
bool LoginSocket::PatchAddress(DWORD ServerID_In)
{
if(m_TCPSocket == NULL)
return false;
CPacket* lpBuffer = new CPacket(sizeof(PktSPI), CmdSysPatchAddress, 0, 0);
LPPktSPI lpSPIPt = reinterpret_cast<LPPktSPI>(lpBuffer->GetBuf());
lpSPIPt->m_dwServerID = ServerID_In;
lpBuffer->WrapPacket(true);
if(!Send(m_TCPSocket, lpBuffer->GetWSABuf()))
{
lpBuffer->Release();
return false;
}
lpBuffer->Release();
return true;
}
//Interface/////////////////////////////////////////////////////////////////////////////////////
//
// 패치 주소 [ public ]
// - 패치 주소 얻기
//
// Parameter :
// 1st : 패치 주소[In]
//
// Return :
// 에러 코드
//
///////////////////////////////////////////////////////////////////////////////////////////////
DWORD LoginSocket::HandlePatchAddress(char *pBuffer_In, DWORD *ClientVer_Out, char *PatchAddress_Out)
{
LPPktSPIAck lpSPIAckPt = (LPPktSPIAck)pBuffer_In;
if(lpSPIAckPt == NULL)
return WrongParameter;
if(lpSPIAckPt->Error() != NoError)
return lpSPIAckPt->Error();
*ClientVer_Out = lpSPIAckPt->m_dwClientVer;
strncpy(PatchAddress_Out, lpSPIAckPt->m_PatchAddress, PktSPIAck::PATCH_ADDRESS_LENGTH);
return NoError;
}

View File

@@ -0,0 +1,58 @@
///////////////////////////////////////////////////////////////////////////////////////////////
//
// LoginSocket Class
//
// Last Update : 2002. 8.28
//
///////////////////////////////////////////////////////////////////////////////////////////////
#ifndef _LoginSocket
#define _LoginSocket
// Àü¹æ ÂüÁ¶
struct SERVER_LIST;
#include "NetBase.h"
const unsigned long WM_LOGIN_SOCKET = RegisterWindowMessage("WM_LOGIN_SOCKET");
///////////////////////////////////////////////////////////////////////////////////////////////
//
// Ŭ·¡½º Á¤ÀÇ
//
///////////////////////////////////////////////////////////////////////////////////////////////
class LoginSocket : public NetBase
{
private:
HWND m_hMainWnd;
IN_ADDR m_RegAddress;
int m_ConnectServer;
public:
typedef enum AuthFlag { AuthFlag_RegDB = 0x8000, AuthFlag_Email = 0x4000 };
typedef enum CO_SRV { CO_LOGIN = 0, CO_AUTH = 1 };
LoginSocket(HWND hWnd_In);
virtual ~LoginSocket(void);
inline IN_ADDR GetRegAddress() { return m_RegAddress; }
inline char* GetRegString() { return inet_ntoa(m_RegAddress); }
inline int GetConnectServer() { return m_ConnectServer; }
bool ConnectToLoginServer(char* Address_In);
bool ConnectToAuthServer(void);
bool Disconnect(void);
bool SendSysPing(void);
bool AuthAccount(char* UserID_In, char* UserPW_In, DWORD ClientVer_In, unsigned short CnFlag_In, unsigned short Flag_In = 0);
bool ServerList(DWORD ClientVersion_In);
bool ServerGroup(unsigned char Group_In);
bool PatchAddress(DWORD ServerID_In);
DWORD HandleAuthAccount(char *pBuffer_In, DWORD *SessionID_Out, DWORD *UserID_Out);
DWORD HandleServerList(char *pBuffer_In, DWORD *UserID_Out, SERVER_LIST* lpServerList_Out);
DWORD HandleServerGroup(char *pBuffer_In, DWORD *ServerID_Out);
DWORD HandlePatchAddress(char *pBuffer_In, DWORD *ClientVer_Out, char *PatchAddress_Out);
};
#endif

View File

@@ -0,0 +1,92 @@
///////////////////////////////////////////////////////////////////////////////////////////////
//
// NetBase Class
//
///////////////////////////////////////////////////////////////////////////////////////////////
#include "NetBase.h"
#include <Network/XORCrypt/XORCrypt.h>
NetBase::NetBase(void) :
m_TCPSocket(INVALID_SOCKET), m_UDPSocket(INVALID_SOCKET)
{
m_pSendDataBuffer.buf = m_pSendBuffer;
m_pSendDataBuffer.len = 0;
m_pRecvDataBuffer.buf = m_pRecvBuffer;
m_pRecvDataBuffer.len = 0;
m_pRecvUDPDataBuffer.buf = m_pRecvUDPBuffer;
m_pRecvUDPDataBuffer.len = 0;
}
NetBase::~NetBase(void)
{
SAFE_CLOSESOCK(m_TCPSocket);
SAFE_CLOSESOCK(m_UDPSocket);
}
int NetBase::Recv(void)
{
return SocketIO::Recv(m_TCPSocket, m_pRecvDataBuffer);
}
int NetBase::UDPRecv(LPSOCKADDR_IN Address_Out)
{
return SocketIO::RecvFrom(m_UDPSocket, m_pRecvUDPDataBuffer, Address_Out);
}
int NetBase::PutRecvBufferToPtBuffer(char *pBuffer_Out, int BufferSize_In)
{
return SocketIO::PutRecvBufferToPtBuffer(pBuffer_Out, BufferSize_In, m_pRecvDataBuffer, m_pRecvBuffer, 0, 0);
}
int NetBase::PutUDPRecvBufferToPtBuffer(char *pBuffer_Out, int BufferSize_In)
{
return SocketIO::PutRecvBufferToPtBuffer(pBuffer_Out, BufferSize_In, m_pRecvUDPDataBuffer, m_pRecvUDPBuffer, 0, 0);
}
void NetBase::PutSendBuffer(bool Crypt_In)
{
CXORCrypt& Crypt = CXORCrypt::GetInstance();
DWORD dwCodePage = Crypt.GetCodePage();
LPPktBase lpBasePt = (LPPktBase)m_pSendDataBuffer.buf;
int Len = lpBasePt->GetLen();
// ÀÎÄÚµù ÆÐŶ
if(Crypt_In)
{
Crypt.EncodePacket(m_pSendDataBuffer.buf + PktBaseSize, Len - PktBaseSize, dwCodePage);
lpBasePt->SetCodePage(dwCodePage);
lpBasePt->SetCrypt();
}
// ÀÎÄÚµù ÇØ´õ
Crypt.EncodeHeader(m_pSendDataBuffer.buf + 1, PktBaseSize - 1, 0, 0);
m_pSendDataBuffer.len += Len;
m_pSendDataBuffer.buf += Len;
}
bool NetBase::FlushSendBuffer(void)
{
WSABUF SendBuf = { m_pSendDataBuffer.len, m_pSendBuffer };
CheckServerState();
if(m_pSendDataBuffer.len <= 0)
return true;
if(!Send(m_TCPSocket, SendBuf))
{
m_pSendDataBuffer.buf = m_pSendBuffer;
m_pSendDataBuffer.len = 0;
return false;
}
m_pSendDataBuffer.buf = m_pSendBuffer;
m_pSendDataBuffer.len = 0;
return true;
}

View File

@@ -0,0 +1,77 @@
///////////////////////////////////////////////////////////////////////////////////////////////
//
// NetBase Class
//
// Last Update : 2002. 8. 28
//
///////////////////////////////////////////////////////////////////////////////////////////////
#ifndef _NetBase
#define _NetBase
#include "Packet.h"
#include "Socket/SocketIO.h"
const unsigned int DemonLoginTCPPort = 10101; // Client Login TCP Port
const unsigned int DemonGameTCPPort = 10104; // Client Game TCP Port
const unsigned int DemonAuthTCPPort = 10110; // Client Auth TCP Port
const unsigned int DemonClientUDPPort = 20002; // Client UDP Port
const unsigned short NoError = 0x0000; // 에러 없음
const unsigned short WrongParameter = 0x4001; // 잘못된 인자
const unsigned short ExceptionError = 0x4002; // 예외 값 발생
///////////////////////////////////////////////////////////////////////////////////////////////
//
// 클래스 정의
//
///////////////////////////////////////////////////////////////////////////////////////////////
class NetBase : public SocketIO
{
public:
WSABUF m_pSendDataBuffer;
char m_pSendBuffer[BufferSize];
WSABUF m_pRecvDataBuffer;
char m_pRecvBuffer[BufferSize];
WSABUF m_pRecvUDPDataBuffer;
char m_pRecvUDPBuffer[BufferSize];
SOCKET m_TCPSocket;
SOCKET m_UDPSocket;
public:
NetBase(void);
~NetBase(void);
inline int GetUseSendBuffer(void) { return m_pSendDataBuffer.len; }
inline int GetUseRecvBuffer(void) { return static_cast<int>((m_pRecvDataBuffer.buf - m_pRecvBuffer) + m_pRecvDataBuffer.len); }
inline int GetUseRecvUDPBuffer(void) { return static_cast<int>((m_pRecvUDPDataBuffer.buf - m_pRecvUDPBuffer) + m_pRecvUDPDataBuffer.len); }
int Recv(void);
int UDPRecv(LPSOCKADDR_IN Address_Out);
int PutRecvBufferToPtBuffer(char *pBuffer_Out, int BufferSize_In);
int PutUDPRecvBufferToPtBuffer(char *pBuffer_Out, int BufferSize_In);
char* GetSendBuffer(void) { return m_pSendDataBuffer.buf; }
void PutSendBuffer(bool Crypt_In);
bool FlushSendBuffer(void);
public:
inline DWORD GetDiskSerial(char Drv_In)
{
unsigned long VolumeSerial = 0;
char Root[10] = "";
sprintf(Root, "%c:\\", Drv_In);
if(!GetVolumeInformation(Root, 0, 0, &VolumeSerial, 0, 0, 0, 0))
return 0;
return VolumeSerial;
}
};
#endif

View File

@@ -0,0 +1,108 @@
#include "stdafx.h"
#include "Packet.h"
#include <Network/Packet/PacketBase.h>
#include <Network/XORCrypt/XORCrypt.h>
#include <algorithm>
CMemoryPool::CMemoryPool(size_t nPerAllocateSize, size_t nPerAllocateNum)
: m_nPerAllocateSize(nPerAllocateSize), m_nPerAllocateNum(nPerAllocateNum)
{
for(size_t nCount = 0; nCount < m_nPerAllocateNum; ++nCount)
{
m_Pool.push_back(new char[m_nPerAllocateSize]);
}
}
struct FnPoolDeleteArray
{
bool operator () (char* lpPtr)
{
if(NULL != lpPtr)
{
delete [] lpPtr;
}
return true;
}
};
CMemoryPool::~CMemoryPool()
{
CCSLock::Syncronize sync(m_PoolLock);
std::for_each(m_Pool.begin(), m_Pool.end(), FnPoolDeleteArray());
}
void* CMemoryPool::Alloc(size_t size)
{
CCSLock::Syncronize sync(m_PoolLock);
if(m_Pool.empty())
{
for(size_t nCount = 0; nCount < m_nPerAllocateNum; ++nCount)
{
m_Pool.push_back(new char[m_nPerAllocateSize]);
}
}
char* lpResult = m_Pool.back();
m_Pool.pop_back();
return lpResult;
}
void CMemoryPool::Free(void* ptr)
{
CCSLock::Syncronize sync(m_PoolLock);
m_Pool.push_back(reinterpret_cast<char*>(ptr));
}
CMemoryPool CPacket::ms_PacketPool(sizeof(CPacket), 20);
CPacket::CPacket()
: m_Len(0), m_nRefCount(1), m_bWrap(false)
{
}
CPacket::CPacket(unsigned short Len_In, unsigned char Cmd_In, unsigned short State_In, unsigned short Error_In)
: m_Len(0), m_nRefCount(1), m_bWrap(false)
{
((PktBase* )m_Buffer)->InitPtHead(Len_In, Cmd_In, State_In, Error_In);
}
CPacket::CPacket(unsigned short Len_In, unsigned char Cmd_In, unsigned long Tick_In)
: m_Len(0), m_nRefCount(1), m_bWrap(false)
{
((PktBase* )m_Buffer)->InitPtHead(Len_In, Cmd_In, Tick_In);
}
CPacket::~CPacket()
{
}
bool CPacket::WrapPacket(bool Crypt_In)
{
CXORCrypt& Crypt = CXORCrypt::GetInstance();
DWORD dwCodePage = Crypt.GetCodePage();
PktBase* lpBasePt = (PktBase* )m_Buffer;
m_Len = lpBasePt->GetLen();
if(m_bWrap)
return false;
// ÀÎÄÚµù ÆÐŶ
if(Crypt_In)
{
Crypt.EncodePacket(m_Buffer + PktBaseSize, m_Len - PktBaseSize, dwCodePage);
lpBasePt->SetCodePage(dwCodePage);
lpBasePt->SetCrypt();
}
// ÀÎÄÚµù ÇØ´õ
Crypt.EncodeHeader(m_Buffer + 1, PktBaseSize - 1, 0, 0);
return m_bWrap = true;
}

View File

@@ -0,0 +1,80 @@
#ifndef _CPacket
#define _CPacket
#define WIN32_LEAN_AND_MEAN
#include <Winsock2.h>
#include <windows.h>
#include <new>
#include <vector>
#include <Thread/Lock.h>
#include "Socket/SocketIO.h"
class CMemoryPool
{
public:
CMemoryPool(size_t nPerAllocateSize, size_t PerAllocateNum);
~CMemoryPool();
void* Alloc(size_t size);
void Free(void* ptr);
private:
CCSLock m_PoolLock;
CACHE_PAD(PoolLockPadding, sizeof(CCSLock));
size_t m_nPerAllocateSize;
size_t m_nPerAllocateNum;
std::vector<char*> m_Pool;
};
class CPacket
{
protected:
volatile LONG m_nRefCount;
char m_Buffer[BufferSize];
unsigned short m_Len;
bool m_bWrap;
public:
CPacket();
CPacket(unsigned short Len_In, unsigned char Cmd_In, unsigned short State_In, unsigned short Error_In);
CPacket(unsigned short Len_In, unsigned char Cmd_In, unsigned long Tick_In);
~CPacket();
WSABUF GetWSABuf() {
WSABUF WSABuf = { m_Len, m_Buffer };
return WSABuf;
}
char * GetBuf(void) { return m_Buffer; };
inline LONG AddRef() { return InterlockedIncrement(&m_nRefCount); }
inline LONG Release();
bool WrapPacket(bool Crypt_In);
static CMemoryPool ms_PacketPool;
static void* operator new(size_t size) { return ms_PacketPool.Alloc(size); }
static void operator delete(void *ptr) { ms_PacketPool.Free(ptr); }
};
typedef CPacket* LPCPacket;
inline LONG CPacket::Release()
{
LONG nRefCount = InterlockedDecrement(&m_nRefCount);
if(0 == nRefCount)
{
delete this;
}
return nRefCount;
}
#endif

View File

@@ -0,0 +1,284 @@
#include "Socket.h"
void Socket::InitWinsock(void)
{
WSADATA WsaData;
WSAStartup(MAKEWORD( 2, 2), &WsaData);
}
void Socket::ReleaseWinsock(void)
{
WSACleanup();
}
SOCKADDR_IN Socket::MakeSockAddr(char *IP_In, int Port_In)
{
SOCKADDR_IN Address = {0,};
Address.sin_family = AF_INET;
Address.sin_addr.s_addr = (NULL == IP_In) ? htonl(INADDR_ANY) : inet_addr(IP_In);
Address.sin_port = (0 == Port_In) ? 0 : htons(Port_In);
return Address;
}
SOCKADDR_IN Socket::MakeSockAddr(IN_ADDR Addr, int Port_In)
{
SOCKADDR_IN Address = {0,};
Address.sin_family = AF_INET;
Address.sin_addr = Addr;
Address.sin_port = (0 == Port_In) ? 0 : htons(Port_In);
return Address;
}
bool Socket::CreateTCPSocket(SOCKET *Socket_Out, HWND hWnd_In, unsigned int Msg_In)
{
BOOL KeepAlive = TRUE;
linger Linger;
Linger.l_onoff = 1;
Linger.l_linger = 0;
if(Socket_Out == NULL)
return false;
if((*Socket_Out = socket(AF_INET, SOCK_STREAM, IPPROTO_IP)) == SOCKET_ERROR)
return false;
if(setsockopt(*Socket_Out, SOL_SOCKET, SO_KEEPALIVE, (char *)&KeepAlive, sizeof(BOOL)) == SOCKET_ERROR)
return false;
if(setsockopt(*Socket_Out, SOL_SOCKET, SO_LINGER, (char *)&Linger, sizeof(linger)) == SOCKET_ERROR)
return false;
if(WSAAsyncSelect(*Socket_Out, hWnd_In, Msg_In, FD_READ | FD_CONNECT | FD_CLOSE) == SOCKET_ERROR)
return false;
return true;
}
bool Socket::CreateUDPSocket(SOCKET *Socket_Out, SOCKADDR_IN Address_In, HWND hWnd_In, unsigned int Msg_In)
{
BOOL ReUseAddr = TRUE;
if(Socket_Out == NULL)
return false;
if((*Socket_Out = socket(AF_INET, SOCK_DGRAM, 0)) == SOCKET_ERROR)
return false;
if(bind(*Socket_Out, (sockaddr *)&Address_In, sizeof(SOCKADDR_IN)) == SOCKET_ERROR)
return false;
if(setsockopt(*Socket_Out, SOL_SOCKET, SO_REUSEADDR, (char *)&ReUseAddr, sizeof(BOOL)) == SOCKET_ERROR)
return false;
if(WSAAsyncSelect(*Socket_Out, hWnd_In, Msg_In, FD_READ) == SOCKET_ERROR)
return false;
return true;
}
bool Socket::DeleteSocket(SOCKET *Socket_In, HWND hWnd_In)
{
if(Socket_In == NULL)
return false;
WSAAsyncSelect(*Socket_In, hWnd_In, 0, 0);
SAFE_CLOSESOCK(*Socket_In);
return true;
}
bool Socket::GetNATAddress(SOCKET Socket_In, SOCKADDR_IN *Address_Out, bool AllowVirtual)
{
int AddressSize = sizeof(SOCKADDR_IN);
if(getsockname(Socket_In, (struct sockaddr *)Address_Out, &AddressSize) != SOCKET_ERROR)
{
char HostName[256];
if(!gethostname(HostName, 255))
{
PHOSTENT pHost = gethostbyname(HostName);
if(NULL == pHost)
{
return false;
}
IN_ADDR& Addr = Address_Out->sin_addr;
for(int Count = 0;pHost->h_addr_list[Count]; ++Count)
{
memcpy(&(Addr.S_un.S_addr), pHost->h_addr_list[Count], sizeof(IN_ADDR));
if(!AllowVirtual)
{
// 가상 아이피 확인
// 10.0.0.0 ~ 10.255.255.255
// 172.16.0.0 ~ 172.31.255.255
// 192.168.0.0 ~ 192.168.255.255
if((unsigned char)10 == Addr.S_un.S_un_b.s_b1)
{
continue;
}
else if((unsigned char)172 == Addr.S_un.S_un_b.s_b1)
{
if(Addr.S_un.S_un_b.s_b2 >= (unsigned char)16 && Addr.S_un.S_un_b.s_b2 <= (unsigned char)31)
{
continue;
}
}
else if((unsigned char)192 == Addr.S_un.S_un_b.s_b1)
{
if((unsigned char)168 == Addr.S_un.S_un_b.s_b2)
{
continue;
}
}
}
// 잘못된 아이피
// 169.X.X.X 자동 아이피 할당 ( SyGate )
// 0.X.X.X
if((unsigned char)169 == Addr.S_un.S_un_b.s_b1)
{
continue;
}
else if((unsigned char)0 == Addr.S_un.S_un_b.s_b1)
{
continue;
}
return true;
}
if(0 != Count)
return true;
}
return false;
}
return false;
}
bool Socket::GetHostName(char *Name_Out, int Size)
{
if(!gethostname(Name_Out, Size))
return true;
return false;
}
bool Socket::GetHostIP(IN_ADDR &Addr, bool AllowVirtual)
{
char HostName[256];
if(!gethostname(HostName, 255))
{
PHOSTENT pHost = gethostbyname(HostName);
if(NULL == pHost)
{
return false;
}
for(int Count = 0;pHost->h_addr_list[Count]; ++Count)
{
memcpy(&(Addr.S_un.S_addr), pHost->h_addr_list[Count], sizeof(IN_ADDR));
if(!AllowVirtual)
{
// 가상 아이피 확인
// 10.0.0.0 ~ 10.255.255.255
// 172.16.0.0 ~ 172.31.255.255
// 192.168.0.0 ~ 192.168.255.255
if((unsigned char)10 == Addr.S_un.S_un_b.s_b1)
{
continue;
}
else if((unsigned char)172 == Addr.S_un.S_un_b.s_b1)
{
if(Addr.S_un.S_un_b.s_b2 >= (unsigned char)16 && Addr.S_un.S_un_b.s_b2 <= (unsigned char)31)
{
continue;
}
}
else if((unsigned char)192 == Addr.S_un.S_un_b.s_b1)
{
if((unsigned char)168 == Addr.S_un.S_un_b.s_b2)
{
continue;
}
}
}
// 잘못된 아이피
// 169.X.X.X 자동 아이피 할당 ( SyGate )
// 0.X.X.X
if((unsigned char)169 == Addr.S_un.S_un_b.s_b1)
{
continue;
}
else if((unsigned char)0 == Addr.S_un.S_un_b.s_b1)
{
continue;
}
return true;
}
if(0 != Count)
return true;
}
return false;
}
bool Socket::GetHostIP(IN_ADDR &Addr, char *Domain)
{
PHOSTENT pHost = gethostbyname(Domain);
if(NULL == pHost)
{
return false;
}
memcpy(&(Addr.S_un.S_addr), pHost->h_addr_list[0], sizeof(IN_ADDR));
return true;
}
bool Socket::IsWrongIP(IN_ADDR &Addr)
{
if((unsigned char)169 == Addr.S_un.S_un_b.s_b1)
{
if((unsigned char)254 == Addr.S_un.S_un_b.s_b2)
{
return true;
}
}
if((unsigned char)0 == Addr.S_un.S_un_b.s_b1)
return true;
return false;
}
bool Socket::IsEmptyAddr(IN_ADDR &Addr)
{
if((unsigned char)0 == Addr.S_un.S_un_b.s_b1)
{
return true;
}
return true;
}
bool Socket::Connect(SOCKET Socket_In, SOCKADDR_IN Address_In, WSABUF *WSABuf_In)
{
if(WSAConnect(Socket_In, (sockaddr *)&Address_In, sizeof(SOCKADDR_IN), 0, WSABuf_In, 0, 0) == SOCKET_ERROR)
{
DWORD dwError = GetLastError();
if(ERROR_IO_PENDING != dwError && WSAEWOULDBLOCK != (int)dwError)
return false;
}
return true;
}

View File

@@ -0,0 +1,33 @@
#define WIN32_LEAN_AND_MEAN
#include <winsock2.h>
#include <iphlpapi.h>
#include <windows.h>
#define SelectEvent(dwError) WSAGETSELECTEVENT(dwError)
#define SelectError(dwError) WSAGETSELECTERROR(dwError)
#define SAFE_CLOSESOCK(p) { if (INVALID_SOCKET != (p)) { closesocket(p); (p) = INVALID_SOCKET; } }
namespace Socket
{
void InitWinsock(void);
void ReleaseWinsock(void);
SOCKADDR_IN MakeSockAddr(IN_ADDR Addr, int Port_In);
SOCKADDR_IN MakeSockAddr(char *IP_In, int Port_In);
bool CreateTCPSocket(SOCKET *Socket_Out, HWND hWnd_In, unsigned int Msg_In);
bool CreateUDPSocket(SOCKET *Socket_Out, SOCKADDR_IN Address_In, HWND hWnd_In, unsigned int Msg_In);
bool DeleteSocket(SOCKET *Socket_In, HWND hWnd_In);
bool GetNATAddress(SOCKET Socket_In, SOCKADDR_IN *Address_Out, bool AllowVirtual);
bool GetHostName(char *Name_Out, int Size);
bool GetHostIP(IN_ADDR &Addr, bool AllowVirtual);
bool GetHostIP(IN_ADDR &Addr, char *Domain);
bool IsWrongIP(IN_ADDR &Addr);
bool IsEmptyAddr(IN_ADDR &Addr);
bool Connect(SOCKET Socket_In, SOCKADDR_IN Address_In, WSABUF *WSABuf_In);
};

View File

@@ -0,0 +1,191 @@
///////////////////////////////////////////////////////////////////////////////////////////////
//
// SocketIO Class
//
///////////////////////////////////////////////////////////////////////////////////////////////
#include "SocketIO.h"
#include <Network/XORCrypt/XORCrypt.h>
#include <Utility/Compress/MiniLZO/MiniLZOWrapper.h>
SocketIO::SocketIO(void)
: m_ServerState(ServerInfo::SS_SMOOTH), m_PacketCount(0), m_Crypt(CXORCrypt::GetInstance())
{
Socket::InitWinsock();
}
SocketIO::~SocketIO(void)
{
Socket::ReleaseWinsock();
}
int SocketIO::Send(SOCKET Socket_In, WSABUF SendData_In)
{
int send_byte;
send_byte = send(Socket_In, (char *)SendData_In.buf, SendData_In.len, 0);
if(send_byte == SOCKET_ERROR || (int)SendData_In.len != send_byte)
return 0;
return send_byte;
}
int SocketIO::SendTo(SOCKET Socket_In, SOCKADDR_IN Addreess_In, WSABUF SendData_In)
{
int AddressSize = sizeof(SOCKADDR_IN);
int send_byte = 0;
send_byte = sendto(Socket_In, (char *)SendData_In.buf, SendData_In.len, 0, (struct sockaddr *)&Addreess_In, AddressSize);
if(send_byte == SOCKET_ERROR || (int)SendData_In.len != send_byte)
return 0;
return send_byte;
}
int SocketIO::Recv(SOCKET Socket_In, WSABUF &RecvData_In)
{
DWORD recv_byte;
if((recv_byte = recv(Socket_In, RecvData_In.buf, BufferSize, 0)) != SOCKET_ERROR)
{
RecvData_In.len = recv_byte;
return recv_byte;
}
return 0;
}
int SocketIO::RecvFrom(SOCKET Socket_In, WSABUF &RecvData_In, LPSOCKADDR_IN Address_Out)
{
int AddressSize = sizeof(SOCKADDR_IN);
DWORD recv_byte;
if((recv_byte = recvfrom(Socket_In, RecvData_In.buf, BufferSize, 0, (struct sockaddr *)Address_Out, &AddressSize)) != SOCKET_ERROR)
{
RecvData_In.len = recv_byte;
return recv_byte;
}
return 0;
}
int SocketIO::PutRecvBufferToPtBuffer(char *pBuffer_Out, int BufferSize_In, WSABUF &RecvData_In, char *RecvBuffer_In, unsigned short PageVer_In, unsigned char PageNum_In)
{
LPPktBase lpPktBase = NULL;;
if(pBuffer_Out == NULL || RecvData_In.len == 0)
return false;
try
{
lpPktBase = (LPPktBase)RecvData_In.buf;
if(lpPktBase->GetStartBit() != StartBit)
{
// 패킷 시작 아닐 경우
if(RecvData_In.buf != RecvBuffer_In)
{
// 이전 패킷 존재 ( 패킷 연결 )
RecvData_In.len = static_cast<u_long>((RecvData_In.buf - RecvBuffer_In) + RecvData_In.len);
RecvData_In.buf = RecvBuffer_In;
}
else
{
// 이전 패킷 존재 하지 않음 잘못된 패킷 ( 버퍼 리셋 )
RecvData_In.len = 0;
RecvData_In.buf = RecvBuffer_In;
return 0;
}
}
lpPktBase = (LPPktBase)RecvData_In.buf;
if(lpPktBase->GetStartBit() == StartBit)
{
// 디코딩 해더
if(RecvData_In.len < PktBaseSize)
{
// 잘린 패킷 전송 ( 데이터 버퍼 포인터 이동 )
RecvData_In.buf = RecvData_In.buf + RecvData_In.len;
RecvData_In.len = 0;
return 0;
}
m_Crypt.DecodeHeader((char *)lpPktBase + 1, PktBaseSize - 1, PageVer_In, PageNum_In);
unsigned short PacketLength = lpPktBase->GetLen();
if(PktMinLen <= PacketLength && PacketLength <= PktMaxLen)
{
// 정상 길이의 패킷
if(PacketLength <= RecvData_In.len)
{
if(lpPktBase->IsCrypt())
{
m_Crypt.DecodePacket((char *)lpPktBase + PktBaseSize, PacketLength - PktBaseSize, lpPktBase->GetCodePage());
}
if(lpPktBase->IsCompress())
{
// 압축 패킷 처리
DWORD Len = BufferSize_In;
CopyMemory(pBuffer_Out, (char *)lpPktBase, PktBaseSize);
CMiniLZOCompress::Decompress((char *)lpPktBase + PktBaseSize, PacketLength - PktBaseSize, pBuffer_Out + PktBaseSize, &Len);
lpPktBase->SetLen((unsigned short)Len + PktBaseSize);
}
else
{
// 비 압축 패킷 처리
CopyMemory(pBuffer_Out, (char *)lpPktBase, PacketLength);
}
RecvData_In.len = RecvData_In.len - PacketLength;
if(RecvData_In.len)
{
// 받은 데이터가 남았을 경우
CopyMemory((char *)lpPktBase, (char *)lpPktBase + PacketLength, RecvData_In.len);
}
return PacketLength;
}
else
{
m_Crypt.EncodeHeader((char *)lpPktBase + 1, PktBaseSize - 1, PageVer_In, PageNum_In);
// 잘린 패킷 전송 ( 데이터 버퍼 포인터 이동 )
RecvData_In.buf = RecvData_In.buf + RecvData_In.len;
RecvData_In.len = 0;
return 0;
}
}
else
{
// 비정상적 길이의 패킷
RecvData_In.buf = RecvBuffer_In;
RecvData_In.len = 0;
return 0;
}
}
else
{
// 잘못된 패킷 ( 버퍼 리셋 )
RecvData_In.buf = RecvBuffer_In;
RecvData_In.len = 0;
return 0;
}
}
catch(...)
{
return 0;
}
return 0;
}

View File

@@ -0,0 +1,95 @@
///////////////////////////////////////////////////////////////////////////////////////////////
//
// SocketIO Class
//
// Last Update : 2002. 8. 28
//
///////////////////////////////////////////////////////////////////////////////////////////////
#ifndef _SocketIO
#define _SocketIO
#include "Socket.h"
#include <Network/Packet/PacketBase.h>
// 전방 참조
class CXORCrypt;
///////////////////////////////////////////////////////////////////////////////////////////////
//
// 상수 설정
//
///////////////////////////////////////////////////////////////////////////////////////////////
const unsigned int BufferSize = 8192 * 100;
///////////////////////////////////////////////////////////////////////////////////////////////
//
// 클래스 정의
//
///////////////////////////////////////////////////////////////////////////////////////////////
class SocketIO
{
private:
ServerInfo::ServerState m_ServerState;
unsigned long m_PacketCount;
CXORCrypt& m_Crypt;
public:
SocketIO(void);
virtual ~SocketIO(void);
int Send(SOCKET Socket_In, WSABUF SendData_In);
int SendTo(SOCKET Socket_In, SOCKADDR_IN Addreess_In, WSABUF SendData_In);
int Recv(SOCKET Socket_In, WSABUF &RecvData_In);
int RecvFrom(SOCKET Socket_In, WSABUF &RecvData_In, LPSOCKADDR_IN Address_Out);
int PutRecvBufferToPtBuffer(char *pBuffer_Out, int BufferSize_In, WSABUF &RecvData_In, char *RecvBuffer_In, unsigned short PageVer_In, unsigned char PageNum_In);
inline char* InsertPtCount(char *Buffer_In);
inline unsigned long ExtractPtCount(char *Buffer_In);
inline bool CheckServerState();
};
inline char* SocketIO::InsertPtCount(char *Buffer_In)
{
((PktBase* )Buffer_In)->SetServerInfo(m_PacketCount);
if(++m_PacketCount >= 0xFFFFFFF0)
m_PacketCount = 0;
return Buffer_In;
}
inline unsigned long SocketIO::ExtractPtCount(char *Buffer_In)
{
PktBase* lpBasePt = (PktBase* )Buffer_In;
return lpBasePt->GetServerInfo();
}
inline bool SocketIO::CheckServerState()
{
if(m_ServerState == ServerInfo::SS_SMOOTH)
return true;
else if(m_ServerState == ServerInfo::SS_LOADED)
{
Sleep(25);
return true;
}
else if(m_ServerState == ServerInfo::SS_BUSY)
{
Sleep(100);
return true;
}
else if(m_ServerState == ServerInfo::SS_VERYBUSY)
{
Sleep(300);
return true;
}
return false;
}
#endif

View File

@@ -0,0 +1,475 @@
///////////////////////////////////////////////////////////////////////////////////////////////
//
// 리스트 템플릿
//
///////////////////////////////////////////////////////////////////////////////////////////////
#ifndef _TList
#define _TList
#pragma warning(disable:4786) // don't warn about browse name overflow.
#define LPLIST LIST*
///////////////////////////////////////////////////////////////////////////////////////////////
//
// 템플릿 정의
//
///////////////////////////////////////////////////////////////////////////////////////////////
template <class LIST> class TList
{
public:
LIST* m_pListHead;
LIST* m_pListTail;
LIST* m_pGarbageTop;
int m_ListCount;
int m_GarbageLength;
int m_GarbageCount;
///////////////////////////////////////////////////////////////////////////////////////////////
//
// 기본 클래스 메소드
//
///////////////////////////////////////////////////////////////////////////////////////////////
public:
TList(void);
~TList(void);
inline bool IsListEmpty(void)
{
if(m_pListHead == NULL)
return true;
return false;
}
inline int GetListCount(void)
{
return m_ListCount;
}
///////////////////////////////////////////////////////////////////////////////////////////////
//
// 리스트 관련 메소드
//
///////////////////////////////////////////////////////////////////////////////////////////////
LIST* Create(void);
bool Delete(LIST* pDelete_In);
bool InsertToList(LIST* pInsert_In);
bool DeleteFromList(LIST* pDelete_In);
bool DeleteAllFromList(void);
bool IsExistHandleFromList(LIST* pFind_In);
LIST* GetHandleWithCount(int Count_In);
///////////////////////////////////////////////////////////////////////////////////////////////
//
// 가비지 콜랙션 관련 메소드
//
///////////////////////////////////////////////////////////////////////////////////////////////
bool PushItemToGarbage(LIST* pPush_In);
LIST* PopItemFromGarbage(void);
bool SetGarbageStackLength(int StackLength_In);
bool ClearGarbageStack(void);
};
//Interface////////////////////////////////////////////////////////////////////////////////////
//
// TList 생성자 [ public ]
// - 맴버 변수 초기화
//
///////////////////////////////////////////////////////////////////////////////////////////////
template <class LIST> TList<LIST>::TList(void)
{
m_pListHead = NULL;
m_pListTail = NULL;
m_pGarbageTop = NULL;
m_ListCount = 0;
m_GarbageLength = 0;
m_GarbageCount = 0;
}
//Interface////////////////////////////////////////////////////////////////////////////////////
//
// TList 소멸자 [ public ]
// - 리스트 제거
// - 가비지 스택 제거
//
///////////////////////////////////////////////////////////////////////////////////////////////
template <class LIST> TList<LIST>::~TList(void)
{
if(m_pListHead != NULL)
DeleteAllFromList();
if(m_pGarbageTop != NULL)
ClearGarbageStack();
}
//Interface////////////////////////////////////////////////////////////////////////////////////
//
// Create [ public ]
// - 핸들 데이터 생성
//
// Parameter :
//
// Return:
// 성공시 핸들 데이터 포인터 값
//
///////////////////////////////////////////////////////////////////////////////////////////////
template <class LIST> LPLIST TList<LIST>::Create(void)
{
LPLIST pList = NULL;
if(m_GarbageCount)
{
if((pList = PopItemFromGarbage()) != NULL)
{
pList->pNext = NULL;
return pList;
}
}
pList = new LIST;
pList->pNext = NULL;
return pList;
}
//Interface////////////////////////////////////////////////////////////////////////////////////
//
// Delete [ public ]
// - 핸들 데이터 제거
//
// Parameter :
// 1st : 핸들 데이터 포인터
//
// Return:
// 성공시 true
//
///////////////////////////////////////////////////////////////////////////////////////////////
template <class LIST> bool TList<LIST>::Delete(LPLIST pDelete_In)
{
if(pDelete_In == NULL)
return false;
if(PushItemToGarbage(pDelete_In))
return true;
delete pDelete_In;
return true;
}
//Interface////////////////////////////////////////////////////////////////////////////////////
//
// InsertToList [ public ]
// - 데이터 리스트에 추가
//
// Parameter :
// 1st : 데이터 포인터
//
// Return:
// 성공시 true
//
///////////////////////////////////////////////////////////////////////////////////////////////
template <class LIST> bool TList<LIST>::InsertToList(LPLIST pInsert_In)
{
if(pInsert_In == NULL)
return false;
if(m_pListHead == NULL)
{
m_pListHead = pInsert_In;
m_pListTail = m_pListHead;
m_ListCount++;
return true;
}
m_pListTail->pNext = pInsert_In;
m_pListTail = pInsert_In;
m_ListCount++;
return true;
}
//Interface////////////////////////////////////////////////////////////////////////////////////
//
// DeleteFromList [ public ]
// - 데이터 리스트에서 삭제
//
// Parameter :
// 1st : 데이터 포인터
//
// Return:
// 성공시 true
//
///////////////////////////////////////////////////////////////////////////////////////////////
template <class LIST> bool TList<LIST>::DeleteFromList(LPLIST pDelete_In)
{
LPLIST pPosition;
if(pDelete_In == NULL)
return false;
if(m_pListHead == pDelete_In)
{
m_pListHead = m_pListHead->pNext;
if(Delete(pDelete_In))
{
m_ListCount--;
}
return true;
}
else
{
for(pPosition = m_pListHead; pPosition; pPosition = pPosition->pNext)
{
if(pPosition->pNext == pDelete_In)
{
if(m_pListTail == pDelete_In)
m_pListTail = pPosition;
pPosition->pNext = pDelete_In->pNext;
if(Delete(pDelete_In))
{
m_ListCount--;
}
return true;
}
}
}
return false;
}
//Interface////////////////////////////////////////////////////////////////////////////////////
//
// DeleteAllFromList [ public ]
// - 데이터 리스트 모두 삭제
//
// Parameter :
//
// Return:
// 성공시 true
//
///////////////////////////////////////////////////////////////////////////////////////////////
template <class LIST> bool TList<LIST>::DeleteAllFromList(void)
{
LPLIST pDelete;
while(m_pListHead)
{
pDelete = m_pListHead;
m_pListHead = m_pListHead->pNext;
if(!Delete(pDelete))
return false;
}
m_ListCount = 0;
m_pListTail = m_pListHead;
return true;
}
//Interface////////////////////////////////////////////////////////////////////////////////////
//
// IsExistHandleFromList [ public ]
// - 리스트 확인
//
// Parameter :
// 1st : 데이터 포인터
//
// Return:
// 성공시 true
//
///////////////////////////////////////////////////////////////////////////////////////////////
template <class LIST> bool TList<LIST>::IsExistHandleFromList(LPLIST pFind_In)
{
LPLIST pPosition = m_pListHead;
while(pPosition)
{
if(pFind_In == pPosition)
return true;
pPosition = pPosition->pNext;
}
return false;
}
//Interface////////////////////////////////////////////////////////////////////////////////////
//
// GetHandleWithCount [ public ]
// - 카운트로 데이터 얻기
//
// Parameter :
// 1st : 카운트
//
// Return:
// 성공시 데이터 포인터
//
///////////////////////////////////////////////////////////////////////////////////////////////
template <class LIST> LPLIST TList<LIST>::GetHandleWithCount(int Count_In)
{
LPLIST pList;
int Counter;
for(Counter = 0, pList = NULL; Counter <= Count_In && pList; Counter++, pList = pList->pNext);
return pList;
}
//Interface////////////////////////////////////////////////////////////////////////////////////
//
// SetGarbageStackLength [ public ]
// - 가비지 스택 길이 설정
//
// Parameter :
// 1st : 스택 길이
//
// Return:
// 성공시 true
//
///////////////////////////////////////////////////////////////////////////////////////////////
template <class LIST> bool TList<LIST>::SetGarbageStackLength(int StackLength_In)
{
LPLIST pList;
int Counter;
m_GarbageLength = StackLength_In;
if(m_GarbageCount > m_GarbageLength)
{
for(Counter = m_GarbageCount; Counter > m_GarbageLength; Counter--)
if(pList = PopItemFromGarbage())
{
delete pList;
}
else
break;
}
else
{
for(Counter = m_GarbageCount; Counter < m_GarbageLength; Counter++)
{
pList = new LIST;
if(!PushItemToGarbage(pList))
break;
}
}
if(m_GarbageCount == StackLength_In)
return true;
return false;
}
//Interface////////////////////////////////////////////////////////////////////////////////////
//
// ClearGarbageStack [ public ]
// - 가비지 스택 비움
//
// Parameter :
//
// Return:
// 성공시 true
//
///////////////////////////////////////////////////////////////////////////////////////////////
template <class LIST> bool TList<LIST>::ClearGarbageStack(void)
{
LPLIST pDelete;
if(m_pGarbageTop == NULL)
return false;
while(m_pGarbageTop)
{
pDelete = m_pGarbageTop;
m_pGarbageTop = m_pGarbageTop->pNext;
delete pDelete;
}
m_GarbageCount = 0;
return true;
}
///////////////////////////////////////////////////////////////////////////////////////////////
//
// PushItemToGarbage [ public ]
// - 가비지 리스트로 추가
//
// Parameter :
// 1st : 데이터 포인터
//
// Return:
// 성공시 Succeed, 잘못된 인자 Parameter, 예외 발생시 Exception
//
///////////////////////////////////////////////////////////////////////////////////////////////
template <class LIST> bool TList<LIST>::PushItemToGarbage(LPLIST pPush_In)
{
if(pPush_In == NULL || m_GarbageCount >= m_GarbageLength)
return false;
if(m_pGarbageTop == NULL)
{
pPush_In->pNext = NULL;
m_pGarbageTop = pPush_In;
}
else
{
pPush_In->pNext = m_pGarbageTop;
m_pGarbageTop = pPush_In;
}
m_GarbageCount++;
return true;
}
///////////////////////////////////////////////////////////////////////////////////////////////
//
// PopItemFromGarbage [ public ]
// - 가비지 리스트로부터 추출
//
// Parameter :
//
// Return:
// 성공시 데이터 포인터, 비어 있을 경우 Parameter, 예외 발생시 Exception
//
///////////////////////////////////////////////////////////////////////////////////////////////
template <class LIST> LPLIST TList<LIST>::PopItemFromGarbage(void)
{
LPLIST pPop;
if(m_pGarbageTop == NULL)
return NULL;
pPop = m_pGarbageTop;
m_pGarbageTop = m_pGarbageTop->pNext;
m_GarbageCount--;
return pPop;
}
#endif

View File

@@ -0,0 +1,14 @@
///////////////////////////////////////////////////////////////////////////////////////////////
//
// UDPList
//
///////////////////////////////////////////////////////////////////////////////////////////////
#include "UDPList.h"
UDPList::UDPList(void)
{
}
UDPList::~UDPList(void)
{
}

View File

@@ -0,0 +1,144 @@
///////////////////////////////////////////////////////////////////////////////////////////////
//
// UDPList
//
///////////////////////////////////////////////////////////////////////////////////////////////
#ifndef _CSocketHandleList
#define _CSocketHandleList
#define WIN32_LEAN_AND_MEAN
#include <winsock2.h>
#include <winsock.h>
#include "T_List.h"
typedef enum _PEERTYPE
{
Not_Defined = 0, // 정의 안됨
REAL_IP, // 리얼 IP
NAT_Friendly, // 가상 IP (같은 NAT)
NAT_Different // 가상 IP (다른 NAT)
} PEERTYPE;
typedef struct _UDP_LIST
{
DWORD CharID; // 캐릭터 아이디
PEERTYPE PeerType; // 전송 타입
SOCKADDR_IN PublicAddress; // 주소 Public
SOCKADDR_IN PrivateAddress; // 주소 Private
DWORD MoveTick; // 움직임 시간
_UDP_LIST* pNext;
}UDP_LIST, *LPUDP_LIST;
///////////////////////////////////////////////////////////////////////////////////////////////
//
// 클래스 정의
//
///////////////////////////////////////////////////////////////////////////////////////////////
class UDPList : public TList<UDP_LIST>
{
public:
UDPList(void);
~UDPList(void);
inline DWORD InsertIntoAddressList(DWORD CharID_In, SOCKADDR_IN PubAddress_In, SOCKADDR_IN PriAddress_In, PEERTYPE PeerType_In);
inline bool DeleteFromAddressList(DWORD CharID_In);
inline bool DeleteFromAddressList(SOCKADDR_IN Address_In);
inline LPUDP_LIST SearchFromAddressList(DWORD CharID_In);
inline LPUDP_LIST SearchFromAddressList(SOCKADDR_IN Address_In);
};
inline DWORD UDPList::InsertIntoAddressList(DWORD CharID_In, SOCKADDR_IN PubAddress_In, SOCKADDR_IN PriAddress_In, PEERTYPE PeerType_In)
{
LPUDP_LIST lpList = SearchFromAddressList(CharID_In);
if(lpList != NULL)
{
lpList->CharID = CharID_In;
lpList->PublicAddress = PubAddress_In;
lpList->PrivateAddress = PriAddress_In;
lpList->PeerType = PeerType_In;
return 1;
}
lpList = Create();
if(lpList != NULL)
{
lpList->CharID = CharID_In;
lpList->PublicAddress = PubAddress_In;
lpList->PrivateAddress = PriAddress_In;
lpList->PeerType = PeerType_In;
InsertToList(lpList);
return 2;
}
return 0;
}
inline bool UDPList::DeleteFromAddressList(DWORD CharID_In)
{
LPUDP_LIST lpList = SearchFromAddressList(CharID_In);
if(lpList != NULL)
{
DeleteFromList(lpList);
return true;
}
return false;
}
inline bool UDPList::DeleteFromAddressList(SOCKADDR_IN Address_In)
{
LPUDP_LIST lpList = SearchFromAddressList(Address_In);
if(lpList != NULL)
{
DeleteFromList(lpList);
return true;
}
return false;
}
inline LPUDP_LIST UDPList::SearchFromAddressList(DWORD CharID_In)
{
LPUDP_LIST lpList;
lpList = m_pListHead;
while(lpList)
{
if(lpList->CharID == CharID_In)
return lpList;
lpList = lpList->pNext;
}
return NULL;
}
inline LPUDP_LIST UDPList::SearchFromAddressList(SOCKADDR_IN Address_In)
{
LPUDP_LIST lpList;
lpList = m_pListHead;
while(lpList)
{
if(lpList->PrivateAddress.sin_addr.S_un.S_addr == Address_In.sin_addr.S_un.S_addr && lpList->PrivateAddress.sin_port == Address_In.sin_port)
return lpList;
if(lpList->PublicAddress.sin_addr.S_un.S_addr == Address_In.sin_addr.S_un.S_addr && lpList->PublicAddress.sin_port == Address_In.sin_port)
return lpList;
lpList = lpList->pNext;
}
return NULL;
}
#endif

View File

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

View File

@@ -0,0 +1,143 @@
#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
{
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 unsigned short Error(void) { return m_SrvInfo.SrvState.wError; }
inline void SetError(unsigned short Error) { m_SrvInfo.SrvState.wError = Error; }
inline unsigned short GetError(void) { return m_SrvInfo.SrvState.wError; }
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) { 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;
#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;
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,141 @@
////////////////////////////////////////////////////////////////////////////////////////////////////
//
// 패킷 커맨드
//
////////////////////////////////////////////////////////////////////////////////////////////////////
#ifndef _PACKET_COMMAND_H_
#define _PACKET_COMMAND_H_
#include "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; // 캐릭터 채팅 (P2P)
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; // 캐릭터 파티 맴버 정보 전달 (P2P)
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 CmdCharSwitchHand = 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 CmdFinalPacketNum = 0x6A; // 마지막 패킷 번호
#endif

View File

@@ -0,0 +1,58 @@
#ifndef _ADDRESS_PACKET_H_
#define _ADDRESS_PACKET_H_
// AddressPacket.h
#include <Network/Packet/PacketBase.h>
#pragma pack(1)
// UDP 주소 서버 업데이트 ( Update Address )
// : 클라이언트가 로그인 후에 UDP로 서버로 한번 보내준다.
// : 서버는 클라이언트의 패킷으로 외부 UDP 주소를 얻는다.
typedef struct PktUA* LPPktUA;
struct PktUA : public PktBase
{
SOCKADDR_IN m_PrivateAddress;
unsigned long m_dwCharID;
};
// UDP 주소 서버 업데이트 Ack
typedef struct PktUAAck* LPPktUAAck;
struct PktUAAck : public PktBase
{
SOCKADDR_IN m_PublicAddress;
SOCKADDR_IN m_PrivateAddress;
unsigned long m_dwCharID;
};
// 주소 구조체
typedef struct AddressInfo* LPAddressInfo;
struct AddressInfo
{
SOCKADDR_IN m_PublicAddress;
SOCKADDR_IN m_PrivateAddress;
unsigned long m_dwCharID;
AddressInfo() : m_dwCharID(0)
{
memset(&m_PublicAddress, 0, sizeof(m_PublicAddress));
memset(&m_PrivateAddress, 0, sizeof(m_PrivateAddress));
}
AddressInfo(const SOCKADDR_IN& PublicAddress, const SOCKADDR_IN& PrivateAddress, const unsigned long dwCharID)
: m_PublicAddress(PublicAddress), m_PrivateAddress(PrivateAddress), m_dwCharID(dwCharID) { }
};
// UDP 주소 정보 패킷 ( Address Info )
// - 어드레스 구조체
typedef struct PktAI* LPPktAI;
struct PktAI : public PktBase
{
AddressInfo m_AddressInfo;
};
#pragma pack()
#endif

View File

@@ -0,0 +1,135 @@
#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;
};
// 유저 로그인 응답 DBAgentServer -> AuthServer
typedef struct PktULDAck* LPPktULDAck;
struct PktULDAck : public PktDD
{
unsigned long m_dwUserID;
CHAR_VIEW m_CharView[3];
};
// 유저 로그아웃 AuthServer -> DBAgentServer
typedef struct PktULoD *LPPktULoD;
struct PktULoD : public PktDD
{
unsigned long m_dwSessionID;
unsigned long m_dwUserID;
};
// 세션 시작 DBAgentServer -> AuthServer
typedef struct PktSSD *LPPktSSD;
struct PktSSD : public PktDD
{
unsigned long m_dwSessionID;
unsigned long m_dwUserID;
};
// ---------------------------------------------------------
// ---------------------------------------------------------
// 캐릭터 생성 요청 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 = 2 };
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;
};
// ---------------------------------------------------------
// ---------------------------------------------------------
// 캐릭터 생성 아이템 관련 (데이터)
typedef struct PktCCID* LPPktCCID;
struct PktCCID : public PktDD
{
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,55 @@
#ifndef _CHAR_ADMIN_PACKET_H_
#define _CHAR_ADMIN_PACKET_H_
// CharAdminPacket.h
#include <winsock2.h>
#include <windows.h>
#include <Network/Packet/PacketBase.h>
#include <DB/DBdefine.h>
#pragma pack(1)
typedef struct PktAdmin* LPPktAdmin;
struct PktAdmin : public PktBase
{
enum { MAX_NAME_LEN = 16 };
enum CMD
{
NONE = 0, // 운영자 명령
MOVE_ZONE_C = 1, // 캐릭터 존 이동
MOVE_ZONE_P = 2, // 파티 존 이동
MOVE_C = 3, // 캐릭터 이동
MOVE_P = 4, // 파티 이동
RESPAWN_C = 5, // 캐릭터 리스폰
RESPAWN_P = 6, // 파티 리스폰
KILL_C = 7, // 캐릭터 킬
KILL_P = 8, // 파티 킬
DUELINIT = 9, // 듀얼 초기화
CREATEITEM = 10, // 아이템 드롭
CREATEMON = 11, // 몬스터 생성
INFO_C = 12 // 캐릭터 정보
};
unsigned short m_usCmd; // 운영자 명령
char m_stName[MAX_NAME_LEN]; // 이름
union
{
struct ZoneInfo
{
char m_cZone; // 존 번호
char m_cChannel; // 채널 번호
} m_ZoneInfo;
unsigned short m_usProtoTypeID; // 타입 아이디
};
POS m_Position; // 위치
};
#pragma pack()
#endif

View File

@@ -0,0 +1,181 @@
#ifndef _CHAR_ATTACK_PACKET_H_
#define _CHAR_ATTACK_PACKET_H_
// CharAttackPacket.h
#include <DB/DBDefine.h>
#include <Network/Packet/PacketBase.h>
#include "CharAttackPacketStruct.h"
#pragma pack(1)
// 캐릭터 공격 패킷
typedef struct PktAt* LPPktAt;
struct PktAt : public PktBase
{
POS m_Postion; // 공격자 캐릭터 위치
float m_fDir; // 공격자 방향
unsigned long m_dwCharID; // 공격자 캐릭터 아이디
AtType m_AtType; // 공격 타입
AtNode m_AtNode; // 방어자 정보
};
// 캐릭터 공격 패킷 Ack (가변 길이) + 방어자 노드
typedef struct PktAtAck* LPPktAtAck;
struct PktAtAck : public PktBase
{
enum PktAtAckErr
{
NO_SERVER_ERR = 0,
SERVER_ERROR = 1,
FAIL_ATTACK = 2,
FAIL_ALREADY_DEAD = 2
};
unsigned long m_dwCharID; // 공격자 캐릭터 아이디
AtType m_AtType; // 공격 타입
unsigned short m_wHP; // 공격자 HP
unsigned short m_wMP; // 공격자 MP
unsigned char m_cJudge; // 플래그
unsigned char m_cDefenserNum; // 방어자 수
unsigned char m_cRightHandValue; // 사용한 무기 감소도(오른손, 내구도 감소 용)
unsigned char m_cLeftHandValue; // 사용한 무기 감소도(왼손, 내구도 감소 용)
unsigned char m_cRightHandIndex; // 사용한 무기 인덱스(오른손, 내구도 감소 용)
unsigned char m_cLeftHandIndex; // 사용한 무기 인덱스(왼손, 내구도 감소 용)
};
// 캐릭터 공격 정보 (가변 길이) + 방어자 노드
typedef struct PktAtInfo* LPPktAtInfo;
struct PktAtInfo : public PktBase
{
unsigned long m_dwCharID; // 캐릭터 ID
AtType m_AtType; // 공격 타입
unsigned char m_cDefenserNum; // 방어자 수
};
// 캐릭터 공격 받음 패킷
typedef struct PktAted* LPPktAted;
struct PktAted : public PktBase
{
POS m_Postion; // 공격자 위치
float m_fDir; // 공격자 방향
unsigned long m_dwCharID; // 공격자 캐릭터 ID
AtType m_AtType; // 공격 타입
unsigned short m_wMyHP; // 방어자 HP
unsigned short m_wMyMP; // 방어자 MP
unsigned char m_cJudge; // 판정 값
unsigned char m_cMyWeaponIndex; // 방어자 무기 인덱스(내구도 감소용)
unsigned char m_cMyWeaponValue; // 방어자 무기 감소도(내구도 감소용)
};
// 듀얼 명령
//
// 명령 :
// 0 = 제안, 1 = 수락, 2 = 거절, 3 = 로그아웃, 4 = 사망
//
// 에러 :
// 0 = 성공, 1 = 서버 에러, 2 = 이미 듀얼중인 캐릭터에게 듀얼 신청,
// 3 = 거부 옵션이 켜진 상태
typedef struct PktDuC* LPPktDuC;
struct PktDuC : public PktBase
{
enum DuelCmd
{
DUC_PROPOSE = 0, DUC_READY = 1, DUC_REFUSE = 2,
DUC_LOGOUT = 3, DUC_DEAD = 4, DUC_PARTY_PROPOSE = 5,
DUC_PARTY_READY = 6, DUC_REQUEST_PARTY_INFO = 7, DUC_CANCEL = 8
};
enum PktDuCError
{
NO_SERVER_ERR = 0, SERVER_ERROR = 1, FAIL_DUELING_CHAR = 2,
FAIL_REJECT = 3, FAIL_NOT_LEADER = 4, FAIL_NOT_PARTY = 5
};
unsigned long m_dwSenderID; // 보낸이 아이디
unsigned long m_dwRecverID; // 받는이 아이디
unsigned char m_cCmd; // 명령
};
// 팀배틀 정보
typedef struct PktTBInfo* LPPktTBInfo;
struct PktTBInfo : public PktBase
{
enum DuelCmd
{
DUC_PROPOSE = 0, DUC_READY = 1, DUC_REFUSE = 2,
DUC_LOGOUT = 3, DUC_DEAD = 4, DUC_PARTY_PROPOSE = 5,
DUC_PARTY_READY = 6, DUC_REQUEST_PARTY_INFO = 7
};
unsigned long m_dwCharID;
char m_strChallengerName[CHAR_INFOST::MAX_NAME_LEN];
unsigned char m_cCmd;
unsigned char m_cMemberNum;
};
// 캐릭터 챈트&인챈트 정보
typedef struct PktSpInfo* LPPktSpInfo;
struct PktSpInfo : public PktBase
{
unsigned long m_dwCharID; // 캐릭터 아이디
unsigned short m_nEnchantLevel; // 주문 레벨
unsigned char m_cSpellType; // 주문 타입 ( namespace Skill::SpellType참조 )
bool m_bOnOff; // 켜짐/꺼짐
};
// 캐릭터 리스폰
typedef struct PktRs* LPPktRs;
struct PktRs : public PktBase
{
enum RespawnCmd
{
RS_NORMAL = 0, RS_SELECT = 1
};
unsigned long m_dwCharID;
unsigned char m_cCmd;
POS m_Position;
};
// 캐릭터 리스폰 Ack
typedef struct PktRsAck* LPPktRsAck;
struct PktRsAck : public PktBase
{
POS m_Position; // 현재 위치
__int64 m_dlExp; // 현재 경험점
unsigned long m_dwCharID; // 캐릭터 아이디
unsigned short m_wHP; // HP
unsigned short m_wMP; // MP
};
// 어워드 처리
typedef struct PktAw* LPPktAw;
struct PktAw : public PktBase
{
unsigned long m_dwCharID; // 캐릭터 ID
unsigned long m_dwExp; // 경험치
};
#pragma pack()
#endif

View File

@@ -0,0 +1,54 @@
#ifndef _CHAR_ATTACK_PACKET_STRUCT_H_
#define _CHAR_ATTACK_PACKET_STRUCT_H_
#pragma pack(1)
// 방어자 정보 ( 차후 서버에서 처리 시 없어질 구조체 )
typedef struct AtNode *LPAtNode;
struct AtNode
{
enum { MAX_DEFENDER_NUM = 10 };
unsigned char m_wDefenserNum; // 방어자 수
unsigned long m_dwDefenser[MAX_DEFENDER_NUM]; // 방어자 아이디
unsigned char m_cDefenserJudge[MAX_DEFENDER_NUM]; // 방어자 판정
};
// 공격 정보
typedef struct AtType* LPAtType;
struct AtType
{
enum { SkillBitMask = 0x8000 };
enum Attack
{
Normal = 0,
Move = 1,
ComboLast = 2,
Bow = 3,
CrossBow = 4
};
unsigned short m_wType; // 공격 타입 (또는 스킬 ID)
char m_cSkillLevel; // 스킬 레벨 (-127 ~ 128)
unsigned char m_cSkillLockCount : 4; // 스킬 락카운트 (0~5)
unsigned char m_cAtCount : 4; // 공격 카운트 (0~15)
};
// 방어자 노드
typedef struct DefenserNode* LPDefenserNode;
struct DefenserNode
{
unsigned long m_dwCharID; // 방어자 캐릭터 아이디
unsigned short m_wMaxHP; // 최대 HP
unsigned short m_sCurrHP; // 현재 HP
unsigned short m_wMaxMP; // 최대 MP
unsigned short m_sCurrMP; // 현재 MP
unsigned short m_wDamage; // 데미지 값
unsigned char m_cJudge; // 판정 값
};
#pragma pack()
#endif

View File

@@ -0,0 +1,329 @@
#ifndef _CHAR_COMMUNITY_PACKET_H_
#define _CHAR_COMMUNITY_PACKET_H_
// CharCommunityPacket.h
// DBDefine필요.
#include <Network/Packet/PacketBase.h>
#include <Network/Packet/PacketStruct/DataPacket.h>
#include <Network/Packet/PacketStruct/CharItemPacketStruct.h>
#include "AddressPacket.h"
#include "CharCommunityPacketStruct.h"
#pragma pack(1)
// 파티 생성
typedef struct PktPI* LPPktPI;
struct PktPI : public PktBase
{
PARTY m_Party;
};
// 파티 명령
//
// 명령 :
// 0 = 초대, 1 = 가입, 2 = 거절
// 3 = 퇴장, 4 = 탈퇴, 5 = 양도
// 6 = 파괴, 7 = 로그인, 8 = 로그아웃
// 9 = 삭제(캐릭터), 10 = 재로그인,
// 11 = 파티찾기, 12 = 멤버찾기
//
// 에러 :
// 1 = 서버 에러, 2 = 이미 파티에 가입되어 있는 경우, 3 = 가입 실패
// 4 = 퇴장 실패, 5 = 탈퇴 실패, 6 = 양도 실패, 7 = 파티 인원 초과,
// 8 = 초대 실패, 9 = 거부 옵션을 켠 상태
//
typedef struct PktPC* LPPktPC;
struct PktPC : public PktBase
{
enum PartyCmd
{
PC_INVITE = 0, PC_ACCEPT = 1, PC_REFUSE = 2,
PC_BANISH = 3, PC_SECESSION = 4, PC_TRANSFER = 5,
PC_DESTROY = 6, PC_LOGIN = 7, PC_LOGOUT = 8,
PC_DELETE = 9, PC_RELOGIN = 10, PC_FINDPARTY = 11,
PC_FINDMEMBER = 12
};
enum PktPCError
{
SERVER_ERROR = 1, CHAR_JOINED = 2, FAIL_ACCEPT = 3,
FAIL_BANISH = 4, FAIL_SECESSION = 5, FAIL_TRANSFER = 6,
OVER_MEMBER = 7, FAIL_INVITE = 8, FAIL_REJECT = 9
};
unsigned long m_dwPartyID; // 파티 아이디
unsigned long m_dwSenderID; // 캐릭터 아이디(주체)
unsigned long m_dwReferenceID; // 참조 아이디(대상 캐릭터/서버 아이디)
unsigned short m_wCmd; // 명령
};
//
// 파티 명령 Ack
//
// 명령 :
// 0 = 초대, 1 = 가입, 2 = 거절
// 3 = 퇴장, 4 = 탈퇴, 5 = 양도
// 6 = 파괴, 7 = 로그인, 8 = 로그아웃
// 9 = 삭제(캐릭터)
//
// 에러 :
// 1 = 서버 에러, 2 = 이미 파티에 가입되어 있는 경우, 3 = 가입 실패
// 4 = 퇴장 실패, 5 = 탈퇴 실패, 6 = 양도 실패, 7 = 파티 인원 초과
//
typedef struct PktPCAck* LPPktPCAck;
struct PktPCAck : public PktBase
{
enum PartyCmd
{
PC_INVITE = 0, PC_ACCEPT = 1, PC_REFUSE = 2,
PC_BANISH = 3, PC_SECESSION = 4, PC_TRANSFER = 5,
PC_DESTROY = 6, PC_LOGIN = 7, PC_LOGOUT = 8,
PC_DELETE = 9
};
enum PktPCErrorAck
{
SERVER_ERROR = 1, CHAR_JOINED = 2, FAIL_ACCEPT = 3,
FAIL_BANISH = 4, FAIL_SECESSION = 5, FAIL_TRANSFER = 6,
OVER_MEMBER = 7, FAIL_INVITE = 8
};
AddressInfo m_SenderAddressInfo; // Sender의 주소
char m_strSenderName[CHAR_INFOST::MAX_NAME_LEN]; // Sender의 이름
unsigned long m_dwPartyID; // 파티 아이디
unsigned long m_dwSenderID; // 캐릭터 아이디(주체)
unsigned long m_dwReferenceID; // 참조 아이디(대상 캐릭터/서버 아이디)
unsigned char m_cCmd; // 명령
};
//
// 파티 정보
//
// 명령 :
// 0 = 초대, 1 = 가입, 2 = 거절
// 3 = 퇴장, 4 = 탈퇴, 5 = 양도
// 6 = 파괴, 7 = 로그인, 8 = 로그아웃
// 9 = 삭제(캐릭터)
//
// 에러 :
// 1 = 서버 에러, 2 = 이미 파티에 가입되어 있는 경우, 3 = 가입 실패
// 4 = 퇴장 실패, 5 = 탈퇴 실패, 6 = 양도 실패, 7 = 파티 인원 초과
//
typedef struct PktPCInfo* LPPktPCInfo;
struct PktPCInfo : public PktBase
{
enum PartyCmd
{
PC_INVITE = 0, PC_ACCEPT = 1, PC_REFUSE = 2,
PC_BANISH = 3, PC_SECESSION = 4, PC_TRANSFER = 5,
PC_DESTROY = 6, PC_LOGIN = 7, PC_LOGOUT = 8,
PC_DELETE = 9
};
enum PktPCInfoError
{
SERVER_ERROR = 1, CHAR_JOINED = 2, FAIL_ACCEPT = 3,
FAIL_BANISH = 4, FAIL_SECESSION = 5, FAIL_TRANSFER = 6,
OVER_MEMBER = 7, FAIL_INVITE = 8
};
unsigned long m_dwPartyID; // 파티 ID
unsigned long m_dwMemberID; // 멤버 ID
unsigned char m_cCmd; // 명령
};
// 파티 멤버 데이터 (+ 가변길이 데이터)
typedef struct PktMD* LPPktMD;
struct PktMD : public PktBase
{
unsigned long m_dwCharID; // 캐릭터 아이디
unsigned short m_wCmd; // 서브 명령
unsigned short m_wLen; // 길이
};
// 파티 멤버 정보
typedef struct PktPM* LPPktPM;
struct PktPM : public PktBase
{
SOCKADDR_IN m_PublicAddress;
SOCKADDR_IN m_PrivateAddress;
unsigned long m_dwCharID; // 캐릭터 아이디
unsigned long m_dwPartyID; // 파티 아이디
unsigned long m_dwChant; // 챈트 상태
unsigned long m_dwEnchant; // 인챈트 상태
unsigned short m_wMaxHP; // 최대 HP
unsigned short m_sCurrHP; // 현재 HP
unsigned short m_wMaxMP; // 최대 MP
unsigned short m_sCurrMP; // 현재 MP
unsigned char m_cClass; // 캐릭터 클래스
unsigned char m_cLevel; // 캐릭터 레벨
};
// 파티 찾기
typedef struct PktPF* LPPktPF;
struct PktPF : public PktBase
{
unsigned long m_dwCharID;
};
// 파티 찾기 Ack
typedef struct PktPFAck* LPPktPFAck;
struct PktPFAck : public PktBase
{
enum { MAX_LIST = 30, MAX_DIFF_LEVEL_VIEW = 5 };
unsigned long m_dwCharID; // 캐릭터 아이디
unsigned char m_cMemberFindPartyNum; // 파티 찾기 리스트 수
unsigned char m_cPartyFindMemberNum; // 파티원 찾기 리스트 수
};
// 캐릭터 명성(공헌도) 정보
typedef struct PktFI* LPPktFI;
struct PktFI : public PktBase
{
enum InfoKind
{
NONE = 0,
FAME = 1,
MERITS = 2
};
unsigned long m_dwCharID; // 캐릭터 아이디
unsigned char m_cInfoKind; // 정보 종류
};
// 캐릭터 명성(공헌도) 정보 Ack
typedef struct PktFIAck* LPPktFIAck;
struct PktFIAck : public PktBase
{
enum InfoKind
{
NONE = 0,
FAME = 1,
MERITS = 2
};
unsigned long m_dwCharID; // 캐릭터 아이디
unsigned long m_dwFameOrMerits; // 현재 명성(또는 공헌도)
unsigned char m_cRankingByRace; // 종족별 순위
unsigned char m_cRankingByClass; // 클래스별 순위
unsigned char m_cInfoKind; // 정보 종류
};
// 옵션 조정
typedef struct PktCOp* LPPktCOp;
struct PktCOp : public PktBase
{
unsigned long m_dwCharID; // 캐릭터 아이디
RejectOption m_RejectOption; // 거부 옵션 비트셑
};
// 캐릭터 채팅 패킷.
typedef struct PktCt* LPPktCt;
struct PktCt : public PktBase
{
enum PktCtCmd
{
NORMAL = 0, PARTY = 1,
FRIEND = 2, GUILD = 3,
NOTICE = 4, CLIENT_LOG = 5,
STALL = 6,
PktCtMaxSize = 180
};
unsigned long m_dwCharID;
unsigned short m_sCmd;
};
// 캐릭터 속삭임 패킷.
typedef struct PktWh* LPPktWh;
struct PktWh : public PktBase
{
enum
{
SERVER_ERROR = 1,
FAIL_CHAR_LOGOUT = 2,
FAIL_REJECT = 3,
FAIL_ENEMY = 4,
PktWhMaxSize = 180
};
char m_SenderName[CHAR_INFOST::MAX_NAME_LEN];
char m_RecverName[CHAR_INFOST::MAX_NAME_LEN];
};
// 캐릭터 노점상 개설 패킷.
typedef struct PktStO* LPPktStO;
struct PktStO : public PktBase
{
enum { MAX_STALL_NAME_LEN = 32 };
unsigned long m_dwCharID;
char m_StallName[MAX_STALL_NAME_LEN];
};
// 캐릭터 노점상 물건 등록 패킷.
typedef struct PktStRI* LPPktStRI;
struct PktStRI : public PktBase
{
enum PktStRICmd
{
SC_REGISTER = 0,
SC_CHANGEPRICE = 1,
SC_CANCEL = 2
};
enum PktStRIEErr
{
SUCCESS = 0,
SERVER_ERROR = 1,
FAIL_NOT_ITEM = 2
};
unsigned long m_dwCharID;
TakeType m_TakeType;
unsigned long m_dwPrice;
unsigned char m_cCmd;
};
// 캐릭터 노점상 입장 패킷.
typedef struct PktStE* LPPktStE;
struct PktStE : public PktBase
{
enum PktStEErr
{
SUCCESS = 0,
SERVER_ERROR = 1,
FAIL_FULL_STALL = 2,
FAIL_ENTER = 3,
FAIL_LEAVE = 4
};
unsigned long m_dwCustomerID;
unsigned long m_dwOwnerID;
};
// 캐릭터 노점상 아이템 정보 패킷.
typedef struct PktStIInfo* LPPktStIInfo;
struct PktStIInfo : public PktBase
{
unsigned long m_dwItemSize;
unsigned short m_wItemNum;
};
#pragma pack()
#endif

View File

@@ -0,0 +1,52 @@
#ifndef _CHAR_COMMUNITY_PACKET_STRUCT_H_
#define _CHAR_COMMUNITY_PACKET_STRUCT_H_
#pragma pack(1)
#include <DB/DBDefine.h>
// 파티 찾기 구조체
typedef struct MemberFindParty* LPMemberFindParty;
struct MemberFindParty
{
char m_strName[CHAR_INFOST::MAX_NAME_LEN]; // 이름
unsigned char m_cLevel; // 레벨
unsigned char m_cClass; // 클래스
};
// 파티원 찾기 구조체
typedef struct PartyFindMember* LPPartyFindMember;
struct PartyFindMember
{
char m_strLeaderName[CHAR_INFOST::MAX_NAME_LEN]; // 리더 이름
unsigned char m_cAverageLevel; // 평균 레벨
unsigned char m_cMemberNum; // 멤버 수
};
// 거부 옵션
typedef struct RejectOption* LPRejectOption;
struct RejectOption
{
union
{
struct RejectStruct
{
unsigned short m_Party : 1;
unsigned short m_Exchange : 1;
unsigned short m_Duel : 1;
unsigned short m_Whisper : 1;
unsigned short m_Remainder : 12;
};
RejectStruct Reject;
unsigned short m_wReject;
};
RejectOption() : m_wReject(0) { }
RejectOption(unsigned short wReject) : m_wReject(wReject) { }
};
#pragma pack()
#endif

View File

@@ -0,0 +1,451 @@
#ifndef _CHAR_ITEM_PACKET_H_
#define _CHAR_ITEM_PACKET_H_
// CharItemPacket.h
// ItemStructure.h을 포함해야 함. (집기, 떨구기, )
#include <Item/ItemStructure.h>
#include <Network/Packet/PacketBase.h>
#include "CharItemPacketStruct.h"
#pragma pack(1)
// 집기 패킷 (응답 필요)
typedef struct PktPU* LPPktPU;
struct PktPU : public PktBase
{
unsigned long m_dwCharID; // 캐릭터 아이디
unsigned long m_dwObjectID; // 오브젝트 아이디
Item::ItemPos m_itemPos; // 아이템 위치
};
// 집기 패킷 Ack
typedef struct PktPUAck* LPPktPUAck;
struct PktPUAck : public PktBase
{
enum ObjectType { Item = 0, Gold = 1 };
enum PktPUAckError
{
SERVER_ERROR = 1,
FAIL_GET_CELL = 2,
FAIL_GET_ITEM = 3,
FAIL_PICKUP_INVEN = 4
};
unsigned long m_dwCharID; // 캐릭터 아이디
unsigned long m_dwObjectID; // 오브젝트 아이디
unsigned long m_dwSize; // Object크기(혹은 돈 양)
Item::ItemPos m_itemPos; // 아이템이 놓일 위치
unsigned char m_cType; // Object종류(아이템 혹은 돈)
unsigned char m_cNum; // 아이템 개수
};
// 집기 정보
typedef struct PktPUInfo PktPUInfo, *LPPktPUInfo;
struct PktPUInfo : public PktBase
{
unsigned long m_dwCharID; // 캐릭터 정보
unsigned long m_dwObjectID; // 오브젝트 아이디
};
// 떨구기 (응답 필요)
typedef struct PktPD* LPPktPD;
struct PktPD : public PktBase
{
unsigned long m_dwCharID; // 캐릭터 아이디
Item::ItemPos m_itemPos; // 아이템 위치 및 인덱스
unsigned char m_cNum; // 아이템 개수
};
// 떨구기 Ack
typedef struct PktPDAck* LPPktPDAck;
struct PktPDAck : public PktBase
{
enum PktPDAckError
{
SERVER_ERROR = 1,
FAIL_GET_CELL = 2,
FAIL_DROP_INVEN = 3,
FAIL_DROP_FIELD = 4,
FAIL_ZERO_ITEM = 5
};
unsigned long m_dwCharID; // 캐릭터 아이디
FieldObject m_FieldObject; // FieldObject
Item::ItemPos m_itemPos; // 아이템 위치 및 인덱스
};
// 떨구기 정보
typedef struct PktPDInfo* LPPktPDInfo;
struct PktPDInfo : public PktBase
{
unsigned long m_dwCharID;
FieldObject m_FieldObject;
};
// 셀 정보
typedef struct PktCeInfo* LPPktCeInfo;
struct PktCeInfo : public PktBase
{
unsigned char m_cObjectNum; // 오브젝트 개수
};
// 아이템 처리 패킷 (응답 필요)
typedef struct PktTI* LPPktTI;
struct PktTI : public PktBase
{
enum PktTIError
{
SERVER_ERROR = 1,
FAIL_MOVE = 2
};
unsigned long m_dwCharID; // 캐릭터 아이디
TakeType m_TakeType; // 아이템 집기 구조체
};
// 돈 처리 패킷 (응답 필요)
typedef struct PktTG* LPPktTG;
struct PktTG : public PktBase
{
enum PktTGError
{
SERVER_ERROR = 1,
FAIL_MOVE = 2,
GOLD_OVERFLOW = 3
};
unsigned long m_dwCharID; // 캐릭터 아이디
unsigned long m_dwGold; // 돈 액수
unsigned char m_cSrcPos : 4; // Src위치 - TakeType 참조
unsigned char m_cDstPos : 4; // Dst위치 - TakeType 참조
};
// 아이템 처리 패킷 (응답 필요)
typedef struct PktTIs* LPPktTIs;
struct PktTIs : public PktBase
{
enum PktTlsError
{
SERVER_ERROR = 1
};
unsigned long m_dwCharID; // 캐릭터 아이디
unsigned char m_TakeNum; // 아이템 집기 숫자
};
// 아이템 스왑 패킷
typedef struct PktSwI* LPPktSwI;
struct PktSwI : public PktBase
{
enum PktSwlError
{
SERVER_ERROR = 1,
FAIL_SRC_MOVE = 2,
FAIL_DST_MOVE = 3,
CANT_SWAP = 4
};
unsigned long m_dwCharID; // - 캐릭터 아이디
TakeType m_SwapSrc; // - 스왑 소스 아이템 집기 구조체
TakeType m_SwapDst; // - 스왑 대상 아이템 집기 구조체
};
// 아이템 거래 패킷
typedef struct PktTr* LPPktTr;
struct PktTr : public PktBase
{
enum PktTrError
{
NO_SERVER_ERR = 0,
SERVER_ERROR = 1,
FAIL_DROP_INVEN = 2,
WRONG_NPC = 3,
FAIL_ITEM_BUY = 4,
FAIL_PUT_INVEN = 5
};
unsigned long m_dwCustomerID; // 손님 아이디
unsigned long m_dwOwnerID; // 상점 주인 아이디 (NPC 또는 캐릭터)
unsigned short m_wBuyItemID; // 사려고 하는 아이템 종류 ID (0이면 팔기)
TakeType m_TakeType; // 아이템 집기 구조체
};
// 아이템 거래 패킷 Ack (+ 가변길이 아이템)
typedef struct PktTrAck* LPPktTrAck;
struct PktTrAck : public PktBase
{
unsigned long m_dwCharID; // 캐릭터 아이디
unsigned long m_dwNPCID; // 상점 NPC 아이디
unsigned long m_dwGold; // 현재 소지금
unsigned short m_wSize; // 아이템 크기(0 = 팔기, 0이 아니면 사기)
Item::ItemPos m_itemPos; // 아이템 위치
unsigned char m_cNum; // 아이템 갯수
};
// 아이템의 수리 패킷 (응답 필요)
typedef struct PktRpI* LPPktRpI;
struct PktRpI : public PktBase
{
enum Pos
{
EQUIPMENT = 1,
INVENTORY = 2,
EQUIPMENT_ALL = 3,
INVENTORY_ALL = 4,
};
unsigned long m_dwCharID; // 캐릭터 아이디
unsigned long m_dwGold; // 수리 비용
Item::ItemPos m_itemPos; // 수리 아이템 위치
};
// 아이템의 사용 패킷 (응답 필요)
typedef struct PktUI* LPPktUI;
struct PktUI : public PktBase
{
enum PktUIAck
{
SERVER_ERROR = 1,
USE_FAILED = 2
};
unsigned long m_dwSender; // 사용자 아이디
unsigned long m_dwRecver; // 대상자 아이디
Item::ItemPos m_itemPos; // 사용 아이템 위치
};
// 오브젝트 던지기 패킷 ( 응답 필요 )
typedef struct PktCO* LPPktCO;
struct PktCO : public PktBase
{
CastObject m_sCastObject;
unsigned long m_dwSenderID; // 던지는 사람
unsigned long m_dwReceiverID; // 받는 사람
};
// 오브젝트 던지기 패킷 (Cast Object)
typedef struct PktCOInfo* LPPktCOInfo;
struct PktCOInfo : public PktBase
{
CastObject m_sCastObject;
unsigned long m_dwSenderID; // 던지는 사람
unsigned long m_dwReceiverID; // 받는 사람
};
// 소켓 설치 패킷
typedef struct PktIS* LPPktIS;
struct PktIS : public PktBase
{
unsigned long m_dwCharID;
Item::ItemPos m_equipPos; // 장비 위치
Item::ItemPos m_gemPos; // 보석 위치
};
// 소켓 설치 패킷 Ack (+ 소켓이 설치된 장비 아이템)
typedef struct PktISAck* LPPktISAck;
struct PktISAck : public PktBase
{
unsigned long m_dwCharID;
Item::ItemPos m_equipPos; // 장비 위치
Item::ItemPos m_gemPos; // 보석 위치
unsigned char m_wSize; // 아이템 크기
};
// 업그레이드 아이템
typedef struct PktUgI* LPPktUgI;
struct PktUgI : public PktBase
{
unsigned long m_dwCharID; // 캐릭터 아이디
unsigned char m_cMineralNum; // 광물 숫자
};
// 업그레이드 아이템 Ack (+ 아이템 구조체)
typedef struct PktUgIAck* LPPktUgIAck;
struct PktUgIAck : public PktBase
{
unsigned long m_dwCharID; // 캐릭터 아이디
unsigned char m_cSize; // 아이템 크기
};
// 아이템 스플릿 요청 (응답 필요)
typedef struct PktSplt* LPPktSplt;
struct PktSplt : public PktBase
{
unsigned long m_dwCharID; // 캐릭터 아이디
TakeType m_TakeType; // 아이템 집기 구조체
// ( Src : 나눌 아이템, Dst : 나누어서 놓을 자리(항상 비어 있어야 함),
// Num : 나눌 아이템 개수)
};
// 아이템 스플릿 Ack (응답 필요) (+ 가변길이 아이템 구조체 (나누어서 생긴 아이템 정보))
typedef struct PktSpItAck* LPPktSpItAck;
struct PktSpItAck : public PktBase
{
enum PktSpltAckError
{
SERVER_ERROR = 1,
FAIL_SPLIT = 2
};
unsigned long m_dwCharID; // 캐릭터 아이디
TakeType m_TakeType; // 아이템 집기 구조체
unsigned char m_cSize; // 아이템 크기
};
// 퀵 슬롯 이동 (응답 필요)
typedef struct PktQSM* LPPktQSM;
struct PktQSM : public PktBase
{
enum PktQSMError
{
SERVER_ERROR = 1,
FAIL_MOVE = 2
};
TakeType m_TakeType;
};
// 스위치 핸드
typedef struct PktSwH* LPPktSwH;
struct PktSwH : public PktBase
{
unsigned char m_cSelect; // 선택 핸드 ( 1 = 무기1 & 방패1, 2 = 무기2 & 방패2 )
};
// 교환 명령
//
// 명령 :
// 0 = 제안, 1 = 수락, 2 = 거절, 3 = 확인, 4 = 확인 취소, 5 = 거래 성립, 6 = 거래 취소
//
// 에러 :
// 0 = 성공, 1 = 서버 에러, 2 = 이미 교환중인 캐릭터에게 교환 신청,
// 3 = 양쪽 모두 확인하지 않은 상태에서 거래 성립, 4 = 거부 옵션이 켜진 상태
//
typedef struct PktExC* LPPktExC;
struct PktExC : public PktBase
{
enum ExchageCmd
{
EXC_PROPOSE = 0, EXC_ACCEPT = 1, EXC_REFUSE = 2,
EXC_OK = 3, EXC_CANCEL = 4, EXC_EXCHANGE = 5,
EXC_QUIT = 6, EXC_LOCK = 7, EXC_UNLOCK = 8
};
enum PktExCError
{
NO_SERVER_ERR = 0, SERVER_ERROR = 1, FAIL_EXCHANGING_CHAR = 2,
FAIL_NOT_ALL_OK = 3, FAIL_REJECT = 4
};
unsigned long m_dwSenderID; // 보낸이 아이디
unsigned long m_dwRecverID; // 받는이 아이디
unsigned char m_cCmd; // 명령
};
// 교환 아이템 (+ 아이템 구조체)
typedef struct PktExI* LPPktExI;
struct PktExI : public PktBase
{
enum Type
{
Item = 0,
Gold = 1,
Remove = 2
};
unsigned long m_dwCharID; // 캐릭터 아이디
unsigned long m_dwSize; // 아이템 데이터 크기(혹은 돈 양)
Item::ItemPos m_itemPos; // 아이템 위치
unsigned char m_cType; // 아이템 종류(아이템 = 0, 돈 = 1)
unsigned char m_cNum; // 아이템 개수(stack아이템인 경우, 개수만 보냄)
};
namespace Deposit
{
enum Const { PASSWORD_LENGTH = 4 };
};
// 창고 패킷 (GameServer <--> DBAgent)
// 로그인시에, PktDBUpdate를 보낸 후, PktDepositUpdateDB를 여러개 준다.
// 마지막 패킷에 m_bUpdateComplete를 true로 Set해 준다.
// 게임 중에는 게임 서버가 수시로 Update를 한다.
typedef struct PktDepositUpdateDB* LPPktDepositUpdateDB;
struct PktDepositUpdateDB : public PktBase
{
enum TabFlag
{
ITEM_TAB1 = ( 1 << 0 ),
ITEM_TAB2 = ( 1 << 1 ),
ITEM_TAB3 = ( 1 << 2 ),
ITEM_TAB4 = ( 1 << 3 ),
USED_DEPOSIT = ( 1 << 30), // 0 : 창고 사용 X, 1 : 창고 사용함.
SAVED_PASSWORD = ( 1 << 31) // 0 : NOSAVE 1 : SAVE
};
enum TabNum
{
TAB_12 = 0,
TAB_34 = 1,
};
unsigned long m_dwUID; // 캐릭터 UID
unsigned long m_dwCID; // 캐릭터 CID
unsigned long m_dwTabFlag; // 현재 탭의 구입 상태를 나타내는 bitset
unsigned short m_usDataSize; // 탭(혹은 암호) 데이터 크기. 암호인 경우는 Deposit::PASSWORD_LENGTH와 같아야 한다.
unsigned char m_cTabNum; // password인 경우는 PASSWORD_TABNUM임
bool m_bUpdateComplete; // 업데이트가 완료되는 경우, true로 set.
};
// 창고 패킷 (Client <--> GameServer)
struct PktDeposit : public PktBase
{
enum CMD
{
LOGIN = 1, // Ack있음(Ack데이터 없음) (Client<->GameServer) szData[0]~[3]는 password, 그 다음에 암호 저장 여부 1byte (0, 1)
BUY_TAB = 2, // Ack있음(Ack데이터 없음) (Client<->GameServer) szData[0]에 사용할 탭 번호를 넣어 줌
RETURN_TAB = 3, // Ack있음(Ack데이터 없음) (Client<->GameServer) szData[0]에 사용할 탭 번호를 넣어 줌, 아직 구현되지 않음
LOGOUT = 4, // Ack있음 (Client->GameServer) 데이터 없음.
CHANGE_PASS = 5, // Ack있음 (Client->GameServer) szData[0]~[3]는 password. 인증된 상태에서만 가능.
SAVED_PASS = 6, // Ack없음 (GameServer -> Client) 게임 로그인시 줌. szData[0]~[3]는 Gold, [4]는 암호 저장 여부 1byte (0, 1)
PASSWORD = 7, // AgentServer -> GameServer (CID, Password), GameServer -> AgentServer (UID, Password)
GOLD = 8 // AgentServer -> GameServer (CID, Gold), GameServer -> AgentServer (UID, Gold)
};
enum DepositError
{
SERVER_ERROR = 1,
INSUFFICIENT_MONEY = 2,
AUTH_FAILED = 3,
INVALID_ARGUMENT = 4
};
enum { MIN_DATA_SIZE = Deposit::PASSWORD_LENGTH + 4 };
unsigned char m_cCmd;
char m_szData[MIN_DATA_SIZE];
};
#pragma pack()
#endif

View File

@@ -0,0 +1,58 @@
#ifndef _CHAR_ITEM_PACKET_STRUCT_H_
#define _CHAR_ITEM_PACKET_STRUCT_H_
#include <DB/DBDefine.h>
#include <Item/ItemStructure.h>
#pragma pack(1)
// 필드 오브젝트 구조체
typedef struct FieldObject* LPFieldObject;
struct FieldObject
{
enum CheckBit { Gold = 0x80000000 };
POS m_Pos; // 아이템 위치
unsigned long m_dwOID; // 오브젝트 아이디 ( 몬스터 혹은 Object )
unsigned long m_dwTypeID; // 타입 아이디 (상위 1비트 셋이면 돈)
unsigned long m_dwStatusFlag; // 몬스터 chant, enchant 상태 Flag
unsigned char m_cNum; // 아이템 수
};
// TakeType
typedef struct TakeType* LPTakeType;
struct TakeType
{
enum TakeSource
{
TS_NONE = 0, TS_EQUIP = 1,
TS_INVEN = 2, TS_QSLOT = 3,
TS_SSLOT = 4, TS_TEMP = 6,
TS_UPGRADE = 7, TS_EXCHANGE = 8,
TS_DEPOSIT = 9, TS_STALL = 10
};
Item::ItemPos m_srcPos;
Item::ItemPos m_dstPos;
unsigned char m_cNum;
TakeType() : m_cNum(0) { }
TakeType(Item::ItemPos srcPos, Item::ItemPos dstPos, unsigned char cNum)
: m_srcPos(srcPos), m_dstPos(dstPos), m_cNum(cNum) { }
};
// 캐스트 오브젝트 구조체 (Cast Object)
typedef struct CastObject* LPCastObject;
struct CastObject
{
POS m_DstPos; // 목적 위치
unsigned long m_dwTargetID; // 타겟 아이디
unsigned short m_wTypeID; // 아이디 ( 돈일경우 금액 )
unsigned char m_cObjectType; // 종류 ( 0 = 캐스트, 어텍 류, 2 = 돈 )
unsigned char m_cObjectLevel; // 레벨
};
#pragma pack()
#endif

View File

@@ -0,0 +1,66 @@
#ifndef _CHAR_LOGIN_OUT_PACKET_H_
#define _CHAR_LOGIN_OUT_PACKET_H_
// CharLoginOutPacket.h
#include <winsock2.h>
#include <windows.h>
#include <Network/Packet/PacketBase.h>
#include "CharLoginOutPacketStruct.h"
// 전방 참조
class CSession;
#pragma pack(1)
typedef struct PktDBUpdate* LPPktDBUpdate;
struct PktDBUpdate : public PktBase
{
unsigned __int64 m_dlItemSerial; // 가장 마지막으로 업데이트한 아이템 시리얼
unsigned long m_dwSessionID; // 세션 ID
unsigned long m_dwUserID; // 유저 ID
unsigned long m_dwCharID; // 캐릭터 ID
CSession* m_lpSession; // 세션 포인터
IN_ADDR m_Address; // 주소
unsigned short m_TypeCode; // 업데이트 타입
unsigned short m_usUpdate[DBUpdateData::MAX_UPDATE_DB]; // 업데이트 데이터 크기
};
// 캐릭터 로그인 (Char Login)
typedef struct PktCLi* LPPktCLi;
struct PktCLi : public PktBase
{
unsigned long m_dwUserID;
unsigned long m_dwCharID;
unsigned long m_dwSessionID;
};
// 캐릭터 로그인 Ack (1 = 서버 에러, 2 = 데이터 얻기 실패)
typedef struct PktCLiAck* LPPktCLiAck;
struct PktCLiAck : public PktBase
{
SOCKADDR_IN m_GSSUDPAddr;
unsigned long m_dwServerTime;
unsigned char m_cAdmin;
unsigned short m_usUpdate[DBUpdateData::MAX_UPDATE_DB];
};
// 캐릭터 로그아웃 (Char Logout)
typedef struct PktCLo* LPPktCLo;
struct PktCLo : public PktBase
{
unsigned long m_dwCharID;
};
// 캐릭터 로그아웃 (Char Logout)
typedef struct PktCLoAck* LPPktCLoAck;
struct PktCLoAck : public PktBase
{
unsigned long m_dwCharID;
};
#pragma pack()
#endif

View File

@@ -0,0 +1,30 @@
#ifndef _CHAR_LOGIN_OUT_PACKET_STRUCT_
#define _CHAR_LOGIN_OUT_PACKET_STRUCT_
namespace DBUpdateData
{
enum UpdateList
{
STATUS_UPDATE = 0, POSITION_UPDATE = 1,
SKILL_UPDATE = 2, QUICKSLOT_UPDATE = 3,
ITEM_EQUIP_UPDATE = 4, ITEM_INVEN_UPDATE = 5,
ITEM_EXTRA_UPDATE = 6, ITEM_EXCHANGE_UPDATE = 7,
MAX_UPDATE_DB = 8
};
enum UpdateType
{
LOGIN = 0, LOGOUT = 1,
UPDATE = 2, ADMIN_LOGIN = 3,
ZONEMOVE = 4
};
enum Limit
{
MAX_DBUPDATE_SIZE = 8000
};
};
#endif

View File

@@ -0,0 +1,93 @@
#ifndef _CHAR_MOVE_PACKET_H_
#define _CHAR_MOVE_PACKET_H_
// CharMovePacket.h
#include <Network/Packet/PacketBase.h>
#include <DB/DBdefine.h>
#pragma pack(1)
// 캐릭터 이동 패킷 (CharMove)
typedef struct PktMV* LPPktMV;
struct PktMV : public PktBase
{
POS m_Position; // 캐릭터 위치
float m_fDir; // 캐릭터 방향
unsigned long m_dwCharID; // 캐릭터 ID
unsigned long m_dwChantEf; // Chant Effect
unsigned long m_dwEnchantEf; // Enchant Effect
unsigned short m_wUAct; // 액션 번호
unsigned short m_wLAct; // 액션 번호
unsigned char m_wLevel; // 캐릭터 레벨
};
// 캐릭터 이동 업데이트 패킷 ( Char Move Update )
typedef struct PktMU* LPPktMU;
struct PktMU : public PktBase
{
POS m_Position; // 위치
float m_fDir; // 방향
unsigned long m_dwTick; // 클라이언트 틱
bool m_bSitMode; // 앉기 (true = 앉아 있음.)
};
// 캐릭터 이동 업데이트 패킷 Ack ( Char Move Update )
typedef struct PktMUAck* LPPktMUAck;
struct PktMUAck : public PktBase
{
unsigned long m_dwTick; // 클라이언트 틱 (처리 시간 퍼포 측정)
unsigned char m_cFlag; // - 플래그 (0 = 이동, 1 = 셀이동)
};
// 몬스터 움직임 ( Monster Move )
typedef struct PktMM* LPPktMM;
struct PktMM : public PktBase
{
POS m_Position; // 몬스터 위치
float m_fDir; // 몬스터 방향
float m_fVec; // 몬스터 속도
unsigned long m_dwMonID; // 몬스터 아이디
unsigned short m_wAct; // 몬스터 행동
unsigned short m_wAniNum; // 몬스터 이동 횟수
};
namespace CellCommand
{
enum Type
{
CELL_MOVE = 0,
CELL_LOGIN = 1,
RESPAWN = 2
};
};
// 캐릭터 셀 로그인 패킷 (Char Cell Login)
typedef struct PktCCLi* LPPktCCLi;
struct PktCCLi : public PktBase
{
SOCKADDR_IN m_PublicAddress;
SOCKADDR_IN m_PrivateAddress;
POS m_Pos;
unsigned long m_dwCharID;
unsigned char m_cCmd; // see namespace CellCommand
};
// 캐릭터 셀 로그아웃 패킷 ( Char Cell Logout )
typedef struct PktCCLo* LPPktCCLo;
struct PktCCLo : public PktBase
{
unsigned long m_dwCharID;
unsigned char m_cCmd; // see namespace CellCommand
};
// 셀 브로드 캐스팅 + Address구조체
typedef struct PktCB PktCB, *LPPktCB;
struct PktCB : public PktBase
{
unsigned short m_sCharNum; // 셀 캐릭터 수
};
#pragma pack()
#endif

View File

@@ -0,0 +1,181 @@
#ifndef _CHAR_STATUS_PACKET_H_
#define _CHAR_STATUS_PACKET_H_
// CharStatusPacket.h
#include <Network/Packet/PacketBase.h>
#include <DB/DBdefine.h>
#include <Item/ItemStructure.h>
#include "CharStatusPacketStruct.h"
#pragma pack(1)
// 캐릭터 자살
typedef struct PktSC* LPPktSC;
struct PktSC : public PktBase
{
unsigned long m_dwCharID; // 캐릭터 아이디
};
// 캐릭터 자살 Ack
typedef struct PktSCAck PktSCAck, *LPPktSCAck;
struct PktSCAck : public PktBase
{
POS m_Pos;
unsigned long m_dwCharID; // 캐릭터 아이디
};
// 바인드 포지션
typedef struct PktBP* LPPktBP;
struct PktBP : public PktBase
{
POS m_Pos; // 바인드할 위치
char m_cZone; // 바인드할 존
unsigned long m_dwNPCID; // 바인드할 NPC ID
unsigned char m_cCmd; // 포지션 명령 (0 = 세이브 위치, 1 = 위치 이동)
};
// 레벨업 패킷
typedef struct PktLU* LPPktLU;
struct PktLU : public PktBase
{
ChState m_State;
unsigned long m_dwCharID; // 캐릭터 아이디
unsigned char m_cLevel; // 레벨
};
// 레벨업 정보 패킷
typedef struct PktLUInfo* LPPktLUInfo;
struct PktLUInfo : public PktBase
{
unsigned long m_dwCharID; // 캐릭터 아이디
unsigned char m_cLevel; // 캐릭터 레벨
};
// 능력치 증가
typedef struct PktIP* LPPktIP;
struct PktIP : public PktBase
{
unsigned long m_dwCharID; // 캐릭터 ID
unsigned char m_cStateType; // 능력치 타입
};
// 능력치 증가 Ack
typedef struct PktIPAck* LPPktIPAck;
struct PktIPAck : public PktBase
{
ChState m_State;
unsigned long m_dwCharID; // 캐릭터 ID
};
// 클래스 업그레이드
typedef struct PktCU* LPPktCU;
struct PktCU : public PktBase
{
unsigned long m_dwCharID; // 캐릭터 ID
unsigned char m_cClass; // 클래스 번호
};
// 클래스 업그레이드 Ack
typedef struct PktCUAck* LPPktCUAck;
struct PktCUAck : public PktBase
{
ChState m_State; // 캐릭터 상태
unsigned long m_dwCharID; // 캐릭터 ID
unsigned short m_wSkill; // 스킬 ID
unsigned char m_cIndex; // 스킬 인덱스
unsigned char m_cClass; // 클래스 번호
};
// 스킬 (생성/지우기/락/락해제)
typedef struct PktSk* LPPktSk;
struct PktSk : public PktBase
{
enum PktSkError
{
SERVER_ERROR = 1, // 서버 에러
FAIL_NOT_SKILL = 2, // 스킬 관련 공통 에러
FAIL_NOT_ENOUGH_SLOT = 4, // 생성 에러
FAIL_NON_LEVEL = 3, FAIL_ALREADY_LOCK = 4, // 지우기 에러
FAIL_FULL_LOCK = 3, FAIL_NOT_ENOUGH_LEVEL = 4, // 락 에러
FAIL_NON_LOCK = 3, // 락 해제 에러
};
unsigned long m_dwCharID; // 캐릭터 ID
unsigned short m_wSkill; // 스킬 번호
unsigned char m_cIndex; // 스킬 위치
};
// 스킬 락 해제
typedef struct PktSkUL* LPPktSkUL;
struct PktSkUL : public PktSk
{
Item::ItemPos m_itemPos; // 망각의 돌 위치
};
// 스킬 락 해제 Ack
typedef struct PktSkULAck* LPPktSkULAck;
struct PktSkULAck : public PktSk
{
unsigned long m_dwGold; // 소비 금액
Item::ItemPos m_itemPos; // 망각의 돌 위치
};
// HP 리젠 패킷 ( Char HP Regen )
typedef struct PktHP* LPPktHP;
struct PktHP : public PktBase
{
unsigned long m_dwCharID; // 캐릭터 아이디
unsigned short m_sHP; // 현재 hp
unsigned short m_sMP; // 현재 mp
};
// 정보 요청 ( Require Info )
// - P2P로 다른 클라이언트에게 직접 보낼 시에는 주소내용이 추가 되며,
// 해당 클라이언트 아이디는 보내는 이의 캐릭터 아이디가 되겠다.
typedef struct PktRI* LPPktRI;
struct PktRI : public PktBase
{
SOCKADDR_IN m_PublicAddress;
SOCKADDR_IN m_PrivateAddress;
unsigned long m_dwCharID; // 해당 캐릭터 아이디
unsigned char m_cCmd; // 커맨드 (0 : HP, MP 정보, 1 : UDP 주소, 2 : 모양)
};
// 캐릭터 겉모습 정보
typedef struct PktSI* LPPktSI;
struct PktSI : public PktBase
{
enum { MAX_STALL_NAME_LEN = 32 };
enum WEAPON_HAND
{
WEAPON_HAND1 = 1,
WEAPON_HAND2 = 2
};
CHAR_VIEW m_CharView; // 캐릭터 겉모습
unsigned long m_dwStatusFlag; // 캐릭터에 걸려 있는 chant, enchant Flag
unsigned char m_cSelectedHands; // 현재 사용중인 손 (1 = 무기1 & 방패1, 2 = 무기2 & 방패2)
char m_StallName[MAX_STALL_NAME_LEN]; // 노점상 이름
};
// 엘리트 보너스
typedef struct PktEB* LPPktEB;
struct PktEB : public PktBase
{
EliteBonus m_EliteBonus;
};
#pragma pack()
#endif

View File

@@ -0,0 +1,31 @@
#ifndef _CHAR_STATUS_PACKET_STRUCT_H_
#define _CHAR_STATUS_PACKET_STRUCT_H_
#pragma pack(1)
// ij¸¯ÅÍ ´É·ÂÄ¡
typedef struct ChState* LPChState;
struct ChState
{
unsigned short m_wIP;
unsigned short m_wSTR;
unsigned short m_wDEX;
unsigned short m_wCON;
unsigned short m_wINT;
unsigned short m_wWIS;
};
typedef struct EliteBonus* LPEliteBonus;
struct EliteBonus
{
enum { MAX_BONUS_LEVEL = 5 };
char m_cNation;
unsigned char m_cLevel;
EliteBonus() : m_cNation(0), m_cLevel(0) { }
};
#pragma pack()
#endif

View File

@@ -0,0 +1,207 @@
#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 { NAME_LEN = 16 };
char m_UserAccount[NAME_LEN];
char m_UserPassword[NAME_LEN];
unsigned long m_ClientVerInfo;
unsigned short m_cFlag;
unsigned long m_dwSessionID;
};
////////////////////////////////////////////////////////////////////////////////////////////////////
//
// 사용자 인증 응답 (AuthServer to Client)
// - 계정 이름
// - 계정 패스워드
// - 클라이언트 버젼
//
// : 사용자 계정으로 로그인하여 유저 아이디와 로그인 가능한 서버 리스트드을 얻는다.
//
////////////////////////////////////////////////////////////////////////////////////////////////////
typedef struct PktAUAck* LPPktAUAck;
struct PktAUAck : public PktBase
{
unsigned long m_dwSessionID;
unsigned long m_dwUserID;
};
////////////////////////////////////////////////////////////////////////////////////////////////////
//
// 유저 로그인 (Client to AuthServer)
// - 유저 아이디
// - 서버 아이디
// - 예약 큐 포인터
// : 유저 로그인 후에 캐릭터 셀렉트 관련 정보를 얻어온다.
//
////////////////////////////////////////////////////////////////////////////////////////////////////
typedef struct PktULi* LPPktULi;
struct PktULi : public PktBase
{
DWORD m_dwSessionID;
DWORD m_dwUserID;
DWORD m_dwServerID;
DWORD m_dwCheckSum;
};
////////////////////////////////////////////////////////////////////////////////////////////////////
//
// 유저 로그인 Ack (AuthServer to Client)
// - 유저 아이디
// - 캐릭터 정보
//
// (1 = 서버 에러, 2 = 데이터 얻기 실패)
//
////////////////////////////////////////////////////////////////////////////////////////////////////
typedef struct PktULiAck* LPPktULiAck;
struct PktULiAck : public PktBase
{
enum { SERVER_ERROR = 1, FAIL_GET_DATA = 2 };
unsigned long m_dwUserID;
CHAR_VIEW m_CharView[3];
};
////////////////////////////////////////////////////////////////////////////////////////////////////
//
// 캐릭터 선택 ( Char Select )
// - 유저 아이디
// - 캐릭터 아이디
//
// : 캐릭터 선택 후 해당 캐릭터의 서버의 예약 포인터와 주소를 넘겨 받는다.
//
////////////////////////////////////////////////////////////////////////////////////////////////////
typedef struct PktCS* LPPktCS;
struct PktCS : public PktBase
{
unsigned long m_dwUserID;
unsigned long m_dwCharID;
};
////////////////////////////////////////////////////////////////////////////////////////////////////
//
// 캐릭터 선택 Ack
// - 유저 아이디
// - 캐릭터 아이디
// - 예약 큐 포인터
// - GSS 서버 주소
//
////////////////////////////////////////////////////////////////////////////////////////////////////
typedef struct PktCSAck* LPPktCSAck;
struct PktCSAck : public PktBase
{
enum { MAX_CHANNEL_NUM = 2 };
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
};
};
////////////////////////////////////////////////////////////////////////////////////////////////////
//
// 캐릭터 삭제 ( Char Delete )
// - 유저 아이디
// - 캐릭터 아이디
// - 슬롯 번호
// - 파티 아이디
// - 길드 아이디
//
////////////////////////////////////////////////////////////////////////////////////////////////////
typedef struct PktCD* LPPktCD;
struct PktCD : public PktBase
{
unsigned long m_dwUserID;
unsigned long m_dwCharID;
unsigned long m_dwSlotNum;
};
////////////////////////////////////////////////////////////////////////////////////////////////////
//
// 캐릭터 삭제 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 };
};
#pragma pack()
#endif

View File

@@ -0,0 +1,76 @@
#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_ClientVerInfo;
};
// 서버 리스트 응답 패킷 : LoginServer to Launcher
typedef struct PktSvLAck* LPPktSvLAck;
struct PktSvLAck : public PktBase
{
unsigned long m_dwUserID; // 유저 아이디
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 { NAME_LEN = 16 };
char m_UserAccount[NAME_LEN];
char m_UserPassword[NAME_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,50 @@
#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_dwUID;
unsigned short m_wCmd;
enum SubCommands
{
SCmdUserLogin = 0x0001, // 유저 로그인
SCmdUserLogout = 0x0002, // 유저 로그인
SCmdUserMove = 0x0003, // 유저 존 이동
SCmdCharCreate = 0x0021, // 캐릭터 생성
SCmdCharDelete = 0x0022, // 캐릭터 삭제
SCmdCharCreateItem = 0x0023, // 캐릭터 생성 아이템
SCmdCharSelect = 0x0024, // 캐릭터 선택
SCmdCreateParty = 0x0031, // 파티 생성
SCmdDeleteParty = 0x0032, // 파티 삭제
SCmdGetPartyInfo = 0x0033, // 파티 정보 얻기
SCmdInsertPartyMem = 0x0034, // 파티 멤버 추가
SCmdDeletePartyMem = 0x0035, // 파티 멤버 삭제
SCmdLoginPartyMem = 0x0036, // 파티 멤버 로그인
SCmdLogoutPartyMem = 0x0037, // 파티 멤버 로그아웃
SCmdTransferLeader = 0x0038, // 리더 양도
SCmdStartSession = 0x0041, // 세션 시작
SCmdServerZone = 0x0043, // 서버 존
SCmdCharMoveZone = 0x0044 // 캐릭터 존이동
};
inline void InitPtSubCmd(unsigned long dwUID, unsigned short Cmd_In);
};
inline void PktDD::InitPtSubCmd(unsigned long dwUID, unsigned short Cmd_In)
{
m_dwUID = dwUID;
m_wCmd = Cmd_In;
}
#pragma pack()
#endif

View File

@@ -0,0 +1,215 @@
#ifndef _CHAR_FRIEND_PACKET_H_
#define _CHAR_FRIEND_PACKET_H_
// CharFriendPacket.h
#include <Network/Packet/PacketBase.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 FriendInfo
{
private:
enum StatusMask
{
IS_LOGINED = 0x00000001,
GROUP = 0x000000F0
};
public:
enum { MAX_NAME = 16 };
unsigned long m_dwStatusFlag;
char m_szName[MAX_NAME];
bool IsLogined() { return (0 != (m_dwStatusFlag & IS_LOGINED)); }
void SetLoginStatus(bool bLogined)
{
if(bLogined) { m_dwStatusFlag |= IS_LOGINED; }
else { m_dwStatusFlag &= ~IS_LOGINED; }
}
unsigned long GetGroup() { return ((m_dwStatusFlag & GROUP) >> 4); }
bool SetGroup(unsigned long dwGroup)
{
if(0xF < dwGroup) { return false; }
m_dwStatusFlag = (m_dwStatusFlag & (~GROUP)) | (dwGroup << 4);
return true;
}
};
struct BanInfo
{
enum { MAX_NAME = 16 };
char m_szName[MAX_NAME];
};
// 추가 패킷
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 char m_cCmd;
};
// 제거 패킷
struct PktFriendRemoveReq : public PktBase
{
enum CMD
{
REMOVE_FRIEND_REQ = 0, // 친구 제거 (Client->GameServer), m_dwCID는 제거할 사람의 CID.
REMOVE_BAN_REQ = 1, // 거부 등록 제거 (Client->GameServer), m_dwCID는 제거할 사람의 CID.
};
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
{
ADD_FRIEND_ACK = 0, // 친구 등록 Ack (GameServer->Client)
// 가능한 에러 : SERVER_ERROR (서버 에러)
// NOT_LOGINED (로그인되지 않은 캐릭터를 등록하려 함)
// REJECTED (거부 리스트에 있음)
// LIST_FULL (친구 리스트가 꽉 차 있음)
REMOVE_FRIEND_ACK = 1, // 친구 제거 Ack (GameServer->Client)
// 가능한 에러 : SERVER_ERROR (서버 에러)
ADD_BAN_ACK = 2, // 거부 등록 Ack (GameServer->Client)
// 가능한 에러 : SERVER_ERROR (서버 에러)
// NOT_LOGINED (로그인되지 않은 캐릭터를 등록하려 함)
// LIST_FULL (친구 리스트가 꽉 차 있음)
REMOVE_BAN_ACK = 3, // 거부 제거 Ack (GameServer->Client)
// 가능한 에러 : SERVER_ERROR (서버 에러)
FRIEND_LOGIN = 4, // 친구 로그인 (GameServer->Client), m_dwCID는 로그인한 친구의 CID
FRIEND_LOGOUT = 5 // 친구 로그아웃 (GameServer->Client), m_dwCID는 로그아웃한 친구의 CID
};
enum FriendERROR
{
SERVER_ERROR = 1,
NOT_LOGINED = 2,
REJECTED = 3,
LIST_FULL = 4
};
unsigned long m_dwCID;
unsigned char m_cCmd;
};
// 친구 관련 패킷
struct PktFriendDB : public PktBase
{
enum CMD
{
ADD_FRIEND = 0, // 친구 등록 (GameServer->DBAgent) Owner가 Reference를 등록.
REMOVE_FRIEND = 1, // 친구 제거 (GameServer->DBAgent) Owner가 Reference를 제거.
ADD_BAN = 2, // 거부 등록 (GameServer->DBAgent) Owner가 Reference를 등록.
REMOVE_BAN = 3, // 거부 제거 (GameServer->DBAgent) Owner가 Reference를 제거.
SETGROUP = 4, // 그룹 세팅 (GameServer->DBAgent)
// Owner가 Reference를 m_dwData에 들어 있는 그룹으로 세팅.
FRIEND_LIST = 5, // 친구 리스트 (DBAgent->GameServer, GameServer->Client)
// CIDTable에서 SerializeOut한 데이터가 뒤에 붙는다.
// Reference는 의미 없음. m_dwData는 뒤에 붙는 데이터의 크기.
BAN_LIST = 6, // 거부 리스트 (DBAgent->GameServer, GameServer->Client)
// CIDTable에서 SerializeOut한 데이터가 뒤에 붙는다.
// Reference는 의미 없음. m_dwData는 뒤에 붙는 데이터의 크기.
};
unsigned long m_dwOwnerUID; // 등록 하는 사람 UID
unsigned long m_dwOwnerCID; // 등록 하는 사람 CID
unsigned long m_dwReferenceCID; // 등록 되는 사람 CID
unsigned long m_dwData; // Data
unsigned char m_cCmd;
};
#pragma pack()
#endif

View File

@@ -0,0 +1,81 @@
#ifndef _PARTY_INFO_PACKET_H_
#define _PARTY_INFO_PACKET_H_
#include "DataPacket.h"
#pragma pack(1)
////////////////////////////////////////////////////////////////////////////////////////////////////
//
// 파티 정보
//
////////////////////////////////////////////////////////////////////////////////////////////////////
typedef struct PktPID* LPPktPID;
struct PktPID : public PktDD
{
unsigned long m_dwCharID;
unsigned long m_dwPartyID;
};
typedef struct PktPIDAck* LPPktPIDAck;
struct PktPIDAck : public PktDD
{
PARTY m_Party;
};
////////////////////////////////////////////////////////////////////////////////////////////////////
//
// 파티 생성
//
////////////////////////////////////////////////////////////////////////////////////////////////////
typedef struct PktCPD* LPPktCPD;
struct PktCPD : public PktDD
{
DWORD m_dwLeaderID;
DWORD m_dwMemberID;
};
typedef struct PktCPDAck* LPPktCPDAck;
struct PktCPDAck : public PktDD
{
PARTY m_Party;
};
////////////////////////////////////////////////////////////////////////////////////////////////////
//
// 파티 삭제
//
////////////////////////////////////////////////////////////////////////////////////////////////////
typedef struct PktDPD* LPPktDPD;
struct PktDPD : public PktDD
{
unsigned long m_dwPartyID;
};
////////////////////////////////////////////////////////////////////////////////////////////////////
//
// 파티 멤버 정보
//
// Sender(Send/Recv) Reference(Send/Recv)
// 멤버 로그인 : CID/CID 0/SID
// 멤버 로그아웃 : CID/CID 0/리더 아이디(0 일경우 리더 양도 없음)
// 멤버 가입 : CID/CID CID/CID
// 멤버 삭제 : CID/CID CID/리더 아이디(0 일 경우 리더 양도 없음)
//
////////////////////////////////////////////////////////////////////////////////////////////////////
typedef struct PktPMD* LPPktPMD;
struct PktPMD : public PktDD
{
unsigned long m_dwPartyID;
unsigned long m_dwSenderID;
unsigned long m_dwReferenceID;
};
#pragma pack()
#endif

View File

@@ -0,0 +1,104 @@
#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 Zone { ZONE1 = 1, ZONE2 = 2, BATTLE_GROUND = 3 };
typedef struct SID* LPSID;
struct SID
{
char Type;
char Group;
char Channel;
char ID;
};
SID sID;
DWORD dwID;
// 2002-12-24 cppis 가 추가
inline char GetChannel(void) { return sID.Channel; }
inline char GetZone(void) { return sID.ID; }
};
typedef struct SERVER* LPSERVER_GROUP;
struct SERVER_GROUP
{
enum { CHANNEL_NUM = 2, SERVER_NAME = 15 };
char m_Group; // 서버 그룹
char m_Name[SERVER_NAME]; // 서버 이름
unsigned short m_ChannelNum; // 채널 숫자
long m_ClientNum[CHANNEL_NUM]; // 접속 자 수
};
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_dwChannelClientNum[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_dwChannelClientNum, int(SERVER_GROUP::CHANNEL_NUM), 0);
}
};
#endif

View File

@@ -0,0 +1,195 @@
#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 long m_dwServerID;
__int64 m_dlItemUID;
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 = 2 };
unsigned long m_dwServerID;
unsigned char m_wChannelNum;
unsigned short m_dwChannelClientNum[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;
IN_ADDR m_GameAddress;
};
// 서버존 이동
typedef struct PktSZMv* LPPktSZMv;
struct PktSZMv : public PktBase
{
POS m_NewPos;
char m_cZone;
};
// 서버존 선택 Ack
typedef struct PktSZMvAck* LPPktSZMvAck;
struct PktSZMvAck : public PktBase
{
enum { MAX_CHANNEL_NUM = 2 };
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;
POS m_NewPos;
};
typedef struct PktSZMvDAck* LPPktSZMvDAck;
struct PktSZMvDAck : public PktDD
{
enum { MAX_CHANNEL_NUM = 2 };
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
{
unsigned long m_dwServerID;
IN_ADDR m_GameAddress;
};
// ---------------------------------------------------------------------------
// 유저 관련
// 유저 테이블 업데이트
typedef struct PktUUT *LPPktUUT;
struct PktUUT : public PktBase {
enum {
UpdateUIDTableNone = 0, // 없음
UpdateUIDTableLogin = 1, // 로그인
UpdateUIDTableLogout = 2 // 로그아웃
};
unsigned char m_cCmd;
unsigned long m_dwSessionID;
unsigned long m_dwServerID;
unsigned long m_dwUserID;
unsigned long m_dwCharID;
};
// 유저 죽이기.
typedef struct PktUK* LPPktUK;
struct PktUK : public PktBase
{
unsigned long m_dwUserID;
unsigned long m_dwCharID;
unsigned long m_dwServerID;
};
#pragma pack()
#endif

View File

@@ -0,0 +1,191 @@
// XORCrypt.cpp: implementation of the CXORCrypt class.
//
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "XORCrypt.h"
#include <ctime>
#include <cstdlib>
CXORCrypt CXORCrypt::ms_this;
CXORCrypt::CXORCrypt()
{
InitCodePage();
}
CXORCrypt::~CXORCrypt()
{
}
//Interface////////////////////////////////////////////////////////////////////////////////////
// XORF [ public ] - XOR 연산. # 순방향
// Parameter : 1st : 시작 포인터, 2st : 길이, 3st : 코드 페이지
// Return:
void CXORCrypt::XORF(char *Start_In, int Length_In, unsigned short PageVer,
unsigned char PageNum1, unsigned char PageNum2)
{
for (int Counter = 0; Counter < Length_In; ++Counter)
{
*Start_In = *Start_In ^ BitFields[PageVer][PageNum1][Counter % BIT_COUNT];
*Start_In = *Start_In ^ BitFields[PageVer][PageNum2][Counter % BIT_COUNT];
++Start_In;
}
}
//Interface////////////////////////////////////////////////////////////////////////////////////
// XORB [ public ] - XOR 연산. # 역방향
// Parameter : 1st : 시작 포인터, 2st : 길이, 3st : 코드 페이지
// Return:
void CXORCrypt::XORB(char *Start_In, int Length_In, unsigned short PageVer,
unsigned char PageNum1, unsigned char PageNum2)
{
for (int Counter = 0; Counter < Length_In; ++Counter)
{
*Start_In = *Start_In ^ BitFields[PageVer][PageNum2][Counter % BIT_COUNT];
*Start_In = *Start_In ^ BitFields[PageVer][PageNum1][Counter % BIT_COUNT];
++Start_In;
}
}
//Interface////////////////////////////////////////////////////////////////////////////////////
// InitCODE_PAGE [ public ] - 암호 페이지를 초기화 한다
// Parameter :
// Return:
void CXORCrypt::InitCodePage(void)
{
int CODE_PAGENums = CODE_PAGE * 10;
srand((unsigned)time(NULL));
for (int Counter = 0; Counter < CODE_PAGENums; ++Counter)
{
m_CodePage[Counter] = rand() % CODE_PAGE;
if(Counter > 1)
{
if (m_CodePage[Counter] == m_CodePage[Counter - 1])
{
--Counter;
}
}
}
m_CodePageCount = rand() % (CODE_PAGE * 10);
}
//Interface////////////////////////////////////////////////////////////////////////////////////
// GetCODE_PAGE [ public ] - 암호 페이지를 얻는다
// Parameter :
// Return:
unsigned long CXORCrypt::GetCodePage(void)
{
if(0xffffff00 < m_CodePageCount)
{
m_CodePageCount = 0;
}
m_CodePageCount = (m_CodePageCount + 2) % (CODE_PAGE * 10);
return (((unsigned long)PAGE_VERSION << 16) & 0xffff0000) |
(((unsigned long)m_CodePage[m_CodePageCount] << 8) & 0x0000ff00) |
((unsigned long)m_CodePage[m_CodePageCount - 1] & 0x000000ff);
}
unsigned long CXORCrypt::GetCodePage(unsigned short PageVer_In)
{
if(0xffffff00 < m_CodePageCount)
{
m_CodePageCount = 0;
}
m_CodePageCount = (m_CodePageCount + 2) % (CODE_PAGE * 10);
return (((unsigned long)PageVer_In << 16) & 0xffff0000) |
(((unsigned long)m_CodePage[m_CodePageCount] << 8) & 0x0000ff00) |
((unsigned long)m_CodePage[m_CodePageCount - 1] & 0x000000ff);
}
//Interface////////////////////////////////////////////////////////////////////////////////////
// InnerEncodeS [ public ] - 데이터 암호화 : 데이터를 XOR 연산 한다. # 클라이언트 용
// Parameter : 1st : 시작 포인터, 2st : 길이, 3st : 코드 페이지
// Return:
bool CXORCrypt::EncodePacket(char *Start_In, int Length_In, unsigned long CodePage_In)
{
unsigned short PageVer = 0;
unsigned char PageNum1 = 0, PageNum2 = 0;
PageVer = (unsigned short)(((CodePage_In & 0xffff0000) >> 16) & 0x0000ffff);
PageNum1 = (unsigned char)(((CodePage_In & 0xff00) >> 8) & 0x00ff);
PageNum2 = (unsigned char)(CodePage_In & 0x00ff);
if(PageVer < 0 || PageVer > 1)
return false;
if(PageNum1 < 0 || PageNum1 >= CODE_PAGE || PageNum2 < 0 || PageNum2 >= CODE_PAGE)
return false;
XORF(Start_In, Length_In, PageVer, PageNum1, PageNum2);
return true;
}
//Interface////////////////////////////////////////////////////////////////////////////////////
// InnerEncodeS [ public ] - 데이터 암호화 : 데이터를 XOR 연산 한다. # 서버용
// Parameter : 1st : 시작 포인터, 2st : 길이, 3st : 코드 페이지
// Return:
bool CXORCrypt::DecodePacket(char *Start_In, int Length_In, unsigned long CodePage_In)
{
unsigned short PageVer = 0;
unsigned char PageNum1 = 0, PageNum2 = 0;
PageVer = (unsigned short)(((CodePage_In & 0xffff0000) >> 16) & 0x0000ffff);
PageNum1 = (unsigned char)(((CodePage_In & 0xff00) >> 8) & 0x00ff);
PageNum2 = (unsigned char)(CodePage_In & 0x00ff);
if(PageVer < 0 || PageVer > 1)
return false;
if(PageNum1 < 0 || PageNum1 >= CODE_PAGE || PageNum2 < 0 || PageNum2 >= CODE_PAGE)
return false;
XORB(Start_In, Length_In, PageVer, PageNum1, PageNum2);
return true;
}
//Interface////////////////////////////////////////////////////////////////////////////////////
// EncodeHeader [ public ] - 데이터 암호화 : 데이터를 XOR 연산 한다.
// Parameter : 1st : 시작 포인터, 2st : 길이
// Return:
void CXORCrypt::EncodeHeader(char *Start_In, int Length_In, unsigned short PageVer_In, unsigned char PageNum_In)
{
for(int Counter = 0; Counter < Length_In; ++Counter)
{
*Start_In = *Start_In ^ BitFields[PageVer_In][PageNum_In][Counter % BIT_COUNT];
*Start_In = (((*Start_In & 0x80) >> 7) & 0x01) | ((*Start_In << 1) & 0xFE);
++Start_In;
}
}
//Interface////////////////////////////////////////////////////////////////////////////////////
// DecodeHeader [ public ] - 데이터 복호화 : 데이터를 XOR 연산 한다. # 서버용
// Parameter : 1st : 시작 포인터, 2st : 길이
// Return:
void CXORCrypt::DecodeHeader(char *Start_In, int Length_In, unsigned short PageVer_In, unsigned char PageNum_In)
{
for(int Counter = 0; Counter < Length_In; ++Counter)
{
*Start_In = (((*Start_In & 0x01) << 7) & 0x80) | ((*Start_In >> 1) & 0x7F);
*Start_In = *Start_In ^ BitFields[PageVer_In][PageNum_In][Counter % BIT_COUNT];
++Start_In;
}
}

View File

@@ -0,0 +1,58 @@
#ifndef _CXOR_CRYPT_H_
#define _CXOR_CRYPT_H_
#pragma once
#include <Pattern/Singleton.h>
class CXORCrypt : public CSingleton<CXORCrypt>
{
public:
enum
{
PAGE_VERSION = 0,
BIT_COUNT = 40,
CODE_PAGE = 10,
};
private:
static const unsigned char BitFields[][CODE_PAGE][BIT_COUNT];
unsigned char m_CodePage[CODE_PAGE * 10];
unsigned long m_CodePageCount;
void InitCodePage(void);
void XORF(char *Start_In, int Length_In, unsigned short PageVer, unsigned char PageNum1, unsigned char PageNum2);
void XORB(char *Start_In, int Length_In, unsigned short PageVer, unsigned char PageNum1, unsigned char PageNum2);
// To make Singleton Class.
CXORCrypt();
static CXORCrypt ms_this;
public:
~CXORCrypt();
// interface of encoder, decoder
unsigned long GetCodePage(void);
unsigned long GetCodePage(unsigned short PageVer_In);
inline unsigned short GetPageVer(unsigned long CodePage_In);
bool EncodePacket(char *Start_In, int Length_In, unsigned long CodePage_In);
bool DecodePacket(char *Start_In, int Length_In, unsigned long CodePage_In);
void EncodeHeader(char *Start_In, int HeaderLen_In, unsigned short PageVer_In, unsigned char PageNum_In);
void DecodeHeader(char *Start_In, int HeaderLen_In, unsigned short PageVer_In, unsigned char PageNum_In);
};
inline unsigned short CXORCrypt::GetPageVer(unsigned long CodePage_In)
{
return (unsigned short)(((CodePage_In & 0xffff0000) >> 16) & 0x0000ffff);
}
#endif

View File

@@ -0,0 +1,213 @@
#include "stdafx.h"
#include "XORCrypt.h"
const unsigned char CXORCrypt::BitFields[][CODE_PAGE][BIT_COUNT] =
{
///////////////////////////////////////////////////////////////////////
//Code Version 0
{
// Code Page 1
0x82, 0x53, 0x43, 0x4C, 0x2B,
0x0D, 0x37, 0xD7, 0xD9, 0xD8,
0x1B, 0x6D, 0xA0, 0xC3, 0x2B,
0xEE, 0x45, 0x88, 0x1A, 0xA6,
0x18, 0x1D, 0x9D, 0x38, 0x2A,
0x55, 0x03, 0x1D, 0xCD, 0xA6,
0x73, 0x07, 0xED, 0x8D, 0xC5,
0xDB, 0xA3, 0xBD, 0xB6, 0xD5,
// Code Page 2
0x34, 0xB5, 0xB2, 0x3D, 0x7D,
0x43, 0x8C, 0xC0, 0x21, 0x25,
0xCD, 0xB6, 0x53, 0x76, 0xCE,
0x5D, 0xD4, 0x87, 0xCA, 0x84,
0x81, 0xCB, 0x5E, 0x04, 0xBA,
0x69, 0x3E, 0x65, 0xDE, 0x21,
0x8A, 0x63, 0x62, 0x71, 0x90,
0x87, 0x0A, 0x52, 0x28, 0x44,
// Code Page 3
0xA3, 0x49, 0xDC, 0xEA, 0x09,
0xB7, 0x01, 0xA4, 0xA1, 0x11,
0x11, 0x8E, 0x80, 0x35, 0x5B,
0xDD, 0x38, 0xD5, 0x4E, 0x36,
0x0C, 0xA2, 0xBB, 0x05, 0x36,
0x57, 0x2E, 0x98, 0xBE, 0x88,
0x3C, 0x28, 0x43, 0x63, 0xA0,
0xE9, 0xE1, 0x6D, 0x51, 0xCB,
// Code Page 4
0x4D, 0x62, 0x84, 0x43, 0x89,
0xC7, 0x89, 0x83, 0x65, 0x29,
0x53, 0x95, 0x7C, 0xC0, 0xA1,
0x0C, 0xDB, 0xD7, 0x04, 0xD8,
0x6A, 0xD1, 0x73, 0x1D, 0x21,
0x67, 0x86, 0x8D, 0xA4, 0xA0,
0x34, 0xBD, 0x31, 0x20, 0x61,
0x0E, 0xE9, 0x63, 0xB4, 0xC0,
// Code Page 5
0xC7, 0x36, 0x1B, 0x41, 0x23,
0x9C, 0xD1, 0x8C, 0x25, 0x53,
0x42, 0x2E, 0x45, 0x6D, 0x42,
0x7B, 0x4E, 0x5B, 0xEB, 0x24,
0x33, 0x74, 0x52, 0x28, 0xC6,
0x2A, 0xC3, 0x16, 0x60, 0xA5,
0x45, 0x35, 0xDB, 0x9A, 0x54,
0x97, 0xE2, 0xEE, 0x9B, 0xDE,
// Code Page 6
0xE0, 0xC3, 0x84, 0x41, 0xED,
0x45, 0x4C, 0x69, 0xD9, 0x28,
0x55, 0x27, 0x8E, 0x3A, 0x3C,
0x8E, 0x84, 0x97, 0x14, 0xE6,
0x58, 0x51, 0x26, 0x0D, 0xE2,
0x9E, 0x66, 0x7C, 0x0D, 0x01,
0x7D, 0x17, 0x4C, 0x08, 0xDD,
0x97, 0x1C, 0x7B, 0xCE, 0x5D,
// Code Page 7
0x54, 0x37, 0x7C, 0x0C, 0x8E,
0x27, 0x7A, 0x78, 0x2E, 0xE6,
0x6D, 0x25, 0x62, 0x62, 0x98,
0x20, 0x2E, 0x23, 0x15, 0x61,
0x7D, 0x97, 0x50, 0x07, 0x20,
0x7A, 0x04, 0x29, 0x62, 0x90,
0x6B, 0xE9, 0xE6, 0x22, 0x72,
0x38, 0x56, 0xC9, 0x06, 0x2E,
// Code Page 8
0x3B, 0x47, 0x08, 0x2D, 0x21,
0x42, 0x07, 0x69, 0x4A, 0x57,
0x8B, 0x79, 0xE7, 0x56, 0x27,
0x23, 0x24, 0x85, 0x47, 0x74,
0x75, 0x85, 0xA9, 0xEB, 0x10,
0xCB, 0x17, 0x85, 0x4B, 0x5E,
0x20, 0x78, 0xD0, 0x7D, 0x86,
0x5E, 0x14, 0x7E, 0x64, 0x50,
// Code Page 9
0x69, 0x52, 0x4A, 0xBD, 0x8C,
0x9B, 0xD6, 0x63, 0xBD, 0x26,
0x86, 0x32, 0x95, 0xA4, 0x02,
0x9B, 0x01, 0x14, 0x49, 0x78,
0x88, 0x57, 0x3A, 0x01, 0x4A,
0xBC, 0x50, 0xCD, 0x31, 0x39,
0x71, 0x30, 0x5B, 0x9C, 0x4D,
0x21, 0x67, 0x82, 0xE8, 0x5C,
// Code Page 10
0x66, 0x10, 0xA9, 0x7D, 0xD2,
0x36, 0xE2, 0xB1, 0x28, 0x20,
0xD5, 0xE7, 0xD5, 0x0E, 0xD4,
0x0C, 0x2C, 0x77, 0x80, 0x0E,
0xA6, 0x37, 0xBE, 0x61, 0xAD,
0xD6, 0x17, 0x65, 0x13, 0x70,
0xAE, 0x40, 0x3B, 0x52, 0xEE,
0x53, 0x84, 0xEB, 0x04, 0x0D,
},
///////////////////////////////////////////////////////////////////////
//Code Version 1
{
// Code Page 1
0x49, 0x8C, 0x77, 0xC0, 0xC0,
0x64, 0x54, 0x0B, 0x22, 0xBD,
0x82, 0x93, 0x9A, 0x23, 0x8D,
0xE4, 0xC8, 0x9D, 0xB3, 0x50,
0x44, 0xB1, 0xE2, 0x9E, 0x15,
0x7A, 0xA1, 0x0C, 0x24, 0xE3,
0x1E, 0x0A, 0x0A, 0x73, 0x6A,
0xA5, 0x8B, 0x3A, 0x53, 0x33,
// Code Page 2
0xB0, 0xE6, 0xB7, 0x51, 0x70,
0xDA, 0xD6, 0x29, 0xAA, 0x10,
0xB5, 0x8A, 0x38, 0x37, 0x4E,
0x7A, 0x3B, 0x74, 0x7B, 0x63,
0x41, 0x7C, 0x21, 0x65, 0x5E,
0x26, 0x95, 0x44, 0x75, 0xA3,
0x74, 0xDD, 0xB4, 0x33, 0x9E,
0x54, 0x3C, 0x95, 0x5E, 0x34,
// Code Page 3
0x10, 0x19, 0x43, 0x64, 0x78,
0x2B, 0xA6, 0x60, 0x7D, 0xCD,
0xA9, 0x28, 0xB8, 0x85, 0x0E,
0x66, 0xC7, 0x3C, 0x28, 0xDC,
0xA1, 0x4D, 0x60, 0x9B, 0xC7,
0xD3, 0x74, 0x93, 0xE6, 0xC3,
0x97, 0x76, 0x12, 0xA4, 0xCB,
0xB9, 0x22, 0x51, 0xB9, 0x79,
// Code Page 4
0x5C, 0x68, 0xDB, 0xE6, 0x59,
0x57, 0x95, 0xCD, 0xAE, 0xCA,
0x67, 0xB8, 0x37, 0x90, 0xBA,
0x54, 0x98, 0x95, 0x73, 0x8E,
0x47, 0xC1, 0x40, 0xBA, 0x80,
0x26, 0x10, 0xAA, 0x60, 0x64,
0xD8, 0x69, 0xC7, 0x0D, 0x2B,
0x28, 0xA6, 0xBA, 0x01, 0x4A,
// Code Page 5
0xEE, 0x28, 0x65, 0xC4, 0x9D,
0x41, 0x8D, 0x91, 0x6C, 0x91,
0x7E, 0x80, 0xC3, 0xD1, 0xAE,
0xB6, 0x92, 0x41, 0x66, 0x13,
0x72, 0x20, 0x26, 0xA1, 0x72,
0x05, 0x29, 0x08, 0x88, 0x30,
0x40, 0x6D, 0x5A, 0x41, 0x01,
0x7A, 0xDB, 0x2C, 0xEE, 0xC3,
// Code Page 6
0x5C, 0x03, 0x38, 0xD8, 0x95,
0xE7, 0xB4, 0x67, 0x30, 0x51,
0x21, 0x68, 0x78, 0x89, 0x68,
0x0B, 0xE3, 0xB0, 0x28, 0xB3,
0xA9, 0x38, 0x18, 0xE4, 0x59,
0x43, 0xC9, 0x52, 0x75, 0x04,
0x15, 0x07, 0x97, 0x14, 0x07,
0x27, 0xDA, 0xE5, 0xD9, 0xDB,
// Code Page 7
0xDB, 0x08, 0x27, 0xA3, 0x64,
0xDC, 0x42, 0xE3, 0x3D, 0x0D,
0x26, 0xA2, 0xC3, 0x5E, 0x3E,
0xA7, 0x47, 0xE4, 0x1C, 0x73,
0x13, 0x99, 0x9E, 0xBA, 0xD3,
0x08, 0x73, 0x88, 0x03, 0x01,
0x24, 0x2E, 0x09, 0xBD, 0x3A,
0x6E, 0x3C, 0xB6, 0xA2, 0x22,
// Code Page 8
0xE7, 0x27, 0x60, 0x20, 0x85,
0xDA, 0xEA, 0x84, 0x86, 0x41,
0x67, 0x1C, 0x83, 0xBE, 0x7A,
0x61, 0x67, 0x01, 0x18, 0x30,
0xC6, 0x37, 0xBC, 0x51, 0xBC,
0x78, 0xA1, 0x53, 0x53, 0x58,
0x9B, 0x32, 0x05, 0x67, 0x6B,
0xC7, 0x3A, 0x7C, 0xA8, 0xE5,
// Code Page 9
0x70, 0x10, 0x29, 0x88, 0x94,
0xC0, 0xEE, 0x8D, 0x52, 0x20,
0xD9, 0xC3, 0x3C, 0xB3, 0x43,
0x74, 0x83, 0xC8, 0xC5, 0xAA,
0x90, 0x58, 0x0C, 0xD0, 0xBC,
0x2A, 0xED, 0x04, 0x05, 0x8E,
0x27, 0xDE, 0x9C, 0x37, 0x57,
0x2A, 0x93, 0x63, 0x1B, 0x9E,
// Code Page 10
0xC3, 0x52, 0xDB, 0xE9, 0x63,
0x9A, 0x87, 0x18, 0x6D, 0xBE,
0x1B, 0x37, 0x6A, 0xEA, 0x01,
0x02, 0x01, 0xB5, 0x74, 0x71,
0xA5, 0x9A, 0x9A, 0x3A, 0x11,
0x8B, 0x62, 0xD7, 0xB0, 0x06,
0x0C, 0xA0, 0x10, 0x09, 0x97,
0x5A, 0xEB, 0xEA, 0x18, 0xB8,
}
};