Restructure repository to include all source folders
Move git root from Client/ to src/ to track all source code: - Client: Game client source (moved to Client/Client/) - Server: Game server source - GameTools: Development tools - CryptoSource: Encryption utilities - database: Database scripts - Script: Game scripts - rylCoder_16.02.2008_src: Legacy coder tools - GMFont, Game: Additional resources 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,87 @@
|
||||
#include "stdafx.h"
|
||||
#include "CheckPing.h"
|
||||
#include <Utility/Setup/ServerSetup.h>
|
||||
|
||||
CCheckPing::CCheckPing()
|
||||
: m_dwLastPingRecvTime(0), m_dwPingCount(0), m_dwFirstCheckTime(0)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
bool CCheckPing::CheckPing(unsigned long dwCurrentTime)
|
||||
{
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><> üũ<C3BC><C5A9> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><> <20>ִ<EFBFBD>.
|
||||
if (false == CServerSetup::GetInstance().GetPingCheck())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// <20><><EFBFBD><EFBFBD> <20><> <20>м<EFBFBD>
|
||||
CheckPingLock::Syncronize sync(m_PingLock);
|
||||
|
||||
if (0 == m_dwLastPingRecvTime && 0 == m_dwPingCount)
|
||||
{
|
||||
if (0 == m_dwFirstCheckTime)
|
||||
{
|
||||
m_dwFirstCheckTime = dwCurrentTime;
|
||||
|
||||
if (0 == m_dwFirstCheckTime)
|
||||
{
|
||||
++m_dwFirstCheckTime;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// 10<31><30> * 30. <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 300<30><30>(5<><35>) <20><><EFBFBD><EFBFBD> <20><> <20><>Ŷ<EFBFBD><C5B6> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>.
|
||||
|
||||
LONG nFirstDifference = dwCurrentTime - m_dwFirstCheckTime;
|
||||
if (PING_INTERVAL * 30 < nFirstDifference)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
LONG nDifference = dwCurrentTime - m_dwLastPingRecvTime;
|
||||
return (nDifference < PING_INTERVAL * 60) ? true : false;
|
||||
}
|
||||
|
||||
void CCheckPing::SetLastPingRecvTime(unsigned long dwCurrentTime)
|
||||
{
|
||||
CheckPingLock::Syncronize sync(m_PingLock);
|
||||
|
||||
m_dwLastPingRecvTime = dwCurrentTime;
|
||||
++m_dwPingCount;
|
||||
|
||||
if (0 == m_dwPingCount)
|
||||
{
|
||||
++m_dwPingCount;
|
||||
}
|
||||
}
|
||||
|
||||
unsigned long CCheckPing::GetLastPingRecvTime()
|
||||
{
|
||||
CheckPingLock::Syncronize sync(m_PingLock);
|
||||
return m_dwLastPingRecvTime;
|
||||
}
|
||||
|
||||
unsigned long CCheckPing::GetPingCount()
|
||||
{
|
||||
CheckPingLock::Syncronize sync(m_PingLock);
|
||||
return m_dwPingCount;
|
||||
}
|
||||
|
||||
|
||||
void CCheckPing::GetPingData(unsigned long& dwPingCount,
|
||||
unsigned long& dwLastPingRecvTime,
|
||||
unsigned long& dwFirstCheckTime)
|
||||
{
|
||||
CheckPingLock::Syncronize sync(m_PingLock);
|
||||
|
||||
dwPingCount = m_dwPingCount;
|
||||
dwLastPingRecvTime = m_dwLastPingRecvTime;
|
||||
dwFirstCheckTime = m_dwFirstCheckTime;
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
#ifndef _CHECK_PING_H_
|
||||
#define _CHECK_PING_H_
|
||||
|
||||
#include <Thread/Lock.h>
|
||||
|
||||
class CCheckPing
|
||||
{
|
||||
public:
|
||||
|
||||
CCheckPing();
|
||||
|
||||
enum { PING_INTERVAL = 10000 }; // 10<31><30>
|
||||
|
||||
bool CheckPing(unsigned long dwCurrentTime);
|
||||
void SetLastPingRecvTime(unsigned long dwCurrentTime);
|
||||
|
||||
unsigned long GetLastPingRecvTime();
|
||||
unsigned long GetPingCount();
|
||||
|
||||
void GetPingData(unsigned long& dwPingCount,
|
||||
unsigned long& dwLastPingRecvTime, unsigned long& dwFirstCheckTime);
|
||||
|
||||
private:
|
||||
|
||||
typedef CCSLock CheckPingLock;
|
||||
CheckPingLock m_PingLock;
|
||||
CACHE_PAD(CheckPingLockPad, sizeof(CheckPingLock));
|
||||
|
||||
unsigned long m_dwPingCount;
|
||||
unsigned long m_dwLastPingRecvTime;
|
||||
unsigned long m_dwFirstCheckTime;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,188 @@
|
||||
#include "stdafx.h"
|
||||
#include "MultiDispatchStorage.h"
|
||||
|
||||
#include <Log/ServerLog.h>
|
||||
#include <Network/Session/Session.h>
|
||||
#include <Network/Dispatch/Dispatch.h>
|
||||
|
||||
bool CMultiDispatch::SetDispatch(unsigned long dispatchKey, CPacketDispatch* lpDispatch)
|
||||
{
|
||||
if(0 == lpDispatch)
|
||||
{
|
||||
DETLOG1(g_Log, "this:0x%p/Setting null dispatch", this);
|
||||
}
|
||||
else
|
||||
{
|
||||
LockType::Syncronize sync(m_DispatchLock);
|
||||
|
||||
DispatchMap::iterator find = m_DispatchMap.find(dispatchKey);
|
||||
DispatchMap::iterator end = m_DispatchMap.end();
|
||||
|
||||
if(find == end)
|
||||
{
|
||||
lpDispatch->GetSession().AddRef();
|
||||
m_DispatchMap.insert(find, DispatchMap::value_type(dispatchKey, lpDispatch));
|
||||
DETLOG2(g_Log, "Setting new dispatch(Key:%u/DP:0x%p)", dispatchKey, lpDispatch);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
CPacketDispatch* lpOldDispatch = find->second;
|
||||
|
||||
if(0 != lpOldDispatch)
|
||||
{
|
||||
DETLOG1(g_Log, "DP:0x%p/Already dispatch exist. cannot set dispatch", lpOldDispatch);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void CMultiDispatch::ForceSetDispatch(unsigned long dispatchKey, CPacketDispatch* lpDispatch)
|
||||
{
|
||||
if(0 == lpDispatch)
|
||||
{
|
||||
DETLOG1(g_Log, "this:0x%p/Setting null dispatch", this);
|
||||
}
|
||||
else
|
||||
{
|
||||
LockType::Syncronize sync(m_DispatchLock);
|
||||
|
||||
DispatchMap::iterator find = m_DispatchMap.find(dispatchKey);
|
||||
DispatchMap::iterator end = m_DispatchMap.end();
|
||||
|
||||
CPacketDispatch* lpOldDispatch = 0;
|
||||
|
||||
if(find == end)
|
||||
{
|
||||
m_DispatchMap.insert(find, DispatchMap::value_type(dispatchKey, lpDispatch));
|
||||
}
|
||||
else
|
||||
{
|
||||
lpOldDispatch = find->second;
|
||||
find->second = lpDispatch;
|
||||
|
||||
if(0 != lpOldDispatch)
|
||||
{
|
||||
DETLOG1(g_Log, "DP:0x%p/Already dispatch exist. close now", lpOldDispatch);
|
||||
lpOldDispatch->GetSession().CloseSession();
|
||||
lpOldDispatch->GetSession().Release();
|
||||
}
|
||||
}
|
||||
|
||||
DETLOG3(g_Log, "DP:0x%p/Setting new dispatch(Key:%u/DP:0x%p)",
|
||||
lpOldDispatch, dispatchKey, lpDispatch);
|
||||
|
||||
lpDispatch->GetSession().AddRef();
|
||||
}
|
||||
}
|
||||
|
||||
void CMultiDispatch::RemoveDispatch(unsigned long dispatchKey)
|
||||
{
|
||||
LockType::Syncronize sync(m_DispatchLock);
|
||||
InternalRemoveDispatch(dispatchKey);
|
||||
}
|
||||
|
||||
|
||||
size_t CMultiDispatch::GetDispatchNum()
|
||||
{
|
||||
LockType::Syncronize sync(m_DispatchLock);
|
||||
return m_DispatchMap.size();
|
||||
}
|
||||
|
||||
bool CMultiDispatch::IsEmpty()
|
||||
{
|
||||
LockType::Syncronize sync(m_DispatchLock);
|
||||
return m_DispatchMap.empty();
|
||||
}
|
||||
|
||||
CMultiDispatch::CMultiDispatch()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
CMultiDispatch::~CMultiDispatch()
|
||||
{
|
||||
LockType::Syncronize sync(m_DispatchLock);
|
||||
|
||||
if(!m_DispatchMap.empty())
|
||||
{
|
||||
DispatchMap::iterator pos = m_DispatchMap.begin();
|
||||
DispatchMap::iterator end = m_DispatchMap.end();
|
||||
|
||||
for(;pos != end; ++pos)
|
||||
{
|
||||
ERRLOG1(g_Log, "this:0x%p/Dispatch is not removed until destroy", pos->second);
|
||||
}
|
||||
|
||||
m_DispatchMap.clear();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CMultiDispatch::InternalRemoveDispatch(unsigned long dispatchKey)
|
||||
{
|
||||
DispatchMap::iterator find = m_DispatchMap.find(dispatchKey);
|
||||
DispatchMap::iterator end = m_DispatchMap.end();
|
||||
|
||||
if(find == end)
|
||||
{
|
||||
ERRLOG1(g_Log, "Reset dispatch failed. Invalid dispatch key(%u)", dispatchKey);
|
||||
}
|
||||
else
|
||||
{
|
||||
CPacketDispatch* lpDispatch = find->second;
|
||||
|
||||
DETLOG2(g_Log, "Reset dispatch(Key:%u/DP:0x%p)", dispatchKey, lpDispatch);
|
||||
lpDispatch->GetSession().Release();
|
||||
m_DispatchMap.erase(find);
|
||||
}
|
||||
}
|
||||
|
||||
CPacketDispatch* CMultiDispatch::GetDispatch(unsigned long dispatchKey)
|
||||
{
|
||||
LockType::Syncronize sync(m_DispatchLock);
|
||||
|
||||
DispatchMap::iterator find = m_DispatchMap.find(dispatchKey);
|
||||
DispatchMap::iterator end = m_DispatchMap.end();
|
||||
|
||||
if(find != end)
|
||||
{
|
||||
CPacketDispatch* lpDispatch = find->second;
|
||||
lpDispatch->GetSession().AddRef();
|
||||
return lpDispatch;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
CMultiDispatch::Storage::Storage(CMultiDispatch& multiDispatch, unsigned long dispatchKey)
|
||||
: m_lpDispatch(multiDispatch.GetDispatch(dispatchKey)),
|
||||
m_MultiDispatch(multiDispatch)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
CMultiDispatch::Storage::~Storage()
|
||||
{
|
||||
if(0 != m_lpDispatch)
|
||||
{
|
||||
m_lpDispatch->GetSession().Release();
|
||||
m_lpDispatch = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
CPacketDispatch* CMultiDispatch::Storage::ReloadDispatch(unsigned long dispatchKey)
|
||||
{
|
||||
if(0 != m_lpDispatch)
|
||||
{
|
||||
m_lpDispatch->GetSession().Release();
|
||||
}
|
||||
|
||||
m_lpDispatch = m_MultiDispatch.GetDispatch(dispatchKey);
|
||||
return m_lpDispatch;
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
#ifndef _GM_NETWORK_MULTI_DISPATCH_STORAGE_H_
|
||||
#define _GM_NETWORK_MULTI_DISPATCH_STORAGE_H_
|
||||
|
||||
#include <map>
|
||||
#include <Thread/Lock.h>
|
||||
|
||||
#define GET_MULTI_DISPATCH(instanceName, keyValue, type, table) \
|
||||
CMultiDispatch::Storage Storage##instanceName(table, keyValue); \
|
||||
type* instanceName = static_cast<type*>(Storage##instanceName.GetDispatch())
|
||||
|
||||
class CPacketDispatch;
|
||||
|
||||
class CMultiDispatch
|
||||
{
|
||||
public:
|
||||
|
||||
typedef std::map<unsigned long, CPacketDispatch*> DispatchMap;
|
||||
|
||||
class Storage
|
||||
{
|
||||
public:
|
||||
|
||||
Storage(CMultiDispatch& multiDispatch, unsigned long dispatchKey);
|
||||
~Storage();
|
||||
|
||||
CPacketDispatch* ReloadDispatch(unsigned long dispatchKey);
|
||||
CPacketDispatch* GetDispatch() { return m_lpDispatch; }
|
||||
|
||||
private:
|
||||
|
||||
// <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20>Ұ<EFBFBD>.
|
||||
static void* operator new(size_t size);
|
||||
static void operator delete(void* ptr);
|
||||
|
||||
CPacketDispatch* m_lpDispatch;
|
||||
CMultiDispatch& m_MultiDispatch;
|
||||
};
|
||||
|
||||
CMultiDispatch();
|
||||
~CMultiDispatch();
|
||||
|
||||
bool SetDispatch(unsigned long dispatchKey, CPacketDispatch* lpDispatch);
|
||||
void ForceSetDispatch(unsigned long dispatchKey, CPacketDispatch* lpDispatch);
|
||||
void RemoveDispatch(unsigned long dispatchKey);
|
||||
|
||||
template<typename FnProcess>
|
||||
void Process(FnProcess fnProcess)
|
||||
{
|
||||
LockType::Syncronize sync(m_DispatchLock);
|
||||
|
||||
DispatchMap::iterator pos = m_DispatchMap.begin();
|
||||
DispatchMap::iterator end = m_DispatchMap.end();
|
||||
|
||||
for(;pos != end; ++pos)
|
||||
{
|
||||
fnProcess(pos->first, *pos->second);
|
||||
}
|
||||
}
|
||||
|
||||
size_t GetDispatchNum();
|
||||
bool IsEmpty();
|
||||
|
||||
private:
|
||||
|
||||
void InternalRemoveDispatch(unsigned long dispatchKey);
|
||||
CPacketDispatch* GetDispatch(unsigned long dispatchKey);
|
||||
|
||||
typedef CCSLock LockType;
|
||||
|
||||
LockType m_DispatchLock;
|
||||
CACHE_PAD(DispatchLockPad, sizeof(LockType));
|
||||
DispatchMap m_DispatchMap;
|
||||
|
||||
friend class Storage;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,30 @@
|
||||
#include "stdafx.h"
|
||||
#include "MultiThreadDispatch.h"
|
||||
|
||||
#include <Network/Session/Session.h>
|
||||
#include <Stream/Buffer/Buffer.h>
|
||||
#include <Stream/Buffer/BufferFactory.h>
|
||||
|
||||
#include <mmsystem.h>
|
||||
|
||||
|
||||
CRylServerMultiThreadDispatch::CRylServerMultiThreadDispatch(
|
||||
CSession& Session, unsigned long dwMaxProcessPacketPerPulse)
|
||||
: CRylServerDispatch(Session, dwMaxProcessPacketPerPulse)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
CRylServerMultiThreadDispatch::~CRylServerMultiThreadDispatch()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
bool CRylServerMultiThreadDispatch::ParsePacket(char* const lpStream_In,
|
||||
unsigned long* dwStreamSize_InOut)
|
||||
{
|
||||
return CRylServerDispatch::ParsePacket(lpStream_In, dwStreamSize_InOut) ?
|
||||
Dispatch() : false;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
#ifndef _MULTITHREAD_PKT_DISPATCH_H_
|
||||
#define _MULTITHREAD_PKT_DISPATCH_H_
|
||||
|
||||
#include "RylServerDispatch.h"
|
||||
|
||||
// <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
|
||||
class CSession;
|
||||
struct PktBase;
|
||||
|
||||
// <20><>Ŷ ó<><C3B3><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>忡<EFBFBD><E5BFA1> <20>Ѵ<EFBFBD>.
|
||||
// <20><>, <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ѹ<EFBFBD><D1B9><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD>常 <20><><EFBFBD><EFBFBD><EFBFBD>ؼ<EFBFBD> ó<><C3B3><EFBFBD>Ѵ<EFBFBD>.
|
||||
class CRylServerMultiThreadDispatch : public CRylServerDispatch
|
||||
{
|
||||
public:
|
||||
|
||||
virtual bool ParsePacket(char* const lpStream_In, unsigned long* dwStreamSize_InOut);
|
||||
|
||||
protected:
|
||||
|
||||
CRylServerMultiThreadDispatch(CSession& Session, unsigned long dwMaxProcessPacketPerPulse);
|
||||
virtual ~CRylServerMultiThreadDispatch();
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,383 @@
|
||||
#include "stdafx.h"
|
||||
#include "RylServerDispatch.h"
|
||||
|
||||
#include "../Packet/PacketBase.h"
|
||||
#include "../Packet/PacketCommand.h"
|
||||
#include "../XORCrypt/XORCrypt.h"
|
||||
|
||||
#include <Log/ServerLog.h>
|
||||
#include <Stream/Buffer/Buffer.h>
|
||||
#include <Stream/Buffer/BufferFactory.h>
|
||||
|
||||
#include <Network/Session/Session.h>
|
||||
#include <Network/Stream/SendStream.h>
|
||||
#include <Network/Packet/PacketStatistics.h>
|
||||
#include <Utility/Compress/MiniLZO/MiniLZOWrapper.h>
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
enum RylServerDispatchFlags
|
||||
{
|
||||
PROCESS_PACKET_NOW = (1 << 0),
|
||||
SUSPEND_RECV = (1 << 1)
|
||||
};
|
||||
|
||||
|
||||
CRylServerDispatch::CRylServerDispatch(CSession& Session,
|
||||
unsigned long dwMaxProcessPacketPerPulse)
|
||||
: CPacketDispatch(Session), m_SendStream(Session),
|
||||
m_dwMaxProcessPacketPerPulse(dwMaxProcessPacketPerPulse),
|
||||
m_dwFlags(0)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
CRylServerDispatch::~CRylServerDispatch()
|
||||
{
|
||||
BufferQueueLock::Syncronize sync(m_BufferQueueLock);
|
||||
m_ProcessQueue.clear();
|
||||
}
|
||||
|
||||
|
||||
CBufferFactory& CRylServerDispatch::GetBufferFactory()
|
||||
{
|
||||
return m_Session.GetPolicy().GetBufferFactory();
|
||||
}
|
||||
|
||||
INET_Addr& CRylServerDispatch::GetRemoteAddr()
|
||||
{
|
||||
return m_Session.GetRemoteAddr();
|
||||
}
|
||||
|
||||
INET_Addr& CRylServerDispatch::GetLocalAddr()
|
||||
{
|
||||
return m_Session.GetLocalAddr();
|
||||
}
|
||||
|
||||
bool CRylServerDispatch::Shutdown()
|
||||
{
|
||||
return m_Session.Shutdown();
|
||||
}
|
||||
|
||||
void CRylServerDispatch::CloseSession()
|
||||
{
|
||||
m_Session.CloseSession();
|
||||
}
|
||||
|
||||
void CRylServerDispatch::LogErrorPacket(const char* szDetailText,
|
||||
const unsigned char cCmd)
|
||||
{
|
||||
ERRLOG5(g_SessionLog, "SP:0x%p/DP:0x%p/IP:%15s/PktCmd:0x%02x/%s",
|
||||
&m_Session, this, m_Session.GetRemoteAddr().get_addr_string(), cCmd, szDetailText);
|
||||
}
|
||||
|
||||
|
||||
CRylServerDispatch::CreationResult CRylServerDispatch::CreatePacket(
|
||||
CBufferFactory& bufferFactory, CBufferQueue& bufferQueue,
|
||||
char* const lpStream_In, unsigned long* dwStreamSize_InOut)
|
||||
{
|
||||
CXORCrypt& Crypt = CXORCrypt::GetInstance();
|
||||
|
||||
CBuffer* lpBuffer = 0;
|
||||
PktBase* lpPktBase = 0;
|
||||
char* lpBufferPos = lpStream_In;
|
||||
|
||||
unsigned long dwStreamSize = *dwStreamSize_InOut;
|
||||
unsigned long dwDecompressedSize = 0;
|
||||
unsigned long dwPacketNum = 0;
|
||||
|
||||
while(sizeof(PktBase) <= dwStreamSize)
|
||||
{
|
||||
lpPktBase = reinterpret_cast<PktBase*>(lpBufferPos);
|
||||
|
||||
// <20><>Ŷ <20><><EFBFBD><EFBFBD> <20><><EFBFBD>ڵ<EFBFBD>
|
||||
Crypt.DecodeHeader(lpBufferPos + 1, sizeof(PktBase) - 1, 0, 0);
|
||||
|
||||
// <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>.
|
||||
const PktBase::CMDType nPacketCMD = lpPktBase->GetCmd();
|
||||
const PktBase::LengthType nPacketLength = lpPktBase->GetLen();
|
||||
|
||||
// <20><>Ŷ <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> vaild<6C><64><EFBFBD><EFBFBD> Ȯ<><C8AE><EFBFBD>Ѵ<EFBFBD>. invalid<69><64> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>׳<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.
|
||||
if(StartBit != lpPktBase->GetStartBit())
|
||||
{
|
||||
return E_INVALID_STARTBIT;
|
||||
}
|
||||
|
||||
if(dwStreamSize < nPacketLength)
|
||||
{
|
||||
// <20><>ü <20><>Ʈ<EFBFBD><C6AE> <20><><EFBFBD><EFBFBD><EFBFBD> <20>Ľ<EFBFBD><C4BD><EFBFBD> <20>ϱ<CFB1><E2BFA1> <20><><EFBFBD>ڶ<EFBFBD>. <20>ٽ<EFBFBD> <20><><EFBFBD>ڵ<EFBFBD> <20><> <20><> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD>ٸ<EFBFBD>
|
||||
Crypt.EncodeHeader(lpBufferPos + 1, sizeof(PktBase) - 1, 0, 0);
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
// <20><>Ŷ <20><><EFBFBD>ڵ<EFBFBD>.
|
||||
if(lpPktBase->IsCrypt())
|
||||
{
|
||||
Crypt.DecodePacket(lpBufferPos + sizeof(PktBase),
|
||||
nPacketLength - sizeof(PktBase), lpPktBase->GetCodePage());
|
||||
}
|
||||
|
||||
// <20><>Ŷ <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>.
|
||||
if(lpPktBase->IsCompress())
|
||||
{
|
||||
dwDecompressedSize = PktMaxLen - sizeof(PktBase);
|
||||
|
||||
lpBuffer = CREATE_BUFFER(bufferFactory, PktMaxLen);
|
||||
if(0 == lpBuffer)
|
||||
{
|
||||
return E_ALLOCATE_BUFFER_FAILED;
|
||||
}
|
||||
|
||||
char* szDecompressedPacket = lpBuffer->wr_ptr();
|
||||
memcpy(szDecompressedPacket, lpPktBase, sizeof(PktBase));
|
||||
|
||||
// <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>.
|
||||
if(!CMiniLZO::Decompress(
|
||||
lpBufferPos + sizeof(PktBase), // src Pos
|
||||
nPacketLength - sizeof(PktBase), // src Size
|
||||
szDecompressedPacket + sizeof(PktBase), // dst Pos
|
||||
&dwDecompressedSize)) // dst Size
|
||||
{
|
||||
SAFE_RELEASE_BUFFER(lpBuffer);
|
||||
return E_DECOMPRESS_FAILED;
|
||||
}
|
||||
|
||||
lpBuffer->wr_ptr(dwDecompressedSize + sizeof(PktBase));
|
||||
|
||||
lpPktBase = reinterpret_cast<PktBase*>(szDecompressedPacket);
|
||||
lpPktBase->SetLen(static_cast<PktBase::LengthType>(dwDecompressedSize + sizeof(PktBase)));
|
||||
}
|
||||
else
|
||||
{
|
||||
lpBuffer = CREATE_BUFFER(bufferFactory, nPacketLength);
|
||||
|
||||
if(NULL == lpBuffer)
|
||||
{
|
||||
return E_ALLOCATE_BUFFER_FAILED;
|
||||
}
|
||||
|
||||
lpBuffer->push(lpBufferPos, nPacketLength);
|
||||
}
|
||||
|
||||
// <20><>Ŷ<EFBFBD><C5B6> <20>迭<EFBFBD><E8BFAD> <20><><EFBFBD><EFBFBD>.
|
||||
bufferQueue.enqueue(lpBuffer);
|
||||
|
||||
dwStreamSize -= nPacketLength;
|
||||
lpBufferPos += nPacketLength;
|
||||
}
|
||||
}
|
||||
|
||||
*dwStreamSize_InOut -= dwStreamSize;
|
||||
return S_CREATE_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
void CRylServerDispatch::LogErrorPacketCreation(CRylServerDispatch::CreationResult eResult)
|
||||
{
|
||||
const char* lpErrString = 0;
|
||||
|
||||
switch(eResult)
|
||||
{
|
||||
case E_INVALID_STARTBIT: lpErrString = "Invalid packet startbit"; break;
|
||||
case E_ALLOCATE_BUFFER_FAILED: lpErrString = "Allocate packetbuffer failed"; break;
|
||||
case E_DECOMPRESS_FAILED: lpErrString = "Decompress packet failed"; break;
|
||||
default: lpErrString = "Unknown error occured"; break;
|
||||
}
|
||||
|
||||
if(0 != lpErrString)
|
||||
{
|
||||
LogErrorPacket(lpErrString, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CRylServerDispatch::InternalCheckSuspendRecv(CBufferQueue& bufferQueue)
|
||||
{
|
||||
const unsigned long MAX_PACKET = m_dwMaxProcessPacketPerPulse * 5;
|
||||
const unsigned long CUR_PACKET = bufferQueue.getBufferNum();
|
||||
|
||||
if (!(m_dwFlags & SUSPEND_RECV) && MAX_PACKET < CUR_PACKET)
|
||||
{
|
||||
// Recv<63><76><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20>ɷ<EFBFBD> <20>ְ<EFBFBD>, <20><>Ŷ <20><><EFBFBD><EFBFBD> <20>ʹ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> Recv<63><76> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.
|
||||
GetSession().SuspendRecv();
|
||||
m_dwFlags |= SUSPEND_RECV;
|
||||
}
|
||||
else if ((m_dwFlags & SUSPEND_RECV) && CUR_PACKET < MAX_PACKET)
|
||||
{
|
||||
// Recv<63><76><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ɷ<EFBFBD> <20>ְ<EFBFBD>, <20><>Ŷ <20><><EFBFBD><EFBFBD> <20>ٽ<EFBFBD> <20><><EFBFBD><EFBFBD> ȸ<><C8B8><EFBFBD>Ǿ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> Recv<63><76> <20>ٽ<EFBFBD> <20>Ǵ<EFBFBD>.
|
||||
GetSession().ResumeRecv();
|
||||
m_dwFlags &= ~ SUSPEND_RECV;
|
||||
}
|
||||
}
|
||||
|
||||
bool CRylServerDispatch::ParsePacket(char *const lpStream_In, unsigned long* dwStreamSize_InOut)
|
||||
{
|
||||
CBufferFactory& bufferFactory = m_Session.GetPolicy().GetBufferFactory();
|
||||
CBufferQueue bufferQueue;
|
||||
|
||||
CreationResult eCreationResult = CreatePacket(
|
||||
bufferFactory, bufferQueue, lpStream_In, dwStreamSize_InOut);
|
||||
|
||||
if(S_CREATE_SUCCESS != eCreationResult)
|
||||
{
|
||||
LogErrorPacketCreation(eCreationResult);
|
||||
return false;
|
||||
}
|
||||
|
||||
BufferQueueLock::Syncronize sync(m_BufferQueueLock);
|
||||
m_ProcessQueue.splice(bufferQueue);
|
||||
InternalCheckSuspendRecv(m_ProcessQueue);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CRylServerDispatch::Dispatch()
|
||||
{
|
||||
CBufferQueue ProcessQueue;
|
||||
CBufferQueue Processed;
|
||||
PktBase* lpPktBase = 0;
|
||||
|
||||
{
|
||||
BufferQueueLock::Syncronize sync(m_BufferQueueLock);
|
||||
|
||||
if((m_dwFlags & PROCESS_PACKET_NOW))
|
||||
{
|
||||
// <20>̹<EFBFBD> <20><>Ŷ<EFBFBD><C5B6> ó<><C3B3><EFBFBD><EFBFBD><EFBFBD>ε<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>Ͽ<EFBFBD><CFBF><EFBFBD>.
|
||||
return true;
|
||||
}
|
||||
|
||||
// <20><><EFBFBD><EFBFBD> <20><>Ŷ<EFBFBD><C5B6> ó<><C3B3><EFBFBD>Ѵ<EFBFBD>.
|
||||
m_dwFlags |= PROCESS_PACKET_NOW;
|
||||
|
||||
InternalCheckSuspendRecv(m_ProcessQueue);
|
||||
ProcessQueue.splice(m_ProcessQueue);
|
||||
}
|
||||
|
||||
for(unsigned long dwCount = 0; dwCount < GetMaxProcessPacketPerPulse(); ++dwCount)
|
||||
{
|
||||
CBuffer* lpBuffer = ProcessQueue.dequeue();
|
||||
if(0 == lpBuffer)
|
||||
{
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
lpPktBase = reinterpret_cast<PktBase*>(lpBuffer->rd_ptr());
|
||||
|
||||
// <20><>Ŷ <20><><EFBFBD><EFBFBD>.
|
||||
CPacketStatistics::GetInstance().Recv(lpPktBase->GetCmd(), lpPktBase->GetLen());
|
||||
|
||||
// <20><>Ŷ ó<><C3B3>.
|
||||
bool bResult = DispatchPacket(lpPktBase);
|
||||
Processed.enqueue(lpBuffer);
|
||||
|
||||
if(!bResult)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!ProcessQueue.empty())
|
||||
{
|
||||
ProcessTooManyPacket(ProcessQueue);
|
||||
}
|
||||
|
||||
{
|
||||
BufferQueueLock::Syncronize sync(m_BufferQueueLock);
|
||||
|
||||
if(!ProcessQueue.empty())
|
||||
{
|
||||
BufferQueueLock::Syncronize sync(m_BufferQueueLock);
|
||||
m_ProcessQueue.splice(ProcessQueue, true);
|
||||
}
|
||||
|
||||
m_dwFlags &= ~PROCESS_PACKET_NOW;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
template<typename T>
|
||||
bool greator_second(const T& lhspair, const T& rhspair)
|
||||
{
|
||||
return rhspair.second < lhspair.second;
|
||||
}
|
||||
|
||||
|
||||
void CRylServerDispatch::ProcessTooManyPacket(CBufferQueue& bufferQueue)
|
||||
{
|
||||
typedef std::pair<unsigned long, unsigned long> PacketInfoPair;
|
||||
typedef std::vector<PacketInfoPair> PacketStatistics;
|
||||
|
||||
const int MAX_BUFFER = 3072;
|
||||
char szBuffer[MAX_BUFFER];
|
||||
|
||||
int nTotalLength = _snprintf(szBuffer, MAX_BUFFER, "Processed:%d/Remain:%d/Remain packets(cmd:num)/",
|
||||
m_dwMaxProcessPacketPerPulse, bufferQueue.getBufferNum());
|
||||
|
||||
PacketStatistics statistics;
|
||||
PacketStatistics::iterator spos;
|
||||
PacketStatistics::iterator send;
|
||||
|
||||
statistics.reserve(bufferQueue.getBufferNum());
|
||||
|
||||
for(CBuffer* lpBuffer = bufferQueue.getHead();
|
||||
0 != lpBuffer; lpBuffer = lpBuffer->next())
|
||||
{
|
||||
PktBase::CMDType cmd = reinterpret_cast<PktBase*>(lpBuffer->rd_ptr())->GetCmd();
|
||||
|
||||
spos = statistics.begin();
|
||||
send = statistics.end();
|
||||
|
||||
for(;spos != send; ++spos)
|
||||
{
|
||||
if(spos->first == cmd)
|
||||
{
|
||||
++spos->second;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(spos == send)
|
||||
{
|
||||
statistics.push_back(PacketInfoPair(cmd, 1));
|
||||
}
|
||||
}
|
||||
|
||||
std::sort(statistics.begin(), statistics.end(), &greator_second<PacketInfoPair>);
|
||||
|
||||
spos = statistics.begin();
|
||||
send = statistics.end();
|
||||
|
||||
for(; spos != send; ++spos)
|
||||
{
|
||||
int nLength = _snprintf(szBuffer + nTotalLength, MAX_BUFFER - nTotalLength,
|
||||
"0x%02x:%5d/", spos->first, spos->second);
|
||||
|
||||
if(0 < nLength)
|
||||
{
|
||||
nTotalLength += nLength;
|
||||
}
|
||||
}
|
||||
|
||||
LogErrorPacket(szBuffer, 0);
|
||||
}
|
||||
|
||||
|
||||
CSendPacketAllServer::CSendPacketAllServer(const char* szData, unsigned long dwDataLen,
|
||||
unsigned char cPacketCmd)
|
||||
: m_szData(szData),
|
||||
m_dwDataLen(dwDataLen),
|
||||
m_cPacketCmd(cPacketCmd)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bool CSendPacketAllServer::operator () (unsigned long dwServerID, CPacketDispatch& packetDispatch)
|
||||
{
|
||||
return static_cast<CRylServerDispatch&>(packetDispatch).GetSendStream().PutBuffer(
|
||||
m_szData, m_dwDataLen, m_cPacketCmd);
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
#ifndef _RYL_SERVER_DISPATCH_H_
|
||||
#define _RYL_SERVER_DISPATCH_H_
|
||||
|
||||
#include <winsock2.h>
|
||||
#include <windows.h>
|
||||
|
||||
#include <Thread/Lock.h>
|
||||
#include <Network/Dispatch/Dispatch.h>
|
||||
#include <Network/Stream/SendStream.h>
|
||||
#include <Stream/Buffer/BufferQueue.h>
|
||||
|
||||
// forward delc.
|
||||
struct PktBase;
|
||||
class CBuffer;
|
||||
class CBufferFactory;
|
||||
class INET_Addr;
|
||||
|
||||
class CRylServerDispatch : public CPacketDispatch
|
||||
{
|
||||
public:
|
||||
|
||||
enum CreationResult
|
||||
{
|
||||
S_CREATE_SUCCESS,
|
||||
E_INVALID_STARTBIT,
|
||||
E_ALLOCATE_BUFFER_FAILED,
|
||||
E_DECOMPRESS_FAILED
|
||||
};
|
||||
|
||||
static CreationResult CreatePacket(
|
||||
CBufferFactory& bufferFactory,
|
||||
CBufferQueue& bufferQueue, char* const lpStream_In,
|
||||
unsigned long* dwStreamSize_InOut);
|
||||
|
||||
virtual bool ParsePacket(char *const lpStream_In, unsigned long* dwStreamSize_InOut);
|
||||
|
||||
unsigned long GetMaxProcessPacketPerPulse() const { return m_dwMaxProcessPacketPerPulse; }
|
||||
void SetMaxProcessPacketPerPulse(unsigned long dwMaxProcessPacketPerPulse)
|
||||
{ m_dwMaxProcessPacketPerPulse = dwMaxProcessPacketPerPulse; }
|
||||
|
||||
void LogErrorPacket(const char* szDetailText, const unsigned char cCmd);
|
||||
void LogErrorPacketCreation(CreationResult eResult);
|
||||
|
||||
CBufferFactory& GetBufferFactory();
|
||||
CSendStream& GetSendStream() { return m_SendStream; }
|
||||
|
||||
INET_Addr& GetRemoteAddr();
|
||||
INET_Addr& GetLocalAddr();
|
||||
|
||||
bool Shutdown();
|
||||
void CloseSession();
|
||||
|
||||
protected:
|
||||
|
||||
CRylServerDispatch(CSession& Session, unsigned long dwMaxProcessPacketPerPulse);
|
||||
~CRylServerDispatch();
|
||||
|
||||
// <20><>Ŷ ó<><C3B3><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>Ѵ<EFBFBD>.
|
||||
virtual bool Dispatch();
|
||||
|
||||
// <20>ʹ<EFBFBD> <20><><EFBFBD><EFBFBD> <20><>Ŷ<EFBFBD><C5B6> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>, <20><>Ŷ <20><><EFBFBD>뿡 <20><><EFBFBD>ؼ<EFBFBD> <20>α<CEB1> <20><><EFBFBD><EFBFBD><EFBFBD>ų<EFBFBD>, <20><>Ŷ<EFBFBD><C5B6> <20><><EFBFBD><EFBFBD><EFBFBD>Ѵ<EFBFBD>.
|
||||
virtual void ProcessTooManyPacket(CBufferQueue& bufferQueue);
|
||||
|
||||
// <20><>Ŷ<EFBFBD><C5B6> ó<><C3B3><EFBFBD>Ѵ<EFBFBD>.
|
||||
virtual bool DispatchPacket(PktBase* lpPktBase) = 0;
|
||||
|
||||
// Recv<63><76> <20><><EFBFBD>߰ų<DFB0>, <20><><EFBFBD><EFBFBD> Recv<63><76> <20>ٽ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.
|
||||
void InternalCheckSuspendRecv(CBufferQueue& bufferQueue);
|
||||
|
||||
//-------------------------------------------------------------------------------
|
||||
|
||||
typedef CCSLock BufferQueueLock;
|
||||
|
||||
BufferQueueLock m_BufferQueueLock;
|
||||
CACHE_PAD(m_BufferQueueLockPadding, sizeof(BufferQueueLock));
|
||||
|
||||
CBufferQueue m_ProcessQueue;
|
||||
CSendStream m_SendStream;
|
||||
|
||||
unsigned long m_dwMaxProcessPacketPerPulse;
|
||||
unsigned long m_dwFlags;
|
||||
};
|
||||
|
||||
|
||||
class CSendPacketAllServer
|
||||
{
|
||||
public:
|
||||
|
||||
CSendPacketAllServer(const char* szData, unsigned long dwDataLen, unsigned char cPacketCmd);
|
||||
bool operator () (unsigned long dwServerID, CPacketDispatch& packetDispatch);
|
||||
|
||||
private:
|
||||
|
||||
const char* m_szData;
|
||||
unsigned long m_dwDataLen;
|
||||
unsigned char m_cPacketCmd;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,125 @@
|
||||
#include "stdafx.h"
|
||||
#include "SingleDispatchStorage.h"
|
||||
|
||||
#include <Thread/Lock.h>
|
||||
#include <Log/ServerLog.h>
|
||||
#include <Network/Session/Session.h>
|
||||
#include <Network/Dispatch/Dispatch.h>
|
||||
|
||||
class CPacketDispatch;
|
||||
|
||||
|
||||
void CSingleDispatch::SetDispatch(CPacketDispatch* lpDispatch)
|
||||
{
|
||||
if(0 != lpDispatch)
|
||||
{
|
||||
LockType::Syncronize sync(m_DispatchLock);
|
||||
|
||||
if(0 != m_lpDispatch)
|
||||
{
|
||||
DETLOG1(g_Log, "this:0x%p/Already dispatch exist. close now", this);
|
||||
m_lpDispatch->GetSession().CloseSession();
|
||||
m_lpDispatch->GetSession().Release();
|
||||
}
|
||||
|
||||
DETLOG2(g_Log, "DP:0x%p/Setting new dispatch(DP:0x%p)", m_lpDispatch, lpDispatch);
|
||||
m_lpDispatch = lpDispatch;
|
||||
m_lpDispatch->GetSession().AddRef();
|
||||
}
|
||||
}
|
||||
|
||||
void CSingleDispatch::RemoveDispatch(CPacketDispatch* lpDispatch)
|
||||
{
|
||||
LockType::Syncronize sync(m_DispatchLock);
|
||||
InternalRemoveDispatch(lpDispatch);
|
||||
}
|
||||
|
||||
size_t CSingleDispatch::GetDispatchNum()
|
||||
{
|
||||
LockType::Syncronize sync(m_DispatchLock);
|
||||
return 0 != m_lpDispatch ? 1 : 0;
|
||||
}
|
||||
|
||||
bool CSingleDispatch::IsEmpty()
|
||||
{
|
||||
LockType::Syncronize sync(m_DispatchLock);
|
||||
return 0 != m_lpDispatch ? false : true;
|
||||
}
|
||||
|
||||
|
||||
CSingleDispatch::CSingleDispatch()
|
||||
: m_lpDispatch(0)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
CSingleDispatch::~CSingleDispatch()
|
||||
{
|
||||
LockType::Syncronize sync(m_DispatchLock);
|
||||
|
||||
if (0 != m_lpDispatch)
|
||||
{
|
||||
ERRLOG1(g_Log, "DP:0x%p/Dispatch is not removed until destroy", m_lpDispatch);
|
||||
InternalRemoveDispatch(m_lpDispatch);
|
||||
}
|
||||
}
|
||||
|
||||
void CSingleDispatch::InternalRemoveDispatch(CPacketDispatch* lpDispatch)
|
||||
{
|
||||
if (lpDispatch == m_lpDispatch)
|
||||
{
|
||||
DETLOG1(g_Log, "DP:0x%p/Reset dispatch", m_lpDispatch);
|
||||
m_lpDispatch->GetSession().Release();
|
||||
m_lpDispatch = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
ERRLOG2(g_Log, "this:0x%p/Reset dispatch failed. Invalid dispatch(0x%p)",
|
||||
m_lpDispatch, lpDispatch);
|
||||
}
|
||||
}
|
||||
|
||||
CPacketDispatch* CSingleDispatch::GetDispatch()
|
||||
{
|
||||
LockType::Syncronize sync(m_DispatchLock);
|
||||
|
||||
if(0 != m_lpDispatch)
|
||||
{
|
||||
m_lpDispatch->GetSession().AddRef();
|
||||
}
|
||||
|
||||
return m_lpDispatch;
|
||||
}
|
||||
|
||||
|
||||
|
||||
CSingleDispatch::Storage::Storage(CSingleDispatch& singleDispatch)
|
||||
: m_lpDispatch(singleDispatch.GetDispatch()),
|
||||
m_SingleDispatch(singleDispatch)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
CSingleDispatch::Storage::~Storage()
|
||||
{
|
||||
if(0 != m_lpDispatch)
|
||||
{
|
||||
m_lpDispatch->GetSession().Release();
|
||||
m_lpDispatch = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
CPacketDispatch* CSingleDispatch::Storage::ReloadDispatch()
|
||||
{
|
||||
if(0 != m_lpDispatch)
|
||||
{
|
||||
m_lpDispatch->GetSession().Release();
|
||||
}
|
||||
|
||||
m_lpDispatch = m_SingleDispatch.GetDispatch();
|
||||
return m_lpDispatch;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
#ifndef _GM_NETWORK_SINGLE_DISPATCH_STORAGE_H_
|
||||
#define _GM_NETWORK_SINGLE_DISPATCH_STORAGE_H_
|
||||
|
||||
#include <Thread/Lock.h>
|
||||
|
||||
class CPacketDispatch;
|
||||
|
||||
#define GET_SINGLE_DISPATCH(instanceName, type, table) \
|
||||
CSingleDispatch::Storage Storage##instanceName(table); \
|
||||
type* instanceName = static_cast<type*>(Storage##instanceName.GetDispatch())
|
||||
|
||||
class CSingleDispatch
|
||||
{
|
||||
public:
|
||||
|
||||
class Storage
|
||||
{
|
||||
public:
|
||||
|
||||
Storage(CSingleDispatch& singleDispatch);
|
||||
~Storage();
|
||||
|
||||
CPacketDispatch* ReloadDispatch();
|
||||
CPacketDispatch* GetDispatch() { return m_lpDispatch; }
|
||||
|
||||
private:
|
||||
|
||||
// <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20>Ұ<EFBFBD>.
|
||||
static void* operator new(size_t size);
|
||||
static void operator delete(void* ptr);
|
||||
|
||||
CPacketDispatch* m_lpDispatch;
|
||||
CSingleDispatch& m_SingleDispatch;
|
||||
};
|
||||
|
||||
CSingleDispatch();
|
||||
~CSingleDispatch();
|
||||
|
||||
void SetDispatch(CPacketDispatch* lpDispatch);
|
||||
void RemoveDispatch(CPacketDispatch* lpDispatch);
|
||||
|
||||
size_t GetDispatchNum();
|
||||
bool IsEmpty();
|
||||
|
||||
private:
|
||||
|
||||
void InternalRemoveDispatch(CPacketDispatch* lpDispatch);
|
||||
CPacketDispatch* GetDispatch();
|
||||
|
||||
typedef CCSLock LockType;
|
||||
|
||||
LockType m_DispatchLock;
|
||||
CACHE_PAD(DispatchLockPad, sizeof(LockType));
|
||||
|
||||
CPacketDispatch* m_lpDispatch;
|
||||
|
||||
friend class Storage;
|
||||
};
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user