Files
firestorm/Gameleap/code/mw4/Code/MW4Application/mugsocs.h
T
Cyd 2b8ca921cb Initial full mirror of c:\VWE (source + assets + toolchain + outputs) via Git LFS
Complete disaster-recovery snapshot: engine/game source, game data assets,
VC6 toolchain + DX SDKs, build outputs, deployed game, and _UNUSED archive.
Large binaries in Git LFS; text preserved byte-for-byte (core.autocrlf=false,
no eol attributes). See RECOVERY.md for the one-clone rebuild procedure.
2026-06-24 21:28:16 -05:00

1272 lines
40 KiB
C++

#if !defined(__MUGSOCS__)
#define __MUGSOCS__
#define CSOC_SERVER_ID ((UINT)INT_MIN)
#define CSOC_CLIENT_ID ((UINT)0)
#define CSOC_LISTEN_ID ((UINT)-1)
#if !defined(STATIC_FDARRAY_MAX)
#define STATIC_FDARRAY_MAX 4
#endif // !defined(STATIC_FDARRAY_MAX)
#if STATIC_FDARRAY_MAX < 0
#error must : STATIC_FDARRAY_MAX >= 0
#endif
#if defined(SR_ASSERT)
#ifdef ASSERT
#undef ASSERT
#endif // ASSERT
#define ASSERT SR_ASSERT
#endif // SR_ASSERT
#ifndef NULL_CLASS_DEFINED
#define NULL_CLASS_DEFINED
class CNullClass {};
#endif
#if !defined(SOCBase_Class)
#define SOCBase_Class CNullClass
#endif // !defined(SOCBase_Class)
extern char SERVERID[];
#ifdef WIN32
#define ioctl(a,b,c) ioctlsocket(a,b,c)
#endif
//#define CMD_TYPEBREAKER 128
#ifndef MAX_PACKET
#define MAX_PACKET 2048
#endif // !MAX_PACKET
#ifndef MAX_FTPBUF
#define MAX_FTPBUF 1024
// MAX_FTPBUF는 MAX_PACKET보다 반드시 작아야 한다?
// 9+size==sizeof(bCmd) + sizeof(FTID) + sizeof(size) + size
#endif // !MAX_FTPBUF
// #define NO_PDCD - define PDCD for - no check PACKET_DUMP_CHECK_DISASSEMBLE - be very cautious!!!
// #define NO_PDCA - define PDCA for - no check PACKET_DUMP_CHECK_ASSEMBLE - be very cautious???
#ifndef MY_LINGER_TIME
#define MY_LINGER_TIME 250
#endif // !MY_LINGER_TIME
#ifndef RCV_MAX
#define RCV_MAX 10240
#endif // !RCV_MAX
#ifndef SND_MAX
#define SND_MAX 10240
#endif // !SND_MAX
#if (SND_MAX < MAX_PACKET) || (RCV_MAX < MAX_PACKET)
#error Both(SND_MAX & RCV_MAX) >= MAX_PACKET
#endif
#ifdef WIN32
#if !defined(NO_USE_OVRIO)
#define USE_OVRIO
#endif // !defined(NO_USE_OVRIO)
#else // !WIN32
#undef USE_OVRIO
#endif // WIN32
//#undef USE_OVRIO
#define PUSHFLOAT(f) (*(DWORD*)&(f))
enum EException
{
EEXCP_NoError,
// local side...
EEXCP_TooLowVersion,
EEXCP_Unknown,
EEXCP_ConnectionTimeOut,
EEXCP_ConnectionFailure,
EEXCP_SendBufferOverflow,
EEXCP_VersionError,
// fatal socket error...
EEXCP_WSAENETDOWN,
EEXCP_WSANO_RECOVERY,
EEXCP_WSAENETRESET,
EEXCP_WSAECONNRESET,
EEXCP_WSAECONNABORTED,
EEXCP_WSAEADDRINUSE,
EEXCP_WSAETIMEDOUT,
EEXCP_WSAEHOSTUNREACH,
EEXCP_WSAEACCES,
// internal error
EEXCP_WSANOTINITIALISED,
EEXCP_WSAEFAULT,
EEXCP_WSAENOTSOCK,
EEXCP_WSAENOTCONN,
EEXCP_WSAEOPNOTSUPP,
EEXCP_WSAEINVAL,
EEXCP_DupCreation,
};
#if !defined(STRF_MAX_PARAMS)
#define STRF_MAX_PARAMS 7 // should be 3 or 7
#endif
#if !((STRF_MAX_PARAMS==3) || (STRF_MAX_PARAMS==7))
#error STRF_MAX_PARAMS size must be 3 or 7...
#endif
const char* SkipWord(const char* pcsz);
const char* SkipWhite(const char* pcsz);
const char* SkipWhiteReverse(const char* pcsz);
BOOL IsControlExist(const char* pcsz);
BOOL IsAllDigit(const char* pcsz);
BOOL CheckStringOK(const char* pcsz, int nMin, int nMax);
BOOL CheckNumberOK(const char* pcsz, int nMin, int nMax);
BOOL IsInvalidCharsExist(const char* pcsz, const char* pcszInvalidChars);
char* cmd_GetString(char*& psz, int nQuoteType = 0);
int cmd_GetNumber(char*& psz, int& nNumber, int nMin = 0, int nMax = 65536);
#ifdef WIN32
#pragma pack(push, 1)
#endif // WIN32
DECLARE_TARRAYREF(CTEXTFmt);
class CTEXTFmt : public CStr
{
public:
union {
struct {
WORD m_wFmt;
WORD m_wTX;
} m_DW;
DWORD m_dw;
};
char m_caParamType[STRF_MAX_PARAMS + 1];
public:
CTEXTFmt(const char* pcszFormat = NULL);
};
#ifdef WIN32
#pragma pack(pop)
#endif // WIN32
class CTEXTFmtArray : public TARRAYREF(CTEXTFmt)
{
public:
class CAtoms : public TARRAYREF(CStr)
{
public:
CStr m_strTitle;
public:
CAtoms(const char* pcsz)
: m_strTitle(pcsz)
{
SetGrowBy(10);
}
};
TARRAYPTR(CAtoms*) m_paAtoms;
public:
CTEXTFmtArray();
virtual ~CTEXTFmtArray();
int LoadFmts(const char* pcszFile, const char* pcszSignature, BOOL bCheckACP = FALSE);
CTEXTFmt& FindTEXTFmt(WORD wFmt) const;
CAtoms* FindAtoms(const char* pcsz) const;
void Sort();
private:
int ProcessOneLine(BYTE baLine[], const char* pcszSignature, int nSizeOld, int nSize);
CTEXTFmt& FindOnLoad(WORD wFmt, int nSizeOld, int nSize) const;
static void ProcessEscape(BYTE* pb);
};
#define ESTRF_OK 0 // no error
#define ESTRF_ERR (-1)
// Login Error
#define ESTRF_VERSIONERROR 10
#define ESTRF_RESTART_PROGRAM 11
#define ESTRF_TOOMANY_CONNECTIONS 12
#define ESTRF_INVALIDLOGININFO 13 // C_LOGN_INFO invalid id or password
#define ESTRF_INVALIDLOGINNAME 14 // C_LOGN_INFO
#define ESTRF_INVALIDPASSWORD 15 // C_LOGN_INFO, C_ROOM_JOIN
#define ESTRF_ALREADYLOGIN 16 // C_LOGN_INFO
#define ESTRF_SAMEUSEREXIST 17 // C_USER_INFO
#define ESTRF_NOSUCHUSER 18 // C_USER_INFO
#define ESTRF_NAME 19 // C_USER_INFO
#define ESTRF_EMAIL 20 // C_USER_INFO
#define ESTRF_DATEBORN 21 // C_USER_INFO
#define ESTRF_HOMEPAGE 22 // C_USER_INFO
// DB error
#define ESTRF_DBCONNECTION 30 // C_LOGN_INFO
#define ESTRF_DBOPEN 31 // C_LOGN_INFO
#define ESTRF_DBRESTART 32 // C_LOGN_INFO
#define ESTRF_DBACCESS 33 // C_LOGN_INFO
// Room Error
#define ESTRF_TOOMANYROOMS 40 // C_ROOM_MAKE
#define ESTRF_SAMEROOMEXIST 41 // C_ROOM_MAKE
#define ESTRF_NOSUCHROOM 42 // C_ROOM_JOIN
#define ESTRF_ALREADYINROOM 43 // C_ROOM_JOIN
#define ESTRF_NOOTHERUSERS_IN_ROOM 44
#define ESTRF_TOOMANYUSERS_IN_ROOM 45 // C_ROOM_JOIN
#define ESTRF_INVALID_ROOMNAME 46 // C_ROOM_JOIN...
#define ESTRF_INVALID_ROOMPASSWORD 47 // C_ROOM_JOIN...
#define ESTRF_INVALID_MAX 48 // C_ROOM_MAKE
#define ESTRF_ROOM_STAT 49 // C_ROOM_STAT
// Plyr Error
#define ESTRF_OWNERCOMMAND 50
#define ESTRF_KICKEDBYOWNER 51
#define ESTRF_BANISHIEDBYOWNER 52
#define ESTRF_YOUAREALREADYBANISHIED 53
#define ESTRF_NOSUCHUSERINROOM 54
#define ESTRF_NOOWNERCOMMAND_TO_USER_INANOTHERROOM 55
#define ESTRF_OWNER_CHANGED 56
#define ESTRF_OWNER_CHANGED_AUTO 57
#define ESTRF_PLYR_IS_THERE 58
#define ESTRF_PLYR_NOT_LOGGED 59
#define ESTRF_PLYR_IS_THERE_LONELY 60
#define ESTRF_NOP_ON_SELF 61
#define ESTRF_JOIN_ANYROOM 62
#define ESTRF_NO_INVITATION_TO_USER_IN_SAME_ROOM 63
#define ESTRF_INVITATION_CALLED 64
#define ESTRF_INVITATION_CALLED_BY_OTHER 65
#define ESTRF_INVITER_LOGGEDOUT 66
#define ESTRF_INVITER_MOVED_ROOM 67
#define ESTRF_INVITATION_CHECK_ERROR 68
#define ESTRF_INVITITATION_ABORTED 69
#define ESTRF_INVITATION_DENIED 70
#define ESTRF_USER_BANISHIED 71
#define ESTRF_USER_KICKED 72
#define ESTRF_EX_ON 73
#define ESTRF_EX_OFF 74
#define ESTRF_YOUARE_SQUELDED_BY 75
#define ESTRF_USER_IS_NOT_RESPONDING 76
#define ESTRF_ALREADY_SQUELED 77
#define ESTRF_XSQUELED 78
#define ESTRF_YOUARE_XSQUELED_BY 79
#define ESTRF_SQUELED 80
#define ESTRF_YOUARE_SQUELED_BY 81
#define ESTRF_ALREADY_XSQUELED 82
#define ESTRF_SQUEL_COUNT_DROP 83
#define ESTRF_USER_START 100
#define ESTRF_PASSWORDCHANGED 110 // 로그인하고 있는 동안에 패스워드가 바뀜
void Randomize();
union UPacketValue
{
// CPU register specific
WORD m_w;
DWORD m_dw;
float m_f;
double m_dbl;
SINT64 m_i64;
};
#define UPKV(pbPacket) ((UPacketValue*)(pbPacket))
class CDAPacket : public SOCBase_Class
{
// Packet의 앞 부분을 처리하고 난 뒷 부분의 가변 파라미터...
public:
BYTE m_bCmd;
BYTE m_bReserved;
WORD m_wLen;
BYTE* m_pbPacket;
public:
virtual CSOC* IsSOC() const { return NULL; }
DWORD Push() const;
void Pop(DWORD dw);
BYTE* GetData(int nSize);
BYTE* __cdecl Disassemble(const char* pcszFormat, ...);
BYTE* __cdecl vDisassemble(const char* pcszFormat, va_list ap);
};
#define CSCODE_OK 0
#define CSCODE_ERR 0xff
#define CSCODE_CREATE 0
#define CSCODE_ADDED CSCODE_CREATE
#define CSCODE_INFO 2
#define CSCODE_CHANGE 3
#define CSCODE_CHANGED CSCODE_CHANGE
#define CSCODE_DELETE 4
#define CSCODE_DELETED CSCODE_DELETE
#define CSCODE_WHERE 5
#define CSCODE_SAY 6
#define CSCODE_INVITE 7
#define CSCODE_INVITE_RESULT 8
#define CSCODE_TO 9
#define CSCODE_SQUEL 10
#define CSCODE_XSQUEL 11
#define CSCODE_EX 12 // dummy user...
#define CSCODE_KICK 13 // C_PLYR_ACTN...
#define CSCODE_BANISH 14 // C_PLYR_ACTN...
#define CSCODE_CHOWNER 15 // C_PLYR_ACTN...
#define CSCODE_TITLE 20
#define CSCODE_PASSWORD 21
#define CSCODE_MAX 23
#define CSCODE_START 0xfa
#define CSCODE_MORE 0xfb
#define CSCODE_STOP 0xfc
#define S_PROG_INFO 200
#define C_PROG_INFO 200
// D - dwVersion
#define S_LOGN_INFO 210
#define C_LOGN_INFO 210
// s - ID, s - Password
#define S_LOGN_RSLT 211
// b - code(CSCODE_OK - ok or error code)
#define C_USER_INFO 215
// b - code(CSCODE_CREATE/CSCODE_INFO/CSCODE_CHANGE/CSCODE_DELETE), s - ID, s - Password...
#define S_USER_RSLT 215
// b - code(same w/ C_USER_INFO or CSCODE_ERR_...) if (code == CSCODE_INFO) additional user infos...
#define S_PLYR_INFO 220
// b - code(CSCODE_ADDED/CSCODE_CHANGED/CSCODE_DELETED/CSCODE_START/CSCODE_STOP), s - name, ...
#define C_PLYR_INFO 220
// b - code(CSCODE_NEXT/CSCODE_START/CSCODE_STOP)
#define C_PLYR_STAT 221
// s - name
#define S_PLYR_STAT 221
// b - code(CSCODE_OK - ok or error code)
#define C_PLYR_ACTN 222
// b - code(CSCODE_INFO, CSCODE_KICK, CSCODE_BANISH), s - name, ...
#define S_PLYR_ACTN 222
// b - code(CSCODE_KICK)
#define S_SRVR_INFO 225
// b - code(CSCODE_ADDED/CSCODE_CHANGED/CSCODE_DELETED/CSCODE_START/CSCODE_STOP), d - number, s - name, ...
#define C_SRVR_INFO 225
// b - code(CSCODE_NEXT/CSCODE_START/CSCODE_STOP)
#define C_SRVR_STAT 226
// d - name
#define S_SRVR_STAT 226
// b - code(CSCODE_OK - ok or error code)
#define S_ROOM_INFO 230
// b - code(CSCODE_ADDED/CSCODE_CHANGED/CSCODE_DELETED/CSCODE_START/CSCODE_STOP), d - number, s - name, b - Password exist, w - user count...
#define C_ROOM_INFO 230
// b - code(CSCODE_NEXT/CSCODE_START/CSCODE_STOP)
#define C_ROOM_STAT 231 // room number
#define S_ROOM_STAT 231
// b - code(CSCODE_OK - ok or error code)
#define C_ROOM_MAKE 232
// s - name, s - password
#define C_ROOM_JOIN 233
// d - number(Room을 떠나는 것은 -1), s - password
#define S_ROOM_JOIN 233 // C_ROOM_MAKE/C_ROOM_JOIN의 결과...
// b - code(CSCODE_OK or error code), d - number
#define C_ROOM_UPDS 234 // CSCODE_... + @
#define S_GAME_INFO 235
// b - code(CSCODE_ADDED/CSCODE_CHANGED/CSCODE_DELETED/CSCODE_START/CSCODE_STOP), d - number, s - name, ...
#define C_GAME_INFO 235
// b - code(CSCODE_NEXT/CSCODE_START/CSCODE_STOP)
#define C_GAME_STAT 236
// d - name
#define S_GAME_STAT 236
// b - code(CSCODE_OK - ok or error code)
#define C_GAME_RSLT 237
// same server/client command...
#define X_TEXT 250 // %s{Sender/Receiver ID}%s{notify string}%W{TX_...}
#define X_TEXTFMT 251 // %W{Format}%s{ParamFormat}[{params0}[{params2}[...]]]
#define C_FTP 253 //... see ftp.txt
#define S_FTP 254 //... see ftp.txt
#define X_KEEPALIVE 255 // no parameters, should be ignored...
#define TX_SYSTEM 0 // 시스템 메시지...
#define TX_NORMAL 1 // 일반 채팅 텍스트
#define TX_WARNING 2 // 경고
#define TX_ERROR 3 // 오류
#define TX_FATAL 4 // 치명적인 오류
#define TX_INFO 5 // 사용자 정보 등의 Information Result...
#define TX_SAY 6 // 귓속말
#define TX_LOCAL 7 // local echo....
#define TX_UNKNOWN 0xffff // unknown...
typedef long (*PFN_TimerProc)(CTimerEvent& Timer);
class CSOCListen;
class CSOCClient;
typedef CSOCClient* (*PFN_CreateSOCClient)(const CSOCListen& SOCListen, DWORD dwCSCParam1, DWORD dwCSCParam2);
#ifdef WIN32
#pragma pack(push, 1)
#endif // WIN32
class CTimerEvent
{
friend class CTimerPool;
public:
PFN_TimerProc m_pfnTimerProc;
DWORD m_dwTime;
void* m_pVoid;
// no function params...
int m_nParam; // not initialized...
DWORD m_dwParam; // not initialized...
protected:
DWORD m_dwFrame;
};
#ifdef WIN32
#pragma pack(pop)
#endif // WIN32
#define CHK_TIMER_NOVOIDCHECK 0x8000
#define CHK_TIMER_ONCE 0x0001
class CTimerPool : public TARRAY(CTimerEvent)
{
private:
int m_nReEnter;
public:
BOOL m_bDirty;
protected:
DWORD m_dwPrecision;
DWORD m_dwLastTicks;
private:
DWORD m_dwFrame;
public:
CTimerPool();
public:
DWORD GetPrecision() const { return m_dwPrecision; }
void SetPrecision(DWORD dwPrecision) { m_dwPrecision = dwPrecision; }
DWORD GetLastTicks() const { return m_dwLastTicks; }
void SetLastTicks(DWORD dwLastTicks) { m_dwLastTicks = dwLastTicks; }
public:
void CheckTimers();
CTimerEvent& AddTimer(PFN_TimerProc pfnTimerProc, DWORD dwTime, void* pVoid);
BOOL DelTimer(int nIndex);
BOOL DelTimers(PFN_TimerProc pfnTimerProc, void* pVoid, UINT uFlags, int nFromIndex = 0);
BOOL DelTimersAll() { return DelTimers((PFN_TimerProc)NULL, NULL, 0, 0); }
int FindTimer(PFN_TimerProc pfnTimerProc, void* pVoid, UINT uFlags, int nFromIndex = 0);
};
union UFmtParam
{
// CPU register specific
BYTE m_b; // 'B'
unsigned char m_c; // 'b'
WORD m_w; // 'W'
short m_s; // 'w'
int m_n; // 'n'
long m_l; // 'd'
DWORD m_dw; // 'D'
float m_f;
double m_F;
char* m_psz; // 's' or 'S' - don't mix...
SINT64 m_i64; // '6' - 64 bit integer...
// 'x' - binary data, wLen + Data
// 'X' - mainly for Assemble, sub-packet copy... no info for disassemble
// '!' - CPacketDumper*
};
class CPacketDumper
{
public:
public:
CPacketDumper() {}
virtual ~CPacketDumper() {}
virtual BYTE* Disassemble(BYTE* pbPacket, BYTE* pbPacketEnd) = 0;
virtual BYTE* Assemble(BYTE* pbPacket, BYTE* pbPacketEnd) = 0;
};
#ifdef WIN32
#pragma pack(push, 1)
#endif // WIN32
DECLARE_TARRAYREF(CPacket)
class
#ifdef WIN32
__declspec(novtable)
#endif // WIN32
CPacket
{
friend class CSOCConnect;
protected:
CSOC* m_pSOC;
private:
// 이 안의 블럭은 반드시 연속해야 한다...
WORD m_wLen;
BYTE m_ba[MAX_PACKET];
//
public:
CPacket(CSOC* pSOC);
~CPacket();
void Reset();
CSOC& GetSOC() const { ASSERT(this); return *m_pSOC; }
const BYTE* GetPacketStart() const { return (const BYTE*)&m_wLen; }
int GetLength() const { return m_wLen; }
void SetLength(int nLen) { m_wLen = (WORD)(short)nLen; }
BYTE* GetBuffer() const { return (BYTE*)&m_ba[0]; }
int GetTotalLength() const { return sizeof(WORD) + m_wLen; }
BYTE* GetLastPtr() const { return (BYTE*)&m_ba[m_wLen]; }
BYTE* GetEndPtr() const { return (BYTE*)&m_ba[MAX_PACKET]; }
void Prepare(int nSize) { m_wLen += (WORD)nSize; }
BYTE* __cdecl Assemble(const char* pcszFormat, ...);
BYTE* __cdecl vAssemble(const char* pcszFormat, va_list ap);
BYTE* DisassembleParamsAndTextFmt(CSOCConnect& SOC, WORD wFmt, const char* pcszParamType, WORD& wTX);
protected:
void DropSOC();
BYTE* DoTextFmt(const char* pcszFormat, const UFmtParam aFPs[STRF_MAX_PARAMS], const char caParamType[/*STRF_MAX_PARAMS + 1*/]);
};
#ifdef WIN32
#pragma pack(pop)
#endif // WIN32
class CSockAddr : public sockaddr_in
{
public:
CStr m_strTarget;
public:
CSockAddr(int nPort, const char* pcszAddr = NULL, short sFamily = AF_INET);
CSockAddr(int nPort, u_long ulAddr = INADDR_ANY, short sFamily = AF_INET);
public:
sockaddr_in* GetSockAddrIn() { return this; }
const char* GetTarget() const;
u_long GetTargetAddr() const { return ntohl(sin_addr.s_addr); }
void SetTarget(const char* pcszAddr);
void SetTarget(u_long ulAddr);
int GetPort() const;
void SetPort(int nPort);
};
const char* GetHostAddress();
typedef void (CSOC::*PF_PacketProcessor)();
#define PFPP_CallBase ((PF_PacketProcessor)0) // do not change this line...
#define PFPP_Ignore CSOC::OnIgnore // why not? ((PF_PacketProcessor)1)
#define MAX_PACKET_TYPE 256 // 1byte
/****************
start of variable PACKET_MAP definitions...
****************/
struct _SPacketMap
{
public:
_SPacketMap* m_pBaseMap;
PF_PacketProcessor* m_pPFPP;
public:
PF_PacketProcessor TraceAndModifyBaseCall(BYTE bCmd, PF_PacketProcessor& refPFPP) const;
};
#define PACKET_MAP(CLASSNAME) _CAutoStart##CLASSNAME
#define PACKET_MAP_STATIC_INSTANCE(CLASSNAME) _g_AutoStart##CLASSNAME##Instance
#define DECLARE_PACKET_MAP(thisClass) friend class PACKET_MAP(thisClass); protected: static PF_PacketProcessor m_aPFPP[MAX_PACKET_TYPE]; static _SPacketMap m_PacketMap; protected: virtual _SPacketMap* GetPacketMap() const;
// start of BEGIN_PACKET_MAP_RAW, BEGIN_PACKET_MAP
#define BEGIN_PACKET_MAP_RAW(thisClass, basePacketMap) PF_PacketProcessor thisClass::m_aPFPP[MAX_PACKET_TYPE] = { PFPP_CallBase, }; _SPacketMap thisClass::m_PacketMap = { basePacketMap, &thisClass::m_aPFPP[0] }; _SPacketMap* thisClass::GetPacketMap() const { return &thisClass::m_PacketMap; } class PACKET_MAP(thisClass) { public: PACKET_MAP(thisClass)() {
#define BEGIN_PACKET_MAP(thisClass, baseClass) BEGIN_PACKET_MAP_RAW(thisClass, &baseClass::m_PacketMap)
// end of BEGIN_PACKET_MAP_RAW, BEGIN_PACKET_MAP
// start of PACKET_MAP_ENTRY_RAW, PACKET_MAP_ENTRY, PACKET_MAP_ENTRY_IGNORE
#define PACKET_MAP_ENTRY_RAW(thisClass, bCmd, PFPP) ASSERT((0 <= bCmd) && (bCmd < MAX_PACKET_TYPE)); thisClass::m_aPFPP[bCmd] = (PF_PacketProcessor)&PFPP;
#define PACKET_MAP_ENTRY(thisClass, bCmd, PFPP) PACKET_MAP_ENTRY_RAW(thisClass, bCmd, thisClass::PFPP)
#define PACKET_MAP_ENTRY_IGNORE(thisClass, bCmd) PACKET_MAP_ENTRY_RAW(thisClass, bCmd, PFPP_Ignore)
// end of PACKET_MAP_ENTRY & PACKET_MAP_ENTRY_IGNORE
// start of END_PACKET_MAP
#define END_PACKET_MAP(thisClass) } }; static PACKET_MAP(thisClass) PACKET_MAP_STATIC_INSTANCE(thisClass);
// end of END_PACKET_MAP
/****************
end of variable PACKET_MAP definitions...
****************/
class CFileTransfer : public TDBLNK(CFileTransfer*)
{
public:
// 서버로 부터 받은 정보... - 혹은 클라이언트에게 전해줄 정보...
BOOL m_bClientSite;
DWORD m_dwFTID;
DWORD m_dwGUARD;
CStr m_strFileNameRemote;
DWORD m_dwTime;
long m_lSize;
UINT m_uMinBPS;
UINT m_uMaxBPS;
CStr m_strFileNameLocal;
int m_nFile;
long m_lPos;
DWORD m_dwStartTime;
public:
CFileTransfer(DWORD dwFTID, DWORD dwGUARD, const char* pcszFileNameRemote, const char* pcszFileNameLocal);
virtual ~CFileTransfer();
virtual BOOL Setup(DWORD& dwError);
virtual BOOL Setup(DWORD dwTime, long lSize, DWORD& dwError);
virtual int CheckReadPosition(long lPosition) const;
int Close();
void Start();
};
class CFTPArray : TARRAY(CFileTransfer*)
{
public:
public:
CFTPArray();
virtual ~CFTPArray();
int Find(CFileTransfer* pFTP) const;
CFileTransfer* CutIfExist(CFileTransfer* pFTP);
};
#ifdef USE_OVRIO
DECLARE_TARRAYREF(COVRIO);
#ifdef WIN32
#pragma pack(push, 1)
#endif // WIN32
class
#ifdef WIN32
__declspec(novtable)
#endif // WIN32
COVRIO : public TDoubleLinkRef<COVRIO*, WSAOVERLAPPED>
{
public:
CSOC* m_pSOC;
int m_nSize;
BYTE m_ba[/*m_nSize*/];
public:
COVRIO();
~COVRIO();
DECLARE_STATIC_CONSTRUCTION(COVRIO);
};
#ifdef WIN32
#pragma pack(pop)
#endif // WIN32
COVRIO* newCOVRIO(CSOC* pSOC, const BYTE* pb, int nSize);
void deleteCOVRIO(COVRIO* pOVRIO);
void CALLBACK OVRIO_Completion(DWORD dwError, DWORD cbTransferred, LPWSAOVERLAPPED lpOverlapped, DWORD dwFlags);
#endif // USE_OVRIO
#define SOCNEXT_EXCCLIENT 0x0001
#define SOCNEXT_EXCSERVER 0x0002
#define SOCNEXT_EXCLISTEN 0x0004
#define SOCNEXT_EXCINVALID 0x0010
#define SOCNEXT_EXCDROPPING 0x0020
#define SOCNEXT_EXCCONNECTTING 0x0080 // CSOCServer Only...
#define SOCNEXT_CHECKPROC 0x4000
#define SOCNEXT_REVERSE 0x8000
#define SOCNEXT_DEFAULT (SOCNEXT_EXCINVALID|SOCNEXT_EXCDROPPING|SOCNEXT_EXCLISTEN|SOCNEXT_EXCCONNECTTING)
class CSOC : public CDAPacket
{
friend class CSOCManager;
DECLARE_PACKET_MAP(CSOC)
protected:
int m_nLockCount;
SOCKET m_hSocket;
int m_nState;
BOOL m_bSendLoop;
CSOCManager* m_pSOCManager;
CSockAddr m_Addr;
// time - last Rcv/Snd
DWORD m_dwKARcvTicks;
DWORD m_dwKASndTicks;
// time out to Drop...
DWORD m_dwKARcvTimeOut;
#ifdef WIN32
// 보통 Login과정에 쓰이는 윈도우 핸들
HWND m_hWndOwner;
#endif // WIN32
// 보통 글로벌 변수로 쓰이는 소켓포인터에 대한 자동 NULL Assign을 위하여
PSOC* m_ppSOC;
// 소켓을 구분하기 위하여 사용자 프로그램에서 쓰이는 아이디
// 주로 서버의 경우에는 클라이언트가 접속할 때마다 고유 아이디를 부여하여 사용
// 하나의 Client가 다수의 서버에 접속할 때(주로 Star형) 각각의 접속을 구분할 때 사용
// 클라이언트가 하나의 서버에만 접속하는 경우 클라이언트가 서버에 접속 중인지 혹은 접속했는지를 판단할 때
// CSOCManager::FindSOC(CSOC_SERVER_ID==default)->GetConnectionState()를 사용.
// limits.h를 include해야함.
// CSOC생성시의 기본값: CSOCServer == CSOC_SERVER_ID(=INT_MIN), CSOCClient == CSOC_CLIENT_ID(=0), CSOCListen == CSOC_LISTEN_ID(=-1)
union {
int m_nID;
UINT m_uID;
void* m_pvID;
} m_ID;
protected:
DWORD m_dwDroppingTicks;
public:
TDeQueueFixed<BYTE,RCV_MAX, CNullClass> m_aRcv;
#ifdef USE_OVRIO
COVRIO* m_pOVRIOStart;
#else // !USE_OVRIO
TDeQueueFixed<BYTE,SND_MAX, CNullClass> m_aSnd;
#endif // USE_OVRIO
protected:
// don't use this - use get/set functions only...
union {
struct {
DWORD m_xAllowAccept: 1; // CSOCListen Only...
DWORD m_xUseSelect: 1; // Use select() for Acception Check...
DWORD m_xAutoDelete: 1;
DWORD m_xAdded: 1;
DWORD m_xIsConnected: 1;
DWORD m_xIsConnecting: 1;
DWORD m_xDoDelSocket: 1;
DWORD m_xIsDropping: 1;
DWORD m_xIsSetupFailure: 1;
DWORD m_xGracefulLocal: 1;
DWORD m_xErrSEND: 1;
DWORD m_xErrRECEIVE: 1;
DWORD m_xGracefulRemote: 1;
DWORD m_xAbortyLocal: 1;
DWORD m_xAbortyRemote: 1;
DWORD m_xLoginStarted: 1; // 사용자가 직접 값을 Setting해야 한다.
DWORD m_xLoginOK: 1; // 사용자가 직접 값을 Setting해야 한다.
} m_DW;
DWORD m_dwVarFlags;
};
public:
CSOC();
virtual ~CSOC();
void Reset();
public:
operator SOCKET () const { return m_hSocket; }
SOCKET GetSocket() const { return m_hSocket; }
BOOL IsValidSafe() const { return this && (m_hSocket != INVALID_SOCKET); }
BOOL IsValid() const { return m_hSocket != INVALID_SOCKET; }
int GetID() const { return m_ID.m_nID; }
void SetID(int nID) { m_ID.m_nID = nID; }
void Lock() { m_nLockCount++; }
void Unlock() { ASSERT(m_nLockCount > 0); m_nLockCount--; }
int GetLockCount() const { return m_nLockCount; }
BOOL IsConnecting() const { return m_DW.m_xIsConnecting; }
BOOL IsConnected() const { return m_DW.m_xIsConnected; }
BOOL IsDroppingState() const { return m_DW.m_xIsDropping; }
CSockAddr& GetSockAddr() const { return *(CSockAddr*)&m_Addr; }
void SetRcvTimeOut(DWORD dwTimeOut) { m_dwKARcvTimeOut = dwTimeOut; }
#ifdef WIN32
HWND GetOwnerHWND() const { return m_hWndOwner; }
void SetOwnerHWND(HWND hWndOwner) { m_hWndOwner = hWndOwner; }
#endif // WIN32
PSOC* GetSOCPP() const { return m_ppSOC; }
void SetSOCPP(PSOC* ppSOC) { if (this) m_ppSOC = ppSOC; }
BOOL GetLoginStarted() const { return m_DW.m_xLoginStarted; }
void SetLoginStarted(BOOL bLoginStarted) { m_DW.m_xLoginStarted = !!bLoginStarted; }
BOOL GetLoginOK() const { return m_DW.m_xLoginOK; }
void SetLoginOK(BOOL bLoginOK) { m_DW.m_xLoginOK = !!bLoginOK; }
BOOL GetUseSelect() const { return m_DW.m_xUseSelect; }
void SetUseSelect(BOOL bUseSelect) { m_DW.m_xUseSelect = !!bUseSelect; }
BOOL GetSendLoop() const { return m_bSendLoop; }
void SetSendLoop(BOOL bSendLoop) { m_bSendLoop = bSendLoop; }
const char* GetTarget() const { return m_Addr.m_strTarget; }
void SetTarget(const char* pcszTarget) { m_Addr.SetTarget(pcszTarget); }
void SetTarget(u_long ulAddr) { m_Addr.SetTarget(ulAddr); }
int GetPort() const { return m_Addr.GetPort(); }
void SetPort(int nPort) { m_Addr.SetPort(nPort); }
BOOL GetAutoDelete() const { return m_DW.m_xAutoDelete; }
void SetAutoDelete(BOOL bAutoDelete) { m_DW.m_xAutoDelete = !!bAutoDelete; }
int GetState() const { return m_nState; }
void SetState(int nState) { m_nState = nState; }
CSOCManager& GetSOCManager() const { return *m_pSOCManager; }
void SetSOCManager(CSOCManager* pSOCManager) { ASSERT(!m_pSOCManager || !pSOCManager); m_pSOCManager = pSOCManager; }
BOOL IsAdded() const { return m_DW.m_xAdded; }
void SetAdded(BOOL bAdded) { m_DW.m_xAdded = !!bAdded; }
CFileTransfer* FindFTP(DWORD dwFTID) const;
CFileTransfer* FindFTP(const char* pcszFileNameRemote) const;
public:
int GetSignatureFromPort(int nPort) const;
int GetConnectionState() const;
void Drop();
public:
BOOL DoSend(const BYTE* pbBuf, int nSize);
BOOL DoSendCmdWOP(BYTE bCmd);
void DoSendLoginOK();
void DoSendLoginError();
void DoSendLoginError(WORD wErrFMT);
BOOL DoSend(const CPacket& Packet);
BOOL DoSendX(BYTE bCmd, const void* pData, int nLen);
BOOL __cdecl DoSendX(const char* pcszFormat, ...);
BOOL DoSendText(BYTE bCmd, const char* pcsz);
BOOL DoSendText(const char* pcszID, const char* pcsz, WORD wTX = TX_NORMAL);
BOOL __cdecl DoSendFmt(WORD wFmt, const char* pcszParamType = NULL, ...);
BOOL vDoSendFmt(WORD wFmt, const char* pcszParamType, va_list ap);
public:
virtual CSOC* IsSOC() const { return (CSOC*)this; }
virtual BOOL CheckProc(DWORD dwParam) { return TRUE; }
virtual DWORD GetSendTimeOut() const { return 5 * 1000; }
virtual BOOL IsListenSocket() const { return FALSE; }
virtual BOOL IsClientSocket() const { return FALSE; }
virtual BOOL IsServerSocket() const { return FALSE; }
virtual UINT GetType() const { return 0; }
virtual UINT GetType3() const = 0;
virtual const CTEXTFmtArray& GetTEXTFmtArray();
virtual const CTEXTFmt& GetTEXTFmt(WORD wFmt);
virtual BOOL DoProcessPacket();
virtual void OnOpen();
virtual BOOL OnSetupSocket();
virtual void OnAddSocket();
virtual void OnDropping();
virtual void OnDelSocket();
virtual void OnShutdown();
virtual void OnClose();
virtual void OnDelete();
virtual void OnSendKeepAlive();
#if !defined(USE_OVRIO)
virtual BOOL OnOverflow(int nSizeReq, int nRetry, DWORD dwTimeBegin);
#endif // !defined(USE_OVRIO)
public: // packet handler map
void OnIgnore();
void OnKeepAlive();
#ifdef USE_OVRIO
COVRIO* newCOVRIO(const BYTE* pb, int nSize);
void deleteCOVRIO(COVRIO* pOVRIO);
void OnOVRIO_Completion(DWORD dwError, DWORD cbTransferred, COVRIO* pOVRIO, DWORD dwFlags);
#endif // USE_OVRIO
int aSnd_GetDataSize();
protected:
BOOL IsSendPossible() const { return !(m_DW.m_xErrSEND || m_DW.m_xAbortyRemote || m_DW.m_xGracefulLocal); }
BOOL IsReceivePossible() const { return !(m_DW.m_xErrRECEIVE || m_DW.m_xAbortyRemote || m_DW.m_xGracefulRemote); }
BOOL DoClose();
void CheckAutoDelete();
void SetDroppingTicks();
BOOL CreateAndAttach();
void CallOnOpen(SOCKET soc);
void CallOnDropping();
void CallOnShutdown(int nHow);
void CallOnClose();
void CallOnDelete();
protected:
void DoPacketProcessing();
BOOL OnReceive();
int DoReceive(BYTE* pbBuf, int nLen);
int OnSend();
protected:
void SendKeepAlive();
void ResetKeepAliveAll();
void ResetKeepAliveRcv();
void ResetKeepAliveSnd();
protected:
EException GetExceptionCode(int nErrorCode);
EException DoErrorReport(int nErrorCode, BOOL bDropIfErrorOccur = FALSE);
EException DoExceptions(EException eException, BOOL bDropIfErrorOccur = FALSE);
};
class CSOCListen : public CSOC
{
friend class CSOC;
friend class CSOCManager;
protected:
PFN_CreateSOCClient m_pfnCSC;
DWORD m_dwCSCParam1;
DWORD m_dwCSCParam2;
DWORD m_dwListenTime;
DWORD m_dwLastCheck;
public:
CSOCListen(int nPort = 0, DWORD dwListenTime = 250);
virtual ~CSOCListen();
DWORD GetListenTime() const { return m_dwListenTime; }
void SetListenTime(DWORD dwListenTime) { m_dwListenTime = dwListenTime; }
BOOL GetAllowAccept() const { return m_DW.m_xAllowAccept; }
void SetAllowAccept(BOOL bAllowAccept) { m_DW.m_xAllowAccept = !!bAllowAccept; }
void GetCSCParam(PFN_CreateSOCClient& pfnCSC, DWORD& dwCSCParam1, DWORD& dwCSCParam2) const;
void SetCSCParam(PFN_CreateSOCClient pfnCSC, DWORD dwCSCParam1, DWORD dwCSCParam2);
public:
virtual BOOL IsListenSocket() const { return TRUE; }
virtual UINT GetType3() const { return SOCNEXT_EXCLISTEN; }
virtual BOOL BindAndListenSocket();
virtual void OnAcception();
virtual CSOCClient* OnNewClientSocket() const;
virtual BOOL OnAddrAcceptionCheck(const sockaddr_in& Addr) { return TRUE; }
virtual BOOL DoProcessPacket() { m_aRcv.FreeAll(); return FALSE; }
};
class CSOCConnect : public CSOC
{
friend class CSOC;
friend class CSOCManager;
DECLARE_PACKET_MAP(CSOCConnect)
protected:
time_t m_tConnection;
DWORD m_dwLingerTime;
CFileTransfer* m_pFTPStart;
public:
CSOCConnect(DWORD dwLingerTime);
virtual ~CSOCConnect();
public:
time_t GetConnectionTime() const { return m_tConnection; }
DWORD GetConnectionTicks() const;
DWORD GetConnectionTimeString(CStr& strTime, BOOL bForceShowMin = FALSE, BOOL bForceShowHour = FALSE) const;
void SetConnectionTime();
DWORD GetLingerTime() const { return m_dwLingerTime; }
void SetLingerTime(DWORD dwLingerTime) { m_dwLingerTime = dwLingerTime; }
public:
BOOL DoFileTransfer(DWORD dwGUARD, const char* pcszFileNameRemote);
CFileTransfer* FindFTP(DWORD dwFTID) const;
CFileTransfer* FindFTP(const char* pcszFileNameRemote) const;
void DoFTPCloseAllAsError();
public:
virtual void DoTextDisplay(const char* pcszID, const char* pcszMsg, WORD wTX);
public: // FTP virtual...
virtual void OnFTPFileInfoNotify(CFileTransfer* pFTP);
virtual void OnFTPError(CFileTransfer* pFTP, long lErrorCode);
virtual const char* OnFTPDirectory(BOOL bClientSite) const;
virtual const char* OnFTPFileNameValidation(const char* pcszFileName) const;
virtual void OnFTPFileMap(DWORD dwGUARD, const char* pcszFileNameRemote, CStr& strFileNameLocal, BOOL bClientSite) const;
virtual void OnFTPSrvrError(DWORD dwGUARD, const char* pcszFileNameRemote, DWORD dwError);
virtual void OnFTPNotFound(DWORD dwFTID, BOOL bClientSite);
virtual CFileTransfer* OnAllocFileTransfer(DWORD dwGUARD, const char* pcszFileNameRemote, DWORD& dwError);
virtual CFileTransfer* OnAllocFileTransfer(DWORD dwFTID, DWORD dwGUARD, const char* pcszFileNameRemote, DWORD dwTime, long lSize, DWORD& dwError);
virtual CFileTransfer* OnNewFileTransfer(DWORD dwFTID, DWORD dwGUARD, const char* pcszFileNameRemote, const char* pcszFileNameLocal);
virtual void OnFreeFileTransfer(CFileTransfer* pFTP);
virtual void OnFTPRead(CFileTransfer* pFTP, long lSize);
virtual void OnFTPWrite(CFileTransfer* pFTP, long lPosition);
virtual void OnFTPTerminate(CFileTransfer* pFTP);
virtual BOOL DoFTPWrite(CFileTransfer* pFTP, const BYTE* pb, long lSize);
virtual long DoFTPRead(CFileTransfer* pFTP, const BYTE* pb, long lSize);
public: // packet handler map
void OnText();
void OnTextFmt();
void OnFTP();
protected:
BOOL CheckDroppingTicks(DWORD dwTicks);
};
class CSOCClient : public CSOCConnect
{
friend class CSOC;
friend class CSOCListen;
friend class CSOCConnect;
friend class CSOCServer;
friend class CSOCManager;
DECLARE_PACKET_MAP(CSOCClient)
public:
TARRAYREF(CStr) m_astrGroups;
public:
CSOCClient(DWORD dwLingerTime = MY_LINGER_TIME);
virtual ~CSOCClient();
public:
virtual BOOL IsClientSocket() const { return TRUE; }
virtual UINT GetType3() const { return SOCNEXT_EXCCLIENT; }
virtual BOOL OnCheckIDAndPassword(const char* pcszID, const char* pcszPW);
virtual void OnAccept();
public: // packet handler map
protected:
void CallOnAccept();
};
class CSOCServer : public CSOCConnect
{
friend class CSOC;
friend class CSOCListen;
friend class CSOCConnect;
friend class CSOCClient;
friend class CSOCManager;
DECLARE_PACKET_MAP(CSOCServer)
public:
CSOCServer(const char* pcszTarget = NULL, int nPort = 0, DWORD dwLingerTime = MY_LINGER_TIME);
virtual ~CSOCServer();
public:
void CallOnConnectionTimeOut(); // do not use the function, should be protected but...
public:
virtual BOOL IsServerSocket() const { return TRUE; }
virtual UINT GetType3() const { return SOCNEXT_EXCSERVER; }
virtual void OnConnect();
virtual void OnConnectionTimeOut();
public: // packet handler map
protected:
BOOL DoConnect();
void CallOnConnect();
};
class CSOCUDP
{
protected:
CSockAddr m_Addr;
SOCKET m_hSocket;
int m_nPort;
public:
CSOCUDP(int nPort = 0);
virtual ~CSOCUDP();
CSockAddr& GetSockAddr() const { return *(CSockAddr*)&m_Addr; }
operator SOCKET () const { return m_hSocket; }
SOCKET GetSocket() const { return m_hSocket; }
BOOL IsValidSafe() const { return this && (m_hSocket != INVALID_SOCKET); }
BOOL IsValid() const { return m_hSocket != INVALID_SOCKET; }
int GetPort() const { return m_nPort; }
UINT GetMAX_MSG_SIZE() const;
BOOL CreateAndBind(int nPort = 0);
void Drop();
BOOL IsReadable() const;
BOOL IsWritable() const;
int Send(const void* pBuffer, int nLen, DWORD dwAddr, int nPort);
int Recv(void* pBuffer, int nLen, DWORD& dwAddr, int& nPort);
int Send(const void* pBuffer, int nLen, const sockaddr_in& Addr);
int Recv(void* pBuffer, int nLen, sockaddr_in& Addr);
};
template <class CSOCClass>
class TSOCArray : public TARRAY(CSOCClass*)
{
public:
public:
int FindIndex(CSOCClass* pSOC) const
{
int nSize = GetSize();
CSOCClass** pp = &GetAt(nSize);
while(nSize-- > 0) {
if (*--pp == pSOC)
break;
}
return nSize;
}
int DelIfExist(CSOCClass* pSOC)
{
int nIndex = FindIndex(pSOC);
if (nIndex != -1) {
Del(nIndex);
}
return nIndex;
}
};
#ifdef WIN32
#define XFD_ARRAY fd_set
#else // !WIN32
struct XFD_ARRAY
{
public:
int fd_count;
SOCKET fd_array[FD_SETSIZE];
};
#endif // WIN32
class XFD_SET : protected XFD_ARRAY
{
private:
#if !defined(WIN32)
fd_set m_FD_SET;
#endif // !defined(WIN32)
public:
XFD_SET();
XFD_SET(SOCKET soc);
XFD_SET(const XFD_SET& that);
int GetCount() const { return fd_count; }
SOCKET* GetFDs() const { return (SOCKET*)&fd_array[0]; }
void Assign(const XFD_SET& that);
int FindIndexFromHandle(SOCKET soc) const;
void ZERO();
BOOL ISSET(SOCKET soc);
void SET(SOCKET soc);
void CLR(SOCKET soc);
void CLR_Index(int nIndex);
XFD_ARRAY& GetFD_ARRAY() const;
fd_set& GetFD_SET() const;
int Select(int nType);
#ifdef _DEBUG
void CheckHandleMap() const;
#endif // _DEBUG
};
class CFDSet : protected XFD_SET
{
protected:
PSOC m_paSOCs[FD_SETSIZE];
public:
CFDSet();
virtual ~CFDSet();
public:
CSOC* GetSOCFromHandle(SOCKET soc) const;
int GetCount() const { return fd_count; }
PSOC* GetStartOfSOCs() const { return (PSOC*)&m_paSOCs[0]; }
PSOC FindSOC(SOCKET soc, int& nIndex) const;
#ifdef _DEBUG
void CheckHandleMap() const;
#endif // _DEBUG
void SET(const CSOC& SOC);
void CLR(const CSOC& SOC);
void CLR_Index(int nIndex);
protected:
BOOL AddSOC(CSOC& SOC);
void DelSOC(CSOC& SOC);
void DelSOCFromIndex(CSOC& SOC, int nIndex);
};
class CDroppings : protected TSOCArray<CSOC>
{
friend class CSOCManager;
public:
public:
void AddWithFlush(CSOC* pSOC);
};
template <int nFDArrayMAX>
class TFD_SET_Dynamic
{
private:
int m_nLevel;
XFD_SET* m_pFD_SET;
XFD_SET m_aFD_SET[nFDArrayMAX];
TARRAYPTR2(XFD_SET*) m_paFD_SET;
public:
TFD_SET_Dynamic()
{
m_nLevel = 0;
m_pFD_SET = NULL;
m_paFD_SET.SetGrowBy(3);
}
~TFD_SET_Dynamic()
{
ASSERT(m_nLevel == 0);
}
void Alloc()
{
if (m_nLevel < nFDArrayMAX) {
m_pFD_SET = &m_aFD_SET[m_nLevel];
} else {
XFD_SET* p = (XFD_SET*)malloc(sizeof(XFD_SET));
m_paFD_SET.Add() = p;
m_pFD_SET = p;
}
m_nLevel++;
}
void Free()
{
ASSERT(m_nLevel > 0);
#ifdef _DEBUG
if (m_nLevel <= nFDArrayMAX) {
ASSERT(m_paFD_SET.GetSize() == 0);
} else {
ASSERT(nFDArrayMAX + m_paFD_SET.GetSize() == m_nLevel);
}
#endif // _DEBUG
if (--m_nLevel > 0) {
if (m_nLevel < nFDArrayMAX) {
m_pFD_SET = &m_aFD_SET[m_nLevel];
} else {
int nIndex = m_nLevel - nFDArrayMAX;
m_paFD_SET.Del(nIndex);
if (--nIndex < 0) {
m_pFD_SET = &m_aFD_SET[nFDArrayMAX - 1];
} else {
m_pFD_SET = m_paFD_SET.At(nIndex);
}
}
} else {
ASSERT(m_nLevel == 0);
m_pFD_SET = NULL;
}
}
XFD_SET* GetFD_SET(const TSOCArray<CSOC>& aSOCs) const
{
ASSERT(m_pFD_SET && &aSOCs);
int nSize = aSOCs.GetSize();
XFD_SET& fd = *m_pFD_SET;
XFD_ARRAY& fda = fd.GetFD_ARRAY();
fda.fd_count = nSize;
#if !defined(WIN32)
fd_set& u = fd.GetFD_SET();
FD_ZERO(&u);
#endif // !defined(WIN32)
SOCKET* pSOCKET = &fda.fd_array[0];
CSOC** ppSOC = &aSOCs.GetAt(0);
while(nSize-- > 0) {
CSOC* pSOC = *ppSOC++;
*pSOCKET++ = *pSOC;
#if !defined(WIN32)
SOCKET soc = *pSOC;
FD_SET(soc, &u);
#endif // !defined(WIN32)
}
return &fd;
}
XFD_SET* GetFD_SET(const XFD_SET& fd) const
{
ASSERT(m_pFD_SET && &fd);
m_pFD_SET->Assign(fd);
return m_pFD_SET;
}
};
class CSOCManager : public CFDSet
{
friend class CSOC;
friend class CSOCListen;
friend class CSOCConnect;
friend class CSOCClient;
friend class CSOCServer;
private:
TFD_SET_Dynamic<STATIC_FDARRAY_MAX> m_FD_Dynamic;
protected:
int m_nStarted;
// socsystem
WORD m_wVersionRequested;
#ifdef WIN32
WSADATA m_wsaData;
#endif // WIN32
// socmanager
int m_nDroppingSockets;
TSOCArray<CSOC> m_paConnectings;
CDroppings m_paDroppings;
public:
DWORD m_dwConnectTimeOut;
CTimerPool m_aTimerPool;
public:
CSOCManager(DWORD dwConnectTimeOut = 20000);
virtual ~CSOCManager();
public:
BOOL IsStarted() const { return m_nStarted > 0; }
DWORD GetConnectTimeOut() const { return m_dwConnectTimeOut; }
void SetConnectTimeOut(DWORD dwConnectTimeOut) { m_dwConnectTimeOut = dwConnectTimeOut; }
public:
CSOCListen* GetListenSocket() const;
CSOC* FindSOC(int nID = CSOC_SERVER_ID) const;
CSOCServer* FindSOCServeLogin(int nID = CSOC_SERVER_ID) const;
CSOC* GetNextSocket(UINT uType, UINT uMask, CSOC* pSOC, int& nIndex, DWORD dwParam = 0);
BOOL DoListen(CSOCListen* pSOCListen, int nPort = 0);
CSOCListen* DoListen(int nPort, PFN_CreateSOCClient pfnCSC, DWORD dwCSCParam1, DWORD dwCSCParam2);
BOOL DoConnect(CSOCServer* pSOCServer, const char* pcszTarget = NULL, int nPort = 0);
void DropAll(BOOL bWait = TRUE);
EException OnExceptions(CSOC* pSOC, EException eException, BOOL bDropIfErrorOccur = FALSE);
public:
virtual BOOL Init();
virtual void Exit();
virtual BOOL Startup();
virtual void Shutdown();
virtual BOOL SetupInitialOption();
virtual BOOL InitSignal();
virtual void ExitSignal();
virtual void OnAddSocket(CSOC& SOC);
virtual void OnDelSocket(CSOC& SOC);
virtual void SingleStep();
virtual CSOCClient* OnNewClientSocket(const CSOCListen& SOCListen, DWORD dwCSCParam1, DWORD dwCSCParam2) const;
protected:
BOOL AddSocket(CSOC& SOC);
void CallOnAddSocket(CSOC& SOC);
void CallOnDelSocket(CSOC& SOC);
void OnDrop(CSOC* pSOC);
void DoConnecting(CSOCServer* pSOCServer, BOOL bConnecting);
BOOL IsSafeToShutdown() const;
protected: // in single step
void CheckDropping();
void CheckFlush();
void CheckReading();
protected:
EException DoErrorReport(CSOC* pSOC, int nErrorCode, BOOL bDropIfErrorOccur = FALSE);
};
#endif // !defined(__MUGSOCS__)