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