Adam Johnson
13 years ago
59 changed files with 9 additions and 10569 deletions
@ -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]; |
|
||||||
} |
|
@ -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
|
|
Loading…
Reference in new issue