mirror of
https://foundry.openuru.org/gitblit/r/CWE-ou-minkata.git
synced 2025-07-14 02:27:40 -04:00
@ -142,8 +142,6 @@ target_link_libraries(plClient pnDispatch)
|
|||||||
target_link_libraries(plClient pnEncryption)
|
target_link_libraries(plClient pnEncryption)
|
||||||
target_link_libraries(plClient pnFactory)
|
target_link_libraries(plClient pnFactory)
|
||||||
target_link_libraries(plClient pnGameMgr)
|
target_link_libraries(plClient pnGameMgr)
|
||||||
target_link_libraries(plClient pnIni)
|
|
||||||
target_link_libraries(plClient pnIniExe)
|
|
||||||
target_link_libraries(plClient pnInputCore)
|
target_link_libraries(plClient pnInputCore)
|
||||||
target_link_libraries(plClient pnKeyedObject)
|
target_link_libraries(plClient pnKeyedObject)
|
||||||
target_link_libraries(plClient pnMessage)
|
target_link_libraries(plClient pnMessage)
|
||||||
|
@ -4,32 +4,24 @@ add_subdirectory(inc)
|
|||||||
add_subdirectory(pnAddrInfo)
|
add_subdirectory(pnAddrInfo)
|
||||||
add_subdirectory(pnAsyncCore)
|
add_subdirectory(pnAsyncCore)
|
||||||
add_subdirectory(pnAsyncCoreExe)
|
add_subdirectory(pnAsyncCoreExe)
|
||||||
#add_subdirectory(pnCrash) # Not being used in any current sln
|
|
||||||
#add_subdirectory(pnCrashExe) # Not being used in any current sln
|
|
||||||
#add_subdirectory(pnCsrCli) # Not being used in any current sln
|
#add_subdirectory(pnCsrCli) # Not being used in any current sln
|
||||||
add_subdirectory(pnCsrNet)
|
add_subdirectory(pnCsrNet)
|
||||||
add_subdirectory(pnDispatch)
|
add_subdirectory(pnDispatch)
|
||||||
add_subdirectory(pnEncryption)
|
add_subdirectory(pnEncryption)
|
||||||
add_subdirectory(pnFactory)
|
add_subdirectory(pnFactory)
|
||||||
add_subdirectory(pnGameMgr)
|
add_subdirectory(pnGameMgr)
|
||||||
add_subdirectory(pnIni)
|
|
||||||
add_subdirectory(pnIniExe)
|
|
||||||
add_subdirectory(pnInputCore)
|
add_subdirectory(pnInputCore)
|
||||||
add_subdirectory(pnKeyedObject)
|
add_subdirectory(pnKeyedObject)
|
||||||
add_subdirectory(pnMail)
|
|
||||||
add_subdirectory(pnMessage)
|
add_subdirectory(pnMessage)
|
||||||
add_subdirectory(pnModifier)
|
add_subdirectory(pnModifier)
|
||||||
add_subdirectory(pnNetBase)
|
add_subdirectory(pnNetBase)
|
||||||
add_subdirectory(pnNetCli)
|
add_subdirectory(pnNetCli)
|
||||||
add_subdirectory(pnNetCommon)
|
add_subdirectory(pnNetCommon)
|
||||||
add_subdirectory(pnNetDiag)
|
add_subdirectory(pnNetDiag)
|
||||||
#add_subdirectory(pnNetLog) # Not being used in any current sln
|
|
||||||
add_subdirectory(pnNetProtocol)
|
add_subdirectory(pnNetProtocol)
|
||||||
#add_subdirectory(pnOraLib) # Not being used in any current sln
|
|
||||||
add_subdirectory(pnProduct)
|
add_subdirectory(pnProduct)
|
||||||
add_subdirectory(pnSceneObject)
|
add_subdirectory(pnSceneObject)
|
||||||
add_subdirectory(pnSimpleNet)
|
add_subdirectory(pnSimpleNet)
|
||||||
#add_subdirectory(pnSqlLib) # Not being used in any current sln
|
|
||||||
add_subdirectory(pnTimer)
|
add_subdirectory(pnTimer)
|
||||||
add_subdirectory(pnUtils)
|
add_subdirectory(pnUtils)
|
||||||
add_subdirectory(pnUtilsExe)
|
add_subdirectory(pnUtilsExe)
|
||||||
|
@ -55,10 +55,6 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
|||||||
#include "pnNetBase/pnNetBase.h"
|
#include "pnNetBase/pnNetBase.h"
|
||||||
#include "pnAsyncCore/pnAsyncCore.h"
|
#include "pnAsyncCore/pnAsyncCore.h"
|
||||||
|
|
||||||
#ifdef SERVER
|
|
||||||
#include "pnCrash/pnCrash.h" // deadlock API
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "Private/pnAceInt.h"
|
#include "Private/pnAceInt.h"
|
||||||
#include "Private/W9x/pnAceW9x.h"
|
#include "Private/W9x/pnAceW9x.h"
|
||||||
#include "Private/Nt/pnAceNt.h"
|
#include "Private/Nt/pnAceNt.h"
|
||||||
|
@ -267,19 +267,9 @@ static unsigned THREADCALL NtWorkerThreadProc (AsyncThread * thread) {
|
|||||||
);
|
);
|
||||||
|
|
||||||
if (op) {
|
if (op) {
|
||||||
// Queue for deadlock detection
|
|
||||||
#ifdef SERVER
|
|
||||||
void * check = CrashAddDeadlockCheck(thread->handle, L"pnAceNt.NtWorkerThread");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Dispatch event to app
|
// Dispatch event to app
|
||||||
INtOpDispatch(ntObj, op, bytes);
|
INtOpDispatch(ntObj, op, bytes);
|
||||||
|
|
||||||
// Unqueue from deadlock detection
|
|
||||||
#ifdef SERVER
|
|
||||||
CrashRemoveDeadlockCheck(check);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
sleepMs = 0;
|
sleepMs = 0;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -137,16 +137,8 @@ static unsigned THREADCALL ThreadTaskProc (AsyncThread * thread) {
|
|||||||
PerfAddCounter(kAsyncPerfThreadTaskThreadsActive, 1);
|
PerfAddCounter(kAsyncPerfThreadTaskThreadsActive, 1);
|
||||||
|
|
||||||
if (task) {
|
if (task) {
|
||||||
#ifdef SERVER
|
|
||||||
void * check = CrashAddDeadlockCheck(thread->handle, task->debugStr);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
task->callback(task->param, task->taskList->error);
|
task->callback(task->param, task->taskList->error);
|
||||||
|
|
||||||
#ifdef SERVER
|
|
||||||
CrashRemoveDeadlockCheck(check);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
task->taskList->DecRef("task");
|
task->taskList->DecRef("task");
|
||||||
delete task;
|
delete task;
|
||||||
}
|
}
|
||||||
|
@ -1,16 +0,0 @@
|
|||||||
include_directories(../../CoreLib)
|
|
||||||
include_directories(../../NucleusLib)
|
|
||||||
|
|
||||||
set(pnCrash_SOURCES
|
|
||||||
pnCrash.cpp
|
|
||||||
)
|
|
||||||
|
|
||||||
set(pnCrash_HEADERS
|
|
||||||
Pch.h
|
|
||||||
pnCrash.h
|
|
||||||
)
|
|
||||||
|
|
||||||
add_library(pnCrash STATIC ${pnCrash_SOURCES} ${pnCrash_HEADERS})
|
|
||||||
|
|
||||||
source_group("Source Files" FILES ${pnCrash_SOURCES})
|
|
||||||
source_group("Header Files" FILES ${pnCrash_HEADERS})
|
|
@ -1,54 +0,0 @@
|
|||||||
/*==LICENSE==*
|
|
||||||
|
|
||||||
CyanWorlds.com Engine - MMOG client, server and tools
|
|
||||||
Copyright (C) 2011 Cyan Worlds, Inc.
|
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
Additional permissions under GNU GPL version 3 section 7
|
|
||||||
|
|
||||||
If you modify this Program, or any covered work, by linking or
|
|
||||||
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
|
|
||||||
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
|
|
||||||
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
|
|
||||||
(or a modified version of those libraries),
|
|
||||||
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
|
|
||||||
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
|
|
||||||
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
|
|
||||||
licensors of this Program grant you additional
|
|
||||||
permission to convey the resulting work. Corresponding Source for a
|
|
||||||
non-source form of such a combination shall include the source code for
|
|
||||||
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
|
|
||||||
work.
|
|
||||||
|
|
||||||
You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
|
||||||
or by snail mail at:
|
|
||||||
Cyan Worlds, Inc.
|
|
||||||
14617 N Newport Hwy
|
|
||||||
Mead, WA 99021
|
|
||||||
|
|
||||||
*==LICENSE==*/
|
|
||||||
/*****************************************************************************
|
|
||||||
*
|
|
||||||
* $/Plasma20/Sources/Plasma/NucleusLib/pnCrash/Pch.h
|
|
||||||
*
|
|
||||||
***/
|
|
||||||
|
|
||||||
#ifdef PLASMA20_SOURCES_PLASMA_NUCLEUSLIB_PNCRASH_PCH_H
|
|
||||||
#error "Header $/Plasma20/Sources/Plasma/NucleusLib/pnCrash/Pch.h included more than once"
|
|
||||||
#endif
|
|
||||||
#define PLASMA20_SOURCES_PLASMA_NUCLEUSLIB_PNCRASH_PCH_H
|
|
||||||
|
|
||||||
|
|
||||||
#include "pnUtils/pnUtils.h"
|
|
@ -1,6 +0,0 @@
|
|||||||
@echo off
|
|
||||||
:Top
|
|
||||||
echo Running pnCrash.py
|
|
||||||
C:\Python23\python pnCrash.py
|
|
||||||
Sleep 1
|
|
||||||
goto :Top
|
|
@ -1,49 +0,0 @@
|
|||||||
/*==LICENSE==*
|
|
||||||
|
|
||||||
CyanWorlds.com Engine - MMOG client, server and tools
|
|
||||||
Copyright (C) 2011 Cyan Worlds, Inc.
|
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
Additional permissions under GNU GPL version 3 section 7
|
|
||||||
|
|
||||||
If you modify this Program, or any covered work, by linking or
|
|
||||||
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
|
|
||||||
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
|
|
||||||
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
|
|
||||||
(or a modified version of those libraries),
|
|
||||||
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
|
|
||||||
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
|
|
||||||
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
|
|
||||||
licensors of this Program grant you additional
|
|
||||||
permission to convey the resulting work. Corresponding Source for a
|
|
||||||
non-source form of such a combination shall include the source code for
|
|
||||||
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
|
|
||||||
work.
|
|
||||||
|
|
||||||
You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
|
||||||
or by snail mail at:
|
|
||||||
Cyan Worlds, Inc.
|
|
||||||
14617 N Newport Hwy
|
|
||||||
Mead, WA 99021
|
|
||||||
|
|
||||||
*==LICENSE==*/
|
|
||||||
/*****************************************************************************
|
|
||||||
*
|
|
||||||
* $/Plasma20/Sources/Plasma/NucleusLib/pnCrash/pnCrash.cpp
|
|
||||||
*
|
|
||||||
***/
|
|
||||||
|
|
||||||
#include "Pch.h"
|
|
||||||
#pragma hdrstop
|
|
@ -1,99 +0,0 @@
|
|||||||
/*==LICENSE==*
|
|
||||||
|
|
||||||
CyanWorlds.com Engine - MMOG client, server and tools
|
|
||||||
Copyright (C) 2011 Cyan Worlds, Inc.
|
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
Additional permissions under GNU GPL version 3 section 7
|
|
||||||
|
|
||||||
If you modify this Program, or any covered work, by linking or
|
|
||||||
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
|
|
||||||
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
|
|
||||||
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
|
|
||||||
(or a modified version of those libraries),
|
|
||||||
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
|
|
||||||
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
|
|
||||||
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
|
|
||||||
licensors of this Program grant you additional
|
|
||||||
permission to convey the resulting work. Corresponding Source for a
|
|
||||||
non-source form of such a combination shall include the source code for
|
|
||||||
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
|
|
||||||
work.
|
|
||||||
|
|
||||||
You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
|
||||||
or by snail mail at:
|
|
||||||
Cyan Worlds, Inc.
|
|
||||||
14617 N Newport Hwy
|
|
||||||
Mead, WA 99021
|
|
||||||
|
|
||||||
*==LICENSE==*/
|
|
||||||
/*****************************************************************************
|
|
||||||
*
|
|
||||||
* $/Plasma20/Sources/Plasma/NucleusLib/pnCrash/pnCrash.h
|
|
||||||
*
|
|
||||||
***/
|
|
||||||
|
|
||||||
#ifndef PLASMA20_SOURCES_PLASMA_NUCLEUSLIB_PNCRASH_PNCRASH_H
|
|
||||||
#define PLASMA20_SOURCES_PLASMA_NUCLEUSLIB_PNCRASH_PNCRASH_H
|
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************************
|
|
||||||
*
|
|
||||||
* Crash API
|
|
||||||
*
|
|
||||||
***/
|
|
||||||
|
|
||||||
void CrashExceptionDump (const char occasion[], void * info);
|
|
||||||
|
|
||||||
void CrashSetEmailParameters (
|
|
||||||
const char smtp[],
|
|
||||||
const char sender[],
|
|
||||||
const char recipients[], // separate multiple recipients with semicolons
|
|
||||||
const char username[], // optional (see auth notes in pnMail.h)
|
|
||||||
const char password[], // optional (see auth notes in pnMail.h)
|
|
||||||
const char replyTo[] // optional
|
|
||||||
);
|
|
||||||
|
|
||||||
void * CrashAddModule (
|
|
||||||
uintptr_t address,
|
|
||||||
unsigned buildId,
|
|
||||||
unsigned branchId,
|
|
||||||
const wchar_t name[],
|
|
||||||
const wchar_t buildString[]
|
|
||||||
);
|
|
||||||
|
|
||||||
void CrashRemoveModule (
|
|
||||||
void * module
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************************
|
|
||||||
*
|
|
||||||
* Deadlock detection (server only)
|
|
||||||
*
|
|
||||||
***/
|
|
||||||
|
|
||||||
#ifdef SERVER
|
|
||||||
void * CrashAddDeadlockCheck (void * thread, const wchar_t debugstr[] );
|
|
||||||
void CrashRemoveDeadlockCheck (void * check);
|
|
||||||
void CrashSetDeadlockCheckTimes (unsigned emailSec, unsigned terminateSec);
|
|
||||||
// returns previous setting
|
|
||||||
bool CrashEnableDeadlockChecking (bool enable);
|
|
||||||
void CrashDeadlockCheckNow ();
|
|
||||||
void CrashSendThreadReport ();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#endif // PLASMA20_SOURCES_PLASMA_NUCLEUSLIB_PNCRASH_PNCRASH_H
|
|
@ -1,469 +0,0 @@
|
|||||||
""" *==LICENSE==*
|
|
||||||
|
|
||||||
CyanWorlds.com Engine - MMOG client, server and tools
|
|
||||||
Copyright (C) 2011 Cyan Worlds, Inc.
|
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
Additional permissions under GNU GPL version 3 section 7
|
|
||||||
|
|
||||||
If you modify this Program, or any covered work, by linking or
|
|
||||||
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
|
|
||||||
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
|
|
||||||
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
|
|
||||||
(or a modified version of those libraries),
|
|
||||||
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
|
|
||||||
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
|
|
||||||
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
|
|
||||||
licensors of this Program grant you additional
|
|
||||||
permission to convey the resulting work. Corresponding Source for a
|
|
||||||
non-source form of such a combination shall include the source code for
|
|
||||||
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
|
|
||||||
work.
|
|
||||||
|
|
||||||
You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
|
||||||
or by snail mail at:
|
|
||||||
Cyan Worlds, Inc.
|
|
||||||
14617 N Newport Hwy
|
|
||||||
Mead, WA 99021
|
|
||||||
|
|
||||||
*==LICENSE==* """
|
|
||||||
import sys, os, re, poplib, smtplib, time
|
|
||||||
|
|
||||||
|
|
||||||
#*****************************************************************************
|
|
||||||
#*
|
|
||||||
#* Private data
|
|
||||||
#*
|
|
||||||
#***
|
|
||||||
|
|
||||||
s_pop3Srv = 'catherine.cyan.com'
|
|
||||||
s_pop3User = 'crashhandler'
|
|
||||||
s_pop3Pass = 'crashhandler'
|
|
||||||
|
|
||||||
s_smtpSrv = 'catherine.cyan.com'
|
|
||||||
#s_smtpRecipients = ['eric@cyan.com']
|
|
||||||
s_smtpRecipients = ['crash2@cyan.com']
|
|
||||||
|
|
||||||
#s_mapFileBasePath = 'P:\\Plasma20\\Scripts\\Server\\Admin\\';
|
|
||||||
s_mapFileBasePath = '\\\\dirtcake\\MapFiles\\';
|
|
||||||
|
|
||||||
s_modules = {}
|
|
||||||
s_mapfiles = {}
|
|
||||||
s_sortedModuleKeys = []
|
|
||||||
|
|
||||||
|
|
||||||
#*****************************************************************************
|
|
||||||
#*
|
|
||||||
#* Local functions
|
|
||||||
#*
|
|
||||||
#***
|
|
||||||
|
|
||||||
#=============================================================================
|
|
||||||
def UndecorateCppName (name):
|
|
||||||
name = re.sub('^\?', '', name, 1)
|
|
||||||
name = re.sub('^_', '', name, 1)
|
|
||||||
name = re.sub('@', ' ', name)
|
|
||||||
name = re.sub('\s+', ' ', name)
|
|
||||||
return name
|
|
||||||
|
|
||||||
#=============================================================================
|
|
||||||
# returns index of the first entry for which 'eval' returns false
|
|
||||||
def bsearch (a, eval):
|
|
||||||
low = 0
|
|
||||||
high = len(a)
|
|
||||||
|
|
||||||
if low != high:
|
|
||||||
while True:
|
|
||||||
mid = (low + high) // 2
|
|
||||||
result = eval(a[mid])
|
|
||||||
if result > 0:
|
|
||||||
if mid == low:
|
|
||||||
break
|
|
||||||
low = mid
|
|
||||||
else:
|
|
||||||
high = mid
|
|
||||||
if mid == low:
|
|
||||||
break
|
|
||||||
return high
|
|
||||||
|
|
||||||
|
|
||||||
#*****************************************************************************
|
|
||||||
#*
|
|
||||||
#* Function class
|
|
||||||
#*
|
|
||||||
#***
|
|
||||||
|
|
||||||
class Function:
|
|
||||||
|
|
||||||
#=========================================================================
|
|
||||||
def __init__ (self, name, baseAddr, relocAddr, module):
|
|
||||||
self.name = UndecorateCppName(name)
|
|
||||||
self.baseAddr = baseAddr
|
|
||||||
self.relocAddr = relocAddr
|
|
||||||
self.module = module
|
|
||||||
#print "Function: %08x,%s,%s" % (self.relocAddr, self.module, self.name)
|
|
||||||
|
|
||||||
|
|
||||||
#*****************************************************************************
|
|
||||||
#*
|
|
||||||
#* Mapfile class
|
|
||||||
#*
|
|
||||||
#***
|
|
||||||
|
|
||||||
class Mapfile:
|
|
||||||
#=========================================================================
|
|
||||||
def __init__ (self, filename):
|
|
||||||
self.filename = filename
|
|
||||||
self.prefLoadAddr = 0
|
|
||||||
self.functions = {}
|
|
||||||
self.sortedFunctionKeys = []
|
|
||||||
|
|
||||||
try:
|
|
||||||
file = open(filename, 'rb')
|
|
||||||
# print "mapfile opened " + filename
|
|
||||||
lines = file.readlines()
|
|
||||||
file.close()
|
|
||||||
self.ParseMapfile(lines)
|
|
||||||
except IOError:
|
|
||||||
# print 'mapfile not found: ' + filename
|
|
||||||
pass
|
|
||||||
|
|
||||||
#=========================================================================
|
|
||||||
def ParseMapfile (self, lines):
|
|
||||||
# Preferred load address is xxxxxxxx
|
|
||||||
pattern = re.compile('\s*Preferred.*([\dA-Fa-f]{8})')
|
|
||||||
for line in lines:
|
|
||||||
match = pattern.match(line)
|
|
||||||
if not match:
|
|
||||||
continue
|
|
||||||
self.prefLoadAddr = int(match.group(1), 16)
|
|
||||||
break
|
|
||||||
|
|
||||||
# section:baseAddr functionName relocAddr flags module
|
|
||||||
pattern = re.compile('^\s?([\dA-Fa-f]{4}:[\dA-Fa-f]{8})\s+(\S+)\s+([\dA-Fa-f]{8})\s(.)\s.\s(\S+)')
|
|
||||||
for line in lines:
|
|
||||||
match = pattern.match(line)
|
|
||||||
if not match:
|
|
||||||
continue
|
|
||||||
baseAddr = match.group(1)
|
|
||||||
name = match.group(2)
|
|
||||||
relocAddr = int(match.group(3), 16)
|
|
||||||
if match.group(4) != 'f':
|
|
||||||
continue
|
|
||||||
module = match.group(5)
|
|
||||||
if self.functions.has_key(relocAddr):
|
|
||||||
# print " duplicate: %s %08x %s" % (baseAddr, relocAddr, name)
|
|
||||||
# print " with : %s %08x %s" % (self.functions[relocAddr].baseAddr, self.functions[relocAddr].relocAddr, self.functions[relocAddr].name)
|
|
||||||
pass
|
|
||||||
else:
|
|
||||||
self.functions[relocAddr] = Function(name, baseAddr, relocAddr, module)
|
|
||||||
|
|
||||||
self.sortedFunctionKeys = self.functions.keys()
|
|
||||||
self.sortedFunctionKeys.sort()
|
|
||||||
# print " function count: %u" % (len(self.sortedFunctionKeys))
|
|
||||||
|
|
||||||
#=========================================================================
|
|
||||||
def FindNearestFunction (self, relocAddr):
|
|
||||||
|
|
||||||
#=====================================================================
|
|
||||||
def eval (a, b=relocAddr):
|
|
||||||
return b > a
|
|
||||||
|
|
||||||
index = bsearch(self.sortedFunctionKeys, eval)
|
|
||||||
if index > 0 and index < len(self.sortedFunctionKeys):
|
|
||||||
return self.functions[self.sortedFunctionKeys[index-1]]
|
|
||||||
return Function("<FunctionNotFound> relocAddr %x" % (relocAddr), 0, relocAddr, self.filename)
|
|
||||||
|
|
||||||
#=============================================================================
|
|
||||||
def LoadMapfile (mapfilename):
|
|
||||||
global s_mapfiles
|
|
||||||
if not s_mapfiles.has_key(mapfilename):
|
|
||||||
s_mapfiles[mapfilename] = Mapfile(mapfilename)
|
|
||||||
return s_mapfiles[mapfilename]
|
|
||||||
|
|
||||||
|
|
||||||
#*****************************************************************************
|
|
||||||
#*
|
|
||||||
#* Module class
|
|
||||||
#*
|
|
||||||
#***
|
|
||||||
|
|
||||||
class Module:
|
|
||||||
#=========================================================================
|
|
||||||
def __init__ (self, loadAddr, name, buildId, buildMark):
|
|
||||||
# print 'module: %s:%u, loadaddr: %08x' % (name, buildId, loadAddr)
|
|
||||||
self.loadAddr = loadAddr
|
|
||||||
self.name = name
|
|
||||||
self.buildMark = buildMark
|
|
||||||
self.buildId = buildId
|
|
||||||
mapfilename = s_mapFileBasePath + buildMark + '\\' + name.split('.')[0].split('_')[0] + '.map'
|
|
||||||
self.mapfile = LoadMapfile(mapfilename)
|
|
||||||
|
|
||||||
#=========================================================================
|
|
||||||
def FindNearestFunction (self, trueAddr):
|
|
||||||
relocAddr = trueAddr + self.mapfile.prefLoadAddr - self.loadAddr
|
|
||||||
# print 'searching for function near Pc:%08x, Ra:%08x in %s' % (trueAddr, relocAddr, self.mapfile.filename)
|
|
||||||
function = self.mapfile.FindNearestFunction(relocAddr)
|
|
||||||
if function:
|
|
||||||
# print " found function %s, Ra:%08x, %s" % (function.baseAddr, function.relocAddr, function.name)
|
|
||||||
return function
|
|
||||||
print "Function not found for Pc:%08x, Ra:%08x in %s" % (trueAddr, relocAddr, self.mapfile.filename)
|
|
||||||
return None
|
|
||||||
|
|
||||||
|
|
||||||
#=============================================================================
|
|
||||||
def FindNearestModule (loadAddr):
|
|
||||||
|
|
||||||
#=========================================================================
|
|
||||||
def eval (a, b=loadAddr):
|
|
||||||
return b > a
|
|
||||||
|
|
||||||
global s_modules
|
|
||||||
global s_sortedModuleKeys
|
|
||||||
|
|
||||||
if len(s_sortedModuleKeys) == 0:
|
|
||||||
return None
|
|
||||||
|
|
||||||
index = bsearch(s_sortedModuleKeys, eval)
|
|
||||||
if index > 0 and index <= len(s_sortedModuleKeys):
|
|
||||||
return s_modules[s_sortedModuleKeys[index-1]]
|
|
||||||
|
|
||||||
print "Module not found for loadAddr %08x" % (loadAddr)
|
|
||||||
return Module(loadAddr, "<ModuleNotFound> loadAddr %x" %(loadAddr), 0, "<NoBuildMark>")
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#*****************************************************************************
|
|
||||||
#*
|
|
||||||
#* pnCrash class
|
|
||||||
#*
|
|
||||||
#***
|
|
||||||
|
|
||||||
class pnCrash:
|
|
||||||
#=========================================================================
|
|
||||||
def SendCrash (self, msgLines, smtp):
|
|
||||||
pass
|
|
||||||
|
|
||||||
#=========================================================================
|
|
||||||
def GetModules (self, msgLines):
|
|
||||||
global s_modules
|
|
||||||
global s_sortedModuleKeys
|
|
||||||
# Parse modules and open mapfiles
|
|
||||||
pattern = re.compile('^([\dA-Fa-f]{8})\s(.*)\((\d+)\.\d+\.(.*)\)')
|
|
||||||
for line in msgLines:
|
|
||||||
match = pattern.match(line)
|
|
||||||
if not match:
|
|
||||||
continue
|
|
||||||
loadAddr = int(match.group(1), 16)
|
|
||||||
filename = os.path.basename(match.group(2)).strip()
|
|
||||||
buildId = int(match.group(3))
|
|
||||||
buildMark = match.group(4)
|
|
||||||
#assert not s_modules.has_key(loadAddr)
|
|
||||||
s_modules[loadAddr] = Module(loadAddr, filename, buildId, buildMark)
|
|
||||||
s_sortedModuleKeys = s_modules.keys()
|
|
||||||
s_sortedModuleKeys.sort()
|
|
||||||
|
|
||||||
# if no modules found, use the reporting application's info
|
|
||||||
if len(s_sortedModuleKeys) == 0:
|
|
||||||
buildId = 0
|
|
||||||
loadAddr = int('00400000', 16) # temp hack
|
|
||||||
patternApp = re.compile('^App\s+:\s+(.*)')
|
|
||||||
patternBuildMark = re.compile('^BuildMark\s+:\s+(.*)')
|
|
||||||
for line in msgLines:
|
|
||||||
if patternApp:
|
|
||||||
match = patternApp.match(line)
|
|
||||||
if match:
|
|
||||||
patternApp = None
|
|
||||||
filename = os.path.basename(match.group(1)).strip().strip('\r\n')
|
|
||||||
continue
|
|
||||||
else:
|
|
||||||
match = patternBuildMark.match(line)
|
|
||||||
if match:
|
|
||||||
buildMark = match.group(1).strip().strip('\r\n')
|
|
||||||
# print 'No modules found, adding %s, %08x, %u, %s' % (filename, loadAddr, buildId, buildMark)
|
|
||||||
s_modules[loadAddr] = Module(loadAddr, filename, buildId, buildMark)
|
|
||||||
s_sortedModuleKeys = s_modules.keys()
|
|
||||||
s_sortedModuleKeys.sort()
|
|
||||||
break
|
|
||||||
|
|
||||||
|
|
||||||
#=========================================================================
|
|
||||||
def ConvertTraces (self, msgLines):
|
|
||||||
lines = []
|
|
||||||
callstack = []
|
|
||||||
intrace = False
|
|
||||||
|
|
||||||
pattern = re.compile('Pc:([\dA-Fa-f]{8})\s+Fr:[\dA-Fa-f]{8}\s+Rt:([\dA-Fa-f]{8})')
|
|
||||||
for rawline in msgLines:
|
|
||||||
line = rawline.strip('\r\n')
|
|
||||||
if line.find('|') >= 0: # a previous conversion, skip over it
|
|
||||||
continue
|
|
||||||
lines.append(line)
|
|
||||||
match = pattern.match(line)
|
|
||||||
if not match:
|
|
||||||
if intrace:
|
|
||||||
callstack.append('')
|
|
||||||
lines += callstack
|
|
||||||
callstack = []
|
|
||||||
lines.append('')
|
|
||||||
intrace = False
|
|
||||||
continue
|
|
||||||
if not intrace:
|
|
||||||
callstack.append('|--------> Callstack <--------')
|
|
||||||
intrace = True
|
|
||||||
returnAddr = int(match.group(2), 16)
|
|
||||||
if not returnAddr:
|
|
||||||
continue
|
|
||||||
programCounter = int(match.group(1), 16)
|
|
||||||
module = FindNearestModule(programCounter)
|
|
||||||
function = module.FindNearestFunction(programCounter)
|
|
||||||
callstack.append('| %s, %s:%s' % (function.name, function.module, module.name))
|
|
||||||
|
|
||||||
if intrace:
|
|
||||||
callstack.append('')
|
|
||||||
lines += callstack
|
|
||||||
callstack = []
|
|
||||||
intrace = False
|
|
||||||
|
|
||||||
return lines
|
|
||||||
|
|
||||||
|
|
||||||
#=========================================================================
|
|
||||||
def ProcessClientCrash(self, msgLines):
|
|
||||||
lines = []
|
|
||||||
fd = open('untranslated.txt', 'w')
|
|
||||||
for x in msgLines:
|
|
||||||
fd.write(x)
|
|
||||||
fd.write('\n')
|
|
||||||
fd.close()
|
|
||||||
os.spawnl(os.P_WAIT, 'plStackTrace.exe', 'plStackTrace.exe', 'untranslated.txt')
|
|
||||||
fd = open('out.txt', 'r')
|
|
||||||
lines = fd.readlines()
|
|
||||||
return lines
|
|
||||||
|
|
||||||
|
|
||||||
#=========================================================================
|
|
||||||
def ProcessCrash (self, msgLines, smtp):
|
|
||||||
global s_modules
|
|
||||||
global s_sortedModuleKeys
|
|
||||||
|
|
||||||
subject = '[Crash]'
|
|
||||||
pattern = re.compile('^Subject: (.*)$')
|
|
||||||
serverPattern = re.compile('App : plServer.exe')
|
|
||||||
serverCrash = 0
|
|
||||||
|
|
||||||
for line in msgLines:
|
|
||||||
match = serverPattern.match(line)
|
|
||||||
if match:
|
|
||||||
serverCrash = 1
|
|
||||||
break
|
|
||||||
|
|
||||||
if not serverCrash:
|
|
||||||
subject = 'Client Crash Report'
|
|
||||||
|
|
||||||
for line in msgLines:
|
|
||||||
match = pattern.match(line)
|
|
||||||
if match:
|
|
||||||
subject = match.group(1)
|
|
||||||
subject.strip('\r\n')
|
|
||||||
|
|
||||||
from_ = 'crash2@cyan.com'
|
|
||||||
pattern = re.compile('^From: (.*)$')
|
|
||||||
for line in msgLines:
|
|
||||||
match = pattern.match(line)
|
|
||||||
if match:
|
|
||||||
from_ = match.group(1)
|
|
||||||
from_.strip('\r\n')
|
|
||||||
break
|
|
||||||
|
|
||||||
print "Rcvd: %s from %s" % (subject, from_)
|
|
||||||
|
|
||||||
smtp.helo()
|
|
||||||
smtp.mail(from_, [])
|
|
||||||
for rcpt in s_smtpRecipients:
|
|
||||||
smtp.rcpt(rcpt, [])
|
|
||||||
|
|
||||||
lines = []
|
|
||||||
lines.append('From: %s' % (from_))
|
|
||||||
lines.append('Subject: %s' % (subject))
|
|
||||||
lines.append('')
|
|
||||||
|
|
||||||
if not serverCrash:
|
|
||||||
lines += self.ProcessClientCrash(msgLines) # process client callstack
|
|
||||||
for x in range(len(lines)):
|
|
||||||
lines[x] = lines[x].strip('\r\n')
|
|
||||||
|
|
||||||
if serverCrash:
|
|
||||||
s_modules.clear()
|
|
||||||
s_sortedModuleKeys = []
|
|
||||||
self.GetModules(msgLines)
|
|
||||||
lines += self.ConvertTraces(msgLines)
|
|
||||||
s_sortedModuleKeys = []
|
|
||||||
s_modules.clear()
|
|
||||||
|
|
||||||
msg = '\n'.join([line for line in lines])
|
|
||||||
smtp.data(msg)
|
|
||||||
print "Sent: %s from %s" % (subject, from_)
|
|
||||||
|
|
||||||
|
|
||||||
#=========================================================================
|
|
||||||
def GetAndProcessCrashes (self):
|
|
||||||
global s_mapfiles
|
|
||||||
s_mapfiles.clear()
|
|
||||||
|
|
||||||
# print "initializing pop3"
|
|
||||||
pop3 = poplib.POP3(s_pop3Srv)
|
|
||||||
pop3.user(s_pop3User)
|
|
||||||
pop3.pass_(s_pop3Pass)
|
|
||||||
pop3.list()
|
|
||||||
(numMsgs, totalSize) = pop3.stat()
|
|
||||||
|
|
||||||
if numMsgs > 0:
|
|
||||||
# print "initializing smtp"
|
|
||||||
smtp = smtplib.SMTP(s_smtpSrv)
|
|
||||||
|
|
||||||
# print "retrieving emails"
|
|
||||||
for i in range(1, numMsgs + 1):
|
|
||||||
(header, msg, octets) = pop3.retr(i)
|
|
||||||
self.ProcessCrash(msg, smtp)
|
|
||||||
pop3.dele(i)
|
|
||||||
|
|
||||||
smtp.quit()
|
|
||||||
|
|
||||||
pop3.quit()
|
|
||||||
|
|
||||||
s_mapfiles.clear()
|
|
||||||
|
|
||||||
#=========================================================================
|
|
||||||
def RunForever (self):
|
|
||||||
global s_modules
|
|
||||||
s_modules[0] = Module(0, "<NilModule>", 0, "<NilBuild>")
|
|
||||||
while 1:
|
|
||||||
self.GetAndProcessCrashes()
|
|
||||||
# sleep for an interruptable minute
|
|
||||||
for i in range(1, 20):
|
|
||||||
time.sleep(1)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#*****************************************************************************
|
|
||||||
#*
|
|
||||||
#* Program entry point
|
|
||||||
#*
|
|
||||||
#***
|
|
||||||
|
|
||||||
#=============================================================================
|
|
||||||
if __name__ == '__main__':
|
|
||||||
pnCrash().RunForever()
|
|
@ -1,28 +0,0 @@
|
|||||||
include_directories(../../CoreLib)
|
|
||||||
include_directories(../../NucleusLib)
|
|
||||||
|
|
||||||
set(pnCrashExe_SOURCES
|
|
||||||
|
|
||||||
)
|
|
||||||
|
|
||||||
set(pnCrashExe_HEADERS
|
|
||||||
Pch.h
|
|
||||||
)
|
|
||||||
|
|
||||||
if(WIN32 AND NOT CYGWIN)
|
|
||||||
set (pnCrashExe_SOURCES ${pnCrashExe_SOURCES}
|
|
||||||
Win32/pnCreError.cpp
|
|
||||||
Win32/pnCreGui.cpp
|
|
||||||
Win32/pnCreMail.cpp
|
|
||||||
Win32/pnCreTools.cpp
|
|
||||||
)
|
|
||||||
|
|
||||||
set (pnCrashExe_HEADERS ${pnCrashExe_HEADERS}
|
|
||||||
Win32/W32Int.h
|
|
||||||
)
|
|
||||||
endif(WIN32 AND NOT CYGWIN)
|
|
||||||
|
|
||||||
add_library(pnCrashExe STATIC ${pnCrashExe_SOURCES} ${pnCrashExe_HEADERS})
|
|
||||||
|
|
||||||
source_group("Source Files" FILES ${pnCrashExe_SOURCES})
|
|
||||||
source_group("Header Files" FILES ${pnCrashExe_HEADERS})
|
|
@ -1,65 +0,0 @@
|
|||||||
/*==LICENSE==*
|
|
||||||
|
|
||||||
CyanWorlds.com Engine - MMOG client, server and tools
|
|
||||||
Copyright (C) 2011 Cyan Worlds, Inc.
|
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
Additional permissions under GNU GPL version 3 section 7
|
|
||||||
|
|
||||||
If you modify this Program, or any covered work, by linking or
|
|
||||||
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
|
|
||||||
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
|
|
||||||
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
|
|
||||||
(or a modified version of those libraries),
|
|
||||||
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
|
|
||||||
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
|
|
||||||
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
|
|
||||||
licensors of this Program grant you additional
|
|
||||||
permission to convey the resulting work. Corresponding Source for a
|
|
||||||
non-source form of such a combination shall include the source code for
|
|
||||||
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
|
|
||||||
work.
|
|
||||||
|
|
||||||
You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
|
||||||
or by snail mail at:
|
|
||||||
Cyan Worlds, Inc.
|
|
||||||
14617 N Newport Hwy
|
|
||||||
Mead, WA 99021
|
|
||||||
|
|
||||||
*==LICENSE==*/
|
|
||||||
/*****************************************************************************
|
|
||||||
*
|
|
||||||
* $/Plasma20/Sources/Plasma/NucleusLib/pnCrashExe/Pch.h
|
|
||||||
*
|
|
||||||
***/
|
|
||||||
|
|
||||||
#ifdef PLASMA20_SOURCES_PLASMA_NUCLEUSLIB_PNCRASHEXE_PCH_H
|
|
||||||
#error "Header $/Plasma20/Sources/Plasma/NucleusLib/pnCrashExe/Pch.h included more than once"
|
|
||||||
#endif
|
|
||||||
#define PLASMA20_SOURCES_PLASMA_NUCLEUSLIB_PNCRASHEXE_PCH_H
|
|
||||||
|
|
||||||
|
|
||||||
#include "pnUtils/pnUtils.h"
|
|
||||||
#include "pnProduct/pnProduct.h"
|
|
||||||
#include "pnNetBase/pnNetBase.h"
|
|
||||||
#include "pnAsyncCore/pnAsyncCore.h"
|
|
||||||
#include "pnMail/pnMail.h"
|
|
||||||
|
|
||||||
#include <ImageHlp.h>
|
|
||||||
#include <process.h>
|
|
||||||
|
|
||||||
#ifdef HS_BUILD_FOR_WIN32
|
|
||||||
#include "Win32/W32Int.h"
|
|
||||||
#endif
|
|
@ -1,147 +0,0 @@
|
|||||||
/*==LICENSE==*
|
|
||||||
|
|
||||||
CyanWorlds.com Engine - MMOG client, server and tools
|
|
||||||
Copyright (C) 2011 Cyan Worlds, Inc.
|
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
Additional permissions under GNU GPL version 3 section 7
|
|
||||||
|
|
||||||
If you modify this Program, or any covered work, by linking or
|
|
||||||
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
|
|
||||||
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
|
|
||||||
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
|
|
||||||
(or a modified version of those libraries),
|
|
||||||
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
|
|
||||||
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
|
|
||||||
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
|
|
||||||
licensors of this Program grant you additional
|
|
||||||
permission to convey the resulting work. Corresponding Source for a
|
|
||||||
non-source form of such a combination shall include the source code for
|
|
||||||
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
|
|
||||||
work.
|
|
||||||
|
|
||||||
You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
|
||||||
or by snail mail at:
|
|
||||||
Cyan Worlds, Inc.
|
|
||||||
14617 N Newport Hwy
|
|
||||||
Mead, WA 99021
|
|
||||||
|
|
||||||
*==LICENSE==*/
|
|
||||||
/*****************************************************************************
|
|
||||||
*
|
|
||||||
* $/Plasma20/Sources/Plasma/NucleusLib/pnCrashExe/Intern.h
|
|
||||||
*
|
|
||||||
***/
|
|
||||||
|
|
||||||
#ifdef PLASMA20_SOURCES_PLASMA_NUCLEUSLIB_PNCRASHEXE_INTERN_H
|
|
||||||
#error "Header $/Plasma20/Sources/Plasma/NucleusLib/pnCrashExe/Intern.h included more than once"
|
|
||||||
#endif
|
|
||||||
#define PLASMA20_SOURCES_PLASMA_NUCLEUSLIB_PNCRASHEXE_INTERN_H
|
|
||||||
|
|
||||||
|
|
||||||
namespace Crash {
|
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************************
|
|
||||||
*
|
|
||||||
* Mail
|
|
||||||
*
|
|
||||||
***/
|
|
||||||
|
|
||||||
void CrashSendEmail (
|
|
||||||
const char smtp[],
|
|
||||||
const char sender[],
|
|
||||||
const char recipients[],
|
|
||||||
const char replyTo[],
|
|
||||||
const char username[],
|
|
||||||
const char password[],
|
|
||||||
const char programName[],
|
|
||||||
const char errorType[],
|
|
||||||
const char logBuffer[]
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************************
|
|
||||||
*
|
|
||||||
* ImgHlp
|
|
||||||
*
|
|
||||||
***/
|
|
||||||
|
|
||||||
// make our own IMAGEAPI type because the real definition uses DECLSPEC_IMPORT
|
|
||||||
#define MYIMAGEAPI __stdcall
|
|
||||||
|
|
||||||
class CImageHelp {
|
|
||||||
private:
|
|
||||||
HMODULE m_libInst;
|
|
||||||
HANDLE m_process;
|
|
||||||
char * m_appName;
|
|
||||||
char m_appPath[MAX_PATH];
|
|
||||||
|
|
||||||
public:
|
|
||||||
CImageHelp (HINSTANCE instance);
|
|
||||||
~CImageHelp ();
|
|
||||||
|
|
||||||
inline HANDLE Process () const {
|
|
||||||
return m_process;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline const char * GetProgramPath () const {
|
|
||||||
return m_appPath;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline const char * GetProgramName () const {
|
|
||||||
return m_appName;
|
|
||||||
}
|
|
||||||
|
|
||||||
BOOL (MYIMAGEAPI * SymGetModuleInfo)(
|
|
||||||
HANDLE hProcess,
|
|
||||||
DWORD dwAddr,
|
|
||||||
IMAGEHLP_MODULE * ModuleInfo
|
|
||||||
);
|
|
||||||
|
|
||||||
BOOL (MYIMAGEAPI * StackWalk)(
|
|
||||||
DWORD MachineType,
|
|
||||||
HANDLE hProcess,
|
|
||||||
HANDLE hThread,
|
|
||||||
LPSTACKFRAME StackFrame,
|
|
||||||
LPVOID ContextRecord,
|
|
||||||
PREAD_PROCESS_MEMORY_ROUTINE ReadMemoryRoutine,
|
|
||||||
PFUNCTION_TABLE_ACCESS_ROUTINE FunctionTableAccessRoutine,
|
|
||||||
PGET_MODULE_BASE_ROUTINE GetModuleBaseRoutine,
|
|
||||||
PTRANSLATE_ADDRESS_ROUTINE TranslateAddress
|
|
||||||
);
|
|
||||||
|
|
||||||
LPVOID (MYIMAGEAPI * SymFunctionTableAccess)(
|
|
||||||
HANDLE hProcess,
|
|
||||||
DWORD AddrBase
|
|
||||||
);
|
|
||||||
|
|
||||||
DWORD (MYIMAGEAPI * SymGetModuleBase)(
|
|
||||||
HANDLE hProcess,
|
|
||||||
DWORD dwAddr
|
|
||||||
);
|
|
||||||
|
|
||||||
BOOL (MYIMAGEAPI * SymGetSymFromAddr)(
|
|
||||||
HANDLE hProcess,
|
|
||||||
DWORD Address,
|
|
||||||
LPDWORD Displacement,
|
|
||||||
PIMAGEHLP_SYMBOL Symbol
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
} using namespace Crash;
|
|
File diff suppressed because it is too large
Load Diff
@ -1,49 +0,0 @@
|
|||||||
/*==LICENSE==*
|
|
||||||
|
|
||||||
CyanWorlds.com Engine - MMOG client, server and tools
|
|
||||||
Copyright (C) 2011 Cyan Worlds, Inc.
|
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
Additional permissions under GNU GPL version 3 section 7
|
|
||||||
|
|
||||||
If you modify this Program, or any covered work, by linking or
|
|
||||||
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
|
|
||||||
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
|
|
||||||
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
|
|
||||||
(or a modified version of those libraries),
|
|
||||||
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
|
|
||||||
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
|
|
||||||
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
|
|
||||||
licensors of this Program grant you additional
|
|
||||||
permission to convey the resulting work. Corresponding Source for a
|
|
||||||
non-source form of such a combination shall include the source code for
|
|
||||||
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
|
|
||||||
work.
|
|
||||||
|
|
||||||
You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
|
||||||
or by snail mail at:
|
|
||||||
Cyan Worlds, Inc.
|
|
||||||
14617 N Newport Hwy
|
|
||||||
Mead, WA 99021
|
|
||||||
|
|
||||||
*==LICENSE==*/
|
|
||||||
/*****************************************************************************
|
|
||||||
*
|
|
||||||
* $/Plasma20/Sources/Plasma/NucleusLib/pnCrashExe/pnCreGui.cpp
|
|
||||||
*
|
|
||||||
***/
|
|
||||||
|
|
||||||
#include "../Pch.h"
|
|
||||||
#pragma hdrstop
|
|
@ -1,214 +0,0 @@
|
|||||||
/*==LICENSE==*
|
|
||||||
|
|
||||||
CyanWorlds.com Engine - MMOG client, server and tools
|
|
||||||
Copyright (C) 2011 Cyan Worlds, Inc.
|
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
Additional permissions under GNU GPL version 3 section 7
|
|
||||||
|
|
||||||
If you modify this Program, or any covered work, by linking or
|
|
||||||
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
|
|
||||||
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
|
|
||||||
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
|
|
||||||
(or a modified version of those libraries),
|
|
||||||
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
|
|
||||||
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
|
|
||||||
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
|
|
||||||
licensors of this Program grant you additional
|
|
||||||
permission to convey the resulting work. Corresponding Source for a
|
|
||||||
non-source form of such a combination shall include the source code for
|
|
||||||
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
|
|
||||||
work.
|
|
||||||
|
|
||||||
You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
|
||||||
or by snail mail at:
|
|
||||||
Cyan Worlds, Inc.
|
|
||||||
14617 N Newport Hwy
|
|
||||||
Mead, WA 99021
|
|
||||||
|
|
||||||
*==LICENSE==*/
|
|
||||||
/*****************************************************************************
|
|
||||||
*
|
|
||||||
* $/Plasma20/Sources/Plasma/NucleusLib/pnCrashExe/Win32/pnCreMail.cpp
|
|
||||||
*
|
|
||||||
***/
|
|
||||||
|
|
||||||
#include "../Pch.h"
|
|
||||||
#pragma hdrstop
|
|
||||||
|
|
||||||
|
|
||||||
//============================================================================
|
|
||||||
namespace Crash {
|
|
||||||
//============================================================================
|
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************************
|
|
||||||
*
|
|
||||||
* Local functions
|
|
||||||
*
|
|
||||||
***/
|
|
||||||
|
|
||||||
//============================================================================
|
|
||||||
static bool CreateInheritablePipe (
|
|
||||||
HANDLE * read,
|
|
||||||
HANDLE * write,
|
|
||||||
bool inheritRead
|
|
||||||
) {
|
|
||||||
// create pipe for std error read/write
|
|
||||||
if (!CreatePipe(read, write, (LPSECURITY_ATTRIBUTES) NULL, 0))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// make the appropriate handle inheritable
|
|
||||||
HANDLE hProcess = GetCurrentProcess();
|
|
||||||
HANDLE * inherit = inheritRead ? read : write;
|
|
||||||
bool result = DuplicateHandle(
|
|
||||||
hProcess,
|
|
||||||
*inherit,
|
|
||||||
hProcess,
|
|
||||||
inherit,
|
|
||||||
0,
|
|
||||||
true, // make inheritable
|
|
||||||
DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS
|
|
||||||
);
|
|
||||||
if (!result)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************************
|
|
||||||
*
|
|
||||||
* Module functions
|
|
||||||
*
|
|
||||||
***/
|
|
||||||
|
|
||||||
//============================================================================
|
|
||||||
void CrashSendEmail (
|
|
||||||
const char smtp[],
|
|
||||||
const char sender[],
|
|
||||||
const char recipients[],
|
|
||||||
const char replyTo[],
|
|
||||||
const char username[],
|
|
||||||
const char password[],
|
|
||||||
const char programName[],
|
|
||||||
const char errorType[],
|
|
||||||
const char logBuffer[]
|
|
||||||
) {
|
|
||||||
enum {
|
|
||||||
IN_CHILD,
|
|
||||||
IN_PARENT,
|
|
||||||
NUM_PIPES
|
|
||||||
};
|
|
||||||
|
|
||||||
unsigned i;
|
|
||||||
|
|
||||||
HANDLE pipes[NUM_PIPES];
|
|
||||||
for (i = 0; i < arrsize(pipes); ++i)
|
|
||||||
pipes[i] = INVALID_HANDLE_VALUE;
|
|
||||||
|
|
||||||
|
|
||||||
for (;;) {
|
|
||||||
// create pipes for Server -> StdIn -> Client
|
|
||||||
if (!CreateInheritablePipe(&pipes[IN_CHILD], &pipes[IN_PARENT], true))
|
|
||||||
break;
|
|
||||||
|
|
||||||
char subject[512];
|
|
||||||
StrPrintf(
|
|
||||||
subject,
|
|
||||||
arrsize(subject),
|
|
||||||
"\"[Crash] %s, %s\"",
|
|
||||||
programName,
|
|
||||||
errorType
|
|
||||||
);
|
|
||||||
|
|
||||||
char cmdLine[512];
|
|
||||||
StrPrintf(
|
|
||||||
cmdLine,
|
|
||||||
arrsize(cmdLine),
|
|
||||||
"plMail.exe -smtp %s -sender %s",
|
|
||||||
smtp,
|
|
||||||
sender
|
|
||||||
);
|
|
||||||
|
|
||||||
if (replyTo && replyTo[0]) {
|
|
||||||
StrPack(cmdLine, " -replyTo ", arrsize(cmdLine));
|
|
||||||
StrPack(cmdLine, replyTo, arrsize(cmdLine));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (username && username[0]) {
|
|
||||||
StrPack(cmdLine, " -u ", arrsize(cmdLine));
|
|
||||||
StrPack(cmdLine, username, arrsize(cmdLine));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (password && password[0]) {
|
|
||||||
StrPack(cmdLine, " -p ", arrsize(cmdLine));
|
|
||||||
StrPack(cmdLine, password, arrsize(cmdLine));
|
|
||||||
}
|
|
||||||
|
|
||||||
StrPack(cmdLine, " ", arrsize(cmdLine));
|
|
||||||
StrPack(cmdLine, recipients, arrsize(cmdLine));
|
|
||||||
|
|
||||||
StrPack(cmdLine, " ", arrsize(cmdLine));
|
|
||||||
StrPack(cmdLine, subject, arrsize(cmdLine));
|
|
||||||
|
|
||||||
// create process
|
|
||||||
STARTUPINFO si;
|
|
||||||
memset(&si, 0, sizeof(si));
|
|
||||||
si.cb = sizeof(si);
|
|
||||||
si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
|
|
||||||
si.wShowWindow = SW_HIDE;
|
|
||||||
si.hStdInput = pipes[IN_CHILD];
|
|
||||||
si.hStdOutput = INVALID_HANDLE_VALUE;
|
|
||||||
si.hStdError = INVALID_HANDLE_VALUE;
|
|
||||||
PROCESS_INFORMATION pi;
|
|
||||||
BOOL result = CreateProcess(
|
|
||||||
NULL,
|
|
||||||
cmdLine,
|
|
||||||
(LPSECURITY_ATTRIBUTES) NULL,
|
|
||||||
(LPSECURITY_ATTRIBUTES) NULL,
|
|
||||||
true, // => inherit handles
|
|
||||||
NORMAL_PRIORITY_CLASS,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
&si,
|
|
||||||
&pi
|
|
||||||
);
|
|
||||||
if (!result)
|
|
||||||
break;
|
|
||||||
|
|
||||||
CloseHandle(pi.hProcess);
|
|
||||||
CloseHandle(pi.hThread);
|
|
||||||
|
|
||||||
// Write output data
|
|
||||||
DWORD written, length = StrLen(logBuffer);
|
|
||||||
WriteFile(pipes[IN_PARENT], logBuffer, length, &written, NULL);
|
|
||||||
|
|
||||||
// complete
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// cleanup pipes
|
|
||||||
for (i = 0; i < arrsize(pipes); ++i) {
|
|
||||||
if (pipes[i] != INVALID_HANDLE_VALUE)
|
|
||||||
CloseHandle(pipes[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//============================================================================
|
|
||||||
} // namespace Crash
|
|
||||||
//============================================================================
|
|
@ -1,201 +0,0 @@
|
|||||||
/*==LICENSE==*
|
|
||||||
|
|
||||||
CyanWorlds.com Engine - MMOG client, server and tools
|
|
||||||
Copyright (C) 2011 Cyan Worlds, Inc.
|
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
Additional permissions under GNU GPL version 3 section 7
|
|
||||||
|
|
||||||
If you modify this Program, or any covered work, by linking or
|
|
||||||
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
|
|
||||||
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
|
|
||||||
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
|
|
||||||
(or a modified version of those libraries),
|
|
||||||
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
|
|
||||||
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
|
|
||||||
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
|
|
||||||
licensors of this Program grant you additional
|
|
||||||
permission to convey the resulting work. Corresponding Source for a
|
|
||||||
non-source form of such a combination shall include the source code for
|
|
||||||
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
|
|
||||||
work.
|
|
||||||
|
|
||||||
You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
|
||||||
or by snail mail at:
|
|
||||||
Cyan Worlds, Inc.
|
|
||||||
14617 N Newport Hwy
|
|
||||||
Mead, WA 99021
|
|
||||||
|
|
||||||
*==LICENSE==*/
|
|
||||||
/*****************************************************************************
|
|
||||||
*
|
|
||||||
* $/Plasma20/Sources/Plasma/NucleusLib/pnCrashExe/pnCreTools.cpp
|
|
||||||
*
|
|
||||||
***/
|
|
||||||
|
|
||||||
#include "../Pch.h"
|
|
||||||
#pragma hdrstop
|
|
||||||
|
|
||||||
|
|
||||||
//============================================================================
|
|
||||||
namespace Crash {
|
|
||||||
//============================================================================
|
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************************
|
|
||||||
*
|
|
||||||
* Internal functions
|
|
||||||
*
|
|
||||||
***/
|
|
||||||
|
|
||||||
//===========================================================================
|
|
||||||
static BOOL MYIMAGEAPI iSymGetModuleInfo (
|
|
||||||
HANDLE,
|
|
||||||
DWORD,
|
|
||||||
IMAGEHLP_MODULE * ModuleInfo
|
|
||||||
) {
|
|
||||||
memset(ModuleInfo, 0, sizeof(*ModuleInfo));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
//===========================================================================
|
|
||||||
static BOOL MYIMAGEAPI iStackWalk (
|
|
||||||
DWORD,
|
|
||||||
HANDLE,
|
|
||||||
HANDLE,
|
|
||||||
LPSTACKFRAME,
|
|
||||||
LPVOID,
|
|
||||||
PREAD_PROCESS_MEMORY_ROUTINE,
|
|
||||||
PFUNCTION_TABLE_ACCESS_ROUTINE,
|
|
||||||
PGET_MODULE_BASE_ROUTINE,
|
|
||||||
PTRANSLATE_ADDRESS_ROUTINE
|
|
||||||
) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
//===========================================================================
|
|
||||||
static LPVOID MYIMAGEAPI iSymFunctionTableAccess (
|
|
||||||
HANDLE,
|
|
||||||
DWORD
|
|
||||||
) {
|
|
||||||
return nil;
|
|
||||||
}
|
|
||||||
|
|
||||||
//===========================================================================
|
|
||||||
static DWORD MYIMAGEAPI iSymGetModuleBase (
|
|
||||||
HANDLE,
|
|
||||||
DWORD
|
|
||||||
) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
//===========================================================================
|
|
||||||
static BOOL MYIMAGEAPI iSymGetSymFromAddr (
|
|
||||||
HANDLE,
|
|
||||||
DWORD,
|
|
||||||
LPDWORD Displacement,
|
|
||||||
PIMAGEHLP_SYMBOL Symbol
|
|
||||||
) {
|
|
||||||
*Displacement = 0;
|
|
||||||
memset(Symbol, 0, sizeof(*Symbol));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************************
|
|
||||||
*
|
|
||||||
* CImageHelp
|
|
||||||
*
|
|
||||||
***/
|
|
||||||
|
|
||||||
//============================================================================
|
|
||||||
CImageHelp::CImageHelp (HINSTANCE instance)
|
|
||||||
: m_libInst(nil),
|
|
||||||
m_process(nil)
|
|
||||||
{
|
|
||||||
// get program directory and filename
|
|
||||||
if (!GetModuleFileNameA(instance, m_appPath, arrsize(m_appPath)))
|
|
||||||
m_appPath[0] = 0;
|
|
||||||
if (nil != (m_appName = StrChrR(m_appPath, '\\')))
|
|
||||||
*m_appName++ = '\0';
|
|
||||||
else
|
|
||||||
m_appName = m_appPath;
|
|
||||||
|
|
||||||
// initialize symbols
|
|
||||||
for (;;) {
|
|
||||||
if (nil == (m_libInst = LoadLibrary("ImageHlp.dll")))
|
|
||||||
break;
|
|
||||||
|
|
||||||
// initialize symbols for this process
|
|
||||||
BOOL (MYIMAGEAPI * SymInitialize)(HANDLE hProcess, char * path, BOOL fInvade);
|
|
||||||
* (FARPROC *) &SymInitialize = GetProcAddress(m_libInst, "SymInitialize");
|
|
||||||
if (!SymInitialize)
|
|
||||||
break;
|
|
||||||
|
|
||||||
HANDLE hProcess = GetCurrentProcess();
|
|
||||||
if (!SymInitialize(hProcess, m_appPath, false))
|
|
||||||
break;
|
|
||||||
|
|
||||||
// import functions
|
|
||||||
FARPROC proc;
|
|
||||||
#define BIND(x) * (FARPROC *) &(x) = ((proc = GetProcAddress(m_libInst, #x)) != nil) ? proc : (FARPROC) i##x
|
|
||||||
BIND(SymGetModuleInfo);
|
|
||||||
BIND(StackWalk);
|
|
||||||
BIND(SymFunctionTableAccess);
|
|
||||||
BIND(SymGetModuleBase);
|
|
||||||
BIND(SymGetSymFromAddr);
|
|
||||||
#undef BIND
|
|
||||||
|
|
||||||
// success
|
|
||||||
m_process = hProcess;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// failure!
|
|
||||||
if (m_libInst) {
|
|
||||||
FreeLibrary(m_libInst);
|
|
||||||
m_libInst = nil;
|
|
||||||
}
|
|
||||||
|
|
||||||
#define INIT(x) x = i##x
|
|
||||||
INIT(SymGetModuleInfo);
|
|
||||||
INIT(StackWalk);
|
|
||||||
INIT(SymFunctionTableAccess);
|
|
||||||
INIT(SymGetModuleBase);
|
|
||||||
INIT(SymGetSymFromAddr);
|
|
||||||
#undef INIT
|
|
||||||
}
|
|
||||||
|
|
||||||
//============================================================================
|
|
||||||
CImageHelp::~CImageHelp () {
|
|
||||||
if (m_process) {
|
|
||||||
BOOL (MYIMAGEAPI * SymCleanup)(HANDLE hProcess);
|
|
||||||
* (FARPROC *) &SymCleanup = GetProcAddress(m_libInst, "SymCleanup");
|
|
||||||
if (SymCleanup)
|
|
||||||
SymCleanup(m_process);
|
|
||||||
m_process = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_libInst) {
|
|
||||||
FreeLibrary(m_libInst);
|
|
||||||
m_libInst = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//============================================================================
|
|
||||||
} // namespace Crash
|
|
||||||
//============================================================================
|
|
@ -1,21 +0,0 @@
|
|||||||
include_directories("../../CoreLib")
|
|
||||||
include_directories("../../NucleusLib")
|
|
||||||
|
|
||||||
set(pnIni_HEADERS
|
|
||||||
Intern.h
|
|
||||||
Pch.h
|
|
||||||
pnIni.h
|
|
||||||
)
|
|
||||||
|
|
||||||
set(pnIni_PRIVATE
|
|
||||||
Private/pnIniAllIncludes.h
|
|
||||||
Private/pnIniChange.h
|
|
||||||
Private/pnIniCore.h
|
|
||||||
Private/pnIniCore.cpp
|
|
||||||
Private/pnIniSrv.h
|
|
||||||
)
|
|
||||||
|
|
||||||
add_library(pnIni STATIC ${pnIni_HEADERS} ${pnIni_PRIVATE})
|
|
||||||
|
|
||||||
source_group("Header Files" FILES ${pnIni_HEADERS})
|
|
||||||
source_group("Private" FILES ${pnIni_PRIVATE})
|
|
@ -1,101 +0,0 @@
|
|||||||
/*==LICENSE==*
|
|
||||||
|
|
||||||
CyanWorlds.com Engine - MMOG client, server and tools
|
|
||||||
Copyright (C) 2011 Cyan Worlds, Inc.
|
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
Additional permissions under GNU GPL version 3 section 7
|
|
||||||
|
|
||||||
If you modify this Program, or any covered work, by linking or
|
|
||||||
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
|
|
||||||
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
|
|
||||||
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
|
|
||||||
(or a modified version of those libraries),
|
|
||||||
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
|
|
||||||
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
|
|
||||||
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
|
|
||||||
licensors of this Program grant you additional
|
|
||||||
permission to convey the resulting work. Corresponding Source for a
|
|
||||||
non-source form of such a combination shall include the source code for
|
|
||||||
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
|
|
||||||
work.
|
|
||||||
|
|
||||||
You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
|
||||||
or by snail mail at:
|
|
||||||
Cyan Worlds, Inc.
|
|
||||||
14617 N Newport Hwy
|
|
||||||
Mead, WA 99021
|
|
||||||
|
|
||||||
*==LICENSE==*/
|
|
||||||
/*****************************************************************************
|
|
||||||
*
|
|
||||||
* $/Plasma20/Sources/Plasma/NucleusLib/pnIni/Intern.h
|
|
||||||
*
|
|
||||||
***/
|
|
||||||
|
|
||||||
#ifdef PLASMA20_SOURCES_PLASMA_NUCLEUSLIB_PNINI_INTERN_H
|
|
||||||
#error "Header $/Plasma20/Sources/Plasma/NucleusLib/pnIni/Intern.h included more than once"
|
|
||||||
#endif
|
|
||||||
#define PLASMA20_SOURCES_PLASMA_NUCLEUSLIB_PNINI_INTERN_H
|
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************************
|
|
||||||
*
|
|
||||||
* Ini
|
|
||||||
*
|
|
||||||
***/
|
|
||||||
|
|
||||||
struct IniValue {
|
|
||||||
ARRAY(wchar_t *) fArgs;
|
|
||||||
IniKey * fKey;
|
|
||||||
unsigned fIndex;
|
|
||||||
unsigned fLineNum;
|
|
||||||
|
|
||||||
IniValue (IniKey * key, unsigned lineNum);
|
|
||||||
~IniValue ();
|
|
||||||
};
|
|
||||||
|
|
||||||
struct IniKey {
|
|
||||||
HASHLINK(IniKey) fLink;
|
|
||||||
ARRAY(IniValue *) fValues;
|
|
||||||
IniSection * fSection;
|
|
||||||
wchar_t fName[1]; // variable length
|
|
||||||
// no more fields
|
|
||||||
|
|
||||||
IniKey (IniSection * section, const wchar_t name[]);
|
|
||||||
~IniKey ();
|
|
||||||
|
|
||||||
unsigned GetHash () const;
|
|
||||||
bool operator== (const CHashKeyStrPtrI & rhs) const;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct IniSection {
|
|
||||||
HASHTABLEDECL(IniKey, CHashKeyStrPtrI, fLink) fKeys;
|
|
||||||
HASHLINK(IniSection) fLink;
|
|
||||||
wchar_t fName[1]; // variable length
|
|
||||||
// no more fields
|
|
||||||
|
|
||||||
IniSection (const wchar_t name[]);
|
|
||||||
~IniSection ();
|
|
||||||
|
|
||||||
unsigned GetHash () const;
|
|
||||||
bool operator== (const CHashKeyStrPtrI & rhs) const;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Ini {
|
|
||||||
HASHTABLEDECL(IniSection, CHashKeyStrPtrI, fLink) fSections;
|
|
||||||
|
|
||||||
~Ini ();
|
|
||||||
};
|
|
@ -1,63 +0,0 @@
|
|||||||
/*==LICENSE==*
|
|
||||||
|
|
||||||
CyanWorlds.com Engine - MMOG client, server and tools
|
|
||||||
Copyright (C) 2011 Cyan Worlds, Inc.
|
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
Additional permissions under GNU GPL version 3 section 7
|
|
||||||
|
|
||||||
If you modify this Program, or any covered work, by linking or
|
|
||||||
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
|
|
||||||
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
|
|
||||||
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
|
|
||||||
(or a modified version of those libraries),
|
|
||||||
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
|
|
||||||
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
|
|
||||||
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
|
|
||||||
licensors of this Program grant you additional
|
|
||||||
permission to convey the resulting work. Corresponding Source for a
|
|
||||||
non-source form of such a combination shall include the source code for
|
|
||||||
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
|
|
||||||
work.
|
|
||||||
|
|
||||||
You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
|
||||||
or by snail mail at:
|
|
||||||
Cyan Worlds, Inc.
|
|
||||||
14617 N Newport Hwy
|
|
||||||
Mead, WA 99021
|
|
||||||
|
|
||||||
*==LICENSE==*/
|
|
||||||
/*****************************************************************************
|
|
||||||
*
|
|
||||||
* $/Plasma20/Sources/Plasma/NucleusLib/pnIni/Pch.h
|
|
||||||
*
|
|
||||||
***/
|
|
||||||
|
|
||||||
#ifdef PLASMA20_SOURCES_PLASMA_NUCLEUSLIB_PNINI_PCH_H
|
|
||||||
#error "Header $/Plasma20/Sources/Plasma/NucleusLib/pnIni/Pch.h included more than once"
|
|
||||||
#endif
|
|
||||||
#define PLASMA20_SOURCES_PLASMA_NUCLEUSLIB_PNINI_PCH_H
|
|
||||||
|
|
||||||
|
|
||||||
#include "pnUtils/pnUtils.h"
|
|
||||||
#include "pnProduct/pnProduct.h"
|
|
||||||
#include "pnNetBase/pnNetBase.h"
|
|
||||||
#include "pnAsyncCore/pnAsyncCore.h"
|
|
||||||
|
|
||||||
#include "Private/pnIniAllIncludes.h"
|
|
||||||
#include "Intern.h"
|
|
||||||
|
|
||||||
|
|
||||||
#include <malloc.h>
|
|
@ -1,56 +0,0 @@
|
|||||||
/*==LICENSE==*
|
|
||||||
|
|
||||||
CyanWorlds.com Engine - MMOG client, server and tools
|
|
||||||
Copyright (C) 2011 Cyan Worlds, Inc.
|
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
Additional permissions under GNU GPL version 3 section 7
|
|
||||||
|
|
||||||
If you modify this Program, or any covered work, by linking or
|
|
||||||
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
|
|
||||||
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
|
|
||||||
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
|
|
||||||
(or a modified version of those libraries),
|
|
||||||
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
|
|
||||||
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
|
|
||||||
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
|
|
||||||
licensors of this Program grant you additional
|
|
||||||
permission to convey the resulting work. Corresponding Source for a
|
|
||||||
non-source form of such a combination shall include the source code for
|
|
||||||
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
|
|
||||||
work.
|
|
||||||
|
|
||||||
You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
|
||||||
or by snail mail at:
|
|
||||||
Cyan Worlds, Inc.
|
|
||||||
14617 N Newport Hwy
|
|
||||||
Mead, WA 99021
|
|
||||||
|
|
||||||
*==LICENSE==*/
|
|
||||||
/*****************************************************************************
|
|
||||||
*
|
|
||||||
* $/Plasma20/Sources/Plasma/NucleusLib/pnIni/Private/pnIniAllIncludes.h
|
|
||||||
*
|
|
||||||
***/
|
|
||||||
|
|
||||||
#ifdef PLASMA20_SOURCES_PLASMA_NUCLEUSLIB_PNINI_PRIVATE_PNINIALLINCLUDES_H
|
|
||||||
#error "Header $/Plasma20/Sources/Plasma/NucleusLib/pnIni/Private/pnIniAllIncludes.h included more than once"
|
|
||||||
#endif
|
|
||||||
#define PLASMA20_SOURCES_PLASMA_NUCLEUSLIB_PNINI_PRIVATE_PNINIALLINCLUDES_H
|
|
||||||
|
|
||||||
|
|
||||||
#include "pnIniCore.h"
|
|
||||||
#include "pnIniChange.h"
|
|
||||||
#include "pnIniSrv.h"
|
|
@ -1,81 +0,0 @@
|
|||||||
/*==LICENSE==*
|
|
||||||
|
|
||||||
CyanWorlds.com Engine - MMOG client, server and tools
|
|
||||||
Copyright (C) 2011 Cyan Worlds, Inc.
|
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
Additional permissions under GNU GPL version 3 section 7
|
|
||||||
|
|
||||||
If you modify this Program, or any covered work, by linking or
|
|
||||||
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
|
|
||||||
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
|
|
||||||
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
|
|
||||||
(or a modified version of those libraries),
|
|
||||||
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
|
|
||||||
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
|
|
||||||
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
|
|
||||||
licensors of this Program grant you additional
|
|
||||||
permission to convey the resulting work. Corresponding Source for a
|
|
||||||
non-source form of such a combination shall include the source code for
|
|
||||||
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
|
|
||||||
work.
|
|
||||||
|
|
||||||
You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
|
||||||
or by snail mail at:
|
|
||||||
Cyan Worlds, Inc.
|
|
||||||
14617 N Newport Hwy
|
|
||||||
Mead, WA 99021
|
|
||||||
|
|
||||||
*==LICENSE==*/
|
|
||||||
/*****************************************************************************
|
|
||||||
*
|
|
||||||
* $/Plasma20/Sources/Plasma/NucleusLib/pnIni/Private/pnIniChange.h
|
|
||||||
*
|
|
||||||
***/
|
|
||||||
|
|
||||||
#ifdef PLASMA20_SOURCES_PLASMA_NUCLEUSLIB_PNINI_PRIVATE_PNINICHANGE_H
|
|
||||||
#error "Header $/Plasma20/Sources/Plasma/NucleusLib/pnIni/Private/pnIniChange.h included more than once"
|
|
||||||
#endif
|
|
||||||
#define PLASMA20_SOURCES_PLASMA_NUCLEUSLIB_PNINI_PRIVATE_PNINICHANGE_H
|
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************************
|
|
||||||
*
|
|
||||||
* Change notifications for files in the "./Config" directory
|
|
||||||
*
|
|
||||||
***/
|
|
||||||
|
|
||||||
struct IniChangeReg;
|
|
||||||
|
|
||||||
typedef void (* FIniFileChangeCallback)(const wchar_t fullPath[]);
|
|
||||||
|
|
||||||
void IniChangeInitialize (
|
|
||||||
const wchar_t dir[] = L"Config"
|
|
||||||
);
|
|
||||||
void IniChangeDestroy ();
|
|
||||||
|
|
||||||
void IniChangeAdd (
|
|
||||||
const wchar_t filename[], // just filename, no path or extension
|
|
||||||
FIniFileChangeCallback callback,
|
|
||||||
IniChangeReg ** reg
|
|
||||||
);
|
|
||||||
void IniChangeRemove (
|
|
||||||
IniChangeReg * reg,
|
|
||||||
bool wait
|
|
||||||
);
|
|
||||||
void IniChangeSignal (
|
|
||||||
IniChangeReg * reg,
|
|
||||||
bool wait
|
|
||||||
);
|
|
@ -1,785 +0,0 @@
|
|||||||
/*==LICENSE==*
|
|
||||||
|
|
||||||
CyanWorlds.com Engine - MMOG client, server and tools
|
|
||||||
Copyright (C) 2011 Cyan Worlds, Inc.
|
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
Additional permissions under GNU GPL version 3 section 7
|
|
||||||
|
|
||||||
If you modify this Program, or any covered work, by linking or
|
|
||||||
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
|
|
||||||
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
|
|
||||||
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
|
|
||||||
(or a modified version of those libraries),
|
|
||||||
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
|
|
||||||
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
|
|
||||||
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
|
|
||||||
licensors of this Program grant you additional
|
|
||||||
permission to convey the resulting work. Corresponding Source for a
|
|
||||||
non-source form of such a combination shall include the source code for
|
|
||||||
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
|
|
||||||
work.
|
|
||||||
|
|
||||||
You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
|
||||||
or by snail mail at:
|
|
||||||
Cyan Worlds, Inc.
|
|
||||||
14617 N Newport Hwy
|
|
||||||
Mead, WA 99021
|
|
||||||
|
|
||||||
*==LICENSE==*/
|
|
||||||
/*****************************************************************************
|
|
||||||
*
|
|
||||||
* $/Plasma20/Sources/Plasma/NucleusLib/pnIni/Private/pnIniCore.cpp
|
|
||||||
*
|
|
||||||
***/
|
|
||||||
|
|
||||||
#include "../Pch.h"
|
|
||||||
#pragma hdrstop
|
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************************
|
|
||||||
*
|
|
||||||
* Internal functions
|
|
||||||
*
|
|
||||||
***/
|
|
||||||
|
|
||||||
//===========================================================================
|
|
||||||
static wchar_t * TrimWhitespace (wchar_t * name) {
|
|
||||||
while (isspace((char) *name))
|
|
||||||
++name;
|
|
||||||
|
|
||||||
for (wchar_t * term = name; *term; ++term) {
|
|
||||||
if (isspace((char) *term)) {
|
|
||||||
*term = 0;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
*
|
|
||||||
* IniValue
|
|
||||||
*
|
|
||||||
***/
|
|
||||||
|
|
||||||
//===========================================================================
|
|
||||||
IniValue::IniValue (IniKey * key, unsigned lineNum)
|
|
||||||
: fKey(key)
|
|
||||||
, fLineNum(lineNum)
|
|
||||||
{
|
|
||||||
fIndex = key->fValues.Add(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
//===========================================================================
|
|
||||||
IniValue::~IniValue () {
|
|
||||||
wchar_t ** cur = fArgs.Ptr();
|
|
||||||
wchar_t ** end = fArgs.Term();
|
|
||||||
for (; cur < end; ++cur)
|
|
||||||
free(*cur);
|
|
||||||
}
|
|
||||||
|
|
||||||
//===========================================================================
|
|
||||||
static void AddValueString (
|
|
||||||
IniValue * value,
|
|
||||||
const wchar_t src[]
|
|
||||||
) {
|
|
||||||
unsigned chars = StrLen(src) + 1;
|
|
||||||
wchar_t * dst = (wchar_t*)malloc(sizeof(wchar_t) * chars);
|
|
||||||
StrTokenize(&src, dst, chars, L" \t\r\n\"");
|
|
||||||
value->fArgs.Add(StrDup(dst));
|
|
||||||
|
|
||||||
free(dst);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
*
|
|
||||||
* IniKey
|
|
||||||
*
|
|
||||||
***/
|
|
||||||
|
|
||||||
//===========================================================================
|
|
||||||
IniKey::IniKey (IniSection * section, const wchar_t name[])
|
|
||||||
: fSection(section)
|
|
||||||
{
|
|
||||||
StrCopy(fName, name, (unsigned) -1);
|
|
||||||
fSection->fKeys.Add(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
//===========================================================================
|
|
||||||
IniKey::~IniKey () {
|
|
||||||
IniValue ** cur = fValues.Ptr();
|
|
||||||
IniValue ** end = fValues.Term();
|
|
||||||
for (; cur < end; ++cur)
|
|
||||||
delete *cur;
|
|
||||||
}
|
|
||||||
|
|
||||||
//===========================================================================
|
|
||||||
inline unsigned IniKey::GetHash () const {
|
|
||||||
return StrHashI(fName);
|
|
||||||
}
|
|
||||||
|
|
||||||
//===========================================================================
|
|
||||||
inline bool IniKey::operator== (const CHashKeyStrPtrI & rhs) const {
|
|
||||||
return !StrCmpI(fName, rhs.GetString());
|
|
||||||
}
|
|
||||||
|
|
||||||
//===========================================================================
|
|
||||||
static IniValue * AddKeyValue (
|
|
||||||
IniSection * section,
|
|
||||||
wchar_t * string,
|
|
||||||
unsigned lineNum
|
|
||||||
) {
|
|
||||||
string = TrimWhitespace(string);
|
|
||||||
|
|
||||||
// Find or create the key
|
|
||||||
IniKey * key = section->fKeys.Find(string);
|
|
||||||
if (!key) {
|
|
||||||
key = new(malloc(
|
|
||||||
sizeof(*key) - sizeof(key->fName) + StrBytes(string)
|
|
||||||
)) IniKey(section, string);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add a new value holder for the key
|
|
||||||
return new IniValue(key, lineNum);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
*
|
|
||||||
* IniSection
|
|
||||||
*
|
|
||||||
***/
|
|
||||||
|
|
||||||
//===========================================================================
|
|
||||||
IniSection::IniSection (const wchar_t name[]) {
|
|
||||||
StrCopy(fName, name, (unsigned) -1);
|
|
||||||
}
|
|
||||||
|
|
||||||
//===========================================================================
|
|
||||||
IniSection::~IniSection () {
|
|
||||||
fKeys.Clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
//===========================================================================
|
|
||||||
inline unsigned IniSection::GetHash () const {
|
|
||||||
return StrHashI(fName);
|
|
||||||
}
|
|
||||||
|
|
||||||
//===========================================================================
|
|
||||||
inline bool IniSection::operator== (const CHashKeyStrPtrI & rhs) const {
|
|
||||||
return !StrCmpI(fName, rhs.GetString());
|
|
||||||
}
|
|
||||||
|
|
||||||
//===========================================================================
|
|
||||||
static IniSection * AddSection (
|
|
||||||
Ini * ini,
|
|
||||||
wchar_t * string
|
|
||||||
) {
|
|
||||||
// Find or create the section
|
|
||||||
IniSection * section = ini->fSections.Find(string);
|
|
||||||
if (!section) {
|
|
||||||
section = new(malloc(
|
|
||||||
sizeof(*section) - sizeof(section->fName) + StrBytes(string)
|
|
||||||
)) IniSection(string);
|
|
||||||
ini->fSections.Add(section);
|
|
||||||
}
|
|
||||||
return section;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
*
|
|
||||||
* Ini
|
|
||||||
*
|
|
||||||
***/
|
|
||||||
|
|
||||||
//===========================================================================
|
|
||||||
Ini::~Ini () {
|
|
||||||
fSections.Clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
*
|
|
||||||
* ParseBuffer
|
|
||||||
*
|
|
||||||
***/
|
|
||||||
|
|
||||||
//===========================================================================
|
|
||||||
static void ParseBuffer (
|
|
||||||
Ini * ini,
|
|
||||||
const wchar_t buffer[]
|
|
||||||
) {
|
|
||||||
|
|
||||||
const wchar_t SECTION_OPEN_CHAR = '[';
|
|
||||||
const wchar_t SECTION_CLOSE_CHAR = ']';
|
|
||||||
const wchar_t EQUIVALENCE_CHAR = '=';
|
|
||||||
const wchar_t VALUE_SEPARATOR = ',';
|
|
||||||
const wchar_t COMMENT_CHAR = ';';
|
|
||||||
const wchar_t QUOTE_CHAR = '\"';
|
|
||||||
const wchar_t NEWLINE = '\n';
|
|
||||||
|
|
||||||
enum {
|
|
||||||
STATE_BEGIN,
|
|
||||||
STATE_NEWLINE,
|
|
||||||
STATE_SECTION,
|
|
||||||
STATE_STRIP_TRAILING,
|
|
||||||
STATE_KEY,
|
|
||||||
STATE_VALUE,
|
|
||||||
} state = STATE_BEGIN;
|
|
||||||
|
|
||||||
IniSection * section = nil;
|
|
||||||
IniValue * value = nil;
|
|
||||||
const wchar_t * start = nil;
|
|
||||||
bool valInQuotes = false;
|
|
||||||
wchar_t dst[512];
|
|
||||||
dst[0] = 0;
|
|
||||||
|
|
||||||
for (unsigned lineNum = 1;; ++buffer) {
|
|
||||||
|
|
||||||
// Get next character
|
|
||||||
unsigned chr = *buffer;
|
|
||||||
if (!chr)
|
|
||||||
break;
|
|
||||||
if (chr == '\r')
|
|
||||||
continue;
|
|
||||||
if (chr == '\n')
|
|
||||||
++lineNum;
|
|
||||||
if (chr == '\t')
|
|
||||||
chr = ' ';
|
|
||||||
|
|
||||||
switch (state) {
|
|
||||||
case STATE_BEGIN:
|
|
||||||
ASSERT(chr == UNICODE_BOM);
|
|
||||||
state = STATE_NEWLINE;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case STATE_NEWLINE:
|
|
||||||
if (chr == NEWLINE)
|
|
||||||
break;
|
|
||||||
if (chr == ' ')
|
|
||||||
break;
|
|
||||||
if (chr == SECTION_OPEN_CHAR) {
|
|
||||||
start = buffer + 1;
|
|
||||||
state = STATE_SECTION;
|
|
||||||
}
|
|
||||||
else if (chr == COMMENT_CHAR) {
|
|
||||||
state = STATE_STRIP_TRAILING;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
start = buffer;
|
|
||||||
state = STATE_KEY;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case STATE_SECTION:
|
|
||||||
if (chr == NEWLINE) {
|
|
||||||
state = STATE_NEWLINE;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (chr == SECTION_CLOSE_CHAR) {
|
|
||||||
StrCopy(dst, start, min((unsigned long)(buffer - start + 1), arrsize(dst)));
|
|
||||||
section = AddSection(ini, dst);
|
|
||||||
state = STATE_STRIP_TRAILING;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case STATE_STRIP_TRAILING:
|
|
||||||
if (chr == NEWLINE)
|
|
||||||
state = STATE_NEWLINE;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case STATE_KEY:
|
|
||||||
if (chr == NEWLINE) {
|
|
||||||
state = STATE_NEWLINE;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (chr != EQUIVALENCE_CHAR)
|
|
||||||
break;
|
|
||||||
|
|
||||||
if (!section) {
|
|
||||||
state = STATE_STRIP_TRAILING;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
StrCopy(dst, start, min((unsigned long)(buffer - start + 1), arrsize(dst)));
|
|
||||||
value = AddKeyValue(section, dst, lineNum);
|
|
||||||
start = buffer + 1;
|
|
||||||
state = STATE_VALUE;
|
|
||||||
valInQuotes = false;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case STATE_VALUE:
|
|
||||||
if (chr == QUOTE_CHAR)
|
|
||||||
valInQuotes = !valInQuotes;
|
|
||||||
if ((valInQuotes || chr != VALUE_SEPARATOR) && (chr != NEWLINE))
|
|
||||||
break;
|
|
||||||
if (!value) {
|
|
||||||
state = chr == NEWLINE ? STATE_NEWLINE : STATE_STRIP_TRAILING;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (valInQuotes) {
|
|
||||||
state = chr == NEWLINE ? STATE_NEWLINE : STATE_STRIP_TRAILING;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
StrCopy(dst, start, min((unsigned long)(buffer - start + 1), arrsize(dst)));
|
|
||||||
AddValueString(value, dst);
|
|
||||||
if (chr == VALUE_SEPARATOR)
|
|
||||||
start = buffer + 1;
|
|
||||||
else
|
|
||||||
state = STATE_NEWLINE;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// cleanup current value
|
|
||||||
if (state == STATE_VALUE) {
|
|
||||||
StrCopy(dst, start, min((unsigned long)(buffer - start + 1), arrsize(dst)));
|
|
||||||
AddValueString(value, dst);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
*
|
|
||||||
* ParseFile
|
|
||||||
*
|
|
||||||
***/
|
|
||||||
|
|
||||||
//===========================================================================
|
|
||||||
static void IniFileNotifyProc (
|
|
||||||
AsyncFile ,
|
|
||||||
EAsyncNotifyFile ,
|
|
||||||
AsyncNotifyFile * ,
|
|
||||||
void **
|
|
||||||
) {
|
|
||||||
}
|
|
||||||
|
|
||||||
//===========================================================================
|
|
||||||
static bool ParseFile (
|
|
||||||
Ini * ini,
|
|
||||||
const wchar_t fileName[]
|
|
||||||
) {
|
|
||||||
// Open file
|
|
||||||
uint64_t fileSize;
|
|
||||||
uint64_t fileLastWriteTime;
|
|
||||||
EFileError error;
|
|
||||||
AsyncFile file = AsyncFileOpen(
|
|
||||||
fileName,
|
|
||||||
IniFileNotifyProc,
|
|
||||||
&error,
|
|
||||||
kAsyncFileReadAccess,
|
|
||||||
kAsyncFileModeOpenExisting,
|
|
||||||
kAsyncFileShareRead,
|
|
||||||
nil,
|
|
||||||
&fileSize,
|
|
||||||
&fileLastWriteTime
|
|
||||||
);
|
|
||||||
if (!file)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
bool result;
|
|
||||||
if (fileSize > 256 * 1024) {
|
|
||||||
result = false;
|
|
||||||
}
|
|
||||||
else if (!fileSize) {
|
|
||||||
result = true;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// Read entire file into memory and NULL terminate wchar_t
|
|
||||||
uint8_t * buffer = (uint8_t *) malloc((unsigned) fileSize + sizeof(wchar_t));
|
|
||||||
AsyncFileRead(file, 0, buffer, (unsigned) fileSize, kAsyncFileRwSync, nil);
|
|
||||||
* (wchar_t *) &buffer[fileSize] = 0;
|
|
||||||
|
|
||||||
// Convert to unicode if necessary
|
|
||||||
if (* (wchar_t *) buffer != UNICODE_BOM) {
|
|
||||||
uint8_t * src = buffer;
|
|
||||||
// Allocate two extra spaces for UNICODE_BOM and terminator
|
|
||||||
unsigned newBufferSize = ((unsigned) fileSize + 2) * sizeof(wchar_t);
|
|
||||||
|
|
||||||
// Allocate new buffer
|
|
||||||
wchar_t * dst = (wchar_t *) malloc(newBufferSize);
|
|
||||||
|
|
||||||
// If it's UTF-8 file,convert to Unicode
|
|
||||||
if (StrCmpI((char *)buffer, UTF8_BOM, StrLen(UTF8_BOM)) == 0) {
|
|
||||||
// StrUtf8ToUnicode will convert UTF8_BOM to UNICODE_BOM
|
|
||||||
StrUtf8ToUnicode(dst, (char *)src, newBufferSize);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// do simple conversion to Unicode
|
|
||||||
dst[0] = UNICODE_BOM;
|
|
||||||
for (unsigned index = 0;; ++index) {
|
|
||||||
if (0 == (dst[index + 1] = src[index]))
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
free(src);
|
|
||||||
buffer = (uint8_t *) dst;
|
|
||||||
}
|
|
||||||
|
|
||||||
ParseBuffer(ini, (const wchar_t *) buffer);
|
|
||||||
free(buffer);
|
|
||||||
result = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
AsyncFileClose(file, kAsyncFileDontTruncate);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************************
|
|
||||||
*
|
|
||||||
* Exports
|
|
||||||
*
|
|
||||||
***/
|
|
||||||
|
|
||||||
//===========================================================================
|
|
||||||
Ini * IniOpen (
|
|
||||||
const wchar_t fileName[]
|
|
||||||
) {
|
|
||||||
Ini * ini = new Ini;
|
|
||||||
if (!ParseFile(ini, fileName)) {
|
|
||||||
IniClose(ini);
|
|
||||||
return nil;
|
|
||||||
}
|
|
||||||
return ini;
|
|
||||||
}
|
|
||||||
|
|
||||||
//===========================================================================
|
|
||||||
void IniClose (Ini * ini) {
|
|
||||||
delete ini;
|
|
||||||
}
|
|
||||||
|
|
||||||
//===========================================================================
|
|
||||||
const IniSection * IniGetFirstSection (
|
|
||||||
const Ini * ini,
|
|
||||||
wchar_t * name,
|
|
||||||
unsigned chars
|
|
||||||
) {
|
|
||||||
if (chars)
|
|
||||||
*name = 0;
|
|
||||||
if (!ini)
|
|
||||||
return nil;
|
|
||||||
|
|
||||||
const IniSection * section = ini->fSections.Head();
|
|
||||||
if (section)
|
|
||||||
StrCopy(name, section->fName, chars);
|
|
||||||
return section;
|
|
||||||
}
|
|
||||||
|
|
||||||
//===========================================================================
|
|
||||||
const IniSection * IniGetNextSection (
|
|
||||||
const IniSection * section,
|
|
||||||
wchar_t * name,
|
|
||||||
unsigned chars
|
|
||||||
) {
|
|
||||||
if (chars)
|
|
||||||
*name = 0;
|
|
||||||
if (!section)
|
|
||||||
return nil;
|
|
||||||
|
|
||||||
section = section->fLink.Next();
|
|
||||||
if (section)
|
|
||||||
StrCopy(name, section->fName, chars);
|
|
||||||
return section;
|
|
||||||
}
|
|
||||||
|
|
||||||
//===========================================================================
|
|
||||||
const IniSection * IniGetSection (
|
|
||||||
const Ini * ini,
|
|
||||||
const wchar_t name[]
|
|
||||||
) {
|
|
||||||
if (!ini)
|
|
||||||
return nil;
|
|
||||||
|
|
||||||
return ini->fSections.Find(
|
|
||||||
CHashKeyStrPtrI(name)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
//===========================================================================
|
|
||||||
const IniKey * IniGetFirstKey (
|
|
||||||
const IniSection * section,
|
|
||||||
wchar_t * name,
|
|
||||||
unsigned chars
|
|
||||||
) {
|
|
||||||
if (chars)
|
|
||||||
*name = 0;
|
|
||||||
if (!section)
|
|
||||||
return nil;
|
|
||||||
|
|
||||||
const IniKey * key = section->fKeys.Head();
|
|
||||||
if (key)
|
|
||||||
StrCopy(name, key->fName, chars);
|
|
||||||
return key;
|
|
||||||
}
|
|
||||||
|
|
||||||
//============================================================================
|
|
||||||
const IniKey * IniGetFirstKey (
|
|
||||||
const Ini * ini,
|
|
||||||
const wchar_t sectionName[],
|
|
||||||
wchar_t * name,
|
|
||||||
unsigned chars
|
|
||||||
) {
|
|
||||||
if (const IniSection * section = IniGetSection(ini, sectionName))
|
|
||||||
return IniGetFirstKey(section, name, chars);
|
|
||||||
|
|
||||||
return nil;
|
|
||||||
}
|
|
||||||
|
|
||||||
//===========================================================================
|
|
||||||
const IniKey * IniGetNextKey (
|
|
||||||
const IniKey * key,
|
|
||||||
wchar_t * name,
|
|
||||||
unsigned chars
|
|
||||||
) {
|
|
||||||
if (chars)
|
|
||||||
*name = 0;
|
|
||||||
if (!key)
|
|
||||||
return nil;
|
|
||||||
|
|
||||||
key = key->fLink.Next();
|
|
||||||
if (key)
|
|
||||||
StrCopy(name, key->fName, chars);
|
|
||||||
return key;
|
|
||||||
}
|
|
||||||
|
|
||||||
//===========================================================================
|
|
||||||
const IniKey * IniGetKey (
|
|
||||||
const IniSection * section,
|
|
||||||
const wchar_t name[]
|
|
||||||
) {
|
|
||||||
if (!section)
|
|
||||||
return nil;
|
|
||||||
|
|
||||||
return section->fKeys.Find(
|
|
||||||
CHashKeyStrPtrI(name)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
//===========================================================================
|
|
||||||
const IniValue * IniGetFirstValue (
|
|
||||||
const IniKey * key,
|
|
||||||
unsigned * lineNum
|
|
||||||
) {
|
|
||||||
if (lineNum)
|
|
||||||
*lineNum = 0;
|
|
||||||
|
|
||||||
const IniValue * value = nil;
|
|
||||||
for (;;) {
|
|
||||||
if (!key)
|
|
||||||
break;
|
|
||||||
|
|
||||||
value = key->fValues[0];
|
|
||||||
if (lineNum)
|
|
||||||
*lineNum = value->fLineNum;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
//===========================================================================
|
|
||||||
const IniValue * IniGetFirstValue (
|
|
||||||
const IniSection * section,
|
|
||||||
const wchar_t keyName[],
|
|
||||||
unsigned * lineNum
|
|
||||||
) {
|
|
||||||
const IniValue * value = nil;
|
|
||||||
if (lineNum)
|
|
||||||
*lineNum = 0;
|
|
||||||
|
|
||||||
for (;;) {
|
|
||||||
if (!section)
|
|
||||||
break;
|
|
||||||
|
|
||||||
const IniKey * key = section->fKeys.Find(
|
|
||||||
CHashKeyStrPtrI(keyName)
|
|
||||||
);
|
|
||||||
value = IniGetFirstValue(key, lineNum);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
//===========================================================================
|
|
||||||
const IniValue * IniGetFirstValue (
|
|
||||||
const Ini * ini,
|
|
||||||
const wchar_t sectionName[],
|
|
||||||
const wchar_t keyName[],
|
|
||||||
unsigned * lineNum
|
|
||||||
) {
|
|
||||||
const IniValue * value = nil;
|
|
||||||
if (lineNum)
|
|
||||||
*lineNum = 0;
|
|
||||||
|
|
||||||
for (;;) {
|
|
||||||
if (!ini)
|
|
||||||
break;
|
|
||||||
|
|
||||||
const IniSection * section = ini->fSections.Find(
|
|
||||||
CHashKeyStrPtrI(sectionName)
|
|
||||||
);
|
|
||||||
|
|
||||||
value = IniGetFirstValue(section, keyName, lineNum);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
//===========================================================================
|
|
||||||
const IniValue * IniGetNextValue (
|
|
||||||
const IniValue * value,
|
|
||||||
unsigned * lineNum
|
|
||||||
) {
|
|
||||||
if (lineNum)
|
|
||||||
*lineNum = 0;
|
|
||||||
|
|
||||||
const IniKey * key = value->fKey;
|
|
||||||
if (value->fIndex + 1 < key->fValues.Count()) {
|
|
||||||
value = key->fValues[value->fIndex + 1];
|
|
||||||
if (lineNum)
|
|
||||||
*lineNum = value->fLineNum;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
value = nil;
|
|
||||||
}
|
|
||||||
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
//===========================================================================
|
|
||||||
bool IniGetUnsigned (
|
|
||||||
const IniValue * value,
|
|
||||||
unsigned * result,
|
|
||||||
unsigned index,
|
|
||||||
unsigned defaultValue
|
|
||||||
) {
|
|
||||||
ASSERT(result);
|
|
||||||
|
|
||||||
for (;;) {
|
|
||||||
if (!value)
|
|
||||||
break;
|
|
||||||
|
|
||||||
wchar_t str[32];
|
|
||||||
if (!IniGetString(value, str, arrsize(str), index, nil))
|
|
||||||
break;
|
|
||||||
|
|
||||||
if (!str[0])
|
|
||||||
break;
|
|
||||||
|
|
||||||
*result = StrToUnsigned(str, nil, 0);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
*result = defaultValue;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
//===========================================================================
|
|
||||||
bool IniGetString (
|
|
||||||
const IniValue * value,
|
|
||||||
wchar_t * result,
|
|
||||||
unsigned resultChars,
|
|
||||||
unsigned index,
|
|
||||||
const wchar_t defaultValue[]
|
|
||||||
) {
|
|
||||||
ASSERT(result);
|
|
||||||
|
|
||||||
bool found = value && index < value->fArgs.Count();
|
|
||||||
|
|
||||||
if (found)
|
|
||||||
StrCopy(result, value->fArgs[index], resultChars);
|
|
||||||
else if (defaultValue)
|
|
||||||
StrCopy(result, defaultValue, resultChars);
|
|
||||||
|
|
||||||
return found;
|
|
||||||
}
|
|
||||||
|
|
||||||
//===========================================================================
|
|
||||||
bool IniGetUuid (
|
|
||||||
const IniValue * value,
|
|
||||||
Uuid * uuid,
|
|
||||||
unsigned index,
|
|
||||||
const Uuid & defaultValue
|
|
||||||
) {
|
|
||||||
wchar_t str[128];
|
|
||||||
if (IniGetString(value, str, arrsize(str), index, nil))
|
|
||||||
return GuidFromString(str, uuid);
|
|
||||||
else
|
|
||||||
*uuid = defaultValue;
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
//===========================================================================
|
|
||||||
unsigned IniGetBoundedValue (
|
|
||||||
const IniValue * value,
|
|
||||||
const wchar_t section[],
|
|
||||||
const wchar_t key[],
|
|
||||||
unsigned index,
|
|
||||||
unsigned minVal,
|
|
||||||
unsigned maxVal,
|
|
||||||
unsigned defVal
|
|
||||||
) {
|
|
||||||
if (!value)
|
|
||||||
return defVal;
|
|
||||||
|
|
||||||
unsigned result;
|
|
||||||
IniGetUnsigned(value, &result, index, defVal);
|
|
||||||
if ((result < minVal) || (result > maxVal)) {
|
|
||||||
result = defVal;
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
//===========================================================================
|
|
||||||
unsigned IniGetBoundedValue (
|
|
||||||
const Ini * ini,
|
|
||||||
const wchar_t section[],
|
|
||||||
const wchar_t key[],
|
|
||||||
unsigned index,
|
|
||||||
unsigned minVal,
|
|
||||||
unsigned maxVal,
|
|
||||||
unsigned defVal
|
|
||||||
) {
|
|
||||||
unsigned lineNum;
|
|
||||||
const IniValue * value = IniGetFirstValue(
|
|
||||||
ini,
|
|
||||||
section,
|
|
||||||
key,
|
|
||||||
&lineNum
|
|
||||||
);
|
|
||||||
|
|
||||||
return IniGetBoundedValue(
|
|
||||||
value,
|
|
||||||
section,
|
|
||||||
key,
|
|
||||||
index,
|
|
||||||
minVal,
|
|
||||||
maxVal,
|
|
||||||
defVal
|
|
||||||
);
|
|
||||||
}
|
|
@ -1,170 +0,0 @@
|
|||||||
/*==LICENSE==*
|
|
||||||
|
|
||||||
CyanWorlds.com Engine - MMOG client, server and tools
|
|
||||||
Copyright (C) 2011 Cyan Worlds, Inc.
|
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
Additional permissions under GNU GPL version 3 section 7
|
|
||||||
|
|
||||||
If you modify this Program, or any covered work, by linking or
|
|
||||||
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
|
|
||||||
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
|
|
||||||
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
|
|
||||||
(or a modified version of those libraries),
|
|
||||||
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
|
|
||||||
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
|
|
||||||
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
|
|
||||||
licensors of this Program grant you additional
|
|
||||||
permission to convey the resulting work. Corresponding Source for a
|
|
||||||
non-source form of such a combination shall include the source code for
|
|
||||||
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
|
|
||||||
work.
|
|
||||||
|
|
||||||
You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
|
||||||
or by snail mail at:
|
|
||||||
Cyan Worlds, Inc.
|
|
||||||
14617 N Newport Hwy
|
|
||||||
Mead, WA 99021
|
|
||||||
|
|
||||||
*==LICENSE==*/
|
|
||||||
/*****************************************************************************
|
|
||||||
*
|
|
||||||
* $/Plasma20/Sources/Plasma/NucleusLib/pnIni/Private/pnIniCore.h
|
|
||||||
*
|
|
||||||
***/
|
|
||||||
|
|
||||||
#ifdef PLASMA20_SOURCES_PLASMA_NUCLEUSLIB_PNINI_PRIVATE_PNINICORE_H
|
|
||||||
#error "Header $/Plasma20/Sources/Plasma/NucleusLib/pnIni/Private/pnIniCore.h included more than once"
|
|
||||||
#endif
|
|
||||||
#define PLASMA20_SOURCES_PLASMA_NUCLEUSLIB_PNINI_PRIVATE_PNINICORE_H
|
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************************
|
|
||||||
*
|
|
||||||
* Ini file parsing functions
|
|
||||||
*
|
|
||||||
***/
|
|
||||||
|
|
||||||
struct Ini;
|
|
||||||
struct IniKey;
|
|
||||||
struct IniValue;
|
|
||||||
struct IniSection;
|
|
||||||
|
|
||||||
|
|
||||||
// File
|
|
||||||
Ini * IniOpen (
|
|
||||||
const wchar_t filename[]
|
|
||||||
);
|
|
||||||
void IniClose (
|
|
||||||
Ini * ini
|
|
||||||
);
|
|
||||||
|
|
||||||
// Section
|
|
||||||
const IniSection * IniGetFirstSection (
|
|
||||||
const Ini * ini,
|
|
||||||
wchar_t * name,
|
|
||||||
unsigned chars
|
|
||||||
);
|
|
||||||
const IniSection * IniGetNextSection (
|
|
||||||
const IniSection * section,
|
|
||||||
wchar_t * name,
|
|
||||||
unsigned chars
|
|
||||||
);
|
|
||||||
const IniSection * IniGetSection (
|
|
||||||
const Ini * ini,
|
|
||||||
const wchar_t name[]
|
|
||||||
);
|
|
||||||
|
|
||||||
// Key
|
|
||||||
const IniKey * IniGetFirstKey (
|
|
||||||
const IniSection * section,
|
|
||||||
wchar_t * name,
|
|
||||||
unsigned chars
|
|
||||||
);
|
|
||||||
const IniKey * IniGetFirstKey (
|
|
||||||
const Ini * ini,
|
|
||||||
const wchar_t sectionName[],
|
|
||||||
wchar_t * name,
|
|
||||||
unsigned chars
|
|
||||||
);
|
|
||||||
const IniKey * IniGetNextKey (
|
|
||||||
const IniKey * key,
|
|
||||||
wchar_t * name,
|
|
||||||
unsigned chars
|
|
||||||
);
|
|
||||||
const IniKey * IniGetKey (
|
|
||||||
const IniSection * ini,
|
|
||||||
const wchar_t name[]
|
|
||||||
);
|
|
||||||
|
|
||||||
// Value
|
|
||||||
const IniValue * IniGetFirstValue (
|
|
||||||
const IniKey * key,
|
|
||||||
unsigned * iter
|
|
||||||
);
|
|
||||||
const IniValue * IniGetFirstValue (
|
|
||||||
const IniSection * section,
|
|
||||||
const wchar_t keyName[],
|
|
||||||
unsigned * iter
|
|
||||||
);
|
|
||||||
const IniValue * IniGetFirstValue (
|
|
||||||
const Ini * ini,
|
|
||||||
const wchar_t sectionName[],
|
|
||||||
const wchar_t keyName[],
|
|
||||||
unsigned * iter
|
|
||||||
);
|
|
||||||
const IniValue * IniGetNextValue (
|
|
||||||
const IniValue * value,
|
|
||||||
unsigned * iter
|
|
||||||
);
|
|
||||||
|
|
||||||
// Data
|
|
||||||
bool IniGetUnsigned (
|
|
||||||
const IniValue * value,
|
|
||||||
unsigned * result,
|
|
||||||
unsigned index = 0,
|
|
||||||
unsigned defaultValue = 0
|
|
||||||
);
|
|
||||||
bool IniGetString (
|
|
||||||
const IniValue * value,
|
|
||||||
wchar_t * result,
|
|
||||||
unsigned resultChars,
|
|
||||||
unsigned index = 0,
|
|
||||||
const wchar_t defaultValue[] = nil
|
|
||||||
);
|
|
||||||
bool IniGetUuid (
|
|
||||||
const IniValue * value,
|
|
||||||
Uuid * result,
|
|
||||||
unsigned index = 0,
|
|
||||||
const Uuid & defaultValue = kNilGuid
|
|
||||||
);
|
|
||||||
|
|
||||||
// Bounded values
|
|
||||||
unsigned IniGetBoundedValue (
|
|
||||||
const Ini * ini,
|
|
||||||
const wchar_t sectionName[],
|
|
||||||
const wchar_t keyName[],
|
|
||||||
unsigned index,
|
|
||||||
unsigned minVal,
|
|
||||||
unsigned maxVal,
|
|
||||||
unsigned defVal
|
|
||||||
);
|
|
||||||
unsigned IniGetBoundedValue (
|
|
||||||
const IniValue * value,
|
|
||||||
unsigned index,
|
|
||||||
unsigned minVal,
|
|
||||||
unsigned maxVal,
|
|
||||||
unsigned defVal
|
|
||||||
);
|
|
@ -1,56 +0,0 @@
|
|||||||
/*==LICENSE==*
|
|
||||||
|
|
||||||
CyanWorlds.com Engine - MMOG client, server and tools
|
|
||||||
Copyright (C) 2011 Cyan Worlds, Inc.
|
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
Additional permissions under GNU GPL version 3 section 7
|
|
||||||
|
|
||||||
If you modify this Program, or any covered work, by linking or
|
|
||||||
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
|
|
||||||
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
|
|
||||||
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
|
|
||||||
(or a modified version of those libraries),
|
|
||||||
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
|
|
||||||
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
|
|
||||||
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
|
|
||||||
licensors of this Program grant you additional
|
|
||||||
permission to convey the resulting work. Corresponding Source for a
|
|
||||||
non-source form of such a combination shall include the source code for
|
|
||||||
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
|
|
||||||
work.
|
|
||||||
|
|
||||||
You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
|
||||||
or by snail mail at:
|
|
||||||
Cyan Worlds, Inc.
|
|
||||||
14617 N Newport Hwy
|
|
||||||
Mead, WA 99021
|
|
||||||
|
|
||||||
*==LICENSE==*/
|
|
||||||
/*****************************************************************************
|
|
||||||
*
|
|
||||||
* $/Plasma20/Sources/Plasma/NucleusLib/pnIni/Private/pnIniSrv.cpp
|
|
||||||
*
|
|
||||||
***/
|
|
||||||
|
|
||||||
#include "../Pch.h"
|
|
||||||
#pragma hdrstop
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef SERVER
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,77 +0,0 @@
|
|||||||
/*==LICENSE==*
|
|
||||||
|
|
||||||
CyanWorlds.com Engine - MMOG client, server and tools
|
|
||||||
Copyright (C) 2011 Cyan Worlds, Inc.
|
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
Additional permissions under GNU GPL version 3 section 7
|
|
||||||
|
|
||||||
If you modify this Program, or any covered work, by linking or
|
|
||||||
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
|
|
||||||
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
|
|
||||||
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
|
|
||||||
(or a modified version of those libraries),
|
|
||||||
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
|
|
||||||
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
|
|
||||||
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
|
|
||||||
licensors of this Program grant you additional
|
|
||||||
permission to convey the resulting work. Corresponding Source for a
|
|
||||||
non-source form of such a combination shall include the source code for
|
|
||||||
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
|
|
||||||
work.
|
|
||||||
|
|
||||||
You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
|
||||||
or by snail mail at:
|
|
||||||
Cyan Worlds, Inc.
|
|
||||||
14617 N Newport Hwy
|
|
||||||
Mead, WA 99021
|
|
||||||
|
|
||||||
*==LICENSE==*/
|
|
||||||
/*****************************************************************************
|
|
||||||
*
|
|
||||||
* $/Plasma20/Sources/Plasma/NucleusLib/pnIni/Private/pnIniSrv.h
|
|
||||||
*
|
|
||||||
***/
|
|
||||||
|
|
||||||
#ifdef PLASMA20_SOURCES_PLASMA_NUCLEUSLIB_PNINI_PRIVATE_PNINISRV_H
|
|
||||||
#error "Header $/Plasma20/Sources/Plasma/NucleusLib/pnIni/Private/pnIniSrv.h included more than once"
|
|
||||||
#endif
|
|
||||||
#define PLASMA20_SOURCES_PLASMA_NUCLEUSLIB_PNINI_PRIVATE_PNINISRV_H
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef SERVER
|
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************************
|
|
||||||
*
|
|
||||||
* ServerRights API
|
|
||||||
*
|
|
||||||
***/
|
|
||||||
|
|
||||||
// These values may never change because server modules
|
|
||||||
// must use the same values as plServer.exe
|
|
||||||
enum EServerRights {
|
|
||||||
kSrvRightsNone = 0,
|
|
||||||
kSrvRightsBasic = 1,
|
|
||||||
kSrvRightsServer = 2,
|
|
||||||
kNumSrvRights
|
|
||||||
};
|
|
||||||
|
|
||||||
EServerRights SrvIniGetServerRightsByNode (NetAddressNode addrNode);
|
|
||||||
EServerRights SrvIniGetServerRights (const NetAddress & addr);
|
|
||||||
void SrvIniParseServerRights (Ini * ini);
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,53 +0,0 @@
|
|||||||
/*==LICENSE==*
|
|
||||||
|
|
||||||
CyanWorlds.com Engine - MMOG client, server and tools
|
|
||||||
Copyright (C) 2011 Cyan Worlds, Inc.
|
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
Additional permissions under GNU GPL version 3 section 7
|
|
||||||
|
|
||||||
If you modify this Program, or any covered work, by linking or
|
|
||||||
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
|
|
||||||
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
|
|
||||||
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
|
|
||||||
(or a modified version of those libraries),
|
|
||||||
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
|
|
||||||
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
|
|
||||||
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
|
|
||||||
licensors of this Program grant you additional
|
|
||||||
permission to convey the resulting work. Corresponding Source for a
|
|
||||||
non-source form of such a combination shall include the source code for
|
|
||||||
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
|
|
||||||
work.
|
|
||||||
|
|
||||||
You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
|
||||||
or by snail mail at:
|
|
||||||
Cyan Worlds, Inc.
|
|
||||||
14617 N Newport Hwy
|
|
||||||
Mead, WA 99021
|
|
||||||
|
|
||||||
*==LICENSE==*/
|
|
||||||
/*****************************************************************************
|
|
||||||
*
|
|
||||||
* $/Plasma20/Sources/Plasma/NucleusLib/pnIni/pnIni.h
|
|
||||||
*
|
|
||||||
***/
|
|
||||||
|
|
||||||
#ifndef PLASMA20_SOURCES_PLASMA_NUCLEUSLIB_PNINI_PNINI_H
|
|
||||||
#define PLASMA20_SOURCES_PLASMA_NUCLEUSLIB_PNINI_PNINI_H
|
|
||||||
|
|
||||||
#include "Private/pnIniAllIncludes.h"
|
|
||||||
|
|
||||||
#endif // PLASMA20_SOURCES_PLASMA_NUCLEUSLIB_PNINI_PNINI_H
|
|
@ -1,20 +0,0 @@
|
|||||||
include_directories("../../CoreLib")
|
|
||||||
include_directories("../../NucleusLib")
|
|
||||||
|
|
||||||
set(pnIniExe_HEADERS
|
|
||||||
Pch.h
|
|
||||||
)
|
|
||||||
|
|
||||||
set(pnIniExe_PRIVATE
|
|
||||||
Private/pnIniSrv.cpp
|
|
||||||
)
|
|
||||||
|
|
||||||
set(pnIniExe_PRIVATE_WIN32
|
|
||||||
Private/Win32/pnW32IniChange.cpp
|
|
||||||
)
|
|
||||||
|
|
||||||
add_library(pnIniExe STATIC ${pnIniExe_HEADERS} ${pnIniExe_PRIVATE} ${pnIniExe_PRIVATE_WIN32})
|
|
||||||
|
|
||||||
source_group("Header Files" FILES ${pnIniExe_HEADERS})
|
|
||||||
source_group("Private" FILES ${pnIniExe_PRIVATE})
|
|
||||||
source_group("Private\\Win32" FILES ${pnIniExe_PRIVATE_WIN32})
|
|
@ -1,68 +0,0 @@
|
|||||||
/*==LICENSE==*
|
|
||||||
|
|
||||||
CyanWorlds.com Engine - MMOG client, server and tools
|
|
||||||
Copyright (C) 2011 Cyan Worlds, Inc.
|
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
Additional permissions under GNU GPL version 3 section 7
|
|
||||||
|
|
||||||
If you modify this Program, or any covered work, by linking or
|
|
||||||
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
|
|
||||||
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
|
|
||||||
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
|
|
||||||
(or a modified version of those libraries),
|
|
||||||
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
|
|
||||||
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
|
|
||||||
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
|
|
||||||
licensors of this Program grant you additional
|
|
||||||
permission to convey the resulting work. Corresponding Source for a
|
|
||||||
non-source form of such a combination shall include the source code for
|
|
||||||
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
|
|
||||||
work.
|
|
||||||
|
|
||||||
You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
|
||||||
or by snail mail at:
|
|
||||||
Cyan Worlds, Inc.
|
|
||||||
14617 N Newport Hwy
|
|
||||||
Mead, WA 99021
|
|
||||||
|
|
||||||
*==LICENSE==*/
|
|
||||||
/*****************************************************************************
|
|
||||||
*
|
|
||||||
* $/Plasma20/Sources/Plasma/NucleusLib/pnIniExe/Pch.h
|
|
||||||
*
|
|
||||||
***/
|
|
||||||
|
|
||||||
#ifdef PLASMA20_SOURCES_PLASMA_NUCLEUSLIB_PNINIEXE_PCH_H
|
|
||||||
#error "Header $/Plasma20/Sources/Plasma/NucleusLib/pnIniExe/Pch.h included more than once"
|
|
||||||
#endif
|
|
||||||
#define PLASMA20_SOURCES_PLASMA_NUCLEUSLIB_PNINIEXE_PCH_H
|
|
||||||
|
|
||||||
|
|
||||||
#include "pnUtils/pnUtils.h"
|
|
||||||
#include "pnProduct/pnProduct.h"
|
|
||||||
#include "pnNetBase/pnNetBase.h"
|
|
||||||
#include "pnAsyncCore/pnAsyncCore.h"
|
|
||||||
#include "pnIni/pnIni.h"
|
|
||||||
|
|
||||||
#include "pnIni/Intern.h"
|
|
||||||
|
|
||||||
#ifdef SERVER
|
|
||||||
#include "pnCrash/pnCrash.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#include <malloc.h>
|
|
@ -1,395 +0,0 @@
|
|||||||
/*==LICENSE==*
|
|
||||||
|
|
||||||
CyanWorlds.com Engine - MMOG client, server and tools
|
|
||||||
Copyright (C) 2011 Cyan Worlds, Inc.
|
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
Additional permissions under GNU GPL version 3 section 7
|
|
||||||
|
|
||||||
If you modify this Program, or any covered work, by linking or
|
|
||||||
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
|
|
||||||
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
|
|
||||||
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
|
|
||||||
(or a modified version of those libraries),
|
|
||||||
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
|
|
||||||
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
|
|
||||||
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
|
|
||||||
licensors of this Program grant you additional
|
|
||||||
permission to convey the resulting work. Corresponding Source for a
|
|
||||||
non-source form of such a combination shall include the source code for
|
|
||||||
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
|
|
||||||
work.
|
|
||||||
|
|
||||||
You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
|
||||||
or by snail mail at:
|
|
||||||
Cyan Worlds, Inc.
|
|
||||||
14617 N Newport Hwy
|
|
||||||
Mead, WA 99021
|
|
||||||
|
|
||||||
*==LICENSE==*/
|
|
||||||
/*****************************************************************************
|
|
||||||
*
|
|
||||||
* $/Plasma20/Sources/Plasma/NucleusLib/pnIniExe/Private/Win32/pnW32IniChange.cpp
|
|
||||||
*
|
|
||||||
***/
|
|
||||||
|
|
||||||
#include "../../Pch.h"
|
|
||||||
#pragma hdrstop
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef HS_BUILD_FOR_WIN32
|
|
||||||
|
|
||||||
/*****************************************************************************
|
|
||||||
*
|
|
||||||
* Private
|
|
||||||
*
|
|
||||||
***/
|
|
||||||
|
|
||||||
struct IniChangeFile;
|
|
||||||
|
|
||||||
struct IniChangeReg {
|
|
||||||
LINK(IniChangeReg) fLink;
|
|
||||||
FIniFileChangeCallback fNotify;
|
|
||||||
uint64_t fLastWriteTime;
|
|
||||||
wchar_t fFileName[MAX_PATH];
|
|
||||||
};
|
|
||||||
|
|
||||||
static CLock s_lock;
|
|
||||||
static HANDLE s_event;
|
|
||||||
static HANDLE s_signal;
|
|
||||||
static HANDLE s_thread;
|
|
||||||
static HANDLE s_change;
|
|
||||||
static bool s_running;
|
|
||||||
static IniChangeReg * s_dispatch;
|
|
||||||
static wchar_t s_directory[MAX_PATH];
|
|
||||||
static LISTDECL(IniChangeReg, fLink) s_callbacks;
|
|
||||||
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
*
|
|
||||||
* Change notification
|
|
||||||
*
|
|
||||||
***/
|
|
||||||
|
|
||||||
//===========================================================================
|
|
||||||
static uint64_t GetFileTimestamp (const wchar_t fileName[]) {
|
|
||||||
HANDLE find;
|
|
||||||
WIN32_FIND_DATAW fd;
|
|
||||||
uint64_t lastWriteTime;
|
|
||||||
if (INVALID_HANDLE_VALUE != (find = FindFirstFileW(fileName, &fd))) {
|
|
||||||
COMPILER_ASSERT(sizeof(lastWriteTime) == sizeof(fd.ftLastWriteTime));
|
|
||||||
lastWriteTime = * (const uint64_t *) &fd.ftLastWriteTime;
|
|
||||||
FindClose(find);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
lastWriteTime = 1; // any non-zero, non-valid number
|
|
||||||
}
|
|
||||||
|
|
||||||
return lastWriteTime;
|
|
||||||
}
|
|
||||||
|
|
||||||
//===========================================================================
|
|
||||||
static void ChangeDispatch_WL (IniChangeReg * marker) {
|
|
||||||
|
|
||||||
while (nil != (s_dispatch = s_callbacks.Next(marker))) {
|
|
||||||
// Move the marker to the next location
|
|
||||||
s_callbacks.Link(marker, kListLinkAfter, s_dispatch);
|
|
||||||
|
|
||||||
// If the file record time matches the file data time
|
|
||||||
// then there's no need to reprocess the callbacks
|
|
||||||
uint64_t lastWriteTime = GetFileTimestamp(s_dispatch->fFileName);
|
|
||||||
if (s_dispatch->fLastWriteTime == lastWriteTime)
|
|
||||||
continue;
|
|
||||||
s_dispatch->fLastWriteTime = lastWriteTime;
|
|
||||||
|
|
||||||
// Leave lock to perform callback
|
|
||||||
s_lock.LeaveWrite();
|
|
||||||
s_dispatch->fNotify(s_dispatch->fFileName);
|
|
||||||
s_lock.EnterWrite();
|
|
||||||
}
|
|
||||||
|
|
||||||
// List traversal complete
|
|
||||||
SetEvent(s_signal);
|
|
||||||
}
|
|
||||||
|
|
||||||
//===========================================================================
|
|
||||||
static unsigned THREADCALL IniSrvThreadProc (AsyncThread * thread) {
|
|
||||||
IniChangeReg marker;
|
|
||||||
marker.fNotify = nil;
|
|
||||||
s_lock.EnterWrite();
|
|
||||||
s_callbacks.Link(&marker, kListHead);
|
|
||||||
s_lock.LeaveWrite();
|
|
||||||
|
|
||||||
HANDLE handles[2];
|
|
||||||
handles[0] = s_change;
|
|
||||||
handles[1] = s_event;
|
|
||||||
unsigned sleepMs = INFINITE;
|
|
||||||
for (;;) {
|
|
||||||
|
|
||||||
// Wait until something happens
|
|
||||||
unsigned result = WaitForMultipleObjects(
|
|
||||||
arrsize(handles),
|
|
||||||
handles,
|
|
||||||
false,
|
|
||||||
sleepMs
|
|
||||||
);
|
|
||||||
if (!s_running)
|
|
||||||
break;
|
|
||||||
|
|
||||||
// reset the sleep time
|
|
||||||
sleepMs = INFINITE;
|
|
||||||
|
|
||||||
if (result == WAIT_OBJECT_0) {
|
|
||||||
if (!FindNextChangeNotification(s_change)) {
|
|
||||||
LogMsg(
|
|
||||||
kLogError,
|
|
||||||
"IniSrv: FindNextChangeNotification() failed %#x",
|
|
||||||
GetLastError()
|
|
||||||
);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// a change notification occurs when a file is created, even
|
|
||||||
// though it may take a number of seconds before the file data
|
|
||||||
// has been copied. Wait a few seconds after the last change
|
|
||||||
// notification so that files have a chance to stabilize.
|
|
||||||
sleepMs = 5 * 1000;
|
|
||||||
|
|
||||||
// When the timeout occurs, reprocess the entire list
|
|
||||||
s_lock.EnterWrite();
|
|
||||||
s_callbacks.Link(&marker, kListHead);
|
|
||||||
s_lock.LeaveWrite();
|
|
||||||
}
|
|
||||||
else if ((result == WAIT_OBJECT_0 + 1) || (result == WAIT_TIMEOUT)) {
|
|
||||||
// Queue for deadlock check
|
|
||||||
#ifdef SERVER
|
|
||||||
void * check = CrashAddDeadlockCheck(thread->handle, L"plW32IniChange.NtWorkerThreadProc");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
s_lock.EnterWrite();
|
|
||||||
ChangeDispatch_WL(&marker);
|
|
||||||
s_lock.LeaveWrite();
|
|
||||||
|
|
||||||
// Unqueue for deadlock check
|
|
||||||
#ifdef SERVER
|
|
||||||
CrashRemoveDeadlockCheck(check);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
LogMsg(
|
|
||||||
kLogError,
|
|
||||||
"IniChange: WaitForMultipleObjects failed %#x",
|
|
||||||
GetLastError()
|
|
||||||
);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Cleanup
|
|
||||||
s_lock.EnterWrite();
|
|
||||||
s_callbacks.Unlink(&marker);
|
|
||||||
s_lock.LeaveWrite();
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
*
|
|
||||||
* Exports
|
|
||||||
*
|
|
||||||
***/
|
|
||||||
|
|
||||||
//===========================================================================
|
|
||||||
void IniChangeInitialize (const wchar_t dir[]) {
|
|
||||||
ASSERT(!s_running);
|
|
||||||
s_running = true;
|
|
||||||
|
|
||||||
const char * function;
|
|
||||||
for (;;) {
|
|
||||||
// Create the config directory
|
|
||||||
PathGetProgramDirectory(s_directory, arrsize(s_directory));
|
|
||||||
PathAddFilename(s_directory, s_directory, dir, arrsize(s_directory));
|
|
||||||
if (EPathCreateDirError error = PathCreateDirectory(s_directory, 0))
|
|
||||||
LogMsg(kLogError, "IniChange: CreateDir failed %u", error);
|
|
||||||
|
|
||||||
// Open change notification for directory
|
|
||||||
s_change = FindFirstChangeNotificationW(
|
|
||||||
s_directory,
|
|
||||||
false, // watchSubTree = false
|
|
||||||
FILE_NOTIFY_CHANGE_LAST_WRITE | FILE_NOTIFY_CHANGE_FILE_NAME
|
|
||||||
);
|
|
||||||
if (!s_change) {
|
|
||||||
function = "FindFirstChangeNotification";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// create thread event
|
|
||||||
s_event = CreateEvent(
|
|
||||||
(LPSECURITY_ATTRIBUTES) 0,
|
|
||||||
false, // auto-reset
|
|
||||||
false, // initial state off
|
|
||||||
(LPCTSTR) 0 // name
|
|
||||||
);
|
|
||||||
if (!s_event) {
|
|
||||||
function = "CreateEvent";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// create signal event
|
|
||||||
s_signal = CreateEvent(
|
|
||||||
(LPSECURITY_ATTRIBUTES) 0,
|
|
||||||
true, // manual-reset
|
|
||||||
false, // initial state off
|
|
||||||
(LPCTSTR) 0 // name
|
|
||||||
);
|
|
||||||
if (!s_signal) {
|
|
||||||
function = "CreateEvent";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// create thread
|
|
||||||
s_thread = (HANDLE) AsyncThreadCreate(
|
|
||||||
IniSrvThreadProc,
|
|
||||||
nil,
|
|
||||||
L"IniSrvChange"
|
|
||||||
);
|
|
||||||
if (!s_thread) {
|
|
||||||
function = "AsyncThreadCreate";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Success!
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Failure!
|
|
||||||
LogMsg(
|
|
||||||
kLogError,
|
|
||||||
"IniChange: %s failed (%#x)",
|
|
||||||
function,
|
|
||||||
GetLastError()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
//===========================================================================
|
|
||||||
void IniChangeDestroy () {
|
|
||||||
s_running = false;
|
|
||||||
|
|
||||||
if (s_thread) {
|
|
||||||
SetEvent(s_event);
|
|
||||||
WaitForSingleObject(s_thread, INFINITE);
|
|
||||||
CloseHandle(s_thread);
|
|
||||||
s_thread = nil;
|
|
||||||
}
|
|
||||||
if (s_event) {
|
|
||||||
CloseHandle(s_event);
|
|
||||||
s_event = nil;
|
|
||||||
}
|
|
||||||
if (s_signal) {
|
|
||||||
CloseHandle(s_signal);
|
|
||||||
s_signal = nil;
|
|
||||||
}
|
|
||||||
if (s_change) {
|
|
||||||
FindCloseChangeNotification(s_change);
|
|
||||||
s_change = nil;
|
|
||||||
}
|
|
||||||
|
|
||||||
ASSERT(!s_callbacks.Head());
|
|
||||||
}
|
|
||||||
|
|
||||||
//===========================================================================
|
|
||||||
void IniChangeAdd (
|
|
||||||
const wchar_t fileName[],
|
|
||||||
FIniFileChangeCallback callback,
|
|
||||||
IniChangeReg ** changePtr
|
|
||||||
) {
|
|
||||||
ASSERT(fileName);
|
|
||||||
ASSERT(callback);
|
|
||||||
ASSERT(changePtr);
|
|
||||||
ASSERT(s_running);
|
|
||||||
|
|
||||||
// Create a callback record
|
|
||||||
IniChangeReg * change = new IniChangeReg;
|
|
||||||
change->fNotify = callback;
|
|
||||||
change->fLastWriteTime = 0;
|
|
||||||
PathAddFilename(
|
|
||||||
change->fFileName,
|
|
||||||
s_directory,
|
|
||||||
fileName,
|
|
||||||
arrsize(change->fFileName)
|
|
||||||
);
|
|
||||||
PathRemoveExtension(change->fFileName, change->fFileName, arrsize(change->fFileName));
|
|
||||||
PathAddExtension(change->fFileName, change->fFileName, L".ini", arrsize(change->fFileName));
|
|
||||||
|
|
||||||
// Set result before callback to avoid race condition
|
|
||||||
*changePtr = change;
|
|
||||||
|
|
||||||
// Signal change record for immediate callback
|
|
||||||
// and wait for callback completion
|
|
||||||
IniChangeSignal(change, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
//===========================================================================
|
|
||||||
void IniChangeRemove (
|
|
||||||
IniChangeReg * change,
|
|
||||||
bool wait
|
|
||||||
) {
|
|
||||||
ASSERT(change);
|
|
||||||
|
|
||||||
s_lock.EnterWrite();
|
|
||||||
{
|
|
||||||
// Wait until the callback is no longer being dispatched
|
|
||||||
if (wait) {
|
|
||||||
while (s_dispatch == change) {
|
|
||||||
s_lock.LeaveWrite();
|
|
||||||
AsyncSleep(10);
|
|
||||||
s_lock.EnterWrite();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Remove change object from list so that
|
|
||||||
// it can be deleted outside the lock
|
|
||||||
change->fLink.Unlink();
|
|
||||||
}
|
|
||||||
s_lock.LeaveWrite();
|
|
||||||
|
|
||||||
// Delete object outside critical section
|
|
||||||
delete change;
|
|
||||||
}
|
|
||||||
|
|
||||||
//===========================================================================
|
|
||||||
void IniChangeSignal (
|
|
||||||
IniChangeReg * change,
|
|
||||||
bool wait
|
|
||||||
) {
|
|
||||||
ASSERT(change);
|
|
||||||
|
|
||||||
s_lock.EnterWrite();
|
|
||||||
{
|
|
||||||
s_callbacks.Link(change, kListTail);
|
|
||||||
change->fLastWriteTime = 0;
|
|
||||||
ResetEvent(s_signal);
|
|
||||||
}
|
|
||||||
s_lock.LeaveWrite();
|
|
||||||
|
|
||||||
// Wake up the change thread to process this request
|
|
||||||
SetEvent(s_event);
|
|
||||||
|
|
||||||
// Wait until the request has been processed
|
|
||||||
if (wait)
|
|
||||||
WaitForSingleObject(s_signal, INFINITE);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // HS_BUILD_FOR_WIN32
|
|
@ -1,218 +0,0 @@
|
|||||||
/*==LICENSE==*
|
|
||||||
|
|
||||||
CyanWorlds.com Engine - MMOG client, server and tools
|
|
||||||
Copyright (C) 2011 Cyan Worlds, Inc.
|
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
Additional permissions under GNU GPL version 3 section 7
|
|
||||||
|
|
||||||
If you modify this Program, or any covered work, by linking or
|
|
||||||
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
|
|
||||||
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
|
|
||||||
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
|
|
||||||
(or a modified version of those libraries),
|
|
||||||
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
|
|
||||||
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
|
|
||||||
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
|
|
||||||
licensors of this Program grant you additional
|
|
||||||
permission to convey the resulting work. Corresponding Source for a
|
|
||||||
non-source form of such a combination shall include the source code for
|
|
||||||
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
|
|
||||||
work.
|
|
||||||
|
|
||||||
You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
|
||||||
or by snail mail at:
|
|
||||||
Cyan Worlds, Inc.
|
|
||||||
14617 N Newport Hwy
|
|
||||||
Mead, WA 99021
|
|
||||||
|
|
||||||
*==LICENSE==*/
|
|
||||||
/*****************************************************************************
|
|
||||||
*
|
|
||||||
* $/Plasma20/Sources/Plasma/NucleusLib/pnIniExe/Private/pnIniSrv.cpp
|
|
||||||
*
|
|
||||||
***/
|
|
||||||
|
|
||||||
#include "../Pch.h"
|
|
||||||
#pragma hdrstop
|
|
||||||
|
|
||||||
#ifdef SERVER
|
|
||||||
|
|
||||||
/*****************************************************************************
|
|
||||||
*
|
|
||||||
* Internal
|
|
||||||
*
|
|
||||||
***/
|
|
||||||
|
|
||||||
const unsigned CLASS_C_SUBNET_MASK = 0xFFFFFF00;
|
|
||||||
const NetAddressNode LOOPBACK_ADDRESS_NODE = 0x7F000001;
|
|
||||||
|
|
||||||
|
|
||||||
//============================================================================
|
|
||||||
struct PrivilegedAddressBlock : THashKeyVal<unsigned> {
|
|
||||||
HASHLINK(PrivilegedAddressBlock) link;
|
|
||||||
|
|
||||||
NetAddressNode startAddress;
|
|
||||||
NetAddressNode endAddress;
|
|
||||||
EServerRights serverRights;
|
|
||||||
};
|
|
||||||
|
|
||||||
//============================================================================
|
|
||||||
|
|
||||||
#define ADDRESS_BLOCK_TABLE HASHTABLEDECL(PrivilegedAddressBlock, THashKeyVal<unsigned>, link)
|
|
||||||
|
|
||||||
static CCritSect s_critsect;
|
|
||||||
static ADDRESS_BLOCK_TABLE s_addressBlocks;
|
|
||||||
|
|
||||||
|
|
||||||
//============================================================================
|
|
||||||
static void SrvRightsDestroy () {
|
|
||||||
s_critsect.Enter();
|
|
||||||
{
|
|
||||||
s_addressBlocks.Clear();
|
|
||||||
}
|
|
||||||
s_critsect.Leave();
|
|
||||||
}
|
|
||||||
|
|
||||||
//============================================================================
|
|
||||||
AUTO_INIT_FUNC(InitSrvRightsIni) {
|
|
||||||
atexit(SrvRightsDestroy);
|
|
||||||
}
|
|
||||||
|
|
||||||
//============================================================================
|
|
||||||
static EServerRights GetServerRightsFromString(const wchar_t string[]) {
|
|
||||||
if (StrCmpI(string, L"Server") == 0)
|
|
||||||
return kSrvRightsServer;
|
|
||||||
else if (StrCmpI(string, L"Basic") == 0)
|
|
||||||
return kSrvRightsBasic;
|
|
||||||
else
|
|
||||||
return kSrvRightsNone;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void IAddAddressBlock(ADDRESS_BLOCK_TABLE & addrList, NetAddressNode startAddr, NetAddressNode endAddr, EServerRights srvRights) {
|
|
||||||
PrivilegedAddressBlock* addrBlock = new PrivilegedAddressBlock;
|
|
||||||
|
|
||||||
addrBlock->startAddress = startAddr;
|
|
||||||
addrBlock->serverRights = srvRights;
|
|
||||||
|
|
||||||
if (endAddr == 0)
|
|
||||||
addrBlock->endAddress = addrBlock->startAddress;
|
|
||||||
else
|
|
||||||
addrBlock->endAddress = endAddr;
|
|
||||||
|
|
||||||
if ( (addrBlock->startAddress & CLASS_C_SUBNET_MASK) != (addrBlock->endAddress & CLASS_C_SUBNET_MASK) ) {
|
|
||||||
LogMsg(kLogDebug, L"IniSrv: Error creating privileged address block - start address and end address aren't from the same subnet.");
|
|
||||||
delete addrBlock;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
addrBlock->SetValue(startAddr & CLASS_C_SUBNET_MASK);
|
|
||||||
addrList.Add(addrBlock);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*****************************************************************************
|
|
||||||
*
|
|
||||||
* Exports
|
|
||||||
*
|
|
||||||
***/
|
|
||||||
|
|
||||||
//============================================================================
|
|
||||||
EServerRights SrvIniGetServerRightsByNode (NetAddressNode addrNode) {
|
|
||||||
EServerRights retVal = kSrvRightsBasic;
|
|
||||||
unsigned addrSubNet = (addrNode & CLASS_C_SUBNET_MASK);
|
|
||||||
|
|
||||||
s_critsect.Enter();
|
|
||||||
{
|
|
||||||
PrivilegedAddressBlock* addrBlock = s_addressBlocks.Find(addrSubNet);
|
|
||||||
while (addrBlock) {
|
|
||||||
if (addrBlock->startAddress <= addrNode && addrNode <= addrBlock->endAddress) {
|
|
||||||
retVal = addrBlock->serverRights;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
addrBlock = s_addressBlocks.FindNext(addrSubNet, addrBlock);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
s_critsect.Leave();
|
|
||||||
|
|
||||||
return retVal;
|
|
||||||
}
|
|
||||||
|
|
||||||
//============================================================================
|
|
||||||
EServerRights SrvIniGetServerRights (const NetAddress & addr) {
|
|
||||||
NetAddressNode addrNode = NetAddressGetNode(addr);
|
|
||||||
|
|
||||||
return SrvIniGetServerRightsByNode(addrNode);
|
|
||||||
}
|
|
||||||
|
|
||||||
//============================================================================
|
|
||||||
void SrvIniParseServerRights (Ini * ini) {
|
|
||||||
unsigned iter;
|
|
||||||
const IniValue *value;
|
|
||||||
ADDRESS_BLOCK_TABLE newaddresstable;
|
|
||||||
ADDRESS_BLOCK_TABLE removeaddresstable;
|
|
||||||
|
|
||||||
value = IniGetFirstValue(
|
|
||||||
ini,
|
|
||||||
L"Privileged Addresses",
|
|
||||||
L"Addr",
|
|
||||||
&iter
|
|
||||||
);
|
|
||||||
|
|
||||||
// add ini file address blocks
|
|
||||||
while (value) {
|
|
||||||
wchar_t valStr[20];
|
|
||||||
NetAddressNode start;
|
|
||||||
NetAddressNode end;
|
|
||||||
EServerRights rights;
|
|
||||||
|
|
||||||
IniGetString(value, valStr, arrsize(valStr), 0);
|
|
||||||
start = NetAddressNodeFromString(valStr, nil);
|
|
||||||
|
|
||||||
IniGetString(value, valStr, arrsize(valStr), 1);
|
|
||||||
end = NetAddressNodeFromString(valStr, nil);
|
|
||||||
|
|
||||||
IniGetString(value, valStr, arrsize(valStr), 2);
|
|
||||||
rights = GetServerRightsFromString(valStr);
|
|
||||||
|
|
||||||
IAddAddressBlock(newaddresstable, start, end, rights);
|
|
||||||
|
|
||||||
value = IniGetNextValue(value, &iter);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add local addresses and loopback
|
|
||||||
NetAddressNode nodes[16];
|
|
||||||
unsigned count = NetAddressGetLocal(arrsize(nodes), nodes);
|
|
||||||
|
|
||||||
for (unsigned i = 0; i < count; ++i) {
|
|
||||||
IAddAddressBlock(newaddresstable, nodes[i], nodes[i], kSrvRightsServer);
|
|
||||||
}
|
|
||||||
IAddAddressBlock(newaddresstable, LOOPBACK_ADDRESS_NODE, LOOPBACK_ADDRESS_NODE, kSrvRightsServer);
|
|
||||||
|
|
||||||
s_critsect.Enter();
|
|
||||||
{
|
|
||||||
while (PrivilegedAddressBlock* addrBlock = s_addressBlocks.Head())
|
|
||||||
removeaddresstable.Add(addrBlock);
|
|
||||||
|
|
||||||
while (PrivilegedAddressBlock* addrBlock = newaddresstable.Head())
|
|
||||||
s_addressBlocks.Add(addrBlock);
|
|
||||||
}
|
|
||||||
s_critsect.Leave();
|
|
||||||
|
|
||||||
removeaddresstable.Clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,16 +0,0 @@
|
|||||||
include_directories("../../CoreLib")
|
|
||||||
include_directories("../../NucleusLib")
|
|
||||||
|
|
||||||
set(pnMail_HEADERS
|
|
||||||
Pch.h
|
|
||||||
pnMail.h
|
|
||||||
)
|
|
||||||
|
|
||||||
set(pnMail_SOURCES
|
|
||||||
pnMail.cpp
|
|
||||||
)
|
|
||||||
|
|
||||||
add_library(pnMail STATIC ${pnMail_HEADERS} ${pnMail_SOURCES})
|
|
||||||
|
|
||||||
source_group("Header Files" FILES ${pnMail_HEADERS})
|
|
||||||
source_group("Source Files" FILES ${pnMail_SOURCES})
|
|
@ -1,60 +0,0 @@
|
|||||||
/*==LICENSE==*
|
|
||||||
|
|
||||||
CyanWorlds.com Engine - MMOG client, server and tools
|
|
||||||
Copyright (C) 2011 Cyan Worlds, Inc.
|
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
Additional permissions under GNU GPL version 3 section 7
|
|
||||||
|
|
||||||
If you modify this Program, or any covered work, by linking or
|
|
||||||
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
|
|
||||||
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
|
|
||||||
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
|
|
||||||
(or a modified version of those libraries),
|
|
||||||
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
|
|
||||||
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
|
|
||||||
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
|
|
||||||
licensors of this Program grant you additional
|
|
||||||
permission to convey the resulting work. Corresponding Source for a
|
|
||||||
non-source form of such a combination shall include the source code for
|
|
||||||
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
|
|
||||||
work.
|
|
||||||
|
|
||||||
You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
|
||||||
or by snail mail at:
|
|
||||||
Cyan Worlds, Inc.
|
|
||||||
14617 N Newport Hwy
|
|
||||||
Mead, WA 99021
|
|
||||||
|
|
||||||
*==LICENSE==*/
|
|
||||||
/*****************************************************************************
|
|
||||||
*
|
|
||||||
* $/Plasma20/Sources/Plasma/NucleusLib/pnMail/Pch.h
|
|
||||||
*
|
|
||||||
***/
|
|
||||||
|
|
||||||
#ifdef PLASMA20_SOURCES_PLASMA_NUCLEUSLIB_PNMAIL_PCH_H
|
|
||||||
#error "Header $/Plasma20/Sources/Plasma/NucleusLib/pnMail/Pch.h included more than once"
|
|
||||||
#endif
|
|
||||||
#define PLASMA20_SOURCES_PLASMA_NUCLEUSLIB_PNMAIL_PCH_H
|
|
||||||
|
|
||||||
|
|
||||||
#include "pnUtils/pnUtils.h"
|
|
||||||
#include "pnNetBase/pnNetBase.h"
|
|
||||||
#include "pnAsyncCore/pnAsyncCore.h"
|
|
||||||
|
|
||||||
#include "pnMail.h"
|
|
||||||
|
|
||||||
#include <malloc.h>
|
|
@ -1,726 +0,0 @@
|
|||||||
/*==LICENSE==*
|
|
||||||
|
|
||||||
CyanWorlds.com Engine - MMOG client, server and tools
|
|
||||||
Copyright (C) 2011 Cyan Worlds, Inc.
|
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
Additional permissions under GNU GPL version 3 section 7
|
|
||||||
|
|
||||||
If you modify this Program, or any covered work, by linking or
|
|
||||||
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
|
|
||||||
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
|
|
||||||
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
|
|
||||||
(or a modified version of those libraries),
|
|
||||||
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
|
|
||||||
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
|
|
||||||
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
|
|
||||||
licensors of this Program grant you additional
|
|
||||||
permission to convey the resulting work. Corresponding Source for a
|
|
||||||
non-source form of such a combination shall include the source code for
|
|
||||||
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
|
|
||||||
work.
|
|
||||||
|
|
||||||
You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
|
||||||
or by snail mail at:
|
|
||||||
Cyan Worlds, Inc.
|
|
||||||
14617 N Newport Hwy
|
|
||||||
Mead, WA 99021
|
|
||||||
|
|
||||||
*==LICENSE==*/
|
|
||||||
/*****************************************************************************
|
|
||||||
*
|
|
||||||
* $/Plasma20/Sources/Plasma/NucleusLib/pnMail/pnMail.cpp
|
|
||||||
*
|
|
||||||
***/
|
|
||||||
|
|
||||||
#include "Pch.h"
|
|
||||||
#pragma hdrstop
|
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************************
|
|
||||||
*
|
|
||||||
* Private
|
|
||||||
*
|
|
||||||
***/
|
|
||||||
|
|
||||||
enum EMailStep {
|
|
||||||
kMailStepConnect, // wait for 220, then send "helo" command
|
|
||||||
kMailStepAuth, // wait for 250, then send "AUTH PLAIN <base64data>"
|
|
||||||
kMailStepSender, // wait for 235/250, then send "mail from:" command
|
|
||||||
kMailStepRecipient, // wait for 250, then send "rcpt to:" command
|
|
||||||
kMailStepStartLetter, // wait for 250, then send "data" command
|
|
||||||
kMailStepLetter, // wait for 354, then send letter
|
|
||||||
kMailStepQuit, // wait for 250, then send "quit" command
|
|
||||||
kMailStepDisconnect, // wait for 221, then disconnect
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
struct MailTransaction {
|
|
||||||
LINK(MailTransaction) link;
|
|
||||||
AsyncSocket sock;
|
|
||||||
const char ** stepTable;
|
|
||||||
EMailStep step;
|
|
||||||
unsigned subStep;
|
|
||||||
EMailError error;
|
|
||||||
FMailResult callback;
|
|
||||||
void * param;
|
|
||||||
|
|
||||||
char * smtp;
|
|
||||||
char * sender;
|
|
||||||
char * recipient;
|
|
||||||
char * replyTo;
|
|
||||||
char * subject;
|
|
||||||
char * bodyEncoding;
|
|
||||||
char * body;
|
|
||||||
char * auth;
|
|
||||||
char buffer[1];
|
|
||||||
};
|
|
||||||
|
|
||||||
static bool MailNotifyProc (
|
|
||||||
AsyncSocket sock,
|
|
||||||
EAsyncNotifySocket code,
|
|
||||||
AsyncNotifySocket * notify,
|
|
||||||
void ** userState
|
|
||||||
);
|
|
||||||
|
|
||||||
static void CDECL Send (
|
|
||||||
AsyncSocket sock,
|
|
||||||
const char str[],
|
|
||||||
...
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************************
|
|
||||||
*
|
|
||||||
* Private data
|
|
||||||
*
|
|
||||||
***/
|
|
||||||
|
|
||||||
static bool s_shutdown;
|
|
||||||
static CCritSect s_critsect;
|
|
||||||
static LISTDECL(MailTransaction, link) s_mail;
|
|
||||||
|
|
||||||
|
|
||||||
//===========================================================================
|
|
||||||
// Authenticated email sequence
|
|
||||||
// -> "220 catherine.cyan.com ESMTP\r\n"
|
|
||||||
// <- "HELO cyan.com\r\n"
|
|
||||||
// -> "250 catherine.cyan.com\r\n"
|
|
||||||
// <- "AUTH PLAIN XXXXXXXXX\r\n"
|
|
||||||
// -> "235 go ahead\r\n"
|
|
||||||
// <- "MAIL FROM:<UruClient@cyanworlds.com>\r\n"
|
|
||||||
// -> "250 ok mail from accepted\r\n"
|
|
||||||
// <- "RCPT TO:<UruCrashReport@cyanworlds.com>\r\n"
|
|
||||||
// -> "250 ok recipient accepted\r\n"
|
|
||||||
// <- "DATA\r\n"
|
|
||||||
// -> "354 ok, go ahead:\r\n"
|
|
||||||
// -> <message> + "\r\n.\r\n"
|
|
||||||
// -> "250 message accepted for delivery\r\n"
|
|
||||||
// <- "QUIT\r\n"
|
|
||||||
// -> "221 catherine.cyan.com\r\n"
|
|
||||||
//===========================================================================
|
|
||||||
static const char * s_waitStrAuth[] = {
|
|
||||||
"220 ", // kMailStepConnect
|
|
||||||
"250 ", // kMailStepAuth
|
|
||||||
"235 ", // kMailStepSender
|
|
||||||
"250 ", // kMailStepRecipient
|
|
||||||
"250 ", // kMailStepStartLetter
|
|
||||||
"354 ", // kMailStepLetter
|
|
||||||
"250 ", // kMailStepQuit
|
|
||||||
"221 ", // kMailStepDisconnect
|
|
||||||
};
|
|
||||||
|
|
||||||
//===========================================================================
|
|
||||||
// Unauthenticated email seqeunce
|
|
||||||
// -> "220 catherine.cyan.com ESMTP\r\n"
|
|
||||||
// <- "HELO cyan.com\r\n"
|
|
||||||
// -> "250 catherine.cyan.com\r\n"
|
|
||||||
// <- "MAIL FROM:<UruClient@cyanworlds.com>\r\n"
|
|
||||||
// -> "250 ok mail from accepted\r\n"
|
|
||||||
// <- "RCPT TO:<UruCrashReport@cyanworlds.com>\r\n"
|
|
||||||
// -> "250 ok recipient accepted\r\n"
|
|
||||||
// <- "DATA\r\n"
|
|
||||||
// -> "354 ok, go ahead:\r\n"
|
|
||||||
// -> <message> + "\r\n.\r\n"
|
|
||||||
// -> "250 message accepted for delivery\r\n"
|
|
||||||
// <- "QUIT\r\n"
|
|
||||||
// -> "221 catherine.cyan.com\r\n"
|
|
||||||
//===========================================================================
|
|
||||||
static const char * s_waitStrNoAuth[] = {
|
|
||||||
"220 ", // kMailStepConnect
|
|
||||||
nil, // kMailStepAuth
|
|
||||||
"250 ", // kMailStepSender
|
|
||||||
"250 ", // kMailStepRecipient
|
|
||||||
"250 ", // kMailStepStartLetter
|
|
||||||
"354 ", // kMailStepLetter
|
|
||||||
"250 ", // kMailStepQuit
|
|
||||||
"221 ", // kMailStepDisconnect
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************************
|
|
||||||
*
|
|
||||||
* Internal functions
|
|
||||||
*
|
|
||||||
***/
|
|
||||||
|
|
||||||
//===========================================================================
|
|
||||||
static bool AdvanceStep (
|
|
||||||
MailTransaction * transaction,
|
|
||||||
AsyncSocket sock
|
|
||||||
) {
|
|
||||||
switch (transaction->step) {
|
|
||||||
case kMailStepConnect: {
|
|
||||||
const char * host = transaction->sender;
|
|
||||||
const char * separator = StrChr(host, '@');
|
|
||||||
if (separator)
|
|
||||||
host = separator + 1;
|
|
||||||
Send(sock, "helo ", host, "\r\n", nil);
|
|
||||||
transaction->step = kMailStepSender;
|
|
||||||
|
|
||||||
if (transaction->auth[0])
|
|
||||||
transaction->step = kMailStepAuth;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case kMailStepAuth:
|
|
||||||
Send(sock, "AUTH PLAIN ", transaction->auth, "\r\n", nil);
|
|
||||||
transaction->step = kMailStepSender;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case kMailStepSender:
|
|
||||||
Send(sock, "mail from:<", transaction->sender, ">\r\n", nil);
|
|
||||||
transaction->step = kMailStepRecipient;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case kMailStepRecipient: {
|
|
||||||
const char * start = transaction->recipient + transaction->subStep;
|
|
||||||
while (*start == ' ')
|
|
||||||
++start;
|
|
||||||
const char * term = StrChr(start, ';');
|
|
||||||
if (term) {
|
|
||||||
char * buffer = (char*)malloc(term + 1 - start);
|
|
||||||
StrCopy(buffer, start, term + 1 - start);
|
|
||||||
Send(sock, "rcpt to:<", buffer, ">\r\n", nil);
|
|
||||||
transaction->subStep = term + 1 - transaction->recipient;
|
|
||||||
|
|
||||||
free(buffer);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
Send(sock, "rcpt to:<", start, ">\r\n", nil);
|
|
||||||
transaction->step = kMailStepStartLetter;
|
|
||||||
transaction->subStep = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case kMailStepStartLetter:
|
|
||||||
Send(sock, "data\r\n", nil);
|
|
||||||
transaction->step = kMailStepLetter;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case kMailStepLetter:
|
|
||||||
if (transaction->replyTo[0]) {
|
|
||||||
Send(
|
|
||||||
sock,
|
|
||||||
"Reply-to: ",
|
|
||||||
transaction->replyTo,
|
|
||||||
"\r\n",
|
|
||||||
nil
|
|
||||||
);
|
|
||||||
}
|
|
||||||
if (transaction->bodyEncoding) {
|
|
||||||
Send(
|
|
||||||
sock,
|
|
||||||
"From: ",
|
|
||||||
transaction->sender,
|
|
||||||
"\r\nTo: ",
|
|
||||||
transaction->recipient,
|
|
||||||
"\r\nSubject: ",
|
|
||||||
transaction->subject,
|
|
||||||
"\r\nContent-Type: text/plain; charset=",
|
|
||||||
transaction->bodyEncoding,
|
|
||||||
"\r\n\r\n",
|
|
||||||
transaction->body,
|
|
||||||
"\r\n.\r\n",
|
|
||||||
nil
|
|
||||||
);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
Send(
|
|
||||||
sock,
|
|
||||||
"From: ",
|
|
||||||
transaction->sender,
|
|
||||||
"\r\nTo: ",
|
|
||||||
transaction->recipient,
|
|
||||||
"\r\nSubject: ",
|
|
||||||
transaction->subject,
|
|
||||||
"\r\n\r\n",
|
|
||||||
transaction->body,
|
|
||||||
"\r\n.\r\n",
|
|
||||||
nil
|
|
||||||
);
|
|
||||||
}
|
|
||||||
transaction->step = kMailStepQuit;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case kMailStepQuit:
|
|
||||||
Send(sock, "quit\r\n", nil);
|
|
||||||
transaction->step = kMailStepDisconnect;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case kMailStepDisconnect:
|
|
||||||
return false;
|
|
||||||
|
|
||||||
DEFAULT_FATAL(transaction->step);
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
//===========================================================================
|
|
||||||
static bool NotifyRead (
|
|
||||||
AsyncSocket sock,
|
|
||||||
AsyncNotifySocketRead * read,
|
|
||||||
MailTransaction * transaction
|
|
||||||
) {
|
|
||||||
|
|
||||||
// Parse available lines looking for an acknowledgement of last command
|
|
||||||
const char * compareStr = transaction->stepTable[transaction->step];
|
|
||||||
unsigned compareLen = StrLen(compareStr);
|
|
||||||
unsigned offset = 0;
|
|
||||||
for (;;) {
|
|
||||||
const char * source = (const char *)&read->buffer[offset];
|
|
||||||
|
|
||||||
// Search for an end-of-line marker
|
|
||||||
const char * eol = StrChr(source, '\n', read->bytes - offset);
|
|
||||||
if (!eol)
|
|
||||||
break;
|
|
||||||
offset += (eol + 1 - source);
|
|
||||||
|
|
||||||
// Search for an acknowledgement
|
|
||||||
if (!StrCmp(source, compareStr, compareLen)) {
|
|
||||||
read->bytesProcessed = offset;
|
|
||||||
return AdvanceStep(transaction, sock);
|
|
||||||
}
|
|
||||||
|
|
||||||
// An error was received; log it and bail
|
|
||||||
LogMsg(
|
|
||||||
kLogError,
|
|
||||||
"Mail: step %u error '%.*s'",
|
|
||||||
transaction->step,
|
|
||||||
eol - source - 1,
|
|
||||||
source
|
|
||||||
);
|
|
||||||
transaction->error = kMailErrServerError;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// We did not find an acknowledgement, so skip past fully-received lines
|
|
||||||
// and wait for more data to arrive
|
|
||||||
read->bytesProcessed = offset;
|
|
||||||
return true;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
//===========================================================================
|
|
||||||
static void DestroyTransaction (MailTransaction * transaction) {
|
|
||||||
|
|
||||||
// Remove transaction from list so that it can
|
|
||||||
// be safely deleted outside the critical section
|
|
||||||
s_critsect.Enter();
|
|
||||||
{
|
|
||||||
s_mail.Unlink(transaction);
|
|
||||||
}
|
|
||||||
s_critsect.Leave();
|
|
||||||
|
|
||||||
// Perform callback if requested
|
|
||||||
if (transaction->callback) {
|
|
||||||
transaction->callback(
|
|
||||||
transaction->param,
|
|
||||||
transaction->error
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
delete transaction;
|
|
||||||
}
|
|
||||||
|
|
||||||
//===========================================================================
|
|
||||||
static void MailLookupProc (
|
|
||||||
void * param,
|
|
||||||
const wchar_t * ,
|
|
||||||
unsigned addrCount,
|
|
||||||
const NetAddress addrs[]
|
|
||||||
) {
|
|
||||||
|
|
||||||
// If no address was found, cancel the transaction
|
|
||||||
MailTransaction * transaction = (MailTransaction *) param;
|
|
||||||
if (!addrCount) {
|
|
||||||
LogMsg(kLogError,"Mail: failed to resolve %s", transaction->smtp);
|
|
||||||
transaction->error = kMailErrDnsFailed;
|
|
||||||
DestroyTransaction(transaction);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Initiate a connection
|
|
||||||
AsyncCancelId cancelId;
|
|
||||||
AsyncSocketConnect(
|
|
||||||
&cancelId,
|
|
||||||
addrs[0],
|
|
||||||
MailNotifyProc,
|
|
||||||
transaction
|
|
||||||
);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
//===========================================================================
|
|
||||||
static bool MailNotifyProc (
|
|
||||||
AsyncSocket sock,
|
|
||||||
EAsyncNotifySocket code,
|
|
||||||
AsyncNotifySocket * notify,
|
|
||||||
void ** userState
|
|
||||||
) {
|
|
||||||
switch (code) {
|
|
||||||
case kNotifySocketConnectFailed: {
|
|
||||||
MailTransaction * transaction = (MailTransaction *)notify->param;
|
|
||||||
LogMsg(kLogError, "Mail: unable to connect to %s", transaction->smtp);
|
|
||||||
transaction->error = kMailErrConnectFailed;
|
|
||||||
DestroyTransaction(transaction);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case kNotifySocketConnectSuccess: {
|
|
||||||
MailTransaction * transaction = (MailTransaction *) notify->param;
|
|
||||||
*userState = notify->param;
|
|
||||||
transaction->sock = sock;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case kNotifySocketRead: {
|
|
||||||
MailTransaction * transaction = (MailTransaction *) *userState;
|
|
||||||
return NotifyRead(sock, (AsyncNotifySocketRead *) notify, transaction);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case kNotifySocketDisconnect: {
|
|
||||||
MailTransaction * transaction = (MailTransaction *) *userState;
|
|
||||||
if ((transaction->step != kMailStepDisconnect) && !transaction->error) {
|
|
||||||
transaction->error = kMailErrDisconnected;
|
|
||||||
LogMsg(kLogError, "Mail: unexpected disconnection from %s", transaction->smtp);
|
|
||||||
}
|
|
||||||
DestroyTransaction(transaction);
|
|
||||||
AsyncSocketDelete(sock);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return !s_shutdown;
|
|
||||||
}
|
|
||||||
|
|
||||||
//===========================================================================
|
|
||||||
static void CDECL Send (
|
|
||||||
AsyncSocket sock,
|
|
||||||
const char str[],
|
|
||||||
...
|
|
||||||
) {
|
|
||||||
// Count bytes
|
|
||||||
unsigned bytes = 1;
|
|
||||||
{
|
|
||||||
va_list argList;
|
|
||||||
va_start(argList, str);
|
|
||||||
for (const char * source = str; source; source = va_arg(argList, const char *))
|
|
||||||
bytes += StrLen(source);
|
|
||||||
va_end(argList);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Allocate string buffer
|
|
||||||
char* packed = (char *) malloc(bytes);
|
|
||||||
|
|
||||||
// Pack the string
|
|
||||||
{
|
|
||||||
va_list argList;
|
|
||||||
va_start(argList, str);
|
|
||||||
char * dest = packed;
|
|
||||||
for (const char * source = str; source; source = va_arg(argList, const char *))
|
|
||||||
dest += StrCopyLen(dest, source, packed + bytes - dest);
|
|
||||||
va_end(argList);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Send the string
|
|
||||||
AsyncSocketSend(sock, packed, bytes - 1);
|
|
||||||
|
|
||||||
// Free the string
|
|
||||||
free(packed);
|
|
||||||
}
|
|
||||||
|
|
||||||
//===========================================================================
|
|
||||||
static void IMail (
|
|
||||||
const char * stepTable[],
|
|
||||||
const char smtp[],
|
|
||||||
const char sender[],
|
|
||||||
const char recipient[],
|
|
||||||
const char replyTo[],
|
|
||||||
const char subject[],
|
|
||||||
const char body[],
|
|
||||||
const char auth[],
|
|
||||||
EMailEncoding bodyEncoding,
|
|
||||||
FMailResult callback,
|
|
||||||
void * param
|
|
||||||
) {
|
|
||||||
static const char * utf8 = "\"utf-8\"";
|
|
||||||
const char * encodingStr;
|
|
||||||
|
|
||||||
if (bodyEncoding == kMailEncodeUtf8)
|
|
||||||
encodingStr = utf8;
|
|
||||||
else
|
|
||||||
encodingStr = "";
|
|
||||||
|
|
||||||
// Calculate string lengths
|
|
||||||
unsigned lenSmtp = StrLen(smtp);
|
|
||||||
unsigned lenSender = StrLen(sender);
|
|
||||||
unsigned lenRecipient = StrLen(recipient);
|
|
||||||
unsigned lenReplyTo = StrLen(replyTo);
|
|
||||||
unsigned lenSubject = StrLen(subject);
|
|
||||||
unsigned lenBodyEncoding = StrLen(encodingStr);
|
|
||||||
unsigned lenBody = StrLen(body);
|
|
||||||
unsigned lenAuth = StrLen(auth);
|
|
||||||
|
|
||||||
// Calculate the required buffer size for all strings
|
|
||||||
unsigned bytes = (
|
|
||||||
lenSmtp + 1 +
|
|
||||||
lenSender + 1 +
|
|
||||||
lenRecipient + 1 +
|
|
||||||
lenReplyTo + 1 +
|
|
||||||
lenSubject + 1 +
|
|
||||||
lenBody + 1 +
|
|
||||||
lenAuth + 1
|
|
||||||
) * sizeof(char);
|
|
||||||
|
|
||||||
if (lenBodyEncoding)
|
|
||||||
bytes += (lenBodyEncoding + 1) * sizeof(char);
|
|
||||||
|
|
||||||
// Create a transaction record
|
|
||||||
MailTransaction * transaction = new(
|
|
||||||
malloc(offsetof(MailTransaction, buffer) + bytes)
|
|
||||||
) MailTransaction;
|
|
||||||
transaction->stepTable = stepTable;
|
|
||||||
transaction->sock = nil;
|
|
||||||
transaction->step = kMailStepConnect;
|
|
||||||
transaction->subStep = 0;
|
|
||||||
transaction->error = kMailSuccess;
|
|
||||||
transaction->callback = callback;
|
|
||||||
transaction->param = param;
|
|
||||||
|
|
||||||
unsigned offset = 0;
|
|
||||||
transaction->smtp = transaction->buffer + offset;
|
|
||||||
offset += StrCopyLen(transaction->smtp, smtp, lenSmtp + 1) + 1;
|
|
||||||
transaction->sender = transaction->buffer + offset;
|
|
||||||
offset += StrCopyLen(transaction->sender, sender, lenSender + 1) + 1;
|
|
||||||
transaction->recipient = transaction->buffer + offset;
|
|
||||||
offset += StrCopyLen(transaction->recipient, recipient, lenRecipient + 1) + 1;
|
|
||||||
transaction->replyTo = transaction->buffer + offset;
|
|
||||||
offset += StrCopyLen(transaction->replyTo, replyTo, lenReplyTo + 1) + 1;
|
|
||||||
transaction->subject = transaction->buffer + offset;
|
|
||||||
offset += StrCopyLen(transaction->subject, subject, lenSubject + 1) + 1;
|
|
||||||
if (lenBodyEncoding) {
|
|
||||||
transaction->bodyEncoding = transaction->buffer + offset;
|
|
||||||
offset += StrCopyLen(transaction->bodyEncoding, encodingStr, lenBodyEncoding + 1) + 1;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
transaction->bodyEncoding = nil;
|
|
||||||
}
|
|
||||||
transaction->body = transaction->buffer + offset;
|
|
||||||
offset += StrCopyLen(transaction->body, body, lenBody + 1) + 1;
|
|
||||||
transaction->auth = transaction->buffer + offset;
|
|
||||||
offset += StrCopyLen(transaction->auth, auth, lenAuth + 1) + 1;
|
|
||||||
ASSERT(offset == bytes);
|
|
||||||
|
|
||||||
// Start the transaction with a dns lookup
|
|
||||||
const unsigned kSmtpPort = 25;
|
|
||||||
wchar_t smtpName[256];
|
|
||||||
StrToUnicode(smtpName, smtp, arrsize(smtpName));
|
|
||||||
|
|
||||||
// Add transaction to global list
|
|
||||||
bool shutdown;
|
|
||||||
s_critsect.Enter();
|
|
||||||
{
|
|
||||||
shutdown = s_shutdown;
|
|
||||||
s_mail.Link(transaction);
|
|
||||||
}
|
|
||||||
s_critsect.Leave();
|
|
||||||
|
|
||||||
if (shutdown) {
|
|
||||||
DestroyTransaction(transaction);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
NetAddress addr;
|
|
||||||
if (NetAddressFromString(&addr, smtpName, kSmtpPort)) {
|
|
||||||
AsyncCancelId cancelId;
|
|
||||||
AsyncSocketConnect(
|
|
||||||
&cancelId,
|
|
||||||
addr,
|
|
||||||
MailNotifyProc,
|
|
||||||
transaction
|
|
||||||
);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
AsyncCancelId cancelId;
|
|
||||||
AsyncAddressLookupName(
|
|
||||||
&cancelId,
|
|
||||||
MailLookupProc,
|
|
||||||
smtpName,
|
|
||||||
kSmtpPort,
|
|
||||||
transaction
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
*
|
|
||||||
* Exported functions
|
|
||||||
*
|
|
||||||
***/
|
|
||||||
|
|
||||||
//===========================================================================
|
|
||||||
void MailEncodePassword (
|
|
||||||
const char username[],
|
|
||||||
const char password[],
|
|
||||||
ARRAY(char) * emailAuth
|
|
||||||
) {
|
|
||||||
// base64_encode("\0#{user}\0#{secret}")
|
|
||||||
emailAuth->Reserve(512);
|
|
||||||
emailAuth->Push(0);
|
|
||||||
emailAuth->Add(username, StrBytes(username));
|
|
||||||
emailAuth->Add(password, StrBytes(password));
|
|
||||||
unsigned srcChars = emailAuth->Bytes();
|
|
||||||
|
|
||||||
// Allocate space for encoded data
|
|
||||||
unsigned dstChars = Base64EncodeSize(srcChars);
|
|
||||||
char * dstData = emailAuth->New(dstChars);
|
|
||||||
|
|
||||||
// Encode data and move it back to the front of the array
|
|
||||||
dstChars = Base64Encode(
|
|
||||||
srcChars,
|
|
||||||
(const uint8_t *) emailAuth->Ptr(),
|
|
||||||
dstChars,
|
|
||||||
dstData
|
|
||||||
);
|
|
||||||
emailAuth->Move(
|
|
||||||
0,
|
|
||||||
srcChars,
|
|
||||||
dstChars
|
|
||||||
);
|
|
||||||
emailAuth->SetCountFewer(dstChars);
|
|
||||||
}
|
|
||||||
|
|
||||||
//===========================================================================
|
|
||||||
void Mail (
|
|
||||||
const char smtp[],
|
|
||||||
const char sender[],
|
|
||||||
const char recipient[], // multiple recipients separated by semicolons
|
|
||||||
const char subject[],
|
|
||||||
const char body[],
|
|
||||||
const char username[],
|
|
||||||
const char password[],
|
|
||||||
const char replyTo[],
|
|
||||||
EMailEncoding bodyEncoding,
|
|
||||||
FMailResult callback,
|
|
||||||
void * param
|
|
||||||
) {
|
|
||||||
s_shutdown = false;
|
|
||||||
|
|
||||||
// Get email authorization
|
|
||||||
const char * auth;
|
|
||||||
const char ** stepTable;
|
|
||||||
ARRAY(char) authBuffer;
|
|
||||||
if (!password || !*password) {
|
|
||||||
// No password is specified, use non-authenticated email
|
|
||||||
auth = "";
|
|
||||||
stepTable = s_waitStrNoAuth;
|
|
||||||
}
|
|
||||||
else if (!username || !*username) {
|
|
||||||
// No username specified, user is providing the base64 encoded secret
|
|
||||||
auth = password;
|
|
||||||
stepTable = s_waitStrAuth;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
MailEncodePassword(username, password, &authBuffer);
|
|
||||||
auth = authBuffer.Ptr();
|
|
||||||
stepTable = s_waitStrAuth;
|
|
||||||
}
|
|
||||||
|
|
||||||
IMail(
|
|
||||||
stepTable,
|
|
||||||
smtp,
|
|
||||||
sender,
|
|
||||||
recipient,
|
|
||||||
replyTo ? replyTo : "",
|
|
||||||
subject,
|
|
||||||
body,
|
|
||||||
auth,
|
|
||||||
bodyEncoding,
|
|
||||||
callback,
|
|
||||||
param
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
//===========================================================================
|
|
||||||
void MailStop () {
|
|
||||||
s_critsect.Enter();
|
|
||||||
{
|
|
||||||
s_shutdown = true;
|
|
||||||
MailTransaction * transaction = s_mail.Head();
|
|
||||||
for (; transaction; transaction = s_mail.Next(transaction)) {
|
|
||||||
if (transaction->sock)
|
|
||||||
AsyncSocketDisconnect(transaction->sock, true);
|
|
||||||
transaction->error = kMailErrClientCanceled;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
s_critsect.Leave();
|
|
||||||
|
|
||||||
AsyncAddressLookupCancel(
|
|
||||||
MailLookupProc,
|
|
||||||
0 // cancel all
|
|
||||||
);
|
|
||||||
AsyncSocketConnectCancel(
|
|
||||||
MailNotifyProc,
|
|
||||||
0 // cancel all
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
//===========================================================================
|
|
||||||
bool MailQueued () {
|
|
||||||
bool queued;
|
|
||||||
s_critsect.Enter();
|
|
||||||
queued = s_mail.Head() != nil;
|
|
||||||
s_critsect.Leave();
|
|
||||||
return queued;
|
|
||||||
}
|
|
||||||
|
|
||||||
//============================================================================
|
|
||||||
const wchar_t * MailErrorToString (EMailError error) {
|
|
||||||
|
|
||||||
switch (error) {
|
|
||||||
case kMailSuccess: return L"kMailSuccess";
|
|
||||||
case kMailErrDnsFailed: return L"kMailErrDnsFailed";
|
|
||||||
case kMailErrConnectFailed: return L"kMailErrConnectFailed";
|
|
||||||
case kMailErrDisconnected: return L"kMailErrDisconnected";
|
|
||||||
case kMailErrClientCanceled: return L"kMailErrClientCanceled";
|
|
||||||
case kMailErrServerError: return L"kMailErrServerError";
|
|
||||||
DEFAULT_FATAL(error);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,112 +0,0 @@
|
|||||||
/*==LICENSE==*
|
|
||||||
|
|
||||||
CyanWorlds.com Engine - MMOG client, server and tools
|
|
||||||
Copyright (C) 2011 Cyan Worlds, Inc.
|
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
Additional permissions under GNU GPL version 3 section 7
|
|
||||||
|
|
||||||
If you modify this Program, or any covered work, by linking or
|
|
||||||
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
|
|
||||||
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
|
|
||||||
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
|
|
||||||
(or a modified version of those libraries),
|
|
||||||
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
|
|
||||||
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
|
|
||||||
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
|
|
||||||
licensors of this Program grant you additional
|
|
||||||
permission to convey the resulting work. Corresponding Source for a
|
|
||||||
non-source form of such a combination shall include the source code for
|
|
||||||
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
|
|
||||||
work.
|
|
||||||
|
|
||||||
You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
|
||||||
or by snail mail at:
|
|
||||||
Cyan Worlds, Inc.
|
|
||||||
14617 N Newport Hwy
|
|
||||||
Mead, WA 99021
|
|
||||||
|
|
||||||
*==LICENSE==*/
|
|
||||||
/*****************************************************************************
|
|
||||||
*
|
|
||||||
* $/Plasma20/Sources/Plasma/NucleusLib/pnMail/pnMail.h
|
|
||||||
*
|
|
||||||
***/
|
|
||||||
|
|
||||||
#ifndef PLASMA20_SOURCES_PLASMA_NUCLEUSLIB_PNMAIL_PNMAIL_H
|
|
||||||
#define PLASMA20_SOURCES_PLASMA_NUCLEUSLIB_PNMAIL_PNMAIL_H
|
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************************
|
|
||||||
*
|
|
||||||
* Mail API
|
|
||||||
*
|
|
||||||
***/
|
|
||||||
|
|
||||||
enum EMailEncoding {
|
|
||||||
kMailEncodeNone,
|
|
||||||
kMailEncodeAscii,
|
|
||||||
kMailEncodeUtf8,
|
|
||||||
};
|
|
||||||
|
|
||||||
enum EMailError {
|
|
||||||
kMailSuccess,
|
|
||||||
kMailErrDnsFailed,
|
|
||||||
kMailErrConnectFailed,
|
|
||||||
kMailErrDisconnected,
|
|
||||||
kMailErrClientCanceled,
|
|
||||||
kMailErrServerError,
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
typedef void (* FMailResult)(void * param, EMailError result);
|
|
||||||
|
|
||||||
|
|
||||||
void MailStop ();
|
|
||||||
bool MailQueued ();
|
|
||||||
|
|
||||||
const wchar_t * MailErrorToString (EMailError error);
|
|
||||||
|
|
||||||
|
|
||||||
//============================================================================
|
|
||||||
// AUTHENTICATION NOTES
|
|
||||||
// username, password
|
|
||||||
// NULL NULL --> no authentication
|
|
||||||
// NULL string --> username/password assumed to be pre-encoded with MailEncodePassword
|
|
||||||
// string string --> username/password contain appropriate values for snmp server
|
|
||||||
//============================================================================
|
|
||||||
|
|
||||||
void Mail (
|
|
||||||
const char smtp[],
|
|
||||||
const char sender[],
|
|
||||||
const char recipients[], // separate multiple recipients with semicolons
|
|
||||||
const char subject[],
|
|
||||||
const char body[],
|
|
||||||
const char username[], // optional (see auth notes above)
|
|
||||||
const char password[], // optional (see auth notes above)
|
|
||||||
const char replyTo[], // optional
|
|
||||||
EMailEncoding encoding,
|
|
||||||
FMailResult callback, // optional
|
|
||||||
void * param // optional
|
|
||||||
);
|
|
||||||
|
|
||||||
void MailEncodePassword (
|
|
||||||
const char username[],
|
|
||||||
const char password[],
|
|
||||||
ARRAY(char) * emailAuth
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
#endif // PLASMA20_SOURCES_PLASMA_NUCLEUSLIB_PNMAIL_PNMAIL_H
|
|
@ -1,83 +0,0 @@
|
|||||||
/*==LICENSE==*
|
|
||||||
|
|
||||||
CyanWorlds.com Engine - MMOG client, server and tools
|
|
||||||
Copyright (C) 2011 Cyan Worlds, Inc.
|
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
Additional permissions under GNU GPL version 3 section 7
|
|
||||||
|
|
||||||
If you modify this Program, or any covered work, by linking or
|
|
||||||
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
|
|
||||||
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
|
|
||||||
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
|
|
||||||
(or a modified version of those libraries),
|
|
||||||
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
|
|
||||||
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
|
|
||||||
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
|
|
||||||
licensors of this Program grant you additional
|
|
||||||
permission to convey the resulting work. Corresponding Source for a
|
|
||||||
non-source form of such a combination shall include the source code for
|
|
||||||
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
|
|
||||||
work.
|
|
||||||
|
|
||||||
You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
|
||||||
or by snail mail at:
|
|
||||||
Cyan Worlds, Inc.
|
|
||||||
14617 N Newport Hwy
|
|
||||||
Mead, WA 99021
|
|
||||||
|
|
||||||
*==LICENSE==*/
|
|
||||||
/*****************************************************************************
|
|
||||||
*
|
|
||||||
* $/Plasma20/Sources/Plasma/NucleusLib/pnNetLog/Intern.h
|
|
||||||
*
|
|
||||||
***/
|
|
||||||
|
|
||||||
#ifdef PLASMA20_SOURCES_PLASMA_NUCLEUSLIB_PNNETLOG_INTERN_H
|
|
||||||
#error "Header $/Plasma20/Sources/Plasma/NucleusLib/pnNetLog/Intern.h included more than once"
|
|
||||||
#endif
|
|
||||||
#define PLASMA20_SOURCES_PLASMA_NUCLEUSLIB_PNNETLOG_INTERN_H
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************************
|
|
||||||
*
|
|
||||||
* pnNlApi.cpp
|
|
||||||
*
|
|
||||||
***/
|
|
||||||
|
|
||||||
const NetLogEvent *NetLogFindEvent (unsigned type, ESrvType srvType);
|
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************************
|
|
||||||
*
|
|
||||||
* pnNlCli.cpp
|
|
||||||
*
|
|
||||||
***/
|
|
||||||
|
|
||||||
void NetLogCliInitialize (ESrvType srvType);
|
|
||||||
void NetLogCliShutdown ();
|
|
||||||
void NetLogCliDestroy ();
|
|
||||||
void NetLogCliSendEvent (const NetLogEvent &event, va_list args);
|
|
||||||
|
|
||||||
/*****************************************************************************
|
|
||||||
*
|
|
||||||
* pnNlSrv.cpp
|
|
||||||
*
|
|
||||||
***/
|
|
||||||
|
|
||||||
void NetLogSrvInitialize ();
|
|
||||||
void NetLogSrvShutdown ();
|
|
||||||
void NetLogSrvDestroy ();
|
|
@ -1,74 +0,0 @@
|
|||||||
/*==LICENSE==*
|
|
||||||
|
|
||||||
CyanWorlds.com Engine - MMOG client, server and tools
|
|
||||||
Copyright (C) 2011 Cyan Worlds, Inc.
|
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
Additional permissions under GNU GPL version 3 section 7
|
|
||||||
|
|
||||||
If you modify this Program, or any covered work, by linking or
|
|
||||||
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
|
|
||||||
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
|
|
||||||
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
|
|
||||||
(or a modified version of those libraries),
|
|
||||||
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
|
|
||||||
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
|
|
||||||
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
|
|
||||||
licensors of this Program grant you additional
|
|
||||||
permission to convey the resulting work. Corresponding Source for a
|
|
||||||
non-source form of such a combination shall include the source code for
|
|
||||||
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
|
|
||||||
work.
|
|
||||||
|
|
||||||
You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
|
||||||
or by snail mail at:
|
|
||||||
Cyan Worlds, Inc.
|
|
||||||
14617 N Newport Hwy
|
|
||||||
Mead, WA 99021
|
|
||||||
|
|
||||||
*==LICENSE==*/
|
|
||||||
/*****************************************************************************
|
|
||||||
*
|
|
||||||
* $/Plasma20/Sources/Plasma/NucleusLib/pnNetLog/Pch.h
|
|
||||||
*
|
|
||||||
***/
|
|
||||||
|
|
||||||
#ifdef PLASMA20_SOURCES_PLASMA_NUCLEUSLIB_PNNETLOG_PCH_H
|
|
||||||
#error "Header $/Plasma20/Sources/Plasma/NucleusLib/pnNetLog/Pch.h included more than once"
|
|
||||||
#endif
|
|
||||||
#define PLASMA20_SOURCES_PLASMA_NUCLEUSLIB_PNNETLOG_PCH_H
|
|
||||||
|
|
||||||
|
|
||||||
// NucleusLib
|
|
||||||
#include "pnUtils/pnUtils.h"
|
|
||||||
#include "pnNetBase/pnNetBase.h"
|
|
||||||
#include "pnAsyncCore/pnAsyncCore.h"
|
|
||||||
#include "pnNetCli/pnNetCli.h"
|
|
||||||
|
|
||||||
#ifdef SERVER
|
|
||||||
#include "pnIni/pnIni.h"
|
|
||||||
#include "../ServerLib/psUtils/psUtils.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define USES_PROTOCOL_SRV2LOG
|
|
||||||
#include "pnNetProtocol/pnNetProtocol.h"
|
|
||||||
#include "pnProduct/pnProduct.h"
|
|
||||||
|
|
||||||
// Local
|
|
||||||
#include "pnNetLog.h"
|
|
||||||
#include "Intern.h"
|
|
||||||
|
|
||||||
// System
|
|
||||||
#include <malloc.h> // _alloca
|
|
@ -1,164 +0,0 @@
|
|||||||
/*==LICENSE==*
|
|
||||||
|
|
||||||
CyanWorlds.com Engine - MMOG client, server and tools
|
|
||||||
Copyright (C) 2011 Cyan Worlds, Inc.
|
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
Additional permissions under GNU GPL version 3 section 7
|
|
||||||
|
|
||||||
If you modify this Program, or any covered work, by linking or
|
|
||||||
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
|
|
||||||
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
|
|
||||||
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
|
|
||||||
(or a modified version of those libraries),
|
|
||||||
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
|
|
||||||
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
|
|
||||||
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
|
|
||||||
licensors of this Program grant you additional
|
|
||||||
permission to convey the resulting work. Corresponding Source for a
|
|
||||||
non-source form of such a combination shall include the source code for
|
|
||||||
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
|
|
||||||
work.
|
|
||||||
|
|
||||||
You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
|
||||||
or by snail mail at:
|
|
||||||
Cyan Worlds, Inc.
|
|
||||||
14617 N Newport Hwy
|
|
||||||
Mead, WA 99021
|
|
||||||
|
|
||||||
*==LICENSE==*/
|
|
||||||
/*****************************************************************************
|
|
||||||
*
|
|
||||||
* $/Plasma20/Sources/Plasma/NucleusLib/pnNetLog/pnNetLog.h
|
|
||||||
*
|
|
||||||
***/
|
|
||||||
|
|
||||||
#ifdef PLASMA20_SOURCES_PLASMA_NUCLEUSLIB_PNNETLOG_PNNETLOG_H
|
|
||||||
#error "Header $/Plasma20/Sources/Plasma/NucleusLib/pnNetLog/pnNetLog.h included more than once"
|
|
||||||
#endif
|
|
||||||
#define PLASMA20_SOURCES_PLASMA_NUCLEUSLIB_PNNETLOG_PNNETLOG_H
|
|
||||||
|
|
||||||
#define MAX_NAME_LEN 64
|
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************************
|
|
||||||
*
|
|
||||||
*
|
|
||||||
Look at psLogEvents/psLeAuth for an example of how to create a new LogEvent
|
|
||||||
*
|
|
||||||
***/
|
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************************
|
|
||||||
*
|
|
||||||
* Log Template Definitions
|
|
||||||
*
|
|
||||||
***/
|
|
||||||
|
|
||||||
enum ELogParamType {
|
|
||||||
kLogParamInt, // (int)
|
|
||||||
kLogParamUnsigned, // (unsigned)
|
|
||||||
kLogParamFloat, // (float)
|
|
||||||
kLogParamUuid, // Uuid
|
|
||||||
kLogParamStringW, // (const wchar_t *)
|
|
||||||
kLogParamLong, // (long) or (uint32_t)
|
|
||||||
kLogParamLongLong, // (long long) or (uint64_t)
|
|
||||||
kNumLogParamTypes
|
|
||||||
};
|
|
||||||
|
|
||||||
struct NetLogField {
|
|
||||||
ELogParamType type; // element type
|
|
||||||
wchar_t name[MAX_PATH];
|
|
||||||
};
|
|
||||||
|
|
||||||
struct NetLogEvent {
|
|
||||||
ESrvType srvType;
|
|
||||||
unsigned logEventType;
|
|
||||||
const wchar_t * eventName;
|
|
||||||
const NetLogField * fields;
|
|
||||||
unsigned numFields;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct NetLogSrvField {
|
|
||||||
const wchar_t *name;
|
|
||||||
const wchar_t *data;
|
|
||||||
};
|
|
||||||
|
|
||||||
#define NET_LOG_FIELD_INT(name) { kLogParamInt, name }
|
|
||||||
#define NET_LOG_FIELD_UNSIGNED(name) { kLogParamUnsigned, name }
|
|
||||||
#define NET_LOG_FIELD_FLOAT(name) { kLogParamFloat, name }
|
|
||||||
#define NET_LOG_FIELD_STRING(name) { kLogParamStringW, name }
|
|
||||||
#define NET_LOG_FIELD_UUID(name) { kLogParamUuid, name }
|
|
||||||
#define NET_LOG_FIELD_LONG(name) { kLogParamLong, name }
|
|
||||||
#define NET_LOG_FIELD_LONGLONG(name) { kLogParamLongLong, name }
|
|
||||||
|
|
||||||
#define NET_LOG_EVENT_AUTH(name) { kSrvTypeAuth, kLogEventId_##name, L#name, kLogEventFields_##name, arrsize( kLogEventFields_##name )}
|
|
||||||
#define NET_LOG_EVENT_GAME(name) { kSrvTypeGame, kLogEventId_##name, L#name, kLogEventFields_##name, arrsize( kLogEventFields_##name )}
|
|
||||||
#define NET_LOG_EVENT_MCP(name) { kSrvTypeMcp, kLogEventId_##name, L#name, kLogEventFields_##name, arrsize( kLogEventFields_##name )}
|
|
||||||
#define NET_LOG_EVENT_DB(name) { kSrvTypeDb, kLogEventId_##name, L#name, kLogEventFields_##name, arrsize( kLogEventFields_##name )}
|
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************************
|
|
||||||
*
|
|
||||||
* pnNlApi.cpp
|
|
||||||
*
|
|
||||||
***/
|
|
||||||
|
|
||||||
void NetLogInitialize (ESrvType srvType);
|
|
||||||
void NetLogShutdown ();
|
|
||||||
void NetLogDestroy ();
|
|
||||||
void NetLogRegisterEvents (const NetLogEvent events[], unsigned count);
|
|
||||||
|
|
||||||
// Should only be called by psLogEvents - look there for logging functions
|
|
||||||
void NetLogSendEvent (
|
|
||||||
unsigned type,
|
|
||||||
...
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************************
|
|
||||||
*
|
|
||||||
* pnNlConn.cpp
|
|
||||||
*
|
|
||||||
***/
|
|
||||||
|
|
||||||
enum {
|
|
||||||
kNlCliNumConn,
|
|
||||||
kNlCliNumTrans,
|
|
||||||
kNlCliNumPendingSaves,
|
|
||||||
kNlCliNumPerf,
|
|
||||||
};
|
|
||||||
|
|
||||||
long NlCliGetPerf (unsigned index);
|
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************************
|
|
||||||
*
|
|
||||||
* pnNlSrv.cpp
|
|
||||||
*
|
|
||||||
***/
|
|
||||||
|
|
||||||
struct LogConn;
|
|
||||||
enum {
|
|
||||||
kNlSrvPerfConnCount,
|
|
||||||
kNlSrvPerfConnDenied,
|
|
||||||
kNlSrvNumPerf
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef void (*NlSrvCallback)(const NetLogEvent *event, const ARRAY(wchar_t) &, unsigned, NetAddressNode &, uint64_t, unsigned, unsigned);
|
|
||||||
long NetLogSrvGetPerf (unsigned index);
|
|
||||||
void NetLogSrvRegisterCallback(NlSrvCallback callback);
|
|
||||||
void LogConnIncRef (LogConn * conn);
|
|
||||||
void LogConnDecRef (LogConn * conn);
|
|
@ -1,231 +0,0 @@
|
|||||||
/*==LICENSE==*
|
|
||||||
|
|
||||||
CyanWorlds.com Engine - MMOG client, server and tools
|
|
||||||
Copyright (C) 2011 Cyan Worlds, Inc.
|
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
Additional permissions under GNU GPL version 3 section 7
|
|
||||||
|
|
||||||
If you modify this Program, or any covered work, by linking or
|
|
||||||
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
|
|
||||||
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
|
|
||||||
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
|
|
||||||
(or a modified version of those libraries),
|
|
||||||
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
|
|
||||||
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
|
|
||||||
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
|
|
||||||
licensors of this Program grant you additional
|
|
||||||
permission to convey the resulting work. Corresponding Source for a
|
|
||||||
non-source form of such a combination shall include the source code for
|
|
||||||
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
|
|
||||||
work.
|
|
||||||
|
|
||||||
You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
|
||||||
or by snail mail at:
|
|
||||||
Cyan Worlds, Inc.
|
|
||||||
14617 N Newport Hwy
|
|
||||||
Mead, WA 99021
|
|
||||||
|
|
||||||
*==LICENSE==*/
|
|
||||||
/*****************************************************************************
|
|
||||||
*
|
|
||||||
* $/Plasma20/Sources/Plasma/NucleusLib/pnNetLog/pnNlApi.cpp
|
|
||||||
*
|
|
||||||
***/
|
|
||||||
|
|
||||||
#include "Pch.h"
|
|
||||||
#pragma hdrstop
|
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************************
|
|
||||||
*
|
|
||||||
* Private Data
|
|
||||||
*
|
|
||||||
***/
|
|
||||||
|
|
||||||
struct EventHash {
|
|
||||||
unsigned eventType;
|
|
||||||
ESrvType srvType;
|
|
||||||
|
|
||||||
inline EventHash (
|
|
||||||
unsigned eventType,
|
|
||||||
ESrvType srvType
|
|
||||||
);
|
|
||||||
|
|
||||||
inline uint32_t GetHash () const;
|
|
||||||
inline bool operator== (const EventHash & rhs) const;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct NetLogEventHash : EventHash {
|
|
||||||
const NetLogEvent * event;
|
|
||||||
|
|
||||||
NetLogEventHash(
|
|
||||||
unsigned eventType,
|
|
||||||
ESrvType srvType,
|
|
||||||
const NetLogEvent *event
|
|
||||||
);
|
|
||||||
HASHLINK(NetLogEventHash) link;
|
|
||||||
};
|
|
||||||
|
|
||||||
static CCritSect s_critsect;
|
|
||||||
static ESrvType s_srvType;
|
|
||||||
static HASHTABLEDECL(NetLogEventHash, EventHash, link) s_registeredEvents;
|
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************************
|
|
||||||
*
|
|
||||||
* NetLogEventHash
|
|
||||||
*
|
|
||||||
***/
|
|
||||||
|
|
||||||
//============================================================================
|
|
||||||
NetLogEventHash::NetLogEventHash (
|
|
||||||
unsigned eventType,
|
|
||||||
ESrvType srvType,
|
|
||||||
const NetLogEvent *event
|
|
||||||
) : EventHash(eventType, srvType),
|
|
||||||
event(event)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************************
|
|
||||||
*
|
|
||||||
* Event Hash
|
|
||||||
*
|
|
||||||
***/
|
|
||||||
|
|
||||||
//============================================================================
|
|
||||||
inline EventHash::EventHash (
|
|
||||||
unsigned eventType,
|
|
||||||
ESrvType srvType
|
|
||||||
) : eventType(eventType)
|
|
||||||
, srvType(srvType)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
//============================================================================
|
|
||||||
inline uint32_t EventHash::GetHash () const {
|
|
||||||
CHashValue hash(this, sizeof(*this));
|
|
||||||
return hash.GetHash();
|
|
||||||
}
|
|
||||||
|
|
||||||
//============================================================================
|
|
||||||
inline bool EventHash::operator== (const EventHash & rhs) const {
|
|
||||||
return
|
|
||||||
eventType == rhs.eventType &&
|
|
||||||
srvType == rhs.srvType;
|
|
||||||
}
|
|
||||||
/*****************************************************************************
|
|
||||||
*
|
|
||||||
* Private Functions
|
|
||||||
*
|
|
||||||
***/
|
|
||||||
|
|
||||||
//============================================================================
|
|
||||||
static void NetLogUnRegisterEvents () {
|
|
||||||
HASHTABLEDECL(NetLogEventHash, EventHash, link) tempHashTable;
|
|
||||||
s_critsect.Enter();
|
|
||||||
{
|
|
||||||
while(NetLogEventHash *hash = s_registeredEvents.Head()) {
|
|
||||||
tempHashTable.Add(hash);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
s_critsect.Leave();
|
|
||||||
|
|
||||||
while(NetLogEventHash *hash = tempHashTable.Head()) {
|
|
||||||
delete hash;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************************
|
|
||||||
*
|
|
||||||
* Public Functions
|
|
||||||
*
|
|
||||||
***/
|
|
||||||
|
|
||||||
//============================================================================
|
|
||||||
void NetLogInitialize (ESrvType srvType) {
|
|
||||||
s_srvType = srvType;
|
|
||||||
if(s_srvType == kSrvTypeLog)
|
|
||||||
NetLogSrvInitialize();
|
|
||||||
else
|
|
||||||
NetLogCliInitialize(srvType);
|
|
||||||
}
|
|
||||||
|
|
||||||
//============================================================================
|
|
||||||
void NetLogShutdown () {
|
|
||||||
if(s_srvType == kSrvTypeLog)
|
|
||||||
NetLogSrvShutdown();
|
|
||||||
else
|
|
||||||
NetLogCliShutdown();
|
|
||||||
NetLogUnRegisterEvents();
|
|
||||||
}
|
|
||||||
|
|
||||||
//============================================================================
|
|
||||||
void NetLogDestroy () {
|
|
||||||
if(s_srvType == kSrvTypeLog)
|
|
||||||
NetLogSrvDestroy();
|
|
||||||
else
|
|
||||||
NetLogCliDestroy();
|
|
||||||
}
|
|
||||||
|
|
||||||
//============================================================================
|
|
||||||
void NetLogRegisterEvents (const NetLogEvent events[], unsigned count) {
|
|
||||||
NetLogEventHash *hash;
|
|
||||||
HASHTABLEDECL(NetLogEventHash, EventHash, link) tempHashTable;
|
|
||||||
|
|
||||||
for(unsigned i = 0; i < count; ++i) {
|
|
||||||
hash = new NetLogEventHash(events[i].logEventType, events[i].srvType, &events[i]);
|
|
||||||
tempHashTable.Add(hash);
|
|
||||||
}
|
|
||||||
s_critsect.Enter();
|
|
||||||
{
|
|
||||||
while(NetLogEventHash *hash = tempHashTable.Head()) {
|
|
||||||
s_registeredEvents.Add(hash);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
s_critsect.Leave();
|
|
||||||
}
|
|
||||||
|
|
||||||
//============================================================================
|
|
||||||
const NetLogEvent *NetLogFindEvent (unsigned type, ESrvType srvType) {
|
|
||||||
NetLogEventHash *hash;
|
|
||||||
s_critsect.Enter();
|
|
||||||
{
|
|
||||||
hash = s_registeredEvents.Find(EventHash(type, srvType));
|
|
||||||
}
|
|
||||||
s_critsect.Leave();
|
|
||||||
return hash ? hash->event : nil;
|
|
||||||
}
|
|
||||||
|
|
||||||
//============================================================================
|
|
||||||
void NetLogSendEvent (
|
|
||||||
unsigned type
|
|
||||||
...
|
|
||||||
) {
|
|
||||||
const NetLogEvent *event = NetLogFindEvent(type, s_srvType);
|
|
||||||
|
|
||||||
if(event) {
|
|
||||||
va_list args;
|
|
||||||
va_start(args, type);
|
|
||||||
NetLogCliSendEvent(*event, args);
|
|
||||||
va_end(args);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
LogMsg( kLogError, "unable to log event, event not found SrvType: %d EventType: %d.", s_srvType, type);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,558 +0,0 @@
|
|||||||
/*==LICENSE==*
|
|
||||||
|
|
||||||
CyanWorlds.com Engine - MMOG client, server and tools
|
|
||||||
Copyright (C) 2011 Cyan Worlds, Inc.
|
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
Additional permissions under GNU GPL version 3 section 7
|
|
||||||
|
|
||||||
If you modify this Program, or any covered work, by linking or
|
|
||||||
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
|
|
||||||
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
|
|
||||||
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
|
|
||||||
(or a modified version of those libraries),
|
|
||||||
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
|
|
||||||
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
|
|
||||||
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
|
|
||||||
licensors of this Program grant you additional
|
|
||||||
permission to convey the resulting work. Corresponding Source for a
|
|
||||||
non-source form of such a combination shall include the source code for
|
|
||||||
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
|
|
||||||
work.
|
|
||||||
|
|
||||||
You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
|
||||||
or by snail mail at:
|
|
||||||
Cyan Worlds, Inc.
|
|
||||||
14617 N Newport Hwy
|
|
||||||
Mead, WA 99021
|
|
||||||
|
|
||||||
*==LICENSE==*/
|
|
||||||
/*****************************************************************************
|
|
||||||
*
|
|
||||||
* $/Plasma20/Sources/Plasma/NucleusLib/pnNetLog/pnNlCli.cpp
|
|
||||||
*
|
|
||||||
***/
|
|
||||||
|
|
||||||
#include "Pch.h"
|
|
||||||
#pragma hdrstop
|
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************************
|
|
||||||
*
|
|
||||||
* Private
|
|
||||||
*
|
|
||||||
***/
|
|
||||||
|
|
||||||
struct NetLogConn : SrvConn {
|
|
||||||
NetAddress netaddr;
|
|
||||||
ESrvType srvType;
|
|
||||||
|
|
||||||
NetLogConn (const NetAddress & addr, ESrvType srvType);
|
|
||||||
~NetLogConn ();
|
|
||||||
|
|
||||||
void Connect (
|
|
||||||
AsyncCancelId * cancelId,
|
|
||||||
FAsyncNotifySocketProc notifyProc,
|
|
||||||
void * param
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
struct LogMsgTrans : SrvTrans {
|
|
||||||
Srv2Log_LogMsg *msgBuffer;
|
|
||||||
|
|
||||||
LogMsgTrans();
|
|
||||||
~LogMsgTrans();
|
|
||||||
bool OnTransReply (
|
|
||||||
ENetError * error,
|
|
||||||
SrvMsgHeader * msg
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
struct LogConnEventNode {
|
|
||||||
LINK(LogConnEventNode) link;
|
|
||||||
Srv2Log_LogMsg * msg;
|
|
||||||
unsigned sendTimeMs;
|
|
||||||
|
|
||||||
LogConnEventNode(Srv2Log_LogMsg *msg, unsigned timeStampMs);
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************************
|
|
||||||
*
|
|
||||||
* Private Data
|
|
||||||
*
|
|
||||||
***/
|
|
||||||
|
|
||||||
static NetLogConn * s_conn;
|
|
||||||
static CCritSect s_critsect;
|
|
||||||
static IniChangeReg * s_change;
|
|
||||||
static ESrvType s_srvType;
|
|
||||||
static LISTDECL(LogConnEventNode, link) s_eventQueue;
|
|
||||||
static AsyncTimer * s_timer;
|
|
||||||
static long s_perf[kNlCliNumPerf];
|
|
||||||
static bool s_running;
|
|
||||||
|
|
||||||
static const unsigned kIssueSaveMs = 100;
|
|
||||||
static const unsigned kMaxNumberOfTransactions = 2000;
|
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************************
|
|
||||||
*
|
|
||||||
* Private Functions
|
|
||||||
*
|
|
||||||
***/
|
|
||||||
|
|
||||||
//============================================================================
|
|
||||||
static NetLogConn * GetConnIncRef () {
|
|
||||||
NetLogConn * conn;
|
|
||||||
s_critsect.Enter();
|
|
||||||
{
|
|
||||||
if (nil != (conn = s_conn))
|
|
||||||
conn->IncRef();
|
|
||||||
}
|
|
||||||
s_critsect.Leave();
|
|
||||||
return conn;
|
|
||||||
}
|
|
||||||
|
|
||||||
//============================================================================
|
|
||||||
static void NetLogConnConnect (NetAddress & addr, ESrvType srvType) {
|
|
||||||
NetLogConn *conn = SRV_CONN_ALLOC(NetLogConn)(addr, srvType);
|
|
||||||
|
|
||||||
s_critsect.Enter();
|
|
||||||
{
|
|
||||||
SWAP(s_conn, conn);
|
|
||||||
}
|
|
||||||
s_critsect.Leave();
|
|
||||||
|
|
||||||
if (conn)
|
|
||||||
conn->Destroy();
|
|
||||||
}
|
|
||||||
|
|
||||||
//============================================================================
|
|
||||||
static void NetLogConnDisconnect () {
|
|
||||||
NetLogConn *conn = nil;
|
|
||||||
|
|
||||||
s_critsect.Enter();
|
|
||||||
{
|
|
||||||
SWAP(s_conn, conn);
|
|
||||||
}
|
|
||||||
s_critsect.Leave();
|
|
||||||
|
|
||||||
if (conn)
|
|
||||||
conn->Destroy();
|
|
||||||
}
|
|
||||||
|
|
||||||
//============================================================================
|
|
||||||
static void AddEventNode (Srv2Log_LogMsg *msg) {
|
|
||||||
LogConnEventNode *node = new LogConnEventNode(msg, TimeGetMs() + kIssueSaveMs);
|
|
||||||
s_critsect.Enter();
|
|
||||||
{
|
|
||||||
s_eventQueue.Link(node);
|
|
||||||
}
|
|
||||||
s_critsect.Leave();
|
|
||||||
|
|
||||||
AsyncTimerUpdate(
|
|
||||||
s_timer,
|
|
||||||
kIssueSaveMs,
|
|
||||||
kAsyncTimerUpdateSetPriorityHigher
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
//============================================================================
|
|
||||||
static void ParseIni (Ini * ini) {
|
|
||||||
unsigned iter;
|
|
||||||
const IniValue * value = IniGetFirstValue(
|
|
||||||
ini,
|
|
||||||
L"Server Locations",
|
|
||||||
L"LogSrv",
|
|
||||||
&iter
|
|
||||||
);
|
|
||||||
|
|
||||||
if (value) {
|
|
||||||
wchar_t addrStr[32];
|
|
||||||
IniGetString(value, addrStr, arrsize(addrStr), 0, nil);
|
|
||||||
NetAddress addr;
|
|
||||||
NetAddressFromString(&addr, addrStr, kNetDefaultServerPort);
|
|
||||||
NetLogConnConnect(addr, s_srvType);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//============================================================================
|
|
||||||
static void IniChangeCallback (const wchar_t fullPath[]) {
|
|
||||||
Ini * ini = IniOpen(fullPath);
|
|
||||||
ParseIni(ini);
|
|
||||||
IniClose(ini);
|
|
||||||
}
|
|
||||||
|
|
||||||
//============================================================================
|
|
||||||
static unsigned TimerCallback (void *) {
|
|
||||||
LISTDECL(LogConnEventNode, link) sendList;
|
|
||||||
unsigned sleepMs = kAsyncTimeInfinite;
|
|
||||||
|
|
||||||
s_critsect.Enter();
|
|
||||||
{
|
|
||||||
int allowedNumTrans = kMaxNumberOfTransactions - s_perf[kNlCliNumPendingSaves]; // find the number of transactions that we can send based on the number in transit, and the max number allowed
|
|
||||||
if(allowedNumTrans < 0) // this could be negative, if so set to zero
|
|
||||||
allowedNumTrans = 0;
|
|
||||||
|
|
||||||
uint32_t currTime = TimeGetMs();
|
|
||||||
LogConnEventNode *hash;
|
|
||||||
int timeDiff;
|
|
||||||
|
|
||||||
// Add pending saves, up to the max allowed per update
|
|
||||||
for(;;) {
|
|
||||||
if(!allowedNumTrans && s_running) {
|
|
||||||
sleepMs = 5000; // we are at our max number of transactions sleep for 5 seconds and try again
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
hash = s_eventQueue.Head();
|
|
||||||
if(!hash)
|
|
||||||
break; // no messages left. We will wait until another message comes in before another timer update
|
|
||||||
|
|
||||||
timeDiff = hash->sendTimeMs - currTime;
|
|
||||||
|
|
||||||
// nodes are naturally ordered by increasing sendTimeMs
|
|
||||||
if(!s_running || (timeDiff <= 0)) {
|
|
||||||
sendList.Link(hash);
|
|
||||||
--allowedNumTrans;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
sleepMs = timeDiff;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
s_critsect.Leave();
|
|
||||||
|
|
||||||
while(LogConnEventNode *node = sendList.Head()) {
|
|
||||||
LogMsgTrans * trans = SRV_TRANS_ALLOC(LogMsgTrans);
|
|
||||||
trans->msgBuffer = node->msg;
|
|
||||||
|
|
||||||
if (NetLogConn * conn = GetConnIncRef()) {
|
|
||||||
conn->SendRequest(trans, node->msg);
|
|
||||||
conn->DecRef();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
trans->TransCancel(kNetErrTimeout);
|
|
||||||
}
|
|
||||||
delete node;
|
|
||||||
}
|
|
||||||
return sleepMs;
|
|
||||||
}
|
|
||||||
|
|
||||||
//============================================================================
|
|
||||||
static unsigned CalcArgsLength (const NetLogEvent &event, va_list args) {
|
|
||||||
unsigned length = 0;
|
|
||||||
unsigned paramType = kNumLogParamTypes; // invalidate
|
|
||||||
unsigned field = 0;
|
|
||||||
|
|
||||||
for(unsigned i = 0; i < event.numFields * 2; ++i) {
|
|
||||||
if(!(i % 2)) {
|
|
||||||
paramType = va_arg(args, unsigned);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
//validate parameter type
|
|
||||||
if(paramType != (unsigned)event.fields[field].type) {
|
|
||||||
length = 0;
|
|
||||||
LogMsg( kLogError, "Log parameter types do not match for event: %s parameter: %s?", event.eventName, event.fields[field].name);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch(event.fields[field].type) {
|
|
||||||
case kLogParamInt: {
|
|
||||||
va_arg(args, int);
|
|
||||||
length += sizeof(int);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case kLogParamUnsigned: {
|
|
||||||
va_arg(args, unsigned);
|
|
||||||
length += sizeof(unsigned);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case kLogParamFloat: {
|
|
||||||
va_arg(args, float);
|
|
||||||
length += sizeof(float);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case kLogParamLong: {
|
|
||||||
va_arg(args, long);
|
|
||||||
length += sizeof(long);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case kLogParamLongLong: {
|
|
||||||
va_arg(args, long long);
|
|
||||||
length += sizeof(long long);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case kLogParamUuid: {
|
|
||||||
va_arg(args, Uuid);
|
|
||||||
length += sizeof(Uuid);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case kLogParamStringW: {
|
|
||||||
wchar_t *str = va_arg(args, wchar_t *);
|
|
||||||
if(!str)
|
|
||||||
str = L"";
|
|
||||||
length += StrBytes(str);
|
|
||||||
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
hsAssert(false, "Unknown argument type in log statement");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
++field;
|
|
||||||
}
|
|
||||||
return length;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************************
|
|
||||||
*
|
|
||||||
* NetLogConn
|
|
||||||
*
|
|
||||||
***/
|
|
||||||
|
|
||||||
//============================================================================
|
|
||||||
NetLogConn::NetLogConn (const NetAddress & addr, ESrvType srvType)
|
|
||||||
: netaddr(addr),
|
|
||||||
srvType(srvType)
|
|
||||||
{
|
|
||||||
AtomicAdd(&s_perf[kNlCliNumConn], 1);
|
|
||||||
SetAutoPing();
|
|
||||||
AutoReconnect();
|
|
||||||
}
|
|
||||||
|
|
||||||
//============================================================================
|
|
||||||
NetLogConn::~NetLogConn () {
|
|
||||||
AtomicAdd(&s_perf[kNlCliNumConn], -1);
|
|
||||||
}
|
|
||||||
|
|
||||||
//============================================================================
|
|
||||||
void NetLogConn::Connect (
|
|
||||||
AsyncCancelId * cancelId,
|
|
||||||
FAsyncNotifySocketProc notifyProc,
|
|
||||||
void * param
|
|
||||||
) {
|
|
||||||
// Connect to remote server
|
|
||||||
Srv2Log_Connect connect;
|
|
||||||
connect.hdr.connType = kConnTypeSrvToLog;
|
|
||||||
connect.hdr.hdrBytes = sizeof(connect.hdr);
|
|
||||||
connect.hdr.buildId = BuildId();
|
|
||||||
connect.hdr.buildType = BUILD_TYPE_LIVE;
|
|
||||||
connect.hdr.branchId = BranchId();
|
|
||||||
connect.hdr.productId = ProductId();
|
|
||||||
connect.data.dataBytes = sizeof(connect.data);
|
|
||||||
connect.data.buildId = BuildId();
|
|
||||||
connect.data.srvType = srvType;
|
|
||||||
connect.data.buildType = BUILD_TYPE_LIVE;
|
|
||||||
connect.data.productId = ProductId();
|
|
||||||
|
|
||||||
AsyncSocketConnect(
|
|
||||||
cancelId,
|
|
||||||
netaddr,
|
|
||||||
notifyProc,
|
|
||||||
param,
|
|
||||||
&connect,
|
|
||||||
sizeof(connect)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************************
|
|
||||||
*
|
|
||||||
* LogMsgTrans
|
|
||||||
*
|
|
||||||
***/
|
|
||||||
|
|
||||||
//============================================================================
|
|
||||||
LogMsgTrans::LogMsgTrans ()
|
|
||||||
: msgBuffer(nil)
|
|
||||||
{
|
|
||||||
AtomicAdd(&s_perf[kNlCliNumTrans], 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
//============================================================================
|
|
||||||
LogMsgTrans::~LogMsgTrans () {
|
|
||||||
AtomicAdd(&s_perf[kNlCliNumTrans], -1);
|
|
||||||
}
|
|
||||||
|
|
||||||
//============================================================================
|
|
||||||
bool LogMsgTrans::OnTransReply (
|
|
||||||
ENetError * error,
|
|
||||||
SrvMsgHeader * msg
|
|
||||||
) {
|
|
||||||
ref(msg);
|
|
||||||
bool result;
|
|
||||||
if (msg->protocolId != kNetProtocolSrv2Log) {
|
|
||||||
result = SrvTrans::OnTransReply(error, msg);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
result = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(IS_NET_ERROR(*error) && s_running) {
|
|
||||||
AddEventNode(msgBuffer);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
free(msgBuffer);
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************************
|
|
||||||
*
|
|
||||||
* LogConnEventNode
|
|
||||||
*
|
|
||||||
***/
|
|
||||||
|
|
||||||
//============================================================================
|
|
||||||
LogConnEventNode::LogConnEventNode (Srv2Log_LogMsg *msg, unsigned sendTimeMs)
|
|
||||||
: msg(msg),
|
|
||||||
sendTimeMs(sendTimeMs)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************************
|
|
||||||
*
|
|
||||||
* Protected
|
|
||||||
*
|
|
||||||
***/
|
|
||||||
|
|
||||||
//============================================================================
|
|
||||||
void NetLogCliInitialize (ESrvType srvType) {
|
|
||||||
s_running = true;
|
|
||||||
s_srvType = srvType;
|
|
||||||
AsyncTimerCreate(
|
|
||||||
&s_timer,
|
|
||||||
TimerCallback,
|
|
||||||
kAsyncTimeInfinite,
|
|
||||||
nil
|
|
||||||
);
|
|
||||||
IniChangeAdd(L"plServer", IniChangeCallback, &s_change);
|
|
||||||
}
|
|
||||||
|
|
||||||
//============================================================================
|
|
||||||
void NetLogCliShutdown () {
|
|
||||||
s_running = false;
|
|
||||||
if(s_change) {
|
|
||||||
IniChangeRemove(s_change, true);
|
|
||||||
s_change = false;
|
|
||||||
}
|
|
||||||
if(s_timer) {
|
|
||||||
AsyncTimerDeleteCallback(s_timer, TimerCallback);
|
|
||||||
s_timer = nil;
|
|
||||||
}
|
|
||||||
NetLogConnDisconnect();
|
|
||||||
}
|
|
||||||
|
|
||||||
//============================================================================
|
|
||||||
void NetLogCliDestroy () {
|
|
||||||
while(s_perf[kNlCliNumTrans])
|
|
||||||
AsyncSleep(10);
|
|
||||||
while(s_perf[kNlCliNumConn])
|
|
||||||
AsyncSleep(10);
|
|
||||||
}
|
|
||||||
|
|
||||||
//============================================================================
|
|
||||||
void NetLogCliSendEvent (const NetLogEvent &event, va_list args) {
|
|
||||||
Srv2Log_LogMsg *msg;
|
|
||||||
unsigned length = CalcArgsLength(event, args);
|
|
||||||
if(!length)
|
|
||||||
return;
|
|
||||||
|
|
||||||
CSrvPackBuffer pack(
|
|
||||||
sizeof(*msg) +
|
|
||||||
length
|
|
||||||
);
|
|
||||||
|
|
||||||
msg = (Srv2Log_LogMsg *) pack.Alloc(sizeof(*msg));
|
|
||||||
msg->transId = 0;
|
|
||||||
msg->protocolId = kNetProtocolSrv2Log;
|
|
||||||
msg->messageId = kSrv2Log_LogMsg;
|
|
||||||
msg->eventType = event.logEventType;
|
|
||||||
msg->timestamp = TimeGetLocalTime();
|
|
||||||
|
|
||||||
unsigned field = 0;
|
|
||||||
unsigned paramType = kNumLogParamTypes;
|
|
||||||
|
|
||||||
// if we get here the template parameters have already been validated by CalcLength, no need to do that again.
|
|
||||||
for(unsigned i = 0; i < event.numFields * 2; ++i) {
|
|
||||||
if(!(i % 2)) {
|
|
||||||
paramType = va_arg(args, unsigned);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
switch(event.fields[field].type) {
|
|
||||||
case kLogParamInt: {
|
|
||||||
int i = va_arg(args, int);
|
|
||||||
pack.AddData(&i, sizeof(int));
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case kLogParamUnsigned: {
|
|
||||||
unsigned u = va_arg(args, unsigned);
|
|
||||||
pack.AddData(&u, sizeof(unsigned));
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case kLogParamFloat: {
|
|
||||||
float f = va_arg(args, float);
|
|
||||||
pack.AddData(&f, sizeof(float));
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case kLogParamLong: {
|
|
||||||
long l = va_arg(args, long);
|
|
||||||
pack.AddData(&l, sizeof(long));
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case kLogParamLongLong: {
|
|
||||||
long long ll = va_arg(args, long long);
|
|
||||||
pack.AddData(&ll, sizeof(long long));
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case kLogParamUuid: {
|
|
||||||
Uuid uuid = va_arg(args, Uuid);
|
|
||||||
pack.AddData(&uuid, sizeof(Uuid));
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case kLogParamStringW: {
|
|
||||||
wchar_t *str = va_arg(args, wchar_t *);
|
|
||||||
if(!str)
|
|
||||||
str = L"";
|
|
||||||
pack.AddString(str);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
++field;
|
|
||||||
}
|
|
||||||
|
|
||||||
msg->messageBytes = pack.Size();
|
|
||||||
AddEventNode(msg);
|
|
||||||
}
|
|
@ -1,603 +0,0 @@
|
|||||||
/*==LICENSE==*
|
|
||||||
|
|
||||||
CyanWorlds.com Engine - MMOG client, server and tools
|
|
||||||
Copyright (C) 2011 Cyan Worlds, Inc.
|
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
Additional permissions under GNU GPL version 3 section 7
|
|
||||||
|
|
||||||
If you modify this Program, or any covered work, by linking or
|
|
||||||
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
|
|
||||||
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
|
|
||||||
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
|
|
||||||
(or a modified version of those libraries),
|
|
||||||
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
|
|
||||||
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
|
|
||||||
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
|
|
||||||
licensors of this Program grant you additional
|
|
||||||
permission to convey the resulting work. Corresponding Source for a
|
|
||||||
non-source form of such a combination shall include the source code for
|
|
||||||
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
|
|
||||||
work.
|
|
||||||
|
|
||||||
You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
|
||||||
or by snail mail at:
|
|
||||||
Cyan Worlds, Inc.
|
|
||||||
14617 N Newport Hwy
|
|
||||||
Mead, WA 99021
|
|
||||||
|
|
||||||
*==LICENSE==*/
|
|
||||||
/*****************************************************************************
|
|
||||||
*
|
|
||||||
* $/Plasma20/Sources/Plasma/NucleusLib/pnNetLog/pnNlSrv.cpp
|
|
||||||
*
|
|
||||||
***/
|
|
||||||
|
|
||||||
#include "Pch.h"
|
|
||||||
#pragma hdrstop
|
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************************
|
|
||||||
*
|
|
||||||
* Private
|
|
||||||
*
|
|
||||||
***/
|
|
||||||
|
|
||||||
struct EventHash {
|
|
||||||
unsigned eventType;
|
|
||||||
ESrvType srvType;
|
|
||||||
|
|
||||||
inline EventHash (
|
|
||||||
unsigned eventType,
|
|
||||||
ESrvType srvType
|
|
||||||
);
|
|
||||||
|
|
||||||
inline uint32_t GetHash () const;
|
|
||||||
inline bool operator== (const EventHash & rhs) const;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct NetLogEventHash : EventHash {
|
|
||||||
const NetLogEvent * event;
|
|
||||||
|
|
||||||
NetLogEventHash(
|
|
||||||
unsigned eventType,
|
|
||||||
ESrvType srvType,
|
|
||||||
const NetLogEvent *event
|
|
||||||
);
|
|
||||||
HASHLINK(NetLogEventHash) link;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct LogConn : SrvConn {
|
|
||||||
LINK(LogConn) link;
|
|
||||||
ESrvType srvType;
|
|
||||||
unsigned buildId;
|
|
||||||
NetAddressNode addr;
|
|
||||||
unsigned buildType;
|
|
||||||
unsigned productId;
|
|
||||||
|
|
||||||
// Ctor
|
|
||||||
LogConn (
|
|
||||||
AsyncSocket sock,
|
|
||||||
void ** userState,
|
|
||||||
NetAddressNode nodeNumber,
|
|
||||||
unsigned buildId,
|
|
||||||
ESrvType srvType,
|
|
||||||
unsigned buildType,
|
|
||||||
unsigned productId
|
|
||||||
);
|
|
||||||
~LogConn ();
|
|
||||||
|
|
||||||
bool OnSrvMsg (SrvMsgHeader * msg);
|
|
||||||
void OnDisconnect ();
|
|
||||||
|
|
||||||
bool Recv_Srv2Log_LogMsg( const Srv2Log_LogMsg & msg );
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************************
|
|
||||||
*
|
|
||||||
* Private Data
|
|
||||||
*
|
|
||||||
***/
|
|
||||||
|
|
||||||
static IniChangeReg * s_change;
|
|
||||||
static long s_perf[kNlSrvNumPerf];
|
|
||||||
static CCritSect s_critsect;
|
|
||||||
static bool s_running;
|
|
||||||
static LISTDECL(LogConn, link) s_conns;
|
|
||||||
void (*NetLogSrvCallback)(const NetLogEvent *event, const ARRAY(wchar_t) &, unsigned, NetAddressNode &, uint64_t, unsigned, unsigned ) ;
|
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************************
|
|
||||||
*
|
|
||||||
* Private Functions
|
|
||||||
*
|
|
||||||
***/
|
|
||||||
|
|
||||||
//============================================================================
|
|
||||||
static void ParseIni (Ini * ini) {
|
|
||||||
unsigned iter;
|
|
||||||
const IniValue *value;
|
|
||||||
|
|
||||||
value = IniGetFirstValue(
|
|
||||||
ini,
|
|
||||||
L"",
|
|
||||||
L"",
|
|
||||||
&iter
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
//============================================================================
|
|
||||||
static void IniChangeCallback (const wchar_t fullPath[]) {
|
|
||||||
Ini * ini = IniOpen(fullPath);
|
|
||||||
ParseIni(ini);
|
|
||||||
IniClose(ini);
|
|
||||||
}
|
|
||||||
|
|
||||||
//===========================================================================
|
|
||||||
static bool SocketNotifyProc (
|
|
||||||
AsyncSocket sock,
|
|
||||||
EAsyncNotifySocket code,
|
|
||||||
AsyncNotifySocket * notify,
|
|
||||||
void ** userState
|
|
||||||
) {
|
|
||||||
// If the socket is successfully connected then only
|
|
||||||
// kNotifySocketListenSuccess will arrive here, as
|
|
||||||
// the service routine will be changed by SrvConn.
|
|
||||||
if (code != kNotifySocketListenSuccess) {
|
|
||||||
if (code == kNotifySocketDisconnect)
|
|
||||||
AsyncSocketDelete(sock);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: Verify this is from a valid server
|
|
||||||
AsyncNotifySocketListen * listen = (AsyncNotifySocketListen *) notify;
|
|
||||||
EServerRights rights = SrvIniGetServerRights(listen->remoteAddr);
|
|
||||||
if (rights < kSrvRightsServer) {
|
|
||||||
LogMsgDebug("LogConn: insufficient server rights");
|
|
||||||
AtomicAdd(&s_perf[kNlSrvPerfConnDenied], 1);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
NetAddressNode nodeNumber = NetAddressGetNode(listen->remoteAddr);
|
|
||||||
|
|
||||||
// Parse the connect message
|
|
||||||
Srv2Log_ConnData connect;
|
|
||||||
if (!Srv2LogValidateConnect(listen, &connect)) {
|
|
||||||
LogMsgDebug("LogConn: invalid connect packet");
|
|
||||||
AtomicAdd(&s_perf[kNlSrvPerfConnDenied], 1);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create connection record
|
|
||||||
LogConn * conn = SRV_CONN_ALLOC(LogConn)(
|
|
||||||
sock,
|
|
||||||
userState,
|
|
||||||
nodeNumber,
|
|
||||||
connect.buildId,
|
|
||||||
(ESrvType) connect.srvType,
|
|
||||||
connect.buildType,
|
|
||||||
connect.productId
|
|
||||||
);
|
|
||||||
|
|
||||||
// Add this connection
|
|
||||||
bool result;
|
|
||||||
s_critsect.Enter();
|
|
||||||
{
|
|
||||||
s_conns.Link(conn);
|
|
||||||
result = s_running;
|
|
||||||
}
|
|
||||||
s_critsect.Leave();
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************************
|
|
||||||
*
|
|
||||||
* LogConn implementation
|
|
||||||
*
|
|
||||||
***/
|
|
||||||
|
|
||||||
//============================================================================
|
|
||||||
LogConn::LogConn (
|
|
||||||
AsyncSocket sock,
|
|
||||||
void ** userState,
|
|
||||||
NetAddressNode nodeNumber,
|
|
||||||
unsigned buildId,
|
|
||||||
ESrvType srvType,
|
|
||||||
unsigned buildType,
|
|
||||||
unsigned productId
|
|
||||||
) : srvType(srvType),
|
|
||||||
buildId(buildId),
|
|
||||||
buildType(buildType),
|
|
||||||
productId(productId)
|
|
||||||
{
|
|
||||||
ref(nodeNumber);
|
|
||||||
AtomicAdd(&s_perf[kNlSrvPerfConnCount], 1);
|
|
||||||
SetAutoTimeout();
|
|
||||||
NotifyListen(sock, userState);
|
|
||||||
addr = nodeNumber;
|
|
||||||
}
|
|
||||||
|
|
||||||
//============================================================================
|
|
||||||
LogConn::~LogConn () {
|
|
||||||
AtomicAdd(&s_perf[kNlSrvPerfConnCount], -1);
|
|
||||||
}
|
|
||||||
|
|
||||||
//============================================================================
|
|
||||||
void LogConn::OnDisconnect () {
|
|
||||||
// Accepting side just destroys the connection. Connecting side
|
|
||||||
// will reconnect if that's what should happen.
|
|
||||||
Destroy();
|
|
||||||
}
|
|
||||||
|
|
||||||
//============================================================================
|
|
||||||
bool LogConn::OnSrvMsg (SrvMsgHeader * msg) {
|
|
||||||
// Pass along messages not intended for us
|
|
||||||
if (msg->protocolId != kNetProtocolSrv2Log)
|
|
||||||
return SrvConn::OnSrvMsg(msg);
|
|
||||||
|
|
||||||
bool status = false;
|
|
||||||
#define DISPATCH(a) case k##a: status = Recv_##a(*(const a*)msg); break
|
|
||||||
switch (msg->messageId) {
|
|
||||||
DISPATCH(Srv2Log_LogMsg);
|
|
||||||
|
|
||||||
default:
|
|
||||||
status = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
#undef DISPATCH
|
|
||||||
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
//============================================================================
|
|
||||||
bool LogConn::Recv_Srv2Log_LogMsg(const Srv2Log_LogMsg & msg ) {
|
|
||||||
CSrvUnpackBuffer unpack(&msg, msg.messageBytes);
|
|
||||||
(void)unpack.GetData(sizeof(msg));
|
|
||||||
unsigned length = 0;
|
|
||||||
ARRAY(wchar_t) databuf;
|
|
||||||
wchar_t data[256];
|
|
||||||
const void *pData = 0;
|
|
||||||
|
|
||||||
SendReply(msg.transId, kNetSuccess);
|
|
||||||
if(!s_running)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
// WARNING: each parameter type needs to be able to handle the case where GetData returns a nil pointer for backward compatability
|
|
||||||
|
|
||||||
const NetLogEvent *event = NetLogFindEvent(msg.eventType, srvType);
|
|
||||||
if(event) {
|
|
||||||
for(unsigned i = 0; i < event->numFields; ++i) {
|
|
||||||
if(!event->fields[i].name)
|
|
||||||
{
|
|
||||||
LogMsg(kLogError, "Failed logging event because of nil param name: %s", event->eventName);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch(event->fields[i].type) {
|
|
||||||
case kLogParamInt: {
|
|
||||||
int i = 0;
|
|
||||||
pData = unpack.GetData(sizeof(int));
|
|
||||||
if(!pData)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
i = *(int *)pData;
|
|
||||||
StrPrintf(data, arrsize(data), L"%d", i);
|
|
||||||
length += StrLen(data) + 1;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case kLogParamUnsigned: {
|
|
||||||
unsigned u = 0;
|
|
||||||
pData = unpack.GetData(sizeof(unsigned));
|
|
||||||
if(!pData)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
u = *(unsigned *)pData;
|
|
||||||
StrPrintf(data, arrsize(data), L"%d", u);
|
|
||||||
length += StrLen(data) + 1;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case kLogParamFloat: {
|
|
||||||
float f = 0;
|
|
||||||
pData = unpack.GetData(sizeof(float));
|
|
||||||
if(!pData)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
f = *(float *)pData;
|
|
||||||
StrPrintf(data, arrsize(data), L"%f", f);
|
|
||||||
length += StrLen(data) + 1;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case kLogParamLong: {
|
|
||||||
long l = 0;
|
|
||||||
pData = unpack.GetData(sizeof(long));
|
|
||||||
if(!pData)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
l = *(long *)pData;
|
|
||||||
StrPrintf(data, arrsize(data), L"%ld", l);
|
|
||||||
length += StrLen(data) + 1;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case kLogParamLongLong: {
|
|
||||||
long long ll = 0;
|
|
||||||
pData = unpack.GetData(sizeof(long));
|
|
||||||
if(!pData)
|
|
||||||
continue;
|
|
||||||
ll = *(long *)pData;
|
|
||||||
StrPrintf(data, arrsize(data), L"%lld", ll);
|
|
||||||
length += StrLen(data) + 1;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case kLogParamUuid: {
|
|
||||||
Uuid uuid = 0;
|
|
||||||
pData = unpack.GetData(sizeof(Uuid));
|
|
||||||
if(!pData)
|
|
||||||
continue;
|
|
||||||
uuid = *(Uuid *)pData;
|
|
||||||
StrPrintf(data, arrsize(data), L"%s", uuid.data);
|
|
||||||
length += StrLen(data) + 1;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case kLogParamStringW: {
|
|
||||||
const wchar_t *str = unpack.GetString();
|
|
||||||
if(!str) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
length += StrLen(str) + 1;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
length += StrLen(event->fields[i].name) + 1; // this must happen after the parameter check so we can opt out of saving a non existant parameter
|
|
||||||
}
|
|
||||||
|
|
||||||
databuf.Reserve(length + 1);
|
|
||||||
|
|
||||||
{
|
|
||||||
CSrvUnpackBuffer unpack(&msg, msg.messageBytes);
|
|
||||||
(void)unpack.GetData(sizeof(msg));
|
|
||||||
for(unsigned i = 0; i < event->numFields; ++i){
|
|
||||||
|
|
||||||
// the parameter name needs to be written before the data. Also, we need to be able to opt out of writing a parameter.
|
|
||||||
switch(event->fields[i].type) {
|
|
||||||
case kLogParamInt: {
|
|
||||||
pData = unpack.GetData(sizeof(int));
|
|
||||||
if(!pData)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
int val = *(int *)pData;
|
|
||||||
|
|
||||||
// log event name
|
|
||||||
databuf.Add(event->fields[i].name, StrLen(event->fields[i].name));
|
|
||||||
databuf.Add(0);
|
|
||||||
|
|
||||||
// log event data
|
|
||||||
StrPrintf(data, arrsize(data), L"%d", val);
|
|
||||||
databuf.Add(data, StrLen(data));
|
|
||||||
databuf.Add(0);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case kLogParamUnsigned: {
|
|
||||||
pData = unpack.GetData(sizeof(unsigned));
|
|
||||||
if(!pData)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
unsigned u = *(unsigned *)pData;
|
|
||||||
|
|
||||||
// log event name
|
|
||||||
databuf.Add(event->fields[i].name, StrLen(event->fields[i].name));
|
|
||||||
databuf.Add(0);
|
|
||||||
|
|
||||||
// log event data
|
|
||||||
StrPrintf(data, arrsize(data), L"%d", u);
|
|
||||||
databuf.Add(data, StrLen(data));
|
|
||||||
databuf.Add(0);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case kLogParamFloat: {
|
|
||||||
pData = unpack.GetData(sizeof(float));
|
|
||||||
if(!pData)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
float f = *(float *)pData;
|
|
||||||
|
|
||||||
// log event name
|
|
||||||
databuf.Add(event->fields[i].name, StrLen(event->fields[i].name));
|
|
||||||
databuf.Add(0);
|
|
||||||
|
|
||||||
// log event data
|
|
||||||
StrPrintf(data, arrsize(data), L"%f", f);
|
|
||||||
databuf.Add(data, StrLen(data));
|
|
||||||
databuf.Add(0);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case kLogParamLong: {
|
|
||||||
pData = unpack.GetData(sizeof(long));
|
|
||||||
if(!pData)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
long l = *(long *)pData;
|
|
||||||
|
|
||||||
// log event name
|
|
||||||
databuf.Add(event->fields[i].name, StrLen(event->fields[i].name));
|
|
||||||
databuf.Add(0);
|
|
||||||
|
|
||||||
// log event data
|
|
||||||
StrPrintf(data, arrsize(data), L"%ld", l);
|
|
||||||
databuf.Add(data, StrLen(data));
|
|
||||||
databuf.Add(0);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case kLogParamLongLong: {
|
|
||||||
pData = unpack.GetData(sizeof(long long));
|
|
||||||
if(!pData)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
long long ll = *(long long *)pData;
|
|
||||||
|
|
||||||
// log event name
|
|
||||||
databuf.Add(event->fields[i].name, StrLen(event->fields[i].name));
|
|
||||||
databuf.Add(0);
|
|
||||||
|
|
||||||
// log event data
|
|
||||||
StrPrintf(data, arrsize(data), L"%lld", ll);
|
|
||||||
databuf.Add(data, StrLen(data));
|
|
||||||
databuf.Add(0);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case kLogParamUuid: {
|
|
||||||
pData = unpack.GetData(sizeof(Uuid));
|
|
||||||
if(!pData)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
Uuid uuid = *(Uuid *)pData;
|
|
||||||
|
|
||||||
// log event name
|
|
||||||
databuf.Add(event->fields[i].name, StrLen(event->fields[i].name));
|
|
||||||
databuf.Add(0);
|
|
||||||
|
|
||||||
// log event data
|
|
||||||
GuidToString(uuid, data, arrsize(data));
|
|
||||||
databuf.Add(data, StrLen(data));
|
|
||||||
databuf.Add(0);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case kLogParamStringW: {
|
|
||||||
const wchar_t *str = unpack.GetString();
|
|
||||||
if(!str) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// log event name
|
|
||||||
databuf.Add(event->fields[i].name, StrLen(event->fields[i].name));
|
|
||||||
databuf.Add(0);
|
|
||||||
|
|
||||||
// log event data
|
|
||||||
databuf.Add(str, StrLen(str));
|
|
||||||
databuf.Add(0);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
databuf.Add(0);
|
|
||||||
|
|
||||||
if(NetLogSrvCallback) {
|
|
||||||
NetLogSrvCallback(
|
|
||||||
event,
|
|
||||||
databuf,
|
|
||||||
buildId,
|
|
||||||
addr,
|
|
||||||
msg.timestamp,
|
|
||||||
productId,
|
|
||||||
buildType
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
LogMsg(kLogError, "Unable to log event - event not found. type: %d from server: %d. If it is a new event the log server needs to be updated.", msg.eventType, srvType);
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************************
|
|
||||||
*
|
|
||||||
* Module exports
|
|
||||||
*
|
|
||||||
***/
|
|
||||||
|
|
||||||
//============================================================================
|
|
||||||
void NetLogSrvInitialize () {
|
|
||||||
s_running = true;
|
|
||||||
AsyncSocketRegisterNotifyProc(
|
|
||||||
kConnTypeSrvToLog,
|
|
||||||
SocketNotifyProc,
|
|
||||||
0, // Accept all buildIds
|
|
||||||
0, // Accept all buildTypes
|
|
||||||
0, // Accept all branchIds
|
|
||||||
0 // Accept all product Ids
|
|
||||||
);
|
|
||||||
IniChangeAdd(L"Log", IniChangeCallback, &s_change);
|
|
||||||
}
|
|
||||||
|
|
||||||
//============================================================================
|
|
||||||
void NetLogSrvShutdown () {
|
|
||||||
if(s_change) {
|
|
||||||
IniChangeRemove(s_change, true);
|
|
||||||
s_change = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
s_running = false;
|
|
||||||
AsyncSocketUnregisterNotifyProc(
|
|
||||||
kConnTypeSrvToLog,
|
|
||||||
SocketNotifyProc,
|
|
||||||
0, // Accept all buildIds
|
|
||||||
0,
|
|
||||||
0, // Accept all branchIds
|
|
||||||
0
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
//============================================================================
|
|
||||||
void NetLogSrvDestroy () {
|
|
||||||
|
|
||||||
while(s_perf[kNlSrvPerfConnCount])
|
|
||||||
AsyncSleep(10);
|
|
||||||
}
|
|
||||||
|
|
||||||
//============================================================================
|
|
||||||
void NetLogSrvRegisterCallback( void (*NlSrvCallback)(const NetLogEvent *, const ARRAY(wchar_t) &, unsigned, NetAddressNode &, uint64_t, unsigned, unsigned )) {
|
|
||||||
NetLogSrvCallback = NlSrvCallback;
|
|
||||||
}
|
|
||||||
|
|
||||||
//============================================================================
|
|
||||||
void LogConnIncRef (LogConn * conn) {
|
|
||||||
conn->IncRef();
|
|
||||||
}
|
|
||||||
|
|
||||||
//============================================================================
|
|
||||||
void LogConnDecRef (LogConn * conn) {
|
|
||||||
conn->DecRef();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************************
|
|
||||||
*
|
|
||||||
* Public exports
|
|
||||||
*
|
|
||||||
***/
|
|
||||||
|
|
||||||
//============================================================================
|
|
||||||
long NetLogSrvGetPerf (unsigned index) {
|
|
||||||
ASSERT(index < kNlSrvNumPerf);
|
|
||||||
return s_perf[index];
|
|
||||||
}
|
|
@ -57,7 +57,6 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
|||||||
#include "pnNetCli/pnNetCli.h"
|
#include "pnNetCli/pnNetCli.h"
|
||||||
|
|
||||||
#ifdef SERVER
|
#ifdef SERVER
|
||||||
#include "pnIni/pnIni.h"
|
|
||||||
#include "psUtils/psUtils.h" // for SrvMsgHeader, ugh
|
#include "psUtils/psUtils.h" // for SrvMsgHeader, ugh
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -89,7 +89,6 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
|||||||
#ifdef SERVER
|
#ifdef SERVER
|
||||||
# ifdef USES_NETSRV
|
# ifdef USES_NETSRV
|
||||||
// for SrvMsgHeader definition
|
// for SrvMsgHeader definition
|
||||||
# include "pnIni/pnIni.h" // psSrvConn needs ini types
|
|
||||||
# include "psUtils/psUtils.h"
|
# include "psUtils/psUtils.h"
|
||||||
|
|
||||||
# ifdef USES_PROTOCOL_SRV2VAULT
|
# ifdef USES_PROTOCOL_SRV2VAULT
|
||||||
|
@ -1,51 +0,0 @@
|
|||||||
/*==LICENSE==*
|
|
||||||
|
|
||||||
CyanWorlds.com Engine - MMOG client, server and tools
|
|
||||||
Copyright (C) 2011 Cyan Worlds, Inc.
|
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
Additional permissions under GNU GPL version 3 section 7
|
|
||||||
|
|
||||||
If you modify this Program, or any covered work, by linking or
|
|
||||||
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
|
|
||||||
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
|
|
||||||
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
|
|
||||||
(or a modified version of those libraries),
|
|
||||||
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
|
|
||||||
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
|
|
||||||
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
|
|
||||||
licensors of this Program grant you additional
|
|
||||||
permission to convey the resulting work. Corresponding Source for a
|
|
||||||
non-source form of such a combination shall include the source code for
|
|
||||||
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
|
|
||||||
work.
|
|
||||||
|
|
||||||
You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
|
||||||
or by snail mail at:
|
|
||||||
Cyan Worlds, Inc.
|
|
||||||
14617 N Newport Hwy
|
|
||||||
Mead, WA 99021
|
|
||||||
|
|
||||||
*==LICENSE==*/
|
|
||||||
/*****************************************************************************
|
|
||||||
*
|
|
||||||
* $/Plasma20/Sources/Plasma/NucleusLib/pnOraLib/Intern.h
|
|
||||||
*
|
|
||||||
***/
|
|
||||||
|
|
||||||
#ifdef PLASMA20_SOURCES_PLASMA_NUCLEUSLIB_PNORALIB_INTERN_H
|
|
||||||
#error "Header $/Plasma20/Sources/Plasma/NucleusLib/pnOraLib/Intern.h included more than once"
|
|
||||||
#endif
|
|
||||||
#define PLASMA20_SOURCES_PLASMA_NUCLEUSLIB_PNORALIB_INTERN_H
|
|
@ -1,72 +0,0 @@
|
|||||||
/*==LICENSE==*
|
|
||||||
|
|
||||||
CyanWorlds.com Engine - MMOG client, server and tools
|
|
||||||
Copyright (C) 2011 Cyan Worlds, Inc.
|
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
Additional permissions under GNU GPL version 3 section 7
|
|
||||||
|
|
||||||
If you modify this Program, or any covered work, by linking or
|
|
||||||
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
|
|
||||||
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
|
|
||||||
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
|
|
||||||
(or a modified version of those libraries),
|
|
||||||
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
|
|
||||||
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
|
|
||||||
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
|
|
||||||
licensors of this Program grant you additional
|
|
||||||
permission to convey the resulting work. Corresponding Source for a
|
|
||||||
non-source form of such a combination shall include the source code for
|
|
||||||
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
|
|
||||||
work.
|
|
||||||
|
|
||||||
You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
|
||||||
or by snail mail at:
|
|
||||||
Cyan Worlds, Inc.
|
|
||||||
14617 N Newport Hwy
|
|
||||||
Mead, WA 99021
|
|
||||||
|
|
||||||
*==LICENSE==*/
|
|
||||||
/*****************************************************************************
|
|
||||||
*
|
|
||||||
* $/Plasma20/Sources/Plasma/NucleusLib/pnOraLib/Pch.h
|
|
||||||
*
|
|
||||||
***/
|
|
||||||
|
|
||||||
#ifdef PLASMA20_SOURCES_PLASMA_NUCLEUSLIB_PNORALIB_PCH_H
|
|
||||||
#error "Header $/Plasma20/Sources/Plasma/NucleusLib/pnOraLib/Pch.h included more than once"
|
|
||||||
#endif
|
|
||||||
#define PLASMA20_SOURCES_PLASMA_NUCLEUSLIB_PNORALIB_PCH_H
|
|
||||||
|
|
||||||
|
|
||||||
// NucleusLib
|
|
||||||
#include "pnUtils/pnUtils.h"
|
|
||||||
#include "pnProduct/pnProduct.h"
|
|
||||||
#include "pnNetBase/pnNetBase.h"
|
|
||||||
#include "pnAsyncCore/pnAsyncCore.h"
|
|
||||||
#include "pnNetCli/pnNetCli.h"
|
|
||||||
#include "pnIni/pnIni.h"
|
|
||||||
|
|
||||||
// OCCI
|
|
||||||
#define WIN32COMMON
|
|
||||||
#include "occi.h"
|
|
||||||
|
|
||||||
// Local
|
|
||||||
#include "pnOraLib.h"
|
|
||||||
#include "Intern.h"
|
|
||||||
|
|
||||||
// System
|
|
||||||
#include <malloc.h>
|
|
||||||
#include <process.h>
|
|
@ -1,566 +0,0 @@
|
|||||||
/*==LICENSE==*
|
|
||||||
|
|
||||||
CyanWorlds.com Engine - MMOG client, server and tools
|
|
||||||
Copyright (C) 2011 Cyan Worlds, Inc.
|
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
Additional permissions under GNU GPL version 3 section 7
|
|
||||||
|
|
||||||
If you modify this Program, or any covered work, by linking or
|
|
||||||
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
|
|
||||||
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
|
|
||||||
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
|
|
||||||
(or a modified version of those libraries),
|
|
||||||
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
|
|
||||||
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
|
|
||||||
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
|
|
||||||
licensors of this Program grant you additional
|
|
||||||
permission to convey the resulting work. Corresponding Source for a
|
|
||||||
non-source form of such a combination shall include the source code for
|
|
||||||
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
|
|
||||||
work.
|
|
||||||
|
|
||||||
You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
|
||||||
or by snail mail at:
|
|
||||||
Cyan Worlds, Inc.
|
|
||||||
14617 N Newport Hwy
|
|
||||||
Mead, WA 99021
|
|
||||||
|
|
||||||
*==LICENSE==*/
|
|
||||||
/*****************************************************************************
|
|
||||||
*
|
|
||||||
* $/Plasma20/Sources/Plasma/NucleusLib/pnOraLib/pnOraLib.cpp
|
|
||||||
*
|
|
||||||
***/
|
|
||||||
|
|
||||||
#include "Pch.h"
|
|
||||||
#pragma hdrstop
|
|
||||||
|
|
||||||
|
|
||||||
//#define ORACONN_TRACKING
|
|
||||||
//#define ORASTMT_TRACKING
|
|
||||||
|
|
||||||
#ifdef ORACONN_TRACKING
|
|
||||||
#pragma message("pnOraLib: Compiling with ORACONN_TRACKING")
|
|
||||||
#endif
|
|
||||||
#ifdef ORASTMT_TRACKING
|
|
||||||
#pragma message("pnOraLib: Compiling with ORASTMT_TRACKING")
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************************
|
|
||||||
*
|
|
||||||
* Private
|
|
||||||
*
|
|
||||||
***/
|
|
||||||
|
|
||||||
struct OraInitData {
|
|
||||||
unsigned OraStmtCacheSize;
|
|
||||||
wchar_t OraUsername[128];
|
|
||||||
wchar_t OraPassword[128];
|
|
||||||
wchar_t OraConnectString[256];
|
|
||||||
|
|
||||||
OraInitData(
|
|
||||||
unsigned stmtCacheSize,
|
|
||||||
const wchar_t username[],
|
|
||||||
const wchar_t password[],
|
|
||||||
const wchar_t connectString[]
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
struct OraEnv {
|
|
||||||
occi::Environment * occiEnv;
|
|
||||||
occi::StatelessConnectionPool * occiPool;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct OraConnPool {
|
|
||||||
bool needReinit;
|
|
||||||
long perf[kOcciNumPerf];
|
|
||||||
CCritSect critsect;
|
|
||||||
OraEnv oraEnv;
|
|
||||||
OraInitData * data;
|
|
||||||
|
|
||||||
void Initialize_CS ();
|
|
||||||
void Shutdown_CS ();
|
|
||||||
void ReInitialize_CS ();
|
|
||||||
|
|
||||||
void Initialize (
|
|
||||||
const wchar_t username[],
|
|
||||||
const wchar_t password[],
|
|
||||||
const wchar_t connectString[],
|
|
||||||
unsigned stmtCacheSize
|
|
||||||
);
|
|
||||||
void Shutdown ();
|
|
||||||
OraConn * GetConn (const wchar_t tag[]);
|
|
||||||
void FreeConn (OraConn *& conn);
|
|
||||||
|
|
||||||
long GetPerf (long index);
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************************
|
|
||||||
*
|
|
||||||
* Private Data
|
|
||||||
*
|
|
||||||
***/
|
|
||||||
|
|
||||||
static const unsigned kDefaultConnTimeoutSecs = 60 * 30; // half-hour
|
|
||||||
static const unsigned kDefaultConnsPerEnv = 10;
|
|
||||||
|
|
||||||
enum {
|
|
||||||
kPerfOraConnCount,
|
|
||||||
kPerfOraStmtCount,
|
|
||||||
kNumPerf
|
|
||||||
};
|
|
||||||
|
|
||||||
static OraConnPool s_connPool;
|
|
||||||
static long s_perf[kNumPerf];
|
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************************
|
|
||||||
*
|
|
||||||
* Local functions
|
|
||||||
*
|
|
||||||
***/
|
|
||||||
|
|
||||||
/*****************************************************************************
|
|
||||||
*
|
|
||||||
* OraInitData
|
|
||||||
*
|
|
||||||
***/
|
|
||||||
|
|
||||||
//============================================================================
|
|
||||||
OraInitData::OraInitData (
|
|
||||||
unsigned stmtCacheSize,
|
|
||||||
const wchar_t username[],
|
|
||||||
const wchar_t password[],
|
|
||||||
const wchar_t connectString[]
|
|
||||||
) {
|
|
||||||
OraStmtCacheSize = stmtCacheSize;
|
|
||||||
StrCopy(OraUsername, username, arrsize(OraUsername));
|
|
||||||
StrCopy(OraPassword, password, arrsize(OraPassword));
|
|
||||||
StrCopy(OraConnectString, connectString, arrsize(OraConnectString));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************************
|
|
||||||
*
|
|
||||||
* OraConnPool
|
|
||||||
*
|
|
||||||
***/
|
|
||||||
|
|
||||||
//============================================================================
|
|
||||||
void OraConnPool::ReInitialize_CS () {
|
|
||||||
|
|
||||||
Shutdown_CS();
|
|
||||||
Initialize_CS();
|
|
||||||
|
|
||||||
needReinit = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
//============================================================================
|
|
||||||
void OraConnPool::Initialize_CS () {
|
|
||||||
|
|
||||||
ASSERT(data);
|
|
||||||
|
|
||||||
try {
|
|
||||||
const unsigned threads = AsyncThreadTaskGetThreadCount();
|
|
||||||
const unsigned maxConns = threads;
|
|
||||||
const unsigned minConns = 0;
|
|
||||||
const unsigned incConns = max(1, maxConns - 1);
|
|
||||||
|
|
||||||
oraEnv.occiEnv = occi::Environment::createEnvironment(
|
|
||||||
"OCCIUTF16",
|
|
||||||
"OCCIUTF16",
|
|
||||||
occi::Environment::THREADED_MUTEXED,
|
|
||||||
nil
|
|
||||||
);
|
|
||||||
|
|
||||||
// Create the connection pool
|
|
||||||
oraEnv.occiPool = oraEnv.occiEnv->createStatelessConnectionPool(
|
|
||||||
data->OraUsername,
|
|
||||||
data->OraPassword,
|
|
||||||
data->OraConnectString,
|
|
||||||
maxConns,
|
|
||||||
minConns,
|
|
||||||
incConns,
|
|
||||||
occi::StatelessConnectionPool::HOMOGENEOUS
|
|
||||||
);
|
|
||||||
|
|
||||||
// Turn on statement caching
|
|
||||||
oraEnv.occiPool->setStmtCacheSize(data->OraStmtCacheSize);
|
|
||||||
oraEnv.occiPool->setTimeOut(kDefaultConnTimeoutSecs);
|
|
||||||
// If no connections are available, block until one becomes available
|
|
||||||
oraEnv.occiPool->setBusyOption(occi::StatelessConnectionPool::WAIT);
|
|
||||||
}
|
|
||||||
catch (exception & e) {
|
|
||||||
OraLogError(L"OraConnPool::Initialize", e);
|
|
||||||
ErrorFatal(__LINE__, __FILE__, "Failed to initialize occi connection pool");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//============================================================================
|
|
||||||
void OraConnPool::Shutdown_CS () {
|
|
||||||
|
|
||||||
if (oraEnv.occiEnv) {
|
|
||||||
try {
|
|
||||||
// If we aren't connected to oracle, then closing the connection
|
|
||||||
// pool causes oracle to make a pure virtual function call when
|
|
||||||
// closing the environment.
|
|
||||||
if (!needReinit)
|
|
||||||
oraEnv.occiEnv->terminateStatelessConnectionPool(oraEnv.occiPool, occi::StatelessConnectionPool::SPD_FORCE);
|
|
||||||
occi::Environment::terminateEnvironment(oraEnv.occiEnv);
|
|
||||||
}
|
|
||||||
catch (exception & e) {
|
|
||||||
OraLogError(L"OraConnPool::Shutdown", e);
|
|
||||||
}
|
|
||||||
oraEnv.occiEnv = nil;
|
|
||||||
oraEnv.occiPool = nil;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//============================================================================
|
|
||||||
void OraConnPool::Initialize (
|
|
||||||
const wchar_t username[],
|
|
||||||
const wchar_t password[],
|
|
||||||
const wchar_t connectString[],
|
|
||||||
unsigned stmtCacheSize
|
|
||||||
) {
|
|
||||||
data = new OraInitData(stmtCacheSize, username, password, connectString);
|
|
||||||
|
|
||||||
critsect.Enter();
|
|
||||||
{
|
|
||||||
Initialize_CS();
|
|
||||||
}
|
|
||||||
critsect.Leave();
|
|
||||||
}
|
|
||||||
|
|
||||||
//============================================================================
|
|
||||||
void OraConnPool::Shutdown () {
|
|
||||||
|
|
||||||
critsect.Enter();
|
|
||||||
{
|
|
||||||
Shutdown_CS();
|
|
||||||
}
|
|
||||||
critsect.Leave();
|
|
||||||
|
|
||||||
delete data;
|
|
||||||
}
|
|
||||||
|
|
||||||
//============================================================================
|
|
||||||
OraConn * OraConnPool::GetConn (const wchar_t tag[]) {
|
|
||||||
|
|
||||||
OraConn * oraConn = NEWZERO(OraConn);
|
|
||||||
if (tag)
|
|
||||||
StrCopy(oraConn->tag, tag, arrsize(oraConn->tag));
|
|
||||||
|
|
||||||
critsect.Enter();
|
|
||||||
for (;;) try {
|
|
||||||
if (needReinit) {
|
|
||||||
if (GetPerf(kOcciPerfBusyConns))
|
|
||||||
// Wait for all connections to be freed by the app
|
|
||||||
// before environment reinitialization.
|
|
||||||
break;
|
|
||||||
|
|
||||||
ReInitialize_CS();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!oraEnv.occiEnv)
|
|
||||||
break;
|
|
||||||
|
|
||||||
if (nil != (oraConn->occiConn = oraEnv.occiPool->getConnection()))
|
|
||||||
oraConn->oraEnv = &oraEnv;
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
catch (exception & e) {
|
|
||||||
OraLogError(L"OraConnPool::GetConn", e);
|
|
||||||
oraConn = nil;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
critsect.Leave();
|
|
||||||
|
|
||||||
for (;;) {
|
|
||||||
if (!oraConn || !oraConn->occiConn) {
|
|
||||||
delete oraConn;
|
|
||||||
oraConn = nil;
|
|
||||||
LogMsg(kLogError, L"OraConnPool::GetConn: Failed to aquire a database connection");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
const unsigned connCount = AtomicAdd(&s_perf[kPerfOraConnCount], 1) + 1;
|
|
||||||
ref(connCount);
|
|
||||||
|
|
||||||
#ifdef ORACONN_TRACKING
|
|
||||||
LogMsg(kLogPerf, L"OraGetConn: %u, %p, %s", connCount, oraConn, oraConn->tag);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return oraConn;
|
|
||||||
}
|
|
||||||
|
|
||||||
//============================================================================
|
|
||||||
void OraConnPool::FreeConn (OraConn *& oraConn) {
|
|
||||||
|
|
||||||
if (oraConn) try {
|
|
||||||
occi::Connection * occiConn = oraConn->occiConn;
|
|
||||||
occi::StatelessConnectionPool * occiPool = oraConn->oraEnv->occiPool;
|
|
||||||
|
|
||||||
const unsigned connCount = AtomicAdd(&s_perf[kPerfOraConnCount], -1) - 1;
|
|
||||||
ref(connCount);
|
|
||||||
|
|
||||||
#ifdef ORACONN_TRACKING
|
|
||||||
LogMsg(kLogPerf, L"OraFreeConn: %u, %p, %s", connCount, oraConn, oraConn->tag);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
delete oraConn;
|
|
||||||
|
|
||||||
try {
|
|
||||||
occiConn->commit();
|
|
||||||
}
|
|
||||||
catch (exception & e) {
|
|
||||||
OraLogError(L"OraConnPool::FreeConn [commit]", e);
|
|
||||||
needReinit = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
occiPool->releaseConnection(occiConn);
|
|
||||||
}
|
|
||||||
catch (exception & e) {
|
|
||||||
OraLogError(L"OraConnPool::FreeConn [release]", e);
|
|
||||||
}
|
|
||||||
|
|
||||||
oraConn = nil;
|
|
||||||
}
|
|
||||||
|
|
||||||
//============================================================================
|
|
||||||
long OraConnPool::GetPerf (long index) {
|
|
||||||
|
|
||||||
if (!oraEnv.occiEnv)
|
|
||||||
return 0;
|
|
||||||
if (!oraEnv.occiPool)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
switch (index) {
|
|
||||||
case kOcciPerfOpenConns: return oraEnv.occiPool->getOpenConnections();
|
|
||||||
case kOcciPerfBusyConns: return oraEnv.occiPool->getBusyConnections();
|
|
||||||
DEFAULT_FATAL(index);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************************
|
|
||||||
*
|
|
||||||
* Exports
|
|
||||||
*
|
|
||||||
***/
|
|
||||||
|
|
||||||
//============================================================================
|
|
||||||
void OraLogError (const wchar_t sql[], const exception & e) {
|
|
||||||
|
|
||||||
wchar_t buffer[1024];
|
|
||||||
const char * tmp = e.what();
|
|
||||||
|
|
||||||
// Some exceptions we catch are actually unicode strings in a char buffer, but others aren't.
|
|
||||||
if (tmp[0] && !tmp[1]) {
|
|
||||||
const wchar_t * wtmp = (const wchar_t *)tmp;
|
|
||||||
StrCopy(buffer, wtmp, arrsize(buffer));
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
StrToUnicode(buffer, tmp, arrsize(buffer));
|
|
||||||
}
|
|
||||||
LogMsg(kLogError, L"%s, %s", sql, buffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
//============================================================================
|
|
||||||
void OraGetShaDigest (
|
|
||||||
occi::Statement * oraStmt,
|
|
||||||
unsigned index,
|
|
||||||
ShaDigest * digest
|
|
||||||
) {
|
|
||||||
occi::Bytes bytes = oraStmt->getBytes(index);
|
|
||||||
const unsigned length = bytes.length();
|
|
||||||
ASSERT(length == msizeof(ShaDigest, data));
|
|
||||||
bytes.getBytes((uint8_t *)digest->data, length);
|
|
||||||
}
|
|
||||||
|
|
||||||
//============================================================================
|
|
||||||
void OraSetShaDigest (
|
|
||||||
occi::Statement * oraStmt,
|
|
||||||
unsigned index,
|
|
||||||
const ShaDigest & digest
|
|
||||||
) {
|
|
||||||
occi::Bytes bytes((uint8_t *)&digest, sizeof(digest));
|
|
||||||
oraStmt->setBytes(index, bytes);
|
|
||||||
}
|
|
||||||
|
|
||||||
//============================================================================
|
|
||||||
void OraBindString (
|
|
||||||
occi::Statement * oraStmt,
|
|
||||||
unsigned index,
|
|
||||||
wchar_t * buffer,
|
|
||||||
unsigned chars,
|
|
||||||
ub2 * length,
|
|
||||||
sb2 * indicator
|
|
||||||
) {
|
|
||||||
oraStmt->setDataBuffer(
|
|
||||||
index,
|
|
||||||
buffer,
|
|
||||||
occi::OCCI_SQLT_STR,
|
|
||||||
chars * sizeof(buffer[0]),
|
|
||||||
length,
|
|
||||||
indicator
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
//============================================================================
|
|
||||||
void OraBindString (
|
|
||||||
occi::ResultSet * rs,
|
|
||||||
unsigned index,
|
|
||||||
wchar_t * buffer,
|
|
||||||
unsigned chars,
|
|
||||||
ub2 * length,
|
|
||||||
sb2 * indicator
|
|
||||||
) {
|
|
||||||
rs->setDataBuffer(
|
|
||||||
index,
|
|
||||||
buffer,
|
|
||||||
occi::OCCI_SQLT_STR,
|
|
||||||
chars * sizeof(buffer[0]),
|
|
||||||
length,
|
|
||||||
indicator
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
//============================================================================
|
|
||||||
void OraGetUuid (
|
|
||||||
occi::Statement * oraStmt,
|
|
||||||
unsigned index,
|
|
||||||
Uuid * uuid
|
|
||||||
) {
|
|
||||||
occi::Bytes bytes = oraStmt->getBytes(index);
|
|
||||||
if (const unsigned length = bytes.length()) {
|
|
||||||
ASSERT(length == msizeof(Uuid, data));
|
|
||||||
uint8_t * buf = malloc(length);
|
|
||||||
bytes.getBytes(buf, length);
|
|
||||||
GuidFromHex(buf, length, uuid);
|
|
||||||
|
|
||||||
free(buf)
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
GuidClear(uuid);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//============================================================================
|
|
||||||
void OraSetUuid (
|
|
||||||
occi::Statement * oraStmt,
|
|
||||||
unsigned index,
|
|
||||||
const Uuid & uuid
|
|
||||||
) {
|
|
||||||
occi::Bytes bytes((uint8_t *)&uuid, sizeof(uuid));
|
|
||||||
oraStmt->setBytes(index, bytes);
|
|
||||||
}
|
|
||||||
|
|
||||||
//============================================================================
|
|
||||||
OraConn * OraGetConn (const wchar_t tag[]) {
|
|
||||||
|
|
||||||
// grabs a cached connection if available, otherwise creates a new one on-the-fly
|
|
||||||
return s_connPool.GetConn(tag);
|
|
||||||
}
|
|
||||||
|
|
||||||
//============================================================================
|
|
||||||
void OraFreeConn (OraConn *& oraConn) {
|
|
||||||
|
|
||||||
s_connPool.FreeConn(oraConn);
|
|
||||||
}
|
|
||||||
|
|
||||||
//============================================================================
|
|
||||||
occi::Statement * OraGetStmt (
|
|
||||||
OraConn * oraConn,
|
|
||||||
const wchar_t sql[]
|
|
||||||
) {
|
|
||||||
occi::Statement * oraStmt = nil;
|
|
||||||
try {
|
|
||||||
// grabs a matching cached statement if available, otherwise creates a new one
|
|
||||||
oraStmt = oraConn->occiConn->createStatement(sql);
|
|
||||||
// auto-commit causes an exception to be thrown when writing blobs: "ORA-01002: fetch out of sequence"
|
|
||||||
oraStmt->setAutoCommit(false);
|
|
||||||
|
|
||||||
const unsigned stmtCount = AtomicAdd(&s_perf[kPerfOraStmtCount], 1) + 1;
|
|
||||||
ref(stmtCount);
|
|
||||||
|
|
||||||
#ifdef ORASTMT_TRACKING
|
|
||||||
LogMsg(kLogPerf, L"OraGetStmt: %u, %p, %s", stmtCount, oraStmt, sql);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
catch (exception & e) {
|
|
||||||
OraLogError(L"OraGetStmt", e);
|
|
||||||
}
|
|
||||||
return oraStmt;
|
|
||||||
}
|
|
||||||
|
|
||||||
//============================================================================
|
|
||||||
void OraFreeStmt (occi::Statement *& oraStmt) {
|
|
||||||
if (oraStmt) {
|
|
||||||
try {
|
|
||||||
// caches the statement
|
|
||||||
oraStmt->getConnection()->terminateStatement(oraStmt);
|
|
||||||
|
|
||||||
const unsigned stmtCount = AtomicAdd(&s_perf[kPerfOraStmtCount], -1) - 1;
|
|
||||||
ref(stmtCount);
|
|
||||||
|
|
||||||
#ifdef ORASTMT_TRACKING
|
|
||||||
LogMsg(kLogPerf, L"OraFreeStmt: %u, %p", stmtCount, oraStmt);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
catch (exception & e) {
|
|
||||||
OraLogError(L"OraFreeStmt", e);
|
|
||||||
}
|
|
||||||
oraStmt = nil;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//============================================================================
|
|
||||||
void OraInitialize (
|
|
||||||
const wchar_t username[],
|
|
||||||
const wchar_t password[],
|
|
||||||
const wchar_t connectString[],
|
|
||||||
unsigned stmtCacheSize
|
|
||||||
) {
|
|
||||||
// Connect to the database
|
|
||||||
s_connPool.Initialize(
|
|
||||||
username,
|
|
||||||
password,
|
|
||||||
connectString,
|
|
||||||
stmtCacheSize
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
//============================================================================
|
|
||||||
void OraShutdown () {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
//============================================================================
|
|
||||||
void OraDestroy () {
|
|
||||||
s_connPool.Shutdown();
|
|
||||||
}
|
|
||||||
|
|
||||||
//============================================================================
|
|
||||||
long OraLibGetOcciPerf (unsigned index) {
|
|
||||||
return s_connPool.GetPerf(index);
|
|
||||||
}
|
|
@ -1,144 +0,0 @@
|
|||||||
/*==LICENSE==*
|
|
||||||
|
|
||||||
CyanWorlds.com Engine - MMOG client, server and tools
|
|
||||||
Copyright (C) 2011 Cyan Worlds, Inc.
|
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
Additional permissions under GNU GPL version 3 section 7
|
|
||||||
|
|
||||||
If you modify this Program, or any covered work, by linking or
|
|
||||||
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
|
|
||||||
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
|
|
||||||
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
|
|
||||||
(or a modified version of those libraries),
|
|
||||||
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
|
|
||||||
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
|
|
||||||
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
|
|
||||||
licensors of this Program grant you additional
|
|
||||||
permission to convey the resulting work. Corresponding Source for a
|
|
||||||
non-source form of such a combination shall include the source code for
|
|
||||||
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
|
|
||||||
work.
|
|
||||||
|
|
||||||
You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
|
||||||
or by snail mail at:
|
|
||||||
Cyan Worlds, Inc.
|
|
||||||
14617 N Newport Hwy
|
|
||||||
Mead, WA 99021
|
|
||||||
|
|
||||||
*==LICENSE==*/
|
|
||||||
/*****************************************************************************
|
|
||||||
*
|
|
||||||
* $/Plasma20/Sources/Plasma/NucleusLib/pnOraLib/pnOraLib.h
|
|
||||||
*
|
|
||||||
***/
|
|
||||||
|
|
||||||
#ifndef PLASMA20_SOURCES_PLASMA_NUCLEUSLIB_PNORALIB_PNORALIB_H
|
|
||||||
#define PLASMA20_SOURCES_PLASMA_NUCLEUSLIB_PNORALIB_PNORALIB_H
|
|
||||||
|
|
||||||
// OCCI
|
|
||||||
#define WIN32COMMON
|
|
||||||
#include "occi.h"
|
|
||||||
using namespace oracle;
|
|
||||||
struct OraEnv;
|
|
||||||
|
|
||||||
enum {
|
|
||||||
kOcciPerfOpenConns,
|
|
||||||
kOcciPerfBusyConns,
|
|
||||||
kOcciNumPerf
|
|
||||||
};
|
|
||||||
|
|
||||||
long OraLibGetOcciPerf (unsigned index);
|
|
||||||
|
|
||||||
|
|
||||||
struct OraConn {
|
|
||||||
// treat all fields as read-only
|
|
||||||
OraEnv * oraEnv;
|
|
||||||
occi::Connection * occiConn;
|
|
||||||
wchar_t tag[128];
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************************
|
|
||||||
*
|
|
||||||
* OraLib
|
|
||||||
*
|
|
||||||
***/
|
|
||||||
|
|
||||||
void OraLogError (const wchar_t sql[], const exception & e);
|
|
||||||
|
|
||||||
void OraGetShaDigest (
|
|
||||||
occi::Statement * oraStmt,
|
|
||||||
unsigned index,
|
|
||||||
ShaDigest * digest
|
|
||||||
);
|
|
||||||
|
|
||||||
void OraSetShaDigest (
|
|
||||||
occi::Statement * oraStmt,
|
|
||||||
unsigned index,
|
|
||||||
const ShaDigest & digest
|
|
||||||
);
|
|
||||||
|
|
||||||
void OraBindString (
|
|
||||||
occi::Statement * oraStmt,
|
|
||||||
unsigned index,
|
|
||||||
wchar_t * buffer,
|
|
||||||
unsigned chars,
|
|
||||||
ub2 * length,
|
|
||||||
sb2 * indicator
|
|
||||||
);
|
|
||||||
|
|
||||||
void OraBindString (
|
|
||||||
occi::ResultSet * rs,
|
|
||||||
unsigned index,
|
|
||||||
wchar_t * buffer,
|
|
||||||
unsigned chars,
|
|
||||||
ub2 * length,
|
|
||||||
sb2 * indicator
|
|
||||||
);
|
|
||||||
|
|
||||||
void OraGetUuid (
|
|
||||||
occi::Statement * oraStmt,
|
|
||||||
unsigned index,
|
|
||||||
Uuid * uuid
|
|
||||||
);
|
|
||||||
|
|
||||||
void OraSetUuid (
|
|
||||||
occi::Statement * oraStmt,
|
|
||||||
unsigned index,
|
|
||||||
const Uuid & uuid
|
|
||||||
);
|
|
||||||
|
|
||||||
OraConn * OraGetConn (const wchar_t tag[] = nil);
|
|
||||||
|
|
||||||
void OraFreeConn (OraConn *& oraConn);
|
|
||||||
|
|
||||||
occi::Statement * OraGetStmt (
|
|
||||||
OraConn * oraConn,
|
|
||||||
const wchar_t sql[]
|
|
||||||
);
|
|
||||||
|
|
||||||
void OraFreeStmt (occi::Statement *& oraStmt);
|
|
||||||
|
|
||||||
void OraInitialize (
|
|
||||||
const wchar_t username[],
|
|
||||||
const wchar_t password[],
|
|
||||||
const wchar_t connectString[],
|
|
||||||
unsigned stmtCacheSize
|
|
||||||
);
|
|
||||||
void OraShutdown ();
|
|
||||||
void OraDestroy ();
|
|
||||||
|
|
||||||
#endif // PLASMA20_SOURCES_PLASMA_NUCLEUSLIB_PNORALIB_PNORALIB_H
|
|
@ -1,51 +0,0 @@
|
|||||||
/*==LICENSE==*
|
|
||||||
|
|
||||||
CyanWorlds.com Engine - MMOG client, server and tools
|
|
||||||
Copyright (C) 2011 Cyan Worlds, Inc.
|
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
Additional permissions under GNU GPL version 3 section 7
|
|
||||||
|
|
||||||
If you modify this Program, or any covered work, by linking or
|
|
||||||
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
|
|
||||||
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
|
|
||||||
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
|
|
||||||
(or a modified version of those libraries),
|
|
||||||
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
|
|
||||||
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
|
|
||||||
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
|
|
||||||
licensors of this Program grant you additional
|
|
||||||
permission to convey the resulting work. Corresponding Source for a
|
|
||||||
non-source form of such a combination shall include the source code for
|
|
||||||
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
|
|
||||||
work.
|
|
||||||
|
|
||||||
You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
|
||||||
or by snail mail at:
|
|
||||||
Cyan Worlds, Inc.
|
|
||||||
14617 N Newport Hwy
|
|
||||||
Mead, WA 99021
|
|
||||||
|
|
||||||
*==LICENSE==*/
|
|
||||||
/*****************************************************************************
|
|
||||||
*
|
|
||||||
* $/Plasma20/Sources/Plasma/NucleusLib/pnSqlLib/Intern.h
|
|
||||||
*
|
|
||||||
***/
|
|
||||||
|
|
||||||
#ifdef PLASMA20_SOURCES_PLASMA_NUCLEUSLIB_PNSQLLIB_INTERN_H
|
|
||||||
#error "Header $/Plasma20/Sources/Plasma/NucleusLib/pnSqlLib/Intern.h included more than once"
|
|
||||||
#endif
|
|
||||||
#define PLASMA20_SOURCES_PLASMA_NUCLEUSLIB_PNSQLLIB_INTERN_H
|
|
@ -1,62 +0,0 @@
|
|||||||
/*==LICENSE==*
|
|
||||||
|
|
||||||
CyanWorlds.com Engine - MMOG client, server and tools
|
|
||||||
Copyright (C) 2011 Cyan Worlds, Inc.
|
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
Additional permissions under GNU GPL version 3 section 7
|
|
||||||
|
|
||||||
If you modify this Program, or any covered work, by linking or
|
|
||||||
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
|
|
||||||
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
|
|
||||||
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
|
|
||||||
(or a modified version of those libraries),
|
|
||||||
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
|
|
||||||
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
|
|
||||||
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
|
|
||||||
licensors of this Program grant you additional
|
|
||||||
permission to convey the resulting work. Corresponding Source for a
|
|
||||||
non-source form of such a combination shall include the source code for
|
|
||||||
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
|
|
||||||
work.
|
|
||||||
|
|
||||||
You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
|
||||||
or by snail mail at:
|
|
||||||
Cyan Worlds, Inc.
|
|
||||||
14617 N Newport Hwy
|
|
||||||
Mead, WA 99021
|
|
||||||
|
|
||||||
*==LICENSE==*/
|
|
||||||
/*****************************************************************************
|
|
||||||
*
|
|
||||||
* $/Plasma20/Sources/Plasma/NucleusLib/pnSqlLib/Pch.h
|
|
||||||
*
|
|
||||||
***/
|
|
||||||
|
|
||||||
#ifdef PLASMA20_SOURCES_PLASMA_NUCLEUSLIB_PNSQLLIB_PCH_H
|
|
||||||
#error "Header $/Plasma20/Sources/Plasma/NucleusLib/pnSqlLib/Pch.h included more than once"
|
|
||||||
#endif
|
|
||||||
#define PLASMA20_SOURCES_PLASMA_NUCLEUSLIB_PNSQLLIB_PCH_H
|
|
||||||
|
|
||||||
#include "pnUtils/pnUtils.h"
|
|
||||||
#include "pnNetBase/pnNetBase.h"
|
|
||||||
#include "pnAsyncCore/pnAsyncCore.h"
|
|
||||||
|
|
||||||
// Include ODBC API
|
|
||||||
#include <sql.h>
|
|
||||||
#include <sqlext.h>
|
|
||||||
|
|
||||||
#include "Private/pnSqlAllIncludes.h"
|
|
||||||
#include "Intern.h"
|
|
@ -1,55 +0,0 @@
|
|||||||
/*==LICENSE==*
|
|
||||||
|
|
||||||
CyanWorlds.com Engine - MMOG client, server and tools
|
|
||||||
Copyright (C) 2011 Cyan Worlds, Inc.
|
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
Additional permissions under GNU GPL version 3 section 7
|
|
||||||
|
|
||||||
If you modify this Program, or any covered work, by linking or
|
|
||||||
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
|
|
||||||
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
|
|
||||||
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
|
|
||||||
(or a modified version of those libraries),
|
|
||||||
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
|
|
||||||
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
|
|
||||||
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
|
|
||||||
licensors of this Program grant you additional
|
|
||||||
permission to convey the resulting work. Corresponding Source for a
|
|
||||||
non-source form of such a combination shall include the source code for
|
|
||||||
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
|
|
||||||
work.
|
|
||||||
|
|
||||||
You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
|
||||||
or by snail mail at:
|
|
||||||
Cyan Worlds, Inc.
|
|
||||||
14617 N Newport Hwy
|
|
||||||
Mead, WA 99021
|
|
||||||
|
|
||||||
*==LICENSE==*/
|
|
||||||
/*****************************************************************************
|
|
||||||
*
|
|
||||||
* $/Plasma20/Sources/Plasma/NucleusLib/pnSqlLib/Private/pnSqlAllIncludes.h
|
|
||||||
*
|
|
||||||
***/
|
|
||||||
|
|
||||||
#ifdef PLASMA20_SOURCES_PLASMA_NUCLEUSLIB_PNSQLLIB_PRIVATE_PNSQLALLINCLUDES_H
|
|
||||||
#error "Header $/Plasma20/Sources/Plasma/NucleusLib/pnSqlLib/Private/pnSqlAllIncludes.h included more than once"
|
|
||||||
#endif
|
|
||||||
#define PLASMA20_SOURCES_PLASMA_NUCLEUSLIB_PNSQLLIB_PRIVATE_PNSQLALLINCLUDES_H
|
|
||||||
|
|
||||||
|
|
||||||
#include "pnSqlConn.h"
|
|
||||||
#include "pnSqlUtil.h"
|
|
File diff suppressed because it is too large
Load Diff
@ -1,308 +0,0 @@
|
|||||||
/*==LICENSE==*
|
|
||||||
|
|
||||||
CyanWorlds.com Engine - MMOG client, server and tools
|
|
||||||
Copyright (C) 2011 Cyan Worlds, Inc.
|
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
Additional permissions under GNU GPL version 3 section 7
|
|
||||||
|
|
||||||
If you modify this Program, or any covered work, by linking or
|
|
||||||
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
|
|
||||||
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
|
|
||||||
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
|
|
||||||
(or a modified version of those libraries),
|
|
||||||
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
|
|
||||||
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
|
|
||||||
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
|
|
||||||
licensors of this Program grant you additional
|
|
||||||
permission to convey the resulting work. Corresponding Source for a
|
|
||||||
non-source form of such a combination shall include the source code for
|
|
||||||
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
|
|
||||||
work.
|
|
||||||
|
|
||||||
You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
|
||||||
or by snail mail at:
|
|
||||||
Cyan Worlds, Inc.
|
|
||||||
14617 N Newport Hwy
|
|
||||||
Mead, WA 99021
|
|
||||||
|
|
||||||
*==LICENSE==*/
|
|
||||||
/*****************************************************************************
|
|
||||||
*
|
|
||||||
* $/Plasma20/Sources/Plasma/NucleusLib/pnSqlLib/Private/pnSqlConn.h
|
|
||||||
*
|
|
||||||
***/
|
|
||||||
|
|
||||||
#ifdef PLASMA20_SOURCES_PLASMA_NUCLEUSLIB_PNSQLLIB_PRIVATE_PNSQLCONN_H
|
|
||||||
#error "Header $/Plasma20/Sources/Plasma/NucleusLib/pnSqlLib/Private/pnSqlConn.h included more than once"
|
|
||||||
#endif
|
|
||||||
#define PLASMA20_SOURCES_PLASMA_NUCLEUSLIB_PNSQLLIB_PRIVATE_PNSQLCONN_H
|
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************************
|
|
||||||
*
|
|
||||||
* Types
|
|
||||||
*
|
|
||||||
***/
|
|
||||||
|
|
||||||
struct SqlConn;
|
|
||||||
struct SqlStmt;
|
|
||||||
struct SqlTrans;
|
|
||||||
|
|
||||||
typedef void (* FSqlBindPrepare)(
|
|
||||||
SqlStmt * stmt,
|
|
||||||
ARRAY(uint8_t) * bindData
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************************
|
|
||||||
*
|
|
||||||
* Init API
|
|
||||||
*
|
|
||||||
***/
|
|
||||||
|
|
||||||
SqlConn * SqlConnCreate (
|
|
||||||
const wchar_t connectStr[],
|
|
||||||
unsigned maxConnections,
|
|
||||||
unsigned transTimeoutMs
|
|
||||||
);
|
|
||||||
void SqlConnShutdown (SqlConn * conn);
|
|
||||||
void SqlConnDestroy (SqlConn * conn);
|
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************************
|
|
||||||
*
|
|
||||||
* Ad-hoc query API
|
|
||||||
*
|
|
||||||
* For queries that will be performed and therefore don't want to incur
|
|
||||||
* binding and preparing overhead.
|
|
||||||
*
|
|
||||||
***/
|
|
||||||
|
|
||||||
SqlStmt * SqlConnAllocStmt (
|
|
||||||
SqlConn * conn
|
|
||||||
);
|
|
||||||
void SqlConnFreeStmt (
|
|
||||||
SqlStmt * stmt
|
|
||||||
);
|
|
||||||
void SqlStmtSetAttr (
|
|
||||||
SqlStmt * stmt,
|
|
||||||
int attr,
|
|
||||||
void * valPtr,
|
|
||||||
int strLen
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************************
|
|
||||||
*
|
|
||||||
* "Optimized" query API
|
|
||||||
*
|
|
||||||
* The "prepare" function will only be called once for a statement, and it
|
|
||||||
* will retain its bindings and memory set by the prepare function until
|
|
||||||
* SqlConnDisconnect is called (i.e. until program shutdown).
|
|
||||||
*
|
|
||||||
*
|
|
||||||
*
|
|
||||||
***/
|
|
||||||
|
|
||||||
SqlStmt * SqlConnAllocStmt (
|
|
||||||
SqlConn * conn,
|
|
||||||
FSqlBindPrepare prepare,
|
|
||||||
uint8_t ** bindData // [OUT]
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************************
|
|
||||||
*
|
|
||||||
* Error handling
|
|
||||||
*
|
|
||||||
***/
|
|
||||||
|
|
||||||
typedef void (* FSqlConnErrorHandler)(
|
|
||||||
int result,
|
|
||||||
const wchar_t function[],
|
|
||||||
const wchar_t command[],
|
|
||||||
const char diagnostics[], // double-null terminated
|
|
||||||
void * userParam
|
|
||||||
);
|
|
||||||
|
|
||||||
void SqlConnSetErrorHandler (
|
|
||||||
SqlStmt * stmt,
|
|
||||||
FSqlConnErrorHandler handler,
|
|
||||||
void * userParam
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************************
|
|
||||||
*
|
|
||||||
* Output binding
|
|
||||||
*
|
|
||||||
***/
|
|
||||||
|
|
||||||
// Reset all changes done by SqlConnBindCol*() functions
|
|
||||||
void SqlConnBindColReset (SqlStmt * stmt);
|
|
||||||
|
|
||||||
// Obtain multiple rows in a result set by rows or columns
|
|
||||||
void SqlConnBindColMode (
|
|
||||||
SqlStmt * stmt,
|
|
||||||
SQLUINTEGER * rowCount, // SQL_ATTR_ROWS_FETCHED_PTR
|
|
||||||
SQLUINTEGER structSize, // SQL_ATTR_ROW_BIND_TYPE
|
|
||||||
SQLUINTEGER arraySize, // SQL_ATTR_ROW_ARRAY_SIZE
|
|
||||||
SQLUSMALLINT * statusArray // SQL_ATTR_ROW_STATUS_PTR
|
|
||||||
);
|
|
||||||
|
|
||||||
// Bind parameters of various types
|
|
||||||
void SqlConnBindCol (
|
|
||||||
SqlStmt * stmt,
|
|
||||||
SQLINTEGER targetType,
|
|
||||||
SQLPOINTER targetValue,
|
|
||||||
SQLINTEGER bufferLength,
|
|
||||||
SQLINTEGER * indPtr
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************************
|
|
||||||
*
|
|
||||||
* Parameter binding
|
|
||||||
*
|
|
||||||
***/
|
|
||||||
|
|
||||||
// Reset all changes done by SqlConnBindParameter*() functions
|
|
||||||
void SqlConnBindParameterReset (SqlStmt * stmt);
|
|
||||||
|
|
||||||
// Set multiple rows in an output set by rows or columns
|
|
||||||
void SqlConnBindParameterMode (
|
|
||||||
SqlStmt * stmt,
|
|
||||||
SQLUINTEGER * processCount, // SQL_ATTR_PARAMS_PROCESSED_PTR
|
|
||||||
SQLUINTEGER structSize, // SQL_ATTR_PARAM_BIND_TYPE
|
|
||||||
SQLUINTEGER arraySize, // SQL_ATTR_PARAMSET_SIZE
|
|
||||||
SQLUSMALLINT * statusArray // SQL_ATTR_PARAM_STATUS_PTR
|
|
||||||
);
|
|
||||||
|
|
||||||
// Bind parameters of various types
|
|
||||||
void SqlConnBindParameter (
|
|
||||||
SqlStmt * stmt,
|
|
||||||
SQLINTEGER inputOutputType,
|
|
||||||
SQLINTEGER valueType,
|
|
||||||
SQLINTEGER parameterType,
|
|
||||||
SQLUINTEGER columnSize,
|
|
||||||
SQLINTEGER decimalDigits,
|
|
||||||
SQLPOINTER parameterValuePtr,
|
|
||||||
SQLINTEGER bufferLength,
|
|
||||||
SQLINTEGER * indPtr
|
|
||||||
);
|
|
||||||
void SqlConnBindParameterInt (
|
|
||||||
SqlStmt * stmt,
|
|
||||||
SQLINTEGER inputOutputType,
|
|
||||||
SQLINTEGER * parameterValuePtr,
|
|
||||||
SQLINTEGER * indPtr
|
|
||||||
);
|
|
||||||
void SqlConnBindParameterUInt (
|
|
||||||
SqlStmt * stmt,
|
|
||||||
SQLINTEGER inputOutputType,
|
|
||||||
SQLUINTEGER * parameterValuePtr,
|
|
||||||
SQLINTEGER * indPtr
|
|
||||||
);
|
|
||||||
void SqlConnBindParameterString (
|
|
||||||
SqlStmt * stmt,
|
|
||||||
SQLINTEGER inputOutputType,
|
|
||||||
SQLUINTEGER columnSize, // bytes, NOT chars
|
|
||||||
SQLWCHAR * parameterValuePtr,
|
|
||||||
SQLINTEGER * indPtr
|
|
||||||
);
|
|
||||||
void SqlConnBindParameterStringA (
|
|
||||||
SqlStmt * stmt,
|
|
||||||
SQLINTEGER inputOutputType,
|
|
||||||
SQLUINTEGER columnSize, // bytes, NOT chars
|
|
||||||
SQLCHAR * parameterValuePtr,
|
|
||||||
SQLINTEGER * indPtr
|
|
||||||
);
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
*
|
|
||||||
* Execution
|
|
||||||
*
|
|
||||||
***/
|
|
||||||
|
|
||||||
int SqlConnExecDirect (
|
|
||||||
SqlStmt * stmt,
|
|
||||||
const wchar_t string[]
|
|
||||||
);
|
|
||||||
int SqlConnPrepare (
|
|
||||||
SqlStmt * stmt,
|
|
||||||
const wchar_t string[]
|
|
||||||
);
|
|
||||||
int SqlConnExecute (
|
|
||||||
SqlStmt * stmt
|
|
||||||
);
|
|
||||||
int SqlConnFetch (
|
|
||||||
SqlStmt * stmt
|
|
||||||
);
|
|
||||||
int SqlConnMoreResults (
|
|
||||||
SqlStmt * stmt
|
|
||||||
);
|
|
||||||
int SqlConnParamData (
|
|
||||||
SqlStmt * stmt,
|
|
||||||
SQLPOINTER * put
|
|
||||||
);
|
|
||||||
bool SqlConnPutData (
|
|
||||||
SqlStmt * stmt,
|
|
||||||
SQLPOINTER data,
|
|
||||||
SQLINTEGER bytes
|
|
||||||
);
|
|
||||||
int SqlConnGetData (
|
|
||||||
SqlStmt * stmt,
|
|
||||||
SQLINTEGER columnNumber,
|
|
||||||
SQLINTEGER targetType,
|
|
||||||
SQLPOINTER targetValue,
|
|
||||||
SQLINTEGER bufferLength,
|
|
||||||
SQLINTEGER * indPtr
|
|
||||||
);
|
|
||||||
void SqlConnCloseCursor (
|
|
||||||
SqlStmt * stmt
|
|
||||||
);
|
|
||||||
int SqlConnNumResultCols (
|
|
||||||
SqlStmt * stmt
|
|
||||||
);
|
|
||||||
int SqlConnDescribeCol (
|
|
||||||
SqlStmt * stmt,
|
|
||||||
SQLSMALLINT columnNumber,
|
|
||||||
SQLWCHAR * columnName,
|
|
||||||
SQLSMALLINT bufferLength,
|
|
||||||
SQLSMALLINT * nameLengthPtr,
|
|
||||||
SQLSMALLINT * dataTypePtr,
|
|
||||||
SQLUINTEGER * columnSizePtr,
|
|
||||||
SQLSMALLINT * decimalDigitsPtr,
|
|
||||||
SQLSMALLINT * nullablePtr
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************************
|
|
||||||
*
|
|
||||||
* Performance API
|
|
||||||
*
|
|
||||||
***/
|
|
||||||
|
|
||||||
enum {
|
|
||||||
kSqlConnPerfConnDesired,
|
|
||||||
kSqlConnPerfConnCurrent,
|
|
||||||
kSqlConnPerfConnPending,
|
|
||||||
kSqlConnPerfConnCheckDead,
|
|
||||||
kSqlConnPerfCacheHits,
|
|
||||||
kSqlConnPerfCacheMisses,
|
|
||||||
kSqlConnNumPerf
|
|
||||||
};
|
|
||||||
|
|
||||||
unsigned SqlConnGetPerf (unsigned id);
|
|
@ -1,196 +0,0 @@
|
|||||||
/*==LICENSE==*
|
|
||||||
|
|
||||||
CyanWorlds.com Engine - MMOG client, server and tools
|
|
||||||
Copyright (C) 2011 Cyan Worlds, Inc.
|
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
Additional permissions under GNU GPL version 3 section 7
|
|
||||||
|
|
||||||
If you modify this Program, or any covered work, by linking or
|
|
||||||
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
|
|
||||||
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
|
|
||||||
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
|
|
||||||
(or a modified version of those libraries),
|
|
||||||
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
|
|
||||||
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
|
|
||||||
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
|
|
||||||
licensors of this Program grant you additional
|
|
||||||
permission to convey the resulting work. Corresponding Source for a
|
|
||||||
non-source form of such a combination shall include the source code for
|
|
||||||
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
|
|
||||||
work.
|
|
||||||
|
|
||||||
You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
|
||||||
or by snail mail at:
|
|
||||||
Cyan Worlds, Inc.
|
|
||||||
14617 N Newport Hwy
|
|
||||||
Mead, WA 99021
|
|
||||||
|
|
||||||
*==LICENSE==*/
|
|
||||||
/*****************************************************************************
|
|
||||||
*
|
|
||||||
* $/Plasma20/Sources/Plasma/NucleusLib/pnSqlLib/Private/pnSqlUtil.cpp
|
|
||||||
*
|
|
||||||
***/
|
|
||||||
|
|
||||||
#include "../Pch.h"
|
|
||||||
#pragma hdrstop
|
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************************
|
|
||||||
*
|
|
||||||
* Exports
|
|
||||||
*
|
|
||||||
***/
|
|
||||||
|
|
||||||
//===========================================================================
|
|
||||||
void SqlConnBindParameterInputGuid (
|
|
||||||
SqlStmt * stmt,
|
|
||||||
Uuid * uuid,
|
|
||||||
SQLINTEGER * uuidLen
|
|
||||||
) {
|
|
||||||
SqlConnBindParameter(
|
|
||||||
stmt,
|
|
||||||
SQL_PARAM_INPUT,
|
|
||||||
SQL_C_BINARY,
|
|
||||||
SQL_BINARY,
|
|
||||||
sizeof(Uuid),
|
|
||||||
0,
|
|
||||||
uuid,
|
|
||||||
sizeof(Uuid),
|
|
||||||
uuidLen
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
//===========================================================================
|
|
||||||
void SqlConnBindParameterOutputGuid (
|
|
||||||
SqlStmt * stmt,
|
|
||||||
Uuid * uuid,
|
|
||||||
SQLINTEGER * uuidLen
|
|
||||||
) {
|
|
||||||
SqlConnBindParameter(
|
|
||||||
stmt,
|
|
||||||
SQL_PARAM_OUTPUT,
|
|
||||||
SQL_C_BINARY,
|
|
||||||
SQL_BINARY,
|
|
||||||
sizeof(Uuid),
|
|
||||||
0,
|
|
||||||
uuid,
|
|
||||||
sizeof(Uuid),
|
|
||||||
uuidLen
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
//===========================================================================
|
|
||||||
void SqlConnBindParameterBigInt (
|
|
||||||
SqlStmt * stmt,
|
|
||||||
SQLINTEGER inputOutputType,
|
|
||||||
SQLBIGINT * parameterValuePtr,
|
|
||||||
SQLINTEGER * indPtr
|
|
||||||
) {
|
|
||||||
SqlConnBindParameter(
|
|
||||||
stmt,
|
|
||||||
inputOutputType,
|
|
||||||
SQL_C_SBIGINT,
|
|
||||||
SQL_BIGINT,
|
|
||||||
sizeof(uint64_t),
|
|
||||||
0,
|
|
||||||
parameterValuePtr,
|
|
||||||
0,
|
|
||||||
indPtr
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
//===========================================================================
|
|
||||||
bool SqlConnGetBlobData (
|
|
||||||
SqlStmt * stmt,
|
|
||||||
unsigned colIndex,
|
|
||||||
ARRAY(uint8_t) * buffer,
|
|
||||||
unsigned * bytesAdded
|
|
||||||
) {
|
|
||||||
// Since a number of routines use this function, set the chunk size to be
|
|
||||||
// fairly large to avoid the necessity of reallocing the block, and further
|
|
||||||
// to prevent memory fragmentation by allocating variously sized blocks.
|
|
||||||
// In for a penny, in for a pound...
|
|
||||||
const unsigned CHUNK_SIZE = 32 * 1024;
|
|
||||||
SQLINTEGER length = CHUNK_SIZE - 1;
|
|
||||||
unsigned bytes = buffer->Bytes();
|
|
||||||
*bytesAdded = 0 - bytes;
|
|
||||||
for (;;) {
|
|
||||||
// Allocate memory that is evenly aligned to CHUNK_SIZE, which
|
|
||||||
// reduces memory fragmentation by allocating on 32K multiples.
|
|
||||||
// Use SetCount() instead of New() to ensure that this is true
|
|
||||||
// even if the buffer already contains data.
|
|
||||||
buffer->SetCount(
|
|
||||||
MathNextMultiplePow2(
|
|
||||||
buffer->Bytes() + length,
|
|
||||||
CHUNK_SIZE
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
// Read column data
|
|
||||||
int result = SqlConnGetData(
|
|
||||||
stmt,
|
|
||||||
colIndex,
|
|
||||||
SQL_C_BINARY,
|
|
||||||
buffer->Ptr() + bytes,
|
|
||||||
buffer->Bytes() - bytes,
|
|
||||||
&length
|
|
||||||
);
|
|
||||||
|
|
||||||
// Handle SQL_NO_TOTAL and SQL_NULL_DATA values
|
|
||||||
if (length < 0) {
|
|
||||||
buffer->ZeroCount();
|
|
||||||
*bytesAdded = 0;
|
|
||||||
return result == SQL_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Keep getting data until we have the entire buffer
|
|
||||||
if (result == SQL_SUCCESS_WITH_INFO) {
|
|
||||||
// length contains the number of remaining bytes
|
|
||||||
bytes = buffer->Bytes();
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Is the buffer complete?
|
|
||||||
if (result == SQL_SUCCESS) {
|
|
||||||
buffer->SetCountFewer(length + bytes);
|
|
||||||
*bytesAdded += buffer->Bytes();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// An error occurred
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
buffer->ZeroCount();
|
|
||||||
*bytesAdded = 0;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
//===========================================================================
|
|
||||||
int SqlConnPutBlobData (
|
|
||||||
SqlStmt * stmt,
|
|
||||||
unsigned bytes,
|
|
||||||
const uint8_t data[]
|
|
||||||
) {
|
|
||||||
int result;
|
|
||||||
SQLPOINTER putPtr;
|
|
||||||
while (SQL_NEED_DATA == (result = SqlConnParamData(stmt, &putPtr))) {
|
|
||||||
if (!SqlConnPutData(stmt, const_cast<uint8_t *>(data), bytes))
|
|
||||||
return SQL_ERROR;
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
@ -1,86 +0,0 @@
|
|||||||
/*==LICENSE==*
|
|
||||||
|
|
||||||
CyanWorlds.com Engine - MMOG client, server and tools
|
|
||||||
Copyright (C) 2011 Cyan Worlds, Inc.
|
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
Additional permissions under GNU GPL version 3 section 7
|
|
||||||
|
|
||||||
If you modify this Program, or any covered work, by linking or
|
|
||||||
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
|
|
||||||
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
|
|
||||||
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
|
|
||||||
(or a modified version of those libraries),
|
|
||||||
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
|
|
||||||
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
|
|
||||||
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
|
|
||||||
licensors of this Program grant you additional
|
|
||||||
permission to convey the resulting work. Corresponding Source for a
|
|
||||||
non-source form of such a combination shall include the source code for
|
|
||||||
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
|
|
||||||
work.
|
|
||||||
|
|
||||||
You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
|
||||||
or by snail mail at:
|
|
||||||
Cyan Worlds, Inc.
|
|
||||||
14617 N Newport Hwy
|
|
||||||
Mead, WA 99021
|
|
||||||
|
|
||||||
*==LICENSE==*/
|
|
||||||
/*****************************************************************************
|
|
||||||
*
|
|
||||||
* $/Plasma20/Sources/Plasma/NucleusLib/pnSqlLib/Private/pnSqlUtil.h
|
|
||||||
*
|
|
||||||
***/
|
|
||||||
|
|
||||||
#ifdef PLASMA20_SOURCES_PLASMA_NUCLEUSLIB_PNSQLLIB_PRIVATE_PNSQLUTIL_H
|
|
||||||
#error "Header $/Plasma20/Sources/Plasma/NucleusLib/pnSqlLib/Private/pnSqlUtil.h included more than once"
|
|
||||||
#endif
|
|
||||||
#define PLASMA20_SOURCES_PLASMA_NUCLEUSLIB_PNSQLLIB_PRIVATE_PNSQLUTIL_H
|
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************************
|
|
||||||
*
|
|
||||||
* SqlUtil API
|
|
||||||
*
|
|
||||||
***/
|
|
||||||
|
|
||||||
void SqlConnBindParameterInputGuid (
|
|
||||||
SqlStmt * stmt,
|
|
||||||
Uuid * uuid,
|
|
||||||
SQLINTEGER * uuidLen
|
|
||||||
);
|
|
||||||
void SqlConnBindParameterOutputGuid (
|
|
||||||
SqlStmt * stmt,
|
|
||||||
Uuid * uuid,
|
|
||||||
SQLINTEGER * uuidLen
|
|
||||||
);
|
|
||||||
void SqlConnBindParameterBigInt (
|
|
||||||
SqlStmt * stmt,
|
|
||||||
SQLINTEGER inputOutputType,
|
|
||||||
SQLBIGINT * parameterValuePtr,
|
|
||||||
SQLINTEGER * indPtr
|
|
||||||
);
|
|
||||||
bool SqlConnGetBlobData (
|
|
||||||
SqlStmt * stmt,
|
|
||||||
unsigned colIndex,
|
|
||||||
ARRAY(uint8_t) * buffer,
|
|
||||||
unsigned * bytesAdded
|
|
||||||
);
|
|
||||||
int SqlConnPutBlobData (
|
|
||||||
SqlStmt * stmt,
|
|
||||||
unsigned bytes,
|
|
||||||
const uint8_t data[]
|
|
||||||
);
|
|
@ -1,59 +0,0 @@
|
|||||||
/*==LICENSE==*
|
|
||||||
|
|
||||||
CyanWorlds.com Engine - MMOG client, server and tools
|
|
||||||
Copyright (C) 2011 Cyan Worlds, Inc.
|
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
Additional permissions under GNU GPL version 3 section 7
|
|
||||||
|
|
||||||
If you modify this Program, or any covered work, by linking or
|
|
||||||
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
|
|
||||||
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
|
|
||||||
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
|
|
||||||
(or a modified version of those libraries),
|
|
||||||
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
|
|
||||||
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
|
|
||||||
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
|
|
||||||
licensors of this Program grant you additional
|
|
||||||
permission to convey the resulting work. Corresponding Source for a
|
|
||||||
non-source form of such a combination shall include the source code for
|
|
||||||
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
|
|
||||||
work.
|
|
||||||
|
|
||||||
You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
|
||||||
or by snail mail at:
|
|
||||||
Cyan Worlds, Inc.
|
|
||||||
14617 N Newport Hwy
|
|
||||||
Mead, WA 99021
|
|
||||||
|
|
||||||
*==LICENSE==*/
|
|
||||||
/*****************************************************************************
|
|
||||||
*
|
|
||||||
* $/Plasma20/Sources/Plasma/NucleusLib/pnSqlLib/pnSqlLib.h
|
|
||||||
*
|
|
||||||
***/
|
|
||||||
|
|
||||||
#ifndef PLASMA20_SOURCES_PLASMA_NUCLEUSLIB_PNSQLLIB_PNSQLLIB_H
|
|
||||||
#define PLASMA20_SOURCES_PLASMA_NUCLEUSLIB_PNSQLLIB_PNSQLLIB_H
|
|
||||||
|
|
||||||
|
|
||||||
// Include ODBC API
|
|
||||||
#include <sql.h>
|
|
||||||
#include <sqlext.h>
|
|
||||||
|
|
||||||
#include "Private/pnSqlAllIncludes.h"
|
|
||||||
|
|
||||||
|
|
||||||
#endif // PLASMA20_SOURCES_PLASMA_NUCLEUSLIB_PNSQLLIB_PNSQLLIB_H
|
|
@ -51,7 +51,6 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
|||||||
#include "pnProduct/pnProduct.h"
|
#include "pnProduct/pnProduct.h"
|
||||||
#include "pnNetCli/pnNetCli.h"
|
#include "pnNetCli/pnNetCli.h"
|
||||||
#include "plNetGameLib/plNetGameLib.h"
|
#include "plNetGameLib/plNetGameLib.h"
|
||||||
#include "pnIni/pnIni.h"
|
|
||||||
#include "pnEncryption/plChallengeHash.h"
|
#include "pnEncryption/plChallengeHash.h"
|
||||||
|
|
||||||
#include "plMessage/plNetCommMsgs.h"
|
#include "plMessage/plNetCommMsgs.h"
|
||||||
@ -672,182 +671,6 @@ static void INetCliAuthSendFriendInviteCallback (
|
|||||||
kiMsg->Send();
|
kiMsg->Send();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//============================================================================
|
|
||||||
static void IReadNetIni() {
|
|
||||||
wchar_t filename[MAX_PATH];
|
|
||||||
StrPrintf(filename, arrsize(filename), L"%s.cfg", ProductCoreName());
|
|
||||||
|
|
||||||
wchar_t pathAndName[MAX_PATH];
|
|
||||||
PathGetInitDirectory(pathAndName, arrsize(pathAndName));
|
|
||||||
PathAddFilename(pathAndName, pathAndName, filename, arrsize(pathAndName));
|
|
||||||
|
|
||||||
#ifndef PLASMA_EXTERNAL_RELEASE
|
|
||||||
// internal dev build will override user-based setting with local folder if it's there
|
|
||||||
wchar_t localPathAndName[MAX_PATH];
|
|
||||||
PathAddFilename(localPathAndName, L"init", filename, arrsize(localPathAndName));
|
|
||||||
if (PathDoesFileExist(localPathAndName))
|
|
||||||
StrCopy(pathAndName, localPathAndName, arrsize(pathAndName));
|
|
||||||
#endif
|
|
||||||
|
|
||||||
Ini * ini = IniOpen(pathAndName);
|
|
||||||
|
|
||||||
wchar_t password[kMaxPasswordLength];
|
|
||||||
|
|
||||||
if (ini) {
|
|
||||||
// Read [Net.Server] section
|
|
||||||
IniGetString(
|
|
||||||
IniGetFirstValue(
|
|
||||||
ini,
|
|
||||||
L"Net.Server",
|
|
||||||
L"Addr",
|
|
||||||
nil
|
|
||||||
),
|
|
||||||
s_iniServerAddr,
|
|
||||||
arrsize(s_iniServerAddr),
|
|
||||||
0,
|
|
||||||
L""
|
|
||||||
);
|
|
||||||
|
|
||||||
// Read [Net.FileServer] section
|
|
||||||
IniGetString(
|
|
||||||
IniGetFirstValue(
|
|
||||||
ini,
|
|
||||||
L"Net.FileServer",
|
|
||||||
L"Addr",
|
|
||||||
nil
|
|
||||||
),
|
|
||||||
s_iniFileServerAddr,
|
|
||||||
arrsize(s_iniFileServerAddr),
|
|
||||||
0,
|
|
||||||
s_iniServerAddr
|
|
||||||
);
|
|
||||||
|
|
||||||
if (s_iniReadAccountInfo) {
|
|
||||||
// Read [Net.Account] section
|
|
||||||
IniGetString(
|
|
||||||
IniGetFirstValue(
|
|
||||||
ini,
|
|
||||||
L"Net.Account",
|
|
||||||
L"Username",
|
|
||||||
nil
|
|
||||||
),
|
|
||||||
s_iniAccountUsername,
|
|
||||||
arrsize(s_iniAccountUsername),
|
|
||||||
0,
|
|
||||||
L""
|
|
||||||
);
|
|
||||||
IniGetString(
|
|
||||||
IniGetFirstValue(
|
|
||||||
ini,
|
|
||||||
L"Net.Account",
|
|
||||||
L"Password",
|
|
||||||
nil
|
|
||||||
),
|
|
||||||
password,
|
|
||||||
arrsize(password),
|
|
||||||
0,
|
|
||||||
L""
|
|
||||||
);
|
|
||||||
|
|
||||||
// Read [Net.Startup] section
|
|
||||||
IniGetString(
|
|
||||||
IniGetFirstValue(
|
|
||||||
ini,
|
|
||||||
L"Net.Startup",
|
|
||||||
L"AgeName",
|
|
||||||
nil
|
|
||||||
),
|
|
||||||
s_iniStartupAgeName,
|
|
||||||
arrsize(s_iniStartupAgeName),
|
|
||||||
0,
|
|
||||||
L"StartUp"
|
|
||||||
);
|
|
||||||
IniGetString(
|
|
||||||
IniGetFirstValue(
|
|
||||||
ini,
|
|
||||||
L"Net.Startup",
|
|
||||||
L"PlayerName",
|
|
||||||
nil
|
|
||||||
),
|
|
||||||
s_iniStartupPlayerName,
|
|
||||||
arrsize(s_iniStartupPlayerName),
|
|
||||||
0,
|
|
||||||
L""
|
|
||||||
);
|
|
||||||
|
|
||||||
CryptHashPassword(_TEMP_CONVERT_FROM_WCHAR_T(s_iniAccountUsername), _TEMP_CONVERT_FROM_WCHAR_T(password), s_namePassHash);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
StrCopy(s_iniStartupAgeName, L"StartUp", arrsize(s_iniStartupAgeName));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifndef PLASMA_EXTERNAL_RELEASE
|
|
||||||
// @@@: Internal build only: Drop a default version of the file if not found
|
|
||||||
if (!ini) {
|
|
||||||
EFileError fileError;
|
|
||||||
uint64_t fileSize;
|
|
||||||
uint64_t lastWrite;
|
|
||||||
AsyncFile file = AsyncFileOpen(
|
|
||||||
pathAndName,
|
|
||||||
nil,
|
|
||||||
&fileError,
|
|
||||||
kAsyncFileReadAccess|kAsyncFileWriteAccess,
|
|
||||||
kAsyncFileModeCreateNew,
|
|
||||||
0,
|
|
||||||
nil,
|
|
||||||
&fileSize,
|
|
||||||
&lastWrite
|
|
||||||
);
|
|
||||||
|
|
||||||
if (file) {
|
|
||||||
char line[2048];
|
|
||||||
StrPrintf(
|
|
||||||
line,
|
|
||||||
arrsize(line),
|
|
||||||
// format
|
|
||||||
"[Net.Server]\r\n"
|
|
||||||
"\tAddr=%S\r\n"
|
|
||||||
"\r\n"
|
|
||||||
"[Net.FileServer]\r\n"
|
|
||||||
"\tAddr=%S\r\n"
|
|
||||||
"\r\n"
|
|
||||||
"[Net.Account]\r\n"
|
|
||||||
"\tUsername=%S\r\n"
|
|
||||||
"\tPassword=AccountPassword\r\n"
|
|
||||||
"\r\n"
|
|
||||||
"[Net.Startup]\r\n"
|
|
||||||
"\tAgeName=%S\r\n"
|
|
||||||
"\tPlayerName=%S\r\n"
|
|
||||||
, // values
|
|
||||||
L"shard",
|
|
||||||
L"shard",
|
|
||||||
L"AccountUserName",
|
|
||||||
L"StartUp",
|
|
||||||
L"PlayerName",
|
|
||||||
nil
|
|
||||||
);
|
|
||||||
AsyncFileWrite(file, 0, line, StrLen(line), kAsyncFileRwSync, nil);
|
|
||||||
AsyncFileClose(file, kAsyncFileDontTruncate);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Set startup age info
|
|
||||||
memset(&s_startupAge, 0, sizeof(s_startupAge));
|
|
||||||
|
|
||||||
if (StrLen(s_iniStartupAgeName) == 0)
|
|
||||||
StrCopy(s_startupAge.ageDatasetName, "StartUp", arrsize(s_startupAge.ageDatasetName));
|
|
||||||
else
|
|
||||||
StrToAnsi(s_startupAge.ageDatasetName, s_iniStartupAgeName, arrsize(s_startupAge.ageDatasetName));
|
|
||||||
|
|
||||||
s_startupAge.ageInstId = s_iniStartupAgeInstId;
|
|
||||||
StrCopy(s_startupAge.spawnPtName, "LinkInPointDefault", arrsize(s_startupAge.spawnPtName));
|
|
||||||
|
|
||||||
IniClose(ini);
|
|
||||||
}
|
|
||||||
|
|
||||||
//============================================================================
|
//============================================================================
|
||||||
static void AuthSrvIpAddressCallback (
|
static void AuthSrvIpAddressCallback (
|
||||||
ENetError result,
|
ENetError result,
|
||||||
@ -946,7 +769,14 @@ void NetCommStartup () {
|
|||||||
NetCliAuthSetNotifyNewBuildHandler(INotifyNewBuildCallback);
|
NetCliAuthSetNotifyNewBuildHandler(INotifyNewBuildCallback);
|
||||||
NetCliAuthSetConnectCallback(INotifyAuthConnectedCallback);
|
NetCliAuthSetConnectCallback(INotifyAuthConnectedCallback);
|
||||||
|
|
||||||
IReadNetIni();
|
// Set startup age info
|
||||||
|
memset(&s_startupAge, 0, sizeof(s_startupAge));
|
||||||
|
|
||||||
|
StrCopy(s_iniStartupAgeName, L"StartUp", arrsize(s_iniStartupAgeName));
|
||||||
|
StrCopy(s_startupAge.ageDatasetName, "StartUp", arrsize(s_startupAge.ageDatasetName));
|
||||||
|
|
||||||
|
s_startupAge.ageInstId = s_iniStartupAgeInstId;
|
||||||
|
StrCopy(s_startupAge.spawnPtName, "LinkInPointDefault", arrsize(s_startupAge.spawnPtName));
|
||||||
}
|
}
|
||||||
|
|
||||||
//============================================================================
|
//============================================================================
|
||||||
|
@ -180,8 +180,6 @@ target_link_libraries(MaxMain pnDispatch)
|
|||||||
target_link_libraries(MaxMain pnEncryption)
|
target_link_libraries(MaxMain pnEncryption)
|
||||||
target_link_libraries(MaxMain pnFactory)
|
target_link_libraries(MaxMain pnFactory)
|
||||||
target_link_libraries(MaxMain pnGameMgr)
|
target_link_libraries(MaxMain pnGameMgr)
|
||||||
target_link_libraries(MaxMain pnIni)
|
|
||||||
target_link_libraries(MaxMain pnIniExe)
|
|
||||||
target_link_libraries(MaxMain pnInputCore)
|
target_link_libraries(MaxMain pnInputCore)
|
||||||
target_link_libraries(MaxMain pnKeyedObject)
|
target_link_libraries(MaxMain pnKeyedObject)
|
||||||
target_link_libraries(MaxMain pnMessage)
|
target_link_libraries(MaxMain pnMessage)
|
||||||
|
@ -114,8 +114,6 @@ target_link_libraries(MaxPlasmaLights pnDispatch)
|
|||||||
target_link_libraries(MaxPlasmaLights pnEncryption)
|
target_link_libraries(MaxPlasmaLights pnEncryption)
|
||||||
target_link_libraries(MaxPlasmaLights pnFactory)
|
target_link_libraries(MaxPlasmaLights pnFactory)
|
||||||
target_link_libraries(MaxPlasmaLights pnGameMgr)
|
target_link_libraries(MaxPlasmaLights pnGameMgr)
|
||||||
target_link_libraries(MaxPlasmaLights pnIni)
|
|
||||||
target_link_libraries(MaxPlasmaLights pnIniExe)
|
|
||||||
target_link_libraries(MaxPlasmaLights pnInputCore)
|
target_link_libraries(MaxPlasmaLights pnInputCore)
|
||||||
target_link_libraries(MaxPlasmaLights pnKeyedObject)
|
target_link_libraries(MaxPlasmaLights pnKeyedObject)
|
||||||
target_link_libraries(MaxPlasmaLights pnMessage)
|
target_link_libraries(MaxPlasmaLights pnMessage)
|
||||||
|
Reference in New Issue
Block a user