Initial MSVC 2008 projects workspace
This commit is contained in:
304
L2C_Server/utils/Debugging.cpp
Normal file
304
L2C_Server/utils/Debugging.cpp
Normal file
@@ -0,0 +1,304 @@
|
||||
#include "pch.h"
|
||||
#include "Log.h"
|
||||
#include "Debugging.h"
|
||||
|
||||
#define MAX_SYM_NAME_LEN 256
|
||||
|
||||
Debug *Debug::s_instance = NULL;
|
||||
|
||||
Debug *Debug::getInstance()
|
||||
{
|
||||
if( !s_instance )
|
||||
s_instance = new Debug();
|
||||
return s_instance;
|
||||
}
|
||||
|
||||
void Debug::freeInstance()
|
||||
{
|
||||
if( s_instance )
|
||||
{
|
||||
delete s_instance;
|
||||
s_instance = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/*BOOL CALLBACK Debug_EnumerateModulesProc64( PCSTR ModuleName, DWORD64 BaseOfDll, PVOID UserContext )
|
||||
{
|
||||
//LogDebug( L" EnumerateModulesProc [%S] 0x%08X", ModuleName, (DWORD)BaseOfDll );
|
||||
wchar_t w[1024];
|
||||
wsprintfW( w, L" EnumerateModulesProc [%S] 0x%08X", ModuleName, (DWORD)BaseOfDll );
|
||||
MessageBox( NULL, w, L"Enum mod", 0 );
|
||||
return TRUE;
|
||||
}*/
|
||||
|
||||
Debug::Debug()
|
||||
{
|
||||
InitializeCriticalSectionAndSpinCount( &m_lock, 10 );
|
||||
EnterCriticalSection( &m_lock );
|
||||
m_initOK = false;
|
||||
m_symHandle = GetCurrentProcess();
|
||||
// set symbol handler options
|
||||
SymSetOptions( SYMOPT_UNDNAME | /*SYMOPT_DEFERRED_LOADS |*/ SYMOPT_LOAD_LINES );
|
||||
// create symbol search path
|
||||
WCHAR windir[256] = {0};
|
||||
WCHAR szSearchPath[256] = {0};
|
||||
GetWindowsDirectoryW( windir, 255 );
|
||||
wsprintfW( szSearchPath, L".;.\\Symbols;%s\\Symbols;%s\\Symbols\\dll", windir, windir );
|
||||
//MessageBoxW( NULL, szSearchPath, NULL, 0 );
|
||||
// initialize symbol handler
|
||||
BOOL ok = SymInitializeW( m_symHandle, szSearchPath/*NULL*/, TRUE );
|
||||
if( !ok )
|
||||
{
|
||||
DWORD le = GetLastError();
|
||||
wchar_t msg[512];
|
||||
wsprintfW( msg, L"SymInitialize() failed: %u", le );
|
||||
MessageBox( NULL, msg, L"Error", MB_ICONSTOP );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_initOK = true;
|
||||
//
|
||||
// load PDBs for all modules possible
|
||||
//SymEnumerateModules64( m_symHandle, Debug_EnumerateModulesProc64, NULL );
|
||||
//
|
||||
}
|
||||
LeaveCriticalSection( &m_lock );
|
||||
}
|
||||
|
||||
Debug::~Debug()
|
||||
{
|
||||
EnterCriticalSection( &m_lock );
|
||||
if( m_initOK )
|
||||
{
|
||||
SymCleanup( m_symHandle );
|
||||
m_initOK = false;
|
||||
}
|
||||
LeaveCriticalSection( &m_lock );
|
||||
DeleteCriticalSection( &m_lock );
|
||||
}
|
||||
|
||||
void Debug::createStackTrace( DebugStackTrace& traceObject )
|
||||
{
|
||||
traceObject.clear();
|
||||
EnterCriticalSection( &m_lock );
|
||||
//
|
||||
// fill stackframe struct
|
||||
STACKFRAME64 stackFrame;
|
||||
memset( &stackFrame, 0, sizeof(stackFrame) );
|
||||
stackFrame.AddrPC.Mode = AddrModeFlat;
|
||||
stackFrame.AddrFrame.Mode = AddrModeFlat;
|
||||
stackFrame.AddrStack.Mode = AddrModeFlat;
|
||||
unsigned int i;
|
||||
__asm mov i, esp
|
||||
stackFrame.AddrStack.Offset = i;
|
||||
__asm mov i, ebp
|
||||
stackFrame.AddrFrame.Offset = i;
|
||||
//stackFrame.AddrPC.Offset = (DWORD64)(void *)(Debug::createStackTrace);
|
||||
stackFrame.AddrPC.Offset = (DWORD64)(void *)&stackFrame;
|
||||
BOOL bRet = TRUE;
|
||||
//
|
||||
bRet = StackWalk64( IMAGE_FILE_MACHINE_I386, this->m_symHandle, GetCurrentThread(), &stackFrame,
|
||||
NULL, NULL, SymFunctionTableAccess64, SymGetModuleBase64, NULL );
|
||||
while( bRet )
|
||||
{
|
||||
DebugOneStackFrameInfo frameInfo;
|
||||
DWORD64 addr_offset = 0; // address offset
|
||||
SYMBOL_INFO *psymInfo = (SYMBOL_INFO *)malloc( sizeof(SYMBOL_INFO) + MAX_SYM_NAME_LEN + 1 );
|
||||
memset( psymInfo, 0, sizeof(SYMBOL_INFO) + MAX_SYM_NAME_LEN + 1 );
|
||||
psymInfo->SizeOfStruct = sizeof(SYMBOL_INFO);
|
||||
psymInfo->MaxNameLen = MAX_SYM_NAME_LEN;
|
||||
if( stackFrame.AddrReturn.Offset > 0 )
|
||||
{
|
||||
bRet = SymFromAddr( this->m_symHandle, stackFrame.AddrReturn.Offset, &addr_offset, psymInfo );
|
||||
if( bRet )
|
||||
{
|
||||
// get module info
|
||||
char *moduleName = NULL;
|
||||
IMAGEHLP_MODULE64 moduleInfo;
|
||||
memset( &moduleInfo, 0, sizeof(moduleInfo) );
|
||||
moduleInfo.SizeOfStruct = sizeof(IMAGEHLP_MODULE64); // 584?
|
||||
if( !SymGetModuleInfo64( this->m_symHandle, psymInfo->Address, &moduleInfo ) )
|
||||
{
|
||||
Log_Win32Error( L"SymGetModuleInfo64() failed", GetLastError() );
|
||||
LogError( L"For addr 0x%08X name %S", (DWORD)psymInfo->Address, psymInfo->Name );
|
||||
}
|
||||
else moduleName = moduleInfo.ModuleName;
|
||||
//
|
||||
// get file name and line number
|
||||
IMAGEHLP_LINE64 lineinfo;
|
||||
memset( &lineinfo, 0, sizeof(lineinfo) );
|
||||
lineinfo.SizeOfStruct = sizeof(lineinfo);
|
||||
DWORD disp = 0;
|
||||
if( SymGetLineFromAddr64( GetCurrentProcess(), psymInfo->Address, &disp, &lineinfo ) )
|
||||
{
|
||||
frameInfo.set( psymInfo->Name, psymInfo->Address, addr_offset,
|
||||
lineinfo.FileName, lineinfo.LineNumber,
|
||||
moduleName );
|
||||
}
|
||||
else
|
||||
{
|
||||
DWORD le = GetLastError();
|
||||
if( le != ERROR_INVALID_ADDRESS ) // Attempt to access invalid address.
|
||||
{
|
||||
Log_Win32Error( L"dbghelp!SymGetLineFromAddr64() failed", le );
|
||||
LogError( L"For name: [%S]", psymInfo->Name );
|
||||
}
|
||||
frameInfo.set( psymInfo->Name, psymInfo->Address, addr_offset, NULL, 0, moduleName );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
DWORD le = GetLastError();
|
||||
Log_Win32Error( L"dbghelp!SymFromAddr() failed", le );
|
||||
LogError( L"For addr: 0x%08X", (DWORD)stackFrame.AddrReturn.Offset );
|
||||
}
|
||||
// add frame info
|
||||
traceObject.addStackFrame( frameInfo );
|
||||
}
|
||||
free( psymInfo );
|
||||
//
|
||||
bRet = StackWalk64( IMAGE_FILE_MACHINE_I386, GetCurrentProcess(), GetCurrentThread(), &stackFrame, NULL,
|
||||
NULL, SymFunctionTableAccess64, SymGetModuleBase64, NULL );
|
||||
}
|
||||
DWORD le = GetLastError();
|
||||
if( le != ERROR_INVALID_ADDRESS && le != NO_ERROR )
|
||||
Log_Win32Error( L"StackWalk64() ended", le );
|
||||
//
|
||||
// unlock
|
||||
LeaveCriticalSection( &m_lock );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
DebugOneStackFrameInfo::~DebugOneStackFrameInfo()
|
||||
{
|
||||
if( m_name ) free( m_name );
|
||||
m_name = NULL;
|
||||
if( m_fileName ) free( m_fileName );
|
||||
m_fileName = NULL;
|
||||
if( m_moduleName ) free( m_moduleName );
|
||||
m_moduleName = NULL;
|
||||
m_addr = 0;
|
||||
m_addr_offset = 0;
|
||||
m_line = 0;
|
||||
}
|
||||
|
||||
DebugOneStackFrameInfo::DebugOneStackFrameInfo( const DebugOneStackFrameInfo& other )
|
||||
{
|
||||
m_name = NULL;
|
||||
m_fileName = NULL;
|
||||
m_addr = 0;
|
||||
m_addr_offset = 0;
|
||||
m_line = 0;
|
||||
m_moduleName = NULL;
|
||||
this->operator=( other );
|
||||
}
|
||||
|
||||
const DebugOneStackFrameInfo& DebugOneStackFrameInfo::operator=( const DebugOneStackFrameInfo& other )
|
||||
{
|
||||
if( this == &other ) return (*this);
|
||||
set( other.m_name, other.m_addr, other.m_addr_offset, other.m_fileName, other.m_line, other.m_moduleName );
|
||||
return (*this);
|
||||
}
|
||||
|
||||
// compares only address & addr offset
|
||||
bool DebugOneStackFrameInfo::operator==( const DebugOneStackFrameInfo& other )
|
||||
{
|
||||
if( this->m_addr != other.m_addr ) return false; // different addr
|
||||
if( this->m_addr_offset != other.m_addr_offset ) return false; // different offset
|
||||
return true; // addresses equal
|
||||
}
|
||||
|
||||
void DebugOneStackFrameInfo::set(
|
||||
const char *name,
|
||||
unsigned long long addr,
|
||||
unsigned long long addr_offset,
|
||||
const char *fileName,
|
||||
unsigned int line,
|
||||
const char *moduleName )
|
||||
{
|
||||
m_addr = addr;
|
||||
m_addr_offset = addr_offset;
|
||||
m_line = line;
|
||||
if( m_name ) free( m_name );
|
||||
m_name = NULL;
|
||||
if( name ) m_name = _strdup( name );
|
||||
if( m_fileName ) free( m_fileName );
|
||||
m_fileName = NULL;
|
||||
if( fileName ) m_fileName = _strdup( fileName );
|
||||
if( m_moduleName ) free( m_moduleName );
|
||||
m_moduleName = NULL;
|
||||
if( moduleName ) m_moduleName = _strdup( moduleName );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
DebugStackTrace::DebugStackTrace()
|
||||
{
|
||||
m_list.clear();
|
||||
}
|
||||
|
||||
DebugStackTrace::~DebugStackTrace()
|
||||
{
|
||||
m_list.clear();
|
||||
}
|
||||
|
||||
void DebugStackTrace::clear()
|
||||
{
|
||||
m_list.clear();
|
||||
}
|
||||
|
||||
void DebugStackTrace::addStackFrame( DebugOneStackFrameInfo& ref )
|
||||
{
|
||||
m_list.push_back( ref );
|
||||
}
|
||||
|
||||
void DebugStackTrace::logStackTrace()
|
||||
{
|
||||
std::list<DebugOneStackFrameInfo>::const_iterator iter = m_list.begin();
|
||||
int nFrame = 0;
|
||||
while( iter != m_list.end() )
|
||||
{
|
||||
DebugOneStackFrameInfo frm = (*iter);
|
||||
if( frm.getModuleName() == NULL )
|
||||
{
|
||||
if( frm.getFileName() )
|
||||
{
|
||||
Log( L" %2d: %S() (0x%08X + %I64u) [%S line %u]", nFrame,
|
||||
frm.getName(), (unsigned int)frm.getAddr(), frm.getAddrOffset(),
|
||||
frm.getFileName(), frm.getLine() );
|
||||
}
|
||||
else
|
||||
{
|
||||
Log( L" %2d: %S() (0x%08X + %I64u)", nFrame,
|
||||
frm.getName(), (unsigned int)frm.getAddr(), frm.getAddrOffset() );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if( frm.getFileName() )
|
||||
{
|
||||
Log( L" %2d: %S!%S() (0x%08X + %I64u) [%S line %u]", nFrame,
|
||||
frm.getModuleName(), frm.getName(), (unsigned int)frm.getAddr(), frm.getAddrOffset(),
|
||||
frm.getFileName(), frm.getLine() );
|
||||
}
|
||||
else
|
||||
{
|
||||
Log( L" %2d: %S!%S() (0x%08X + %I64u)", nFrame,
|
||||
frm.getModuleName(), frm.getName(), (unsigned int)frm.getAddr(), frm.getAddrOffset() );
|
||||
}
|
||||
}
|
||||
nFrame++;
|
||||
iter++;
|
||||
}
|
||||
}
|
71
L2C_Server/utils/Debugging.h
Normal file
71
L2C_Server/utils/Debugging.h
Normal file
@@ -0,0 +1,71 @@
|
||||
#pragma once
|
||||
|
||||
class DebugOneStackFrameInfo
|
||||
{
|
||||
public:
|
||||
DebugOneStackFrameInfo():
|
||||
m_name(NULL), m_fileName(NULL), m_moduleName(NULL), m_addr(0), m_addr_offset(0), m_line(0) {}
|
||||
DebugOneStackFrameInfo( const DebugOneStackFrameInfo& other );
|
||||
~DebugOneStackFrameInfo();
|
||||
const DebugOneStackFrameInfo& operator=( const DebugOneStackFrameInfo& other );
|
||||
bool operator==( const DebugOneStackFrameInfo& other );
|
||||
public:
|
||||
void set(
|
||||
const char *name,
|
||||
unsigned long long addr,
|
||||
unsigned long long addr_offset,
|
||||
const char *fileName,
|
||||
unsigned int line,
|
||||
const char *moduleName
|
||||
);
|
||||
char *getName() const { return m_name; }
|
||||
unsigned long long getAddr() const { return m_addr; }
|
||||
unsigned long long getAddrOffset() const { return m_addr_offset; }
|
||||
char *getFileName() const { return m_fileName; }
|
||||
unsigned int getLine() const { return m_line; }
|
||||
char *getModuleName() const { return m_moduleName; }
|
||||
public:
|
||||
char *m_name;
|
||||
unsigned long long m_addr;
|
||||
unsigned long long m_addr_offset;
|
||||
char *m_fileName;
|
||||
unsigned int m_line;
|
||||
char *m_moduleName;
|
||||
};
|
||||
|
||||
|
||||
|
||||
class DebugStackTrace
|
||||
{
|
||||
public:
|
||||
DebugStackTrace();
|
||||
~DebugStackTrace();
|
||||
public:
|
||||
void clear();
|
||||
void addStackFrame( DebugOneStackFrameInfo& ref );
|
||||
void logStackTrace();
|
||||
protected:
|
||||
std::list<DebugOneStackFrameInfo> m_list;
|
||||
};
|
||||
|
||||
|
||||
|
||||
class Debug
|
||||
{
|
||||
protected:
|
||||
Debug();
|
||||
~Debug();
|
||||
static Debug *s_instance;
|
||||
|
||||
public:
|
||||
static Debug *getInstance();
|
||||
static void freeInstance();
|
||||
|
||||
public:
|
||||
void createStackTrace( DebugStackTrace& traceObject );
|
||||
|
||||
protected:
|
||||
CRITICAL_SECTION m_lock;
|
||||
HANDLE m_symHandle;
|
||||
bool m_initOK;
|
||||
};
|
98
L2C_Server/utils/Exception.cpp
Normal file
98
L2C_Server/utils/Exception.cpp
Normal file
@@ -0,0 +1,98 @@
|
||||
#include "pch.h"
|
||||
#include "Log.h"
|
||||
#include "Exception.h"
|
||||
|
||||
Exception::Exception()
|
||||
{
|
||||
m_what = NULL;
|
||||
m_trace = new DebugStackTrace();
|
||||
Debug::getInstance()->createStackTrace( (*m_trace) );
|
||||
}
|
||||
|
||||
Exception::Exception( const char *_Format, ... )
|
||||
{
|
||||
m_what = NULL;
|
||||
m_trace = new DebugStackTrace();
|
||||
Debug::getInstance()->createStackTrace( (*m_trace) );
|
||||
//
|
||||
va_list _ArgPtr;
|
||||
va_start( _ArgPtr, _Format );
|
||||
// _vscprintf(): Returns the number of characters in the formatted string using a pointer to a list of arguments.
|
||||
size_t what_len = _vscprintf( _Format, _ArgPtr );
|
||||
m_what = (char *)malloc( what_len + 16 );
|
||||
if( m_what )
|
||||
{
|
||||
va_start( _ArgPtr, _Format );
|
||||
vsprintf( m_what, _Format, _ArgPtr );
|
||||
}
|
||||
}
|
||||
|
||||
Exception::Exception( const Exception& other )
|
||||
{
|
||||
m_what = NULL;
|
||||
m_trace = new DebugStackTrace();
|
||||
Debug::getInstance()->createStackTrace( (*m_trace) );
|
||||
this->operator=( other );
|
||||
}
|
||||
|
||||
Exception::~Exception()
|
||||
{
|
||||
if( m_what )
|
||||
{
|
||||
free( m_what );
|
||||
m_what = NULL;
|
||||
}
|
||||
if( m_trace )
|
||||
{
|
||||
delete m_trace;
|
||||
m_trace = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
const Exception& Exception::operator=( const Exception& other )
|
||||
{
|
||||
if( this == &other ) return (*this);
|
||||
if( m_what )
|
||||
{
|
||||
free( m_what );
|
||||
m_what = NULL;
|
||||
}
|
||||
if( other.m_what ) m_what = _strdup( other.m_what );
|
||||
return (*this);
|
||||
}
|
||||
|
||||
const char *Exception::what() const
|
||||
{
|
||||
if( !m_what ) return "(no comment)";
|
||||
return m_what;
|
||||
}
|
||||
|
||||
void Exception::setWhat( const char *_Format, ... )
|
||||
{
|
||||
if( m_what )
|
||||
{
|
||||
free( m_what );
|
||||
m_what = NULL;
|
||||
}
|
||||
va_list _ArgPtr;
|
||||
va_start( _ArgPtr, _Format );
|
||||
// _vscprintf(): Returns the number of characters in the formatted string using a pointer to a list of arguments.
|
||||
size_t what_len = _vscprintf( _Format, _ArgPtr );
|
||||
m_what = (char *)malloc( what_len + 16 );
|
||||
if( m_what )
|
||||
{
|
||||
va_start( _ArgPtr, _Format );
|
||||
vsprintf( m_what, _Format, _ArgPtr );
|
||||
}
|
||||
}
|
||||
|
||||
void Exception::logStackTrace()
|
||||
{
|
||||
if( !m_trace )
|
||||
{
|
||||
Log( L"Exception: no stack trace!" );
|
||||
return;
|
||||
}
|
||||
m_trace->logStackTrace();
|
||||
}
|
||||
|
22
L2C_Server/utils/Exception.h
Normal file
22
L2C_Server/utils/Exception.h
Normal file
@@ -0,0 +1,22 @@
|
||||
#pragma once
|
||||
#include "Debugging.h"
|
||||
|
||||
class Exception
|
||||
{
|
||||
public:
|
||||
Exception();
|
||||
Exception( const char *_Format, ... );
|
||||
Exception( const Exception& other );
|
||||
virtual ~Exception();
|
||||
|
||||
const Exception& operator=( const Exception& other );
|
||||
|
||||
public:
|
||||
virtual void setWhat( const char *_Format, ... );
|
||||
virtual const char *what() const;
|
||||
virtual void logStackTrace();
|
||||
|
||||
protected:
|
||||
char *m_what;
|
||||
DebugStackTrace *m_trace;
|
||||
};
|
177
L2C_Server/utils/IdFactory.cpp
Normal file
177
L2C_Server/utils/IdFactory.cpp
Normal file
@@ -0,0 +1,177 @@
|
||||
#include "pch.h"
|
||||
#include "IdFactory.h"
|
||||
#include "GS.h"
|
||||
#include "Log.h"
|
||||
//#include "Exception.h"
|
||||
|
||||
IdFactory::IdFactory()
|
||||
{
|
||||
m_bitset = NULL;
|
||||
m_usedMemory = 0;
|
||||
m_lastOid = MIN_OBJECT_ID;
|
||||
}
|
||||
|
||||
IdFactory::~IdFactory()
|
||||
{
|
||||
clear();
|
||||
}
|
||||
|
||||
bool IdFactory::init()
|
||||
{
|
||||
if( m_bitset ) return false;
|
||||
m_lock.Lock();
|
||||
MEMORYSTATUSEX ms;
|
||||
ms.dwLength = sizeof(ms);
|
||||
GlobalMemoryStatusEx( &ms );
|
||||
unsigned long long mem_before = ms.ullAvailVirtual;
|
||||
unsigned long long mem_after = 0;
|
||||
m_bitset = new std::bitset<OBJECT_ID_COUNT>();
|
||||
if( m_bitset )
|
||||
{
|
||||
ms.dwLength = sizeof(ms);
|
||||
GlobalMemoryStatusEx( &ms );
|
||||
mem_after = ms.ullAvailVirtual;
|
||||
m_usedMemory = mem_before - mem_after;
|
||||
m_lastOid = MIN_OBJECT_ID;
|
||||
// restore all currently used objectId's
|
||||
fillObjectIdsFromDB();
|
||||
m_lock.Unlock();
|
||||
return true;
|
||||
}
|
||||
m_lock.Unlock();
|
||||
return false;
|
||||
}
|
||||
|
||||
void IdFactory::clear()
|
||||
{
|
||||
m_lock.Lock();
|
||||
if( m_bitset )
|
||||
{
|
||||
delete m_bitset;
|
||||
m_bitset = NULL;
|
||||
m_usedMemory = 0;
|
||||
}
|
||||
m_lastOid = MIN_OBJECT_ID;
|
||||
m_lock.Unlock();
|
||||
}
|
||||
|
||||
unsigned int IdFactory::getUsedCount()
|
||||
{
|
||||
if( !m_bitset ) return 0;
|
||||
unsigned int r = 0;
|
||||
m_lock.Lock();
|
||||
r = m_bitset->count();
|
||||
m_lock.Unlock();
|
||||
return r;
|
||||
}
|
||||
|
||||
unsigned int IdFactory::getNextObjectId() throw(NoFreeObjectIdException)
|
||||
{
|
||||
if( !m_bitset ) return 0;
|
||||
m_lock.Lock();
|
||||
unsigned int o = findUnusedOid();
|
||||
if( o == 0 )
|
||||
{
|
||||
m_lock.Unlock();
|
||||
throw NoFreeObjectIdException();
|
||||
}
|
||||
m_bitset->set( o-MIN_OBJECT_ID );
|
||||
m_lastOid = o+1; // next time try to give next objectId
|
||||
if( m_lastOid > MAX_OBJECT_ID ) m_lastOid = MIN_OBJECT_ID;
|
||||
m_lock.Unlock();
|
||||
return o;
|
||||
}
|
||||
|
||||
bool IdFactory::releaseObjectId( unsigned int o )
|
||||
{
|
||||
if( !m_bitset ) return false;
|
||||
m_lock.Lock();
|
||||
bool ret = false;
|
||||
if( m_bitset->test( o ) )
|
||||
{
|
||||
ret = true;
|
||||
m_bitset->reset( o );
|
||||
}
|
||||
m_lock.Unlock();
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool IdFactory::isUsedObjectId( unsigned int o )
|
||||
{
|
||||
if( !m_bitset ) return false;
|
||||
bool ret = false;
|
||||
m_lock.Lock();
|
||||
ret = m_bitset->test( o );
|
||||
m_lock.Unlock();
|
||||
return ret;
|
||||
}
|
||||
|
||||
unsigned long long int IdFactory::getUsedMemoryBytes() const
|
||||
{
|
||||
return m_usedMemory;
|
||||
}
|
||||
|
||||
unsigned int IdFactory::findUnusedOid() const
|
||||
{
|
||||
if( !m_bitset ) return 0;
|
||||
// lock should be locked!
|
||||
unsigned int o = m_lastOid;
|
||||
unsigned int start_o = o;
|
||||
while( o >= MIN_OBJECT_ID )
|
||||
{
|
||||
#ifdef _DEBUG_IDFACTORY_INT
|
||||
try
|
||||
{
|
||||
#endif /*_DEBUG_IDFACTORY_INT*/
|
||||
if( !m_bitset->test( o-MIN_OBJECT_ID ) ) return o;
|
||||
#ifdef _DEBUG_IDFACTORY_INT
|
||||
}
|
||||
catch( std::exception& e )
|
||||
{
|
||||
printf( "std::exception: %s\n", e.what() );
|
||||
printf( "o = %u (m_lastOid = %u, start_o = %u)\n", o, m_lastOid, start_o );
|
||||
}
|
||||
#endif /*_DEBUG_IDFACTORY_INT*/
|
||||
o++;
|
||||
if( o > MAX_OBJECT_ID ) o = MIN_OBJECT_ID;
|
||||
if( o == start_o ) break; // search reached start point
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void IdFactory::fillObjectIdsFromDB()
|
||||
{
|
||||
MysqlConnection *con = GameServer::getInstance()->getDBConnection();
|
||||
MysqlQuery q;
|
||||
//"SELECT charId FROM characters"
|
||||
//"SELECT object_id FROM items"
|
||||
//"SELECT object_id FROM itemsonground
|
||||
//"SELECT clan_id FROM clan_data"
|
||||
q.create( L"SELECT charId FROM characters UNION SELECT object_id FROM items "
|
||||
L"UNION SELECT object_id FROM itemsonground UNION SELECT clan_id FROM clan_data" );
|
||||
if( con->executeQuery( q ) )
|
||||
{
|
||||
while( q.getNextRow() )
|
||||
{
|
||||
unsigned int oid = q.getFieldUInt( 0 );
|
||||
fillObjectIdsFromDB_insertOne( oid );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LogError( L"IdFactory::fillObjectIdsFromDB(): MySQL ERROR: %s\n", con->getErrorStr() );
|
||||
}
|
||||
|
||||
GameServer::getInstance()->releaseDBConnection( con );
|
||||
}
|
||||
|
||||
void IdFactory::fillObjectIdsFromDB_insertOne( unsigned int oid )
|
||||
{
|
||||
if( oid >= IdFactory::MIN_OBJECT_ID && oid <= IdFactory::MAX_OBJECT_ID )
|
||||
{
|
||||
m_bitset->set( oid - IdFactory::MIN_OBJECT_ID );
|
||||
}
|
||||
else
|
||||
LogError( L"IdFactory: RESTORE: oid [%u] is not between MIN_OBJECT_ID[%u] and MAX_OBJECT_ID[%u]!\n",
|
||||
oid, IdFactory::MIN_OBJECT_ID, IdFactory::MAX_OBJECT_ID );
|
||||
}
|
44
L2C_Server/utils/IdFactory.h
Normal file
44
L2C_Server/utils/IdFactory.h
Normal file
@@ -0,0 +1,44 @@
|
||||
#pragma once
|
||||
#include "l2c_utils.h"
|
||||
|
||||
// warning C4290: C++ exception specification ignored except to indicate a function is not __declspec(nothrow)
|
||||
#pragma warning (disable: 4290)
|
||||
|
||||
class Exception;
|
||||
|
||||
class IdFactory
|
||||
{
|
||||
public:
|
||||
static const unsigned int MIN_OBJECT_ID = 0x10000000;
|
||||
static const unsigned int MAX_OBJECT_ID = 0x7FFFFFFF;
|
||||
static const unsigned int OBJECT_ID_COUNT = MAX_OBJECT_ID - MIN_OBJECT_ID + 1;
|
||||
|
||||
public:
|
||||
class NoFreeObjectIdException: public std::exception {};
|
||||
|
||||
public:
|
||||
IdFactory();
|
||||
~IdFactory();
|
||||
bool init();
|
||||
void clear();
|
||||
|
||||
public:
|
||||
unsigned int getUsedCount();
|
||||
unsigned int getNextObjectId() throw(NoFreeObjectIdException);
|
||||
bool releaseObjectId( unsigned int o );
|
||||
bool isUsedObjectId( unsigned int o );
|
||||
|
||||
public:
|
||||
unsigned long long int getUsedMemoryBytes() const;
|
||||
|
||||
protected:
|
||||
unsigned int findUnusedOid() const;
|
||||
void fillObjectIdsFromDB();
|
||||
void fillObjectIdsFromDB_insertOne( unsigned int oid );
|
||||
|
||||
protected:
|
||||
std::bitset<OBJECT_ID_COUNT> *m_bitset;
|
||||
unsigned long long int m_usedMemory;
|
||||
CriticalSection m_lock;
|
||||
unsigned int m_lastOid;
|
||||
};
|
16
L2C_Server/utils/Utils.cpp
Normal file
16
L2C_Server/utils/Utils.cpp
Normal file
@@ -0,0 +1,16 @@
|
||||
#include "pch.h"
|
||||
#include "Utils.h"
|
||||
|
||||
bool Utils_isValidCharName( const wchar_t *name )
|
||||
{
|
||||
if( !name ) return false;
|
||||
size_t nl = wcslen( name );
|
||||
if( nl < 3 ) return false;
|
||||
size_t i = 0;
|
||||
for( i=0; i<nl; i++ )
|
||||
{
|
||||
wchar_t c = name[i];
|
||||
if( !iswalnum( c ) ) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
3
L2C_Server/utils/Utils.h
Normal file
3
L2C_Server/utils/Utils.h
Normal file
@@ -0,0 +1,3 @@
|
||||
#pragma once
|
||||
|
||||
bool Utils_isValidCharName( const wchar_t *name );
|
Reference in New Issue
Block a user