Compare commits
28
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
95ab81f0db | ||
|
|
2fb01e412e | ||
|
|
6e9b4bf276 | ||
|
|
b344e81816 | ||
|
|
fec133bee6 | ||
|
|
594cc249ef | ||
|
|
0967035dd0 | ||
|
|
7e93cf8f6b | ||
|
|
7f20a7b6bb | ||
|
|
a9de6ed52c | ||
|
|
f0f50aa7bb | ||
|
|
36fab677a0 | ||
|
|
6c0d2a3743 | ||
|
|
e71eb5f704 | ||
|
|
4532b8a38d | ||
|
|
a089235b21 | ||
|
|
9f9f2baae2 | ||
|
|
49a643f411 | ||
|
|
8d7e8b2a85 | ||
|
|
848bc927a0 | ||
|
|
18d0f2a140 | ||
|
|
91a796b24d | ||
|
|
7e7544e036 | ||
|
|
9d676ed440 | ||
|
|
bad5252ee3 | ||
|
|
a2951b9ea8 | ||
|
|
f98cd68341 | ||
|
|
45b9573348 |
+7
-22
@@ -73,9 +73,7 @@ class SMConfig(object):
|
||||
self.versionlib = None
|
||||
|
||||
def use_auto_versioning(self):
|
||||
if builder.backend != 'amb2':
|
||||
return False
|
||||
return not getattr(builder.options, 'disable_auto_versioning', False)
|
||||
return builder.backend == 'amb2'
|
||||
|
||||
@property
|
||||
def tag(self):
|
||||
@@ -165,15 +163,14 @@ class SMConfig(object):
|
||||
'-fno-strict-aliasing',
|
||||
'-Wall',
|
||||
'-Werror',
|
||||
'-Wno-uninitialized',
|
||||
'-Wno-unused',
|
||||
'-Wno-switch',
|
||||
'-Wno-array-bounds',
|
||||
'-Wno-format',
|
||||
'-Wno-format-security',
|
||||
'-msse',
|
||||
'-m32',
|
||||
]
|
||||
cxx.cxxflags += [
|
||||
'-std=c++11',
|
||||
]
|
||||
|
||||
have_gcc = cxx.vendor == 'gcc'
|
||||
have_clang = cxx.vendor == 'clang'
|
||||
@@ -184,15 +181,6 @@ class SMConfig(object):
|
||||
cxx.cflags += ['-Wno-narrowing']
|
||||
if (have_gcc and cxx.version >= '4.7') or (have_clang and cxx.version >= '3'):
|
||||
cxx.cxxflags += ['-Wno-delete-non-virtual-dtor']
|
||||
if have_gcc and cxx.version >= '4.8':
|
||||
cxx.cflags += ['-Wno-unused-result']
|
||||
if have_clang:
|
||||
cxx.cxxflags += ['-Wno-implicit-exception-spec-mismatch']
|
||||
if cxx.version >= 'apple-clang-5.1' or cxx.version >= 'clang-3.4':
|
||||
cxx.cxxflags += ['-Wno-deprecated-register']
|
||||
else:
|
||||
cxx.cxxflags += ['-Wno-deprecated']
|
||||
cxx.cflags += ['-Wno-sometimes-uninitialized']
|
||||
|
||||
cxx.linkflags += ['-m32']
|
||||
cxx.cxxflags += [
|
||||
@@ -216,8 +204,6 @@ class SMConfig(object):
|
||||
'_CRT_NONSTDC_NO_DEPRECATE',
|
||||
'_ITERATOR_DEBUG_LEVEL=0',
|
||||
]
|
||||
if cxx.version < 1800:
|
||||
cxx.defines += 'strtoull=_strtoui64'
|
||||
cxx.cflags += [
|
||||
'/W3',
|
||||
]
|
||||
@@ -249,7 +235,7 @@ class SMConfig(object):
|
||||
if cxx.like('gcc'):
|
||||
cxx.cflags += ['-O3']
|
||||
elif cxx.like('msvc'):
|
||||
cxx.cflags += ['/Ox', '/Zo']
|
||||
cxx.cflags += ['/Ox']
|
||||
cxx.linkflags += ['/OPT:ICF', '/OPT:REF']
|
||||
|
||||
# Debugging
|
||||
@@ -257,6 +243,8 @@ class SMConfig(object):
|
||||
cxx.defines += ['DEBUG', '_DEBUG']
|
||||
if cxx.like('msvc'):
|
||||
cxx.cflags += ['/Od', '/RTC1']
|
||||
if cxx.version >= 1600:
|
||||
cxx.cflags += ['/d2Zi+']
|
||||
|
||||
# This needs to be after our optimization flags which could otherwise disable it.
|
||||
if cxx.vendor == 'msvc':
|
||||
@@ -393,9 +381,6 @@ class SMConfig(object):
|
||||
if builder.target_platform in ['linux', 'mac']:
|
||||
compiler.defines += ['NO_HOOK_MALLOC', 'NO_MALLOC_OVERRIDE']
|
||||
|
||||
if sdk.name == 'csgo' and builder.target_platform == 'linux':
|
||||
compiler.linkflags += ['-lstdc++']
|
||||
|
||||
for path in paths:
|
||||
compiler.cxxincludes += [os.path.join(sdk.path, *path)]
|
||||
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
Contributing
|
||||
------------
|
||||
|
||||
Please visit [our wiki](https://wiki.alliedmods.net/Contributing_to_SourceMod) for information on how to contribute to Sourcemod.
|
||||
|
||||
As a sidenote, [Travis](https://travis-ci.org/alliedmodders/sourcemod) will automatically build your PR to make sure it compiles on Linux.
|
||||
@@ -1,100 +1,5 @@
|
||||
SourceMod Changelog
|
||||
|
||||
SourceMod 1.7.0 [2015-02-04]
|
||||
|
||||
URL: http://wiki.alliedmods.net/SourceMod_1.7.0_Release_Notes
|
||||
|
||||
User Changes:
|
||||
- Updated game compatibility for TF2, CS:GO, and Dota 2.
|
||||
- Fixed regression in SM 1.6.3 causing load failure on games older than Orangebox. (PR 237)
|
||||
- Rewrote internal Steam auth ID handling (PR 147, PR 153, PR 155, PR 162, PR 204, PR 210, PR 222, PR 246).
|
||||
--- admins.cfg now supports Steam2, Steam3, and SteamID 64 formats for the Steam auth provider.
|
||||
--- admins-simple.ini now supports Steam3 auth IDs in addition to Steam2 IDs.
|
||||
--- Command targeting now supports both Steam3 auth IDs in addition to Steam2 IDs.
|
||||
- Added default timeout for MySQL connections to avoid hangs. (PR 248).
|
||||
- SDKTools' gamerules gamedata is now far less likely to break on updates (PR 220).
|
||||
- Fixed crash with sm_dump_admcache on Windows (PR 163).
|
||||
- Fixed SDKHooks causing crash on player join/leave or plugin load/unload if gamedata missing (PR 236).
|
||||
- Changed default sm_trigger_show ConVar value to 0 / disabled.
|
||||
|
||||
Developer Changes:
|
||||
- Added new SourcePawn Transitional Syntax!
|
||||
--- New methodmap-based APIs have been added for many existing functions and handle types.
|
||||
--- New work-in-progress API doc page.
|
||||
- Added Blocked hook type to SDKHooks (PR 119) (VoiDeD).
|
||||
- Added OnTakeDamage_Alive hook type to SDKHooks (PR 149).
|
||||
- Many more File natives now support Valve FS (PR 120, PR 169, PR 178).
|
||||
- Added SetFilePermissions native (PR 43) (hlstriker).
|
||||
- Added API for iterating StringMaps (formerly "tries").
|
||||
- Added natives for accessing command line parameters (PR 164) (VoiDeD).
|
||||
- Exposed engine Message_DetermineMulticastRecipients as GetClientsInRange native. (PR 234).
|
||||
- CloseHandle (or delete) on INVALID_HANDLE is now a no-op, instead of an error (PR 74).
|
||||
- GetClientAuthString is now deprecated. Use GetClientAuthId instead.
|
||||
- Added OnCoreMapEnd to extension interface (PR 127).
|
||||
- Fixed IThreader threads leaking if they're not joined. (bug 3460, PR 241).
|
||||
- TFHoliday updates no longer require a plugin recompile (PR 217).
|
||||
- Fixed FindFlagChar returning false when passing AdminFlag_Custom6 (bug 6248, PR 203).
|
||||
- Added support for (entity) CLASSPTR and EDICT Prop_Data fields with GetEntPropEnt and SetEntPropEnt (PR 83).
|
||||
- Doubled maximum handle count per plugin to 32,768 (PR 215), (Thordin).
|
||||
- Added support for custom default values with GetEvent* natives, rather than using ""/0 for unset fields (PR 157) (VoiDeD).
|
||||
- Removed old profiler, and added new, pluggable profiler (with hooks to VProf) (PR 54).
|
||||
- Added command to dump profiler output (PR 128) (VoiDeD).
|
||||
- Fixed ICommandLine and related features being reported as unavailable on Dark Messiah.
|
||||
- Fixed OnPlayerRunCommand forward in SDKTools being unavailable on Dark Messiah.
|
||||
- SourceMod now uses some C++11 and has newer compiler requirements.
|
||||
- Added --disable-auto-versioning option to ambuild configure script.
|
||||
|
||||
|
||||
----------------------------------------------------------
|
||||
SourceMod 1.6.3 [2014-11-25]
|
||||
|
||||
URL: http://wiki.alliedmods.net/SourceMod_1.6.3_Release_Notes
|
||||
|
||||
User Changes:
|
||||
- Updated game support for TF2, CS:GO, No More Room in Hell, Insurgency, PVK2 and Fistful of Frags.
|
||||
- Made changes to make TF2, CSS, DoDS, HL2DM, and SDK 2013 mods less likely to break on game update (PR 174, PR 192).
|
||||
- Added support for longer key names in languages.cfg (to fix Portuguese) (bug 6282, PR 208).
|
||||
|
||||
Developer Changes:
|
||||
- Updated TF2 player condition and holiday enums (Ross "Powerlord" Bemrose) (PR 183, PR 181).
|
||||
- Add support for TF2 player conditions >= 96 for condition functions/forwards (PR 205).
|
||||
|
||||
----------------------------------------------------------
|
||||
SourceMod 1.6.2 [2014-09-20]
|
||||
|
||||
URL: http://wiki.alliedmods.net/SourceMod_1.6.2_Release_Notes
|
||||
|
||||
User Changes:
|
||||
- Updated game support for TF2, CS:GO, No More Room in Hell and Fistful of Frags.
|
||||
- Added compatibility shim to force Steam player auth strings to be in "Steam2" rendered format (PR 136).
|
||||
- Fixed possible performance regression in DBI handling.
|
||||
|
||||
Developer Changes:
|
||||
- Added new GetClientAuthId native to retrieve player auth strings in desired format (PR 159).
|
||||
- Updated TF2 weapon and player condition enums (FlaminSarge).
|
||||
|
||||
----------------------------------------------------------
|
||||
SourceMod 1.6.1 [2014-08-17]
|
||||
|
||||
URL: http://wiki.alliedmods.net/SourceMod_1.6.1_Release_Notes
|
||||
|
||||
User Changes:
|
||||
- Updated game support for CS:GO and Fistful of Frags.
|
||||
- Added support for Romanian language.
|
||||
- Re-added languages.cfg, missing from 1.6.0, causing all clients to use server language.
|
||||
- Fixed a regression in version 1.6.0 that caused certain SDKHooks usage patterns to cause a server crash (PR 107).
|
||||
- Improved error reporting in basebans plugin when banreasons.txt is missing (PR 115).
|
||||
- Fixed incorrect logged gravity value for sm_gravity command (Ryan "VoiDeD" Stecker) (PR 116).
|
||||
- Fixed a regression in version 1.6.0 causing SDKHook_ReloadPost hooks to not fire in plugins (Peace-Maker) (PR 96).
|
||||
- Added workaround for game bug in TF2_RemoveWeaponSlot to avoid wearable entities left on map (Ryan "VoiDeD" Stecker) (bug 6206, PR 121).
|
||||
- Removed DisableJIT option from core.cfg. (It was never meant for normal use.)
|
||||
|
||||
Developer Changes:
|
||||
- Added new TF2_RemoveWearable native (Ryan "VoiDeD" Stecker, WildCard65) (PR 114).
|
||||
- Added new functions for interacting with and playing scripted game sounds (Ross "Powerlord" Bemrose) (bug 5942, PR 65).
|
||||
- Added new StringToKeyValues natives (Ryan "VoiDeD" Stecker) (PR 74).
|
||||
|
||||
----------------------------------------------------------
|
||||
SourceMod 1.6.0 [2014-07-03]
|
||||
|
||||
URL: http://wiki.alliedmods.net/SourceMod_1.6.0_Release_Notes
|
||||
|
||||
@@ -132,5 +132,13 @@
|
||||
* passed. You can disable this feature by setting the value to "0".
|
||||
*/
|
||||
"SlowScriptTimeout" "8"
|
||||
|
||||
/**
|
||||
* Disable the SourcePawn just-in-time compiler. This is intended for C++ developers using
|
||||
* debugging tools and finding it difficult to inspect JIT stack frames. The interpreter
|
||||
* is not as well-tested as the JIT and will make script execution roughly 10X slower, so
|
||||
* it is not intended for general purpose use.
|
||||
*/
|
||||
"DisableJIT" "no"
|
||||
}
|
||||
|
||||
|
||||
@@ -31,6 +31,4 @@ run.options.add_option('-s', '--sdks', default='all', dest='sdks',
|
||||
'comma-delimited list of engine names (default: %default)')
|
||||
run.options.add_option('--breakpad-dump', action='store_true', dest='breakpad_dump',
|
||||
default=False, help='Dump and upload breakpad symbols')
|
||||
run.options.add_option('--disable-auto-versioning', action='store_true', dest='disable_auto_versioning',
|
||||
default=False, help='Disable the auto versioning script')
|
||||
run.Configure()
|
||||
|
||||
+8
-6
@@ -9,6 +9,7 @@ project.sources += [
|
||||
'sm_stringutil.cpp',
|
||||
'MenuVoting.cpp',
|
||||
'smn_events.cpp',
|
||||
'smn_menus.cpp',
|
||||
'CDataPack.cpp',
|
||||
'frame_hooks.cpp',
|
||||
'smn_nextmap.cpp',
|
||||
@@ -30,6 +31,7 @@ project.sources += [
|
||||
'smn_console.cpp',
|
||||
'UserMessages.cpp',
|
||||
'MenuManager.cpp',
|
||||
'smn_core.cpp',
|
||||
'smn_hudtext.cpp',
|
||||
'smn_usermsgs.cpp',
|
||||
'MenuStyle_Base.cpp',
|
||||
@@ -39,9 +41,7 @@ project.sources += [
|
||||
'MenuStyle_Radio.cpp',
|
||||
'sm_autonatives.cpp',
|
||||
'sm_srvcmds.cpp',
|
||||
'ConsoleDetours.cpp',
|
||||
'vprof_tool.cpp',
|
||||
'smn_commandline.cpp',
|
||||
'ConsoleDetours.cpp'
|
||||
]
|
||||
|
||||
for sdk_name in SM.sdks:
|
||||
@@ -52,14 +52,17 @@ for sdk_name in SM.sdks:
|
||||
compiler = binary.compiler
|
||||
|
||||
if sdk.name == 'csgo':
|
||||
# Protobuf 2.3 headers have some signed/unsigned compares. I believe that it's fixed in later versions, but Valve.
|
||||
if compiler.cxx.behavior == 'gcc':
|
||||
compiler.cflags += ['-Wno-sign-compare']
|
||||
compiler.cxxincludes += [
|
||||
os.path.join(sdk.path, 'common', 'protobuf-2.5.0', 'src'),
|
||||
os.path.join(sdk.path, 'common', 'protobuf-2.3.0', 'src'),
|
||||
os.path.join(sdk.path, 'public', 'engine', 'protobuf'),
|
||||
os.path.join(sdk.path, 'public', 'game', 'shared', 'csgo', 'protobuf')
|
||||
]
|
||||
elif sdk.name == 'dota':
|
||||
compiler.cxxincludes += [
|
||||
os.path.join(sdk.path, 'common', 'protobuf-2.6.1', 'src'),
|
||||
os.path.join(sdk.path, 'common', 'protobuf-2.4.1', 'src'),
|
||||
os.path.join(sdk.path, 'public', 'engine', 'protobuf'),
|
||||
os.path.join(sdk.path, 'public', 'game', 'shared', 'protobuf'),
|
||||
os.path.join(sdk.path, 'public', 'game', 'shared', 'dota', 'protobuf')
|
||||
@@ -106,7 +109,6 @@ for sdk_name in SM.sdks:
|
||||
binary.sources += [
|
||||
os.path.join(sdk.path, 'public', 'engine', 'protobuf', 'networkbasetypes.pb.cc'),
|
||||
os.path.join(sdk.path, 'public', 'engine', 'protobuf', 'netmessages.pb.cc'),
|
||||
os.path.join(sdk.path, 'public', 'engine', 'protobuf', 'network_connection.pb.cc'),
|
||||
os.path.join(sdk.path, 'public', 'game', 'shared', 'protobuf', 'ai_activity.pb.cc'),
|
||||
os.path.join(sdk.path, 'public', 'game', 'shared', 'protobuf', 'usermessages.pb.cc'),
|
||||
os.path.join(sdk.path, 'public', 'game', 'shared', 'dota', 'protobuf', 'dota_commonmessages.pb.cc'),
|
||||
|
||||
+10
-84
@@ -76,12 +76,9 @@ void CDataPack::ResetSize()
|
||||
|
||||
size_t CDataPack::CreateMemory(size_t size, void **addr)
|
||||
{
|
||||
CheckSize(sizeof(char) + sizeof(size_t) + size);
|
||||
CheckSize(sizeof(size_t) + size);
|
||||
size_t pos = m_curptr - m_pBase;
|
||||
|
||||
*(char *)m_curptr = Raw;
|
||||
m_curptr += sizeof(char);
|
||||
|
||||
*(size_t *)m_curptr = size;
|
||||
m_curptr += sizeof(size_t);
|
||||
|
||||
@@ -91,17 +88,14 @@ size_t CDataPack::CreateMemory(size_t size, void **addr)
|
||||
}
|
||||
|
||||
m_curptr += size;
|
||||
m_size += sizeof(char) + sizeof(size_t) + size;
|
||||
m_size += sizeof(size_t) + size;
|
||||
|
||||
return pos;
|
||||
}
|
||||
|
||||
void CDataPack::PackCell(cell_t cell)
|
||||
{
|
||||
CheckSize(sizeof(char) + sizeof(size_t) + sizeof(cell_t));
|
||||
|
||||
*(char *)m_curptr = Cell;
|
||||
m_curptr += sizeof(char);
|
||||
CheckSize(sizeof(size_t) + sizeof(cell_t));
|
||||
|
||||
*(size_t *)m_curptr = sizeof(cell_t);
|
||||
m_curptr += sizeof(size_t);
|
||||
@@ -109,15 +103,12 @@ void CDataPack::PackCell(cell_t cell)
|
||||
*(cell_t *)m_curptr = cell;
|
||||
m_curptr += sizeof(cell_t);
|
||||
|
||||
m_size += sizeof(char) + sizeof(size_t) + sizeof(cell_t);
|
||||
m_size += sizeof(size_t) + sizeof(cell_t);
|
||||
}
|
||||
|
||||
void CDataPack::PackFloat(float val)
|
||||
{
|
||||
CheckSize(sizeof(char) + sizeof(size_t) + sizeof(float));
|
||||
|
||||
*(char *)m_curptr = Float;
|
||||
m_curptr += sizeof(char);
|
||||
CheckSize(sizeof(size_t) + sizeof(float));
|
||||
|
||||
*(size_t *)m_curptr = sizeof(float);
|
||||
m_curptr += sizeof(size_t);
|
||||
@@ -125,18 +116,15 @@ void CDataPack::PackFloat(float val)
|
||||
*(float *)m_curptr = val;
|
||||
m_curptr += sizeof(float);
|
||||
|
||||
m_size += sizeof(char) + sizeof(size_t) + sizeof(float);
|
||||
m_size += sizeof(size_t) + sizeof(float);
|
||||
}
|
||||
|
||||
void CDataPack::PackString(const char *string)
|
||||
{
|
||||
size_t len = strlen(string);
|
||||
size_t maxsize = sizeof(char) + sizeof(size_t) + len + 1;
|
||||
size_t maxsize = sizeof(size_t) + len + 1;
|
||||
CheckSize(maxsize);
|
||||
|
||||
*(char *)m_curptr = String;
|
||||
m_curptr += sizeof(char);
|
||||
|
||||
// Pack the string length first for buffer overrun checking.
|
||||
*(size_t *)m_curptr = len;
|
||||
m_curptr += sizeof(size_t);
|
||||
@@ -172,16 +160,10 @@ bool CDataPack::SetPosition(size_t pos) const
|
||||
|
||||
cell_t CDataPack::ReadCell() const
|
||||
{
|
||||
if (!IsReadable(sizeof(char) + sizeof(size_t) + sizeof(cell_t)))
|
||||
if (!IsReadable(sizeof(size_t) + sizeof(cell_t)))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
if (*reinterpret_cast<char *>(m_curptr) != Cell)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
m_curptr += sizeof(char);
|
||||
|
||||
if (*reinterpret_cast<size_t *>(m_curptr) != sizeof(cell_t))
|
||||
{
|
||||
return 0;
|
||||
@@ -196,16 +178,10 @@ cell_t CDataPack::ReadCell() const
|
||||
|
||||
float CDataPack::ReadFloat() const
|
||||
{
|
||||
if (!IsReadable(sizeof(char) + sizeof(size_t) + sizeof(float)))
|
||||
if (!IsReadable(sizeof(size_t) + sizeof(float)))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
if (*reinterpret_cast<char *>(m_curptr) != Float)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
m_curptr += sizeof(char);
|
||||
|
||||
if (*reinterpret_cast<size_t *>(m_curptr) != sizeof(float))
|
||||
{
|
||||
return 0;
|
||||
@@ -225,15 +201,10 @@ bool CDataPack::IsReadable(size_t bytes) const
|
||||
|
||||
const char *CDataPack::ReadString(size_t *len) const
|
||||
{
|
||||
if (!IsReadable(sizeof(char) + sizeof(size_t)))
|
||||
if (!IsReadable(sizeof(size_t)))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
if (*reinterpret_cast<char *>(m_curptr) != String)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
m_curptr += sizeof(char);
|
||||
|
||||
size_t real_len = *(size_t *)m_curptr;
|
||||
|
||||
@@ -266,11 +237,6 @@ void *CDataPack::ReadMemory(size_t *size) const
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
if (*reinterpret_cast<char *>(m_curptr) != Raw)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
m_curptr += sizeof(char);
|
||||
|
||||
size_t bytecount = *(size_t *)m_curptr;
|
||||
m_curptr += sizeof(size_t);
|
||||
@@ -291,43 +257,3 @@ void *CDataPack::ReadMemory(size_t *size) const
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
void CDataPack::PackFunction(cell_t function)
|
||||
{
|
||||
CheckSize(sizeof(char) + sizeof(size_t) + sizeof(cell_t));
|
||||
|
||||
*(char *)m_curptr = Function;
|
||||
m_curptr += sizeof(char);
|
||||
|
||||
*(size_t *)m_curptr = sizeof(cell_t);
|
||||
m_curptr += sizeof(size_t);
|
||||
|
||||
*(cell_t *)m_curptr = function;
|
||||
m_curptr += sizeof(cell_t);
|
||||
|
||||
m_size += sizeof(char) + sizeof(size_t) + sizeof(cell_t);
|
||||
}
|
||||
|
||||
cell_t CDataPack::ReadFunction() const
|
||||
{
|
||||
if (!IsReadable(sizeof(char) + sizeof(size_t) + sizeof(cell_t)))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
if (*reinterpret_cast<char *>(m_curptr) != Function)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
m_curptr += sizeof(char);
|
||||
|
||||
if (*reinterpret_cast<size_t *>(m_curptr) != sizeof(cell_t))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
m_curptr += sizeof(size_t);
|
||||
|
||||
cell_t val = *reinterpret_cast<cell_t *>(m_curptr);
|
||||
m_curptr += sizeof(cell_t);
|
||||
return val;
|
||||
}
|
||||
@@ -51,14 +51,12 @@ public: //IDataReader
|
||||
const char *ReadString(size_t *len) const;
|
||||
void *GetMemory() const;
|
||||
void *ReadMemory(size_t *size) const;
|
||||
cell_t ReadFunction() const;
|
||||
public: //IDataPack
|
||||
void ResetSize();
|
||||
void PackCell(cell_t cell);
|
||||
void PackFloat(float val);
|
||||
void PackString(const char *string);
|
||||
size_t CreateMemory(size_t size, void **addr);
|
||||
void PackFunction(cell_t function);
|
||||
public:
|
||||
void Initialize();
|
||||
private:
|
||||
@@ -68,14 +66,6 @@ private:
|
||||
mutable char *m_curptr;
|
||||
size_t m_capacity;
|
||||
size_t m_size;
|
||||
|
||||
enum DataPackType {
|
||||
Raw,
|
||||
Cell,
|
||||
Float,
|
||||
String,
|
||||
Function
|
||||
};
|
||||
};
|
||||
|
||||
#endif //_INCLUDE_SOURCEMOD_CDATAPACK_H_
|
||||
|
||||
@@ -383,7 +383,7 @@ bool ConCmdManager::AddAdminCommand(IPluginFunction *pFunction,
|
||||
{
|
||||
if (!m_CmdGrps.add(i, group))
|
||||
return false;
|
||||
i->value = new CommandGroup();
|
||||
i->value = NoAddRef(new CommandGroup());
|
||||
}
|
||||
Ref<CommandGroup> cmdgroup = i->value;
|
||||
|
||||
|
||||
+2
-12
@@ -648,11 +648,8 @@ QueryCvarCookie_t ConVarManager::QueryClientConVar(edict_t *pPlayer, const char
|
||||
return InvalidQueryCvarCookie;
|
||||
}
|
||||
|
||||
if (pCallback != NULL)
|
||||
{
|
||||
ConVarQuery query = { cookie, pCallback, (cell_t) hndl, IndexOfEdict(pPlayer) };
|
||||
m_ConVarQueries.push_back(query);
|
||||
}
|
||||
ConVarQuery query = {cookie, pCallback, (cell_t)hndl, IndexOfEdict(pPlayer)};
|
||||
m_ConVarQueries.push_back(query);
|
||||
#endif
|
||||
|
||||
return cookie;
|
||||
@@ -756,13 +753,6 @@ void ConVarManager::OnQueryCvarValueFinished(QueryCvarCookie_t cookie, CEntityIn
|
||||
void ConVarManager::OnQueryCvarValueFinished(QueryCvarCookie_t cookie, edict_t *pPlayer, EQueryCvarValueStatus result, const char *cvarName, const char *cvarValue)
|
||||
#endif // SE_DOTA
|
||||
{
|
||||
#if SOURCE_ENGINE == SE_CSGO
|
||||
if (g_Players.HandleConVarQuery(cookie, pPlayer, result, cvarName, cvarValue))
|
||||
{
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
IPluginFunction *pCallback = NULL;
|
||||
cell_t value = 0;
|
||||
List<ConVarQuery>::iterator iter;
|
||||
|
||||
@@ -195,7 +195,7 @@ class GenericCommandHooker : public IConCommandLinkListener
|
||||
size_t index;
|
||||
if (!FindVtable(vtable, index))
|
||||
{
|
||||
logger->LogError("Console detour tried to unhook command \"%s\" but it wasn't found", pBase->GetName());
|
||||
g_Logger.LogError("Console detour tried to unhook command \"%s\" but it wasn't found", pBase->GetName());
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -219,7 +219,7 @@ public:
|
||||
|
||||
if (dispatch.thisptroffs < 0)
|
||||
{
|
||||
logger->LogError("Command filter could not determine ConCommand layout");
|
||||
g_Logger.LogError("Command filter could not determine ConCommand layout");
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -228,7 +228,7 @@ public:
|
||||
|
||||
if (!vtables.size())
|
||||
{
|
||||
logger->LogError("Command filter could not find any cvars!");
|
||||
g_Logger.LogError("Command filter could not find any cvars!");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
+3
-3
@@ -262,7 +262,7 @@ void CoreConfig::Initialize()
|
||||
{
|
||||
/* :TODO: This won't actually log or print anything :( - So fix that somehow */
|
||||
const char *error = textparsers->GetSMCErrorString(err);
|
||||
logger->LogFatal("[SM] Error encountered parsing core config file: %s", error ? error : "");
|
||||
g_Logger.LogFatal("[SM] Error encountered parsing core config file: %s", error ? error : "");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -274,7 +274,7 @@ SMCResult CoreConfig::ReadSMC_KeyValue(const SMCStates *states, const char *key,
|
||||
if (err == ConfigResult_Reject)
|
||||
{
|
||||
/* This is a fatal error */
|
||||
logger->LogFatal("Config error (key: %s) (value: %s) %s", key, value, error);
|
||||
g_Logger.LogFatal("Config error (key: %s) (value: %s) %s", key, value, error);
|
||||
}
|
||||
|
||||
return SMCResult_Continue;
|
||||
@@ -469,7 +469,7 @@ bool SM_ExecuteConfig(IPlugin *pl, AutoConfig *cfg, bool can_create)
|
||||
}
|
||||
else
|
||||
{
|
||||
logger->LogError("Failed to auto generate config for %s, make sure the directory has write permission.", pl->GetFilename());
|
||||
g_Logger.LogError("Failed to auto generate config for %s, make sure the directory has write permission.", pl->GetFilename());
|
||||
return can_create;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -155,7 +155,7 @@ void EventManager::FireGameEvent(IGameEvent *pEvent)
|
||||
Just need to add ourselves as a listener to make our hook on IGameEventManager2::FireEvent work */
|
||||
}
|
||||
|
||||
#if SOURCE_ENGINE >= SE_LEFT4DEAD && SOURCE_ENGINE != SE_DOTA
|
||||
#if SOURCE_ENGINE >= SE_LEFT4DEAD
|
||||
int EventManager::GetEventDebugID()
|
||||
{
|
||||
return EVENT_DEBUG_ID_INIT;
|
||||
|
||||
+1
-1
@@ -110,7 +110,7 @@ public: // IPluginsListener
|
||||
void OnPluginUnloaded(IPlugin *plugin);
|
||||
public: // IGameEventListener2
|
||||
void FireGameEvent(IGameEvent *pEvent);
|
||||
#if SOURCE_ENGINE >= SE_LEFT4DEAD && SOURCE_ENGINE != SE_DOTA
|
||||
#if SOURCE_ENGINE >= SE_LEFT4DEAD
|
||||
int GetEventDebugID();
|
||||
#endif
|
||||
public:
|
||||
|
||||
+19
-41
@@ -153,18 +153,6 @@ void CHalfLife2::OnSourceModAllInitialized_Post()
|
||||
|
||||
void CHalfLife2::InitLogicalEntData()
|
||||
{
|
||||
#if SOURCE_ENGINE == SE_TF2 \
|
||||
|| SOURCE_ENGINE == SE_DODS \
|
||||
|| SOURCE_ENGINE == SE_HL2DM \
|
||||
|| SOURCE_ENGINE == SE_CSS \
|
||||
|| SOURCE_ENGINE == SE_SDK2013
|
||||
|
||||
if (g_SMAPI->GetServerFactory(false)("VSERVERTOOLS003", nullptr))
|
||||
{
|
||||
g_EntList = servertools->GetEntityList();
|
||||
}
|
||||
#endif
|
||||
|
||||
char *addr = NULL;
|
||||
|
||||
/*
|
||||
@@ -174,24 +162,21 @@ void CHalfLife2::InitLogicalEntData()
|
||||
* If symbols aren't present (Windows or stripped Linux/Mac),
|
||||
* attempt find via LevelShutdown + offset
|
||||
*/
|
||||
if (!g_EntList)
|
||||
if (g_pGameConf->GetMemSig("gEntList", (void **)&addr))
|
||||
{
|
||||
if (g_pGameConf->GetMemSig("gEntList", (void **) &addr))
|
||||
#if !defined PLATFORM_WINDOWS
|
||||
if (!addr)
|
||||
{
|
||||
#if !defined PLATFORM_WINDOWS
|
||||
if (!addr)
|
||||
{
|
||||
// Key exists so notify if lookup fails, but try other method.
|
||||
logger->LogError("Failed lookup of gEntList directly - Reverting to lookup via LevelShutdown");
|
||||
}
|
||||
else
|
||||
{
|
||||
#endif
|
||||
g_EntList = reinterpret_cast<void *>(addr);
|
||||
#if !defined PLATFORM_WINDOWS
|
||||
}
|
||||
#endif
|
||||
// Key exists so notify if lookup fails, but try other method.
|
||||
g_Logger.LogError("Failed lookup of gEntList directly - Reverting to lookup via LevelShutdown");
|
||||
}
|
||||
else
|
||||
{
|
||||
#endif
|
||||
g_EntList = reinterpret_cast<void *>(addr);
|
||||
#if !defined PLATFORM_WINDOWS
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
if (!g_EntList)
|
||||
@@ -201,7 +186,7 @@ void CHalfLife2::InitLogicalEntData()
|
||||
int offset;
|
||||
if (!g_pGameConf->GetOffset("gEntList", &offset))
|
||||
{
|
||||
logger->LogError("Logical Entities not supported by this mod (gEntList) - Reverting to networkable entities only");
|
||||
g_Logger.LogError("Logical Entities not supported by this mod (gEntList) - Reverting to networkable entities only");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -213,7 +198,7 @@ void CHalfLife2::InitLogicalEntData()
|
||||
// If we have g_EntList from either of the above methods, make sure we can get the offset from it to EntInfo as well
|
||||
if (g_EntList && !g_pGameConf->GetOffset("EntInfo", &entInfoOffset))
|
||||
{
|
||||
logger->LogError("Logical Entities not supported by this mod (EntInfo) - Reverting to networkable entities only");
|
||||
g_Logger.LogError("Logical Entities not supported by this mod (EntInfo) - Reverting to networkable entities only");
|
||||
g_EntList = NULL;
|
||||
return;
|
||||
}
|
||||
@@ -226,7 +211,7 @@ void CHalfLife2::InitLogicalEntData()
|
||||
|
||||
if (!g_EntList && !g_pEntInfoList)
|
||||
{
|
||||
logger->LogError("Failed lookup of gEntList - Reverting to networkable entities only");
|
||||
g_Logger.LogError("Failed lookup of gEntList - Reverting to networkable entities only");
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -234,13 +219,13 @@ void CHalfLife2::InitLogicalEntData()
|
||||
void CHalfLife2::InitCommandLine()
|
||||
{
|
||||
char error[256];
|
||||
#if SOURCE_ENGINE != SE_DARKMESSIAH
|
||||
|
||||
if (!is_original_engine)
|
||||
{
|
||||
ke::AutoPtr<ILibrary> lib(g_LibSys.OpenLibrary(TIER0_NAME, error, sizeof(error)));
|
||||
if (lib == NULL)
|
||||
{
|
||||
logger->LogError("Could not load %s: %s", TIER0_NAME, error);
|
||||
g_Logger.LogError("Could not load %s: %s", TIER0_NAME, error);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -253,12 +238,11 @@ void CHalfLife2::InitCommandLine()
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
ke::AutoPtr<ILibrary> lib(g_LibSys.OpenLibrary(VSTDLIB_NAME, error, sizeof(error)));
|
||||
if (lib == NULL)
|
||||
{
|
||||
logger->LogError("Could not load %s: %s", VSTDLIB_NAME, error);
|
||||
g_Logger.LogError("Could not load %s: %s", VSTDLIB_NAME, error);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -267,7 +251,7 @@ void CHalfLife2::InitCommandLine()
|
||||
|
||||
if (m_pGetCommandLine == NULL)
|
||||
{
|
||||
logger->LogError("Could not locate any command line functionality");
|
||||
g_Logger.LogError("Could not locate any command line functionality");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1186,12 +1170,6 @@ const char *CHalfLife2::GetEntityClassname(CBaseEntity *pEntity)
|
||||
if (offset == -1)
|
||||
{
|
||||
CBaseEntity *pGetterEnt = ReferenceToEntity(0);
|
||||
if (pGetterEnt == NULL)
|
||||
{
|
||||
// If we don't have a world entity yet, we'll have to rely on the given entity
|
||||
pGetterEnt = pEntity;
|
||||
}
|
||||
|
||||
datamap_t *pMap = GetDataMap(pGetterEnt);
|
||||
|
||||
sm_datatable_info_t info;
|
||||
|
||||
+515
-5
@@ -39,12 +39,61 @@
|
||||
#include "logic_bridge.h"
|
||||
#include <sourcemod_version.h>
|
||||
|
||||
bool g_in_game_log_hook = false;
|
||||
|
||||
static LoggerCore g_LoggerCore;
|
||||
Logger g_Logger;
|
||||
|
||||
SH_DECL_HOOK1_void(IVEngineServer, LogPrint, SH_NOATTRIB, false, const char *);
|
||||
|
||||
/**
|
||||
* :TODO: This should be creating the log folder if it doesn't exist
|
||||
*/
|
||||
|
||||
ConfigResult Logger::OnSourceModConfigChanged(const char *key,
|
||||
const char *value,
|
||||
ConfigSource source,
|
||||
char *error,
|
||||
size_t maxlength)
|
||||
{
|
||||
if (strcasecmp(key, "Logging") == 0)
|
||||
{
|
||||
bool state;
|
||||
|
||||
if (strcasecmp(value, "on") == 0)
|
||||
{
|
||||
state = true;
|
||||
} else if (strcasecmp(value, "off") == 0) {
|
||||
state = false;
|
||||
} else {
|
||||
UTIL_Format(error, maxlength, "Invalid value: must be \"on\" or \"off\"");
|
||||
return ConfigResult_Reject;
|
||||
}
|
||||
|
||||
if (source == ConfigSource_Console)
|
||||
{
|
||||
state ? EnableLogging() : DisableLogging();
|
||||
} else {
|
||||
m_InitialState = state;
|
||||
}
|
||||
|
||||
return ConfigResult_Accept;
|
||||
} else if (strcasecmp(key, "LogMode") == 0) {
|
||||
if (strcasecmp(value, "daily") == 0)
|
||||
{
|
||||
m_Mode = LoggingMode_Daily;
|
||||
} else if (strcasecmp(value, "map") == 0) {
|
||||
m_Mode = LoggingMode_PerMap;
|
||||
} else if (strcasecmp(value, "game") == 0) {
|
||||
m_Mode = LoggingMode_Game;
|
||||
} else {
|
||||
UTIL_Format(error, maxlength, "Invalid value: must be [daily|map|game]");
|
||||
return ConfigResult_Reject;
|
||||
}
|
||||
|
||||
return ConfigResult_Accept;
|
||||
}
|
||||
|
||||
return ConfigResult_Ignore;
|
||||
}
|
||||
|
||||
static void HookLogPrint(const char *message)
|
||||
{
|
||||
g_in_game_log_hook = true;
|
||||
@@ -55,16 +104,477 @@ static void HookLogPrint(const char *message)
|
||||
RETURN_META(MRES_SUPERCEDE);
|
||||
}
|
||||
|
||||
void LoggerCore::OnSourceModStartup(bool late)
|
||||
void Logger::OnSourceModStartup(bool late)
|
||||
{
|
||||
InitLogger(m_Mode);
|
||||
|
||||
SH_ADD_HOOK(IVEngineServer, LogPrint, engine, SH_STATIC(HookLogPrint), false);
|
||||
}
|
||||
|
||||
void LoggerCore::OnSourceModAllShutdown()
|
||||
void Logger::OnSourceModAllShutdown()
|
||||
{
|
||||
CloseLogger();
|
||||
SH_REMOVE_HOOK(IVEngineServer, LogPrint, engine, SH_STATIC(HookLogPrint), false);
|
||||
}
|
||||
|
||||
void Logger::OnSourceModLevelChange(const char *mapName)
|
||||
{
|
||||
MapChange(mapName);
|
||||
}
|
||||
|
||||
void Logger::_NewMapFile()
|
||||
{
|
||||
if (!m_Active)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/* Append "Log file closed" to previous log file */
|
||||
_CloseFile();
|
||||
|
||||
char _filename[256];
|
||||
int i = 0;
|
||||
|
||||
time_t t;
|
||||
GetAdjustedTime(&t);
|
||||
tm *curtime = localtime(&t);
|
||||
|
||||
while (true)
|
||||
{
|
||||
g_SourceMod.BuildPath(Path_SM, _filename, sizeof(_filename), "logs/L%02d%02d%03d.log", curtime->tm_mon + 1, curtime->tm_mday, i);
|
||||
FILE *fp = fopen(_filename, "r");
|
||||
if (!fp)
|
||||
{
|
||||
break;
|
||||
}
|
||||
fclose(fp);
|
||||
i++;
|
||||
}
|
||||
m_NrmFileName.assign(_filename);
|
||||
|
||||
FILE *fp = fopen(m_NrmFileName.c_str(), "w");
|
||||
if (!fp)
|
||||
{
|
||||
char error[255];
|
||||
g_LibSys.GetPlatformError(error, sizeof(error));
|
||||
LogFatal("[SM] Unexpected fatal logging error (file \"%s\")", m_NrmFileName.c_str());
|
||||
LogFatal("[SM] Platform returned error: \"%s\"", error);
|
||||
LogFatal("[SM] Logging has been disabled.");
|
||||
m_Active = false;
|
||||
return;
|
||||
} else {
|
||||
char date[32];
|
||||
strftime(date, sizeof(date), "%m/%d/%Y - %H:%M:%S", curtime);
|
||||
fprintf(fp, "L %s: SourceMod log file started (file \"L%02d%02d%03d.log\") (Version \"%s\")\n", date, curtime->tm_mon + 1, curtime->tm_mday, i, SOURCEMOD_VERSION);
|
||||
fclose(fp);
|
||||
}
|
||||
}
|
||||
|
||||
void Logger::_CloseFile()
|
||||
{
|
||||
if (!m_Active)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
FILE *fp = NULL;
|
||||
if (!m_NrmFileName.empty())
|
||||
{
|
||||
fp = fopen(m_NrmFileName.c_str(), "r+");
|
||||
if (fp)
|
||||
{
|
||||
fseek(fp, 0, SEEK_END);
|
||||
LogMessage("Log file closed.");
|
||||
fclose(fp);
|
||||
}
|
||||
m_NrmFileName.clear();
|
||||
}
|
||||
|
||||
if (!m_ErrMapStart)
|
||||
{
|
||||
return;
|
||||
}
|
||||
fp = fopen(m_ErrFileName.c_str(), "r+");
|
||||
if (fp)
|
||||
{
|
||||
fseek(fp, 0, SEEK_END);
|
||||
LogError("Error log file session closed.");
|
||||
fclose(fp);
|
||||
}
|
||||
m_ErrFileName.clear();
|
||||
}
|
||||
|
||||
void Logger::InitLogger(LoggingMode mode)
|
||||
{
|
||||
m_Mode = mode;
|
||||
m_Active = m_InitialState;
|
||||
|
||||
time_t t;
|
||||
GetAdjustedTime(&t);
|
||||
tm *curtime = localtime(&t);
|
||||
m_NrmCurDay = curtime->tm_mday;
|
||||
m_ErrCurDay = curtime->tm_mday;
|
||||
|
||||
char _filename[256];
|
||||
g_SourceMod.BuildPath(Path_SM, _filename, sizeof(_filename), "logs/errors_%04d%02d%02d.log", curtime->tm_year + 1900, curtime->tm_mon + 1, curtime->tm_mday);
|
||||
m_ErrFileName.assign(_filename);
|
||||
|
||||
switch (m_Mode)
|
||||
{
|
||||
case LoggingMode_PerMap:
|
||||
{
|
||||
if (!m_Active)
|
||||
{
|
||||
m_DelayedStart = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case LoggingMode_Daily:
|
||||
{
|
||||
g_SourceMod.BuildPath(Path_SM, _filename, sizeof(_filename), "logs/L%04d%02d%02d.log", curtime->tm_year + 1900, curtime->tm_mon + 1, curtime->tm_mday);
|
||||
m_NrmFileName.assign(_filename);
|
||||
m_DailyPrintHdr = true;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
/* do nothing... */
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Logger::CloseLogger()
|
||||
{
|
||||
_CloseFile();
|
||||
}
|
||||
|
||||
void Logger::LogToOpenFile(FILE *fp, const char *msg, ...)
|
||||
{
|
||||
if (!m_Active)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
va_list ap;
|
||||
va_start(ap, msg);
|
||||
LogToOpenFileEx(fp, msg, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
void Logger::LogToFileOnly(FILE *fp, const char *msg, ...)
|
||||
{
|
||||
if (!m_Active)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
va_list ap;
|
||||
va_start(ap, msg);
|
||||
LogToFileOnlyEx(fp, msg, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
void Logger::LogToOpenFileEx(FILE *fp, const char *msg, va_list ap)
|
||||
{
|
||||
if (!m_Active)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
static ConVar *sv_logecho = icvar->FindVar("sv_logecho");
|
||||
|
||||
char buffer[3072];
|
||||
UTIL_FormatArgs(buffer, sizeof(buffer), msg, ap);
|
||||
|
||||
char date[32];
|
||||
time_t t;
|
||||
GetAdjustedTime(&t);
|
||||
tm *curtime = localtime(&t);
|
||||
strftime(date, sizeof(date), "%m/%d/%Y - %H:%M:%S", curtime);
|
||||
|
||||
fprintf(fp, "L %s: %s\n", date, buffer);
|
||||
|
||||
if (!sv_logecho || sv_logecho->GetBool())
|
||||
{
|
||||
g_SMAPI->ConPrintf("L %s: %s\n", date, buffer);
|
||||
}
|
||||
}
|
||||
|
||||
void Logger::LogToFileOnlyEx(FILE *fp, const char *msg, va_list ap)
|
||||
{
|
||||
if (!m_Active)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
char buffer[3072];
|
||||
UTIL_FormatArgs(buffer, sizeof(buffer), msg, ap);
|
||||
|
||||
char date[32];
|
||||
time_t t;
|
||||
GetAdjustedTime(&t);
|
||||
tm *curtime = localtime(&t);
|
||||
strftime(date, sizeof(date), "%m/%d/%Y - %H:%M:%S", curtime);
|
||||
|
||||
fprintf(fp, "L %s: %s\n", date, buffer);
|
||||
fflush(fp);
|
||||
}
|
||||
|
||||
void Logger::LogMessage(const char *vafmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
va_start(ap, vafmt);
|
||||
LogMessageEx(vafmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
void Logger::LogMessageEx(const char *vafmt, va_list ap)
|
||||
{
|
||||
if (!m_Active)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_Mode == LoggingMode_Game)
|
||||
{
|
||||
_PrintToGameLog(vafmt, ap);
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_DelayedStart)
|
||||
{
|
||||
m_DelayedStart = false;
|
||||
_NewMapFile();
|
||||
}
|
||||
|
||||
time_t t;
|
||||
GetAdjustedTime(&t);
|
||||
tm *curtime = localtime(&t);
|
||||
|
||||
FILE *fp = NULL;
|
||||
if (m_Mode == LoggingMode_PerMap)
|
||||
{
|
||||
fp = fopen(m_NrmFileName.c_str(), "a+");
|
||||
if (!fp)
|
||||
{
|
||||
_NewMapFile();
|
||||
fp = fopen(m_NrmFileName.c_str(), "a+");
|
||||
if (!fp)
|
||||
{
|
||||
goto print_error;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (m_NrmCurDay != curtime->tm_mday)
|
||||
{
|
||||
char _filename[256];
|
||||
g_SourceMod.BuildPath(Path_SM, _filename, sizeof(_filename), "logs/L%04d%02d%02d.log", curtime->tm_year + 1900, curtime->tm_mon + 1, curtime->tm_mday);
|
||||
m_NrmFileName.assign(_filename);
|
||||
m_NrmCurDay = curtime->tm_mday;
|
||||
m_DailyPrintHdr = true;
|
||||
}
|
||||
fp = fopen(m_NrmFileName.c_str(), "a+");
|
||||
}
|
||||
|
||||
if (fp)
|
||||
{
|
||||
if (m_DailyPrintHdr)
|
||||
{
|
||||
char date[32];
|
||||
m_DailyPrintHdr = false;
|
||||
strftime(date, sizeof(date), "%m/%d/%Y - %H:%M:%S", curtime);
|
||||
fprintf(fp, "L %s: SourceMod log file session started (file \"L%04d%02d%02d.log\") (Version \"%s\")\n", date, curtime->tm_year + 1900, curtime->tm_mon + 1, curtime->tm_mday, SOURCEMOD_VERSION);
|
||||
}
|
||||
LogToOpenFileEx(fp, vafmt, ap);
|
||||
fclose(fp);
|
||||
} else {
|
||||
goto print_error;
|
||||
}
|
||||
|
||||
return;
|
||||
print_error:
|
||||
char error[255];
|
||||
g_LibSys.GetPlatformError(error, sizeof(error));
|
||||
LogFatal("[SM] Unexpected fatal logging error (file \"%s\")", m_NrmFileName.c_str());
|
||||
LogFatal("[SM] Platform returned error: \"%s\"", error);
|
||||
LogFatal("[SM] Logging has been disabled.");
|
||||
m_Active = false;
|
||||
}
|
||||
|
||||
void Logger::LogError(const char *vafmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
va_start(ap, vafmt);
|
||||
LogErrorEx(vafmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
void Logger::LogErrorEx(const char *vafmt, va_list ap)
|
||||
{
|
||||
if (!m_Active)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
time_t t;
|
||||
GetAdjustedTime(&t);
|
||||
tm *curtime = localtime(&t);
|
||||
|
||||
if (curtime->tm_mday != m_ErrCurDay)
|
||||
{
|
||||
char _filename[256];
|
||||
g_SourceMod.BuildPath(Path_SM, _filename, sizeof(_filename), "logs/errors_%04d%02d%02d.log", curtime->tm_year + 1900, curtime->tm_mon + 1, curtime->tm_mday);
|
||||
m_ErrFileName.assign(_filename);
|
||||
m_ErrCurDay = curtime->tm_mday;
|
||||
m_ErrMapStart = false;
|
||||
}
|
||||
|
||||
FILE *fp = fopen(m_ErrFileName.c_str(), "a+");
|
||||
if (fp)
|
||||
{
|
||||
if (!m_ErrMapStart)
|
||||
{
|
||||
char date[32];
|
||||
strftime(date, sizeof(date), "%m/%d/%Y - %H:%M:%S", curtime);
|
||||
fprintf(fp, "L %s: SourceMod error session started\n", date);
|
||||
fprintf(fp, "L %s: Info (map \"%s\") (file \"errors_%04d%02d%02d.log\")\n", date, m_CurMapName.c_str(), curtime->tm_year + 1900, curtime->tm_mon + 1, curtime->tm_mday);
|
||||
m_ErrMapStart = true;
|
||||
}
|
||||
LogToOpenFileEx(fp, vafmt, ap);
|
||||
fclose(fp);
|
||||
}
|
||||
else
|
||||
{
|
||||
char error[255];
|
||||
g_LibSys.GetPlatformError(error, sizeof(error));
|
||||
LogFatal("[SM] Unexpected fatal logging error (file \"%s\")", m_NrmFileName.c_str());
|
||||
LogFatal("[SM] Platform returned error: \"%s\"", error);
|
||||
LogFatal("[SM] Logging has been disabled.");
|
||||
m_Active = false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void Logger::MapChange(const char *mapname)
|
||||
{
|
||||
m_CurMapName.assign(mapname);
|
||||
|
||||
switch (m_Mode)
|
||||
{
|
||||
case LoggingMode_Daily:
|
||||
{
|
||||
LogMessage("-------- Mapchange to %s --------", mapname);
|
||||
break;
|
||||
}
|
||||
case LoggingMode_PerMap:
|
||||
{
|
||||
_NewMapFile();
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
/* Do nothing... */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (m_ErrMapStart)
|
||||
{
|
||||
LogError("Error log file session closed.");
|
||||
}
|
||||
m_ErrMapStart = false;
|
||||
}
|
||||
|
||||
void Logger::_PrintToGameLog(const char *fmt, va_list ap)
|
||||
{
|
||||
char msg[3072];
|
||||
size_t len;
|
||||
|
||||
len = vsnprintf(msg, sizeof(msg)-2, fmt, ap);
|
||||
len = (len >= sizeof(msg)) ? (sizeof(msg) - 2) : len;
|
||||
|
||||
msg[len++] = '\n';
|
||||
msg[len] = '\0';
|
||||
|
||||
Engine_LogPrintWrapper(msg);
|
||||
}
|
||||
|
||||
const char *Logger::GetLogFileName(LogType type) const
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case LogType_Normal:
|
||||
{
|
||||
return m_NrmFileName.c_str();
|
||||
}
|
||||
case LogType_Error:
|
||||
{
|
||||
return m_ErrFileName.c_str();
|
||||
}
|
||||
default:
|
||||
{
|
||||
return "";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LoggingMode Logger::GetLoggingMode() const
|
||||
{
|
||||
return m_Mode;
|
||||
}
|
||||
|
||||
void Logger::EnableLogging()
|
||||
{
|
||||
if (m_Active)
|
||||
{
|
||||
return;
|
||||
}
|
||||
m_Active = true;
|
||||
LogMessage("[SM] Logging enabled manually by user.");
|
||||
}
|
||||
|
||||
void Logger::DisableLogging()
|
||||
{
|
||||
if (!m_Active)
|
||||
{
|
||||
return;
|
||||
}
|
||||
LogMessage("[SM] Logging disabled manually by user.");
|
||||
m_Active = false;
|
||||
}
|
||||
|
||||
void Logger::LogFatal(const char *msg, ...)
|
||||
{
|
||||
va_list ap;
|
||||
va_start(ap, msg);
|
||||
LogFatalEx(msg, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
void Logger::LogFatalEx(const char *msg, va_list ap)
|
||||
{
|
||||
/* :TODO: make this print all pretty-like
|
||||
* In fact, the pretty log printing function should be abstracted.
|
||||
* It's already implemented twice which is bad.
|
||||
*/
|
||||
|
||||
char path[PLATFORM_MAX_PATH];
|
||||
|
||||
g_SourceMod.BuildPath(Path_Game, path, sizeof(path), "sourcemod_fatal.log");
|
||||
|
||||
FILE *fp = fopen(path, "at");
|
||||
if (fp)
|
||||
{
|
||||
m_Active = true;
|
||||
LogToOpenFileEx(fp, msg, ap);
|
||||
m_Active = false;
|
||||
fclose(fp);
|
||||
}
|
||||
}
|
||||
|
||||
bool g_in_game_log_hook = false;
|
||||
|
||||
void Engine_LogPrintWrapper(const char *msg)
|
||||
{
|
||||
if (g_in_game_log_hook)
|
||||
|
||||
+64
-1
@@ -38,13 +38,76 @@
|
||||
|
||||
using namespace SourceHook;
|
||||
|
||||
class LoggerCore : public SMGlobalClass
|
||||
enum LogType
|
||||
{
|
||||
LogType_Normal,
|
||||
LogType_Error
|
||||
};
|
||||
|
||||
enum LoggingMode
|
||||
{
|
||||
LoggingMode_Daily,
|
||||
LoggingMode_PerMap,
|
||||
LoggingMode_Game
|
||||
};
|
||||
|
||||
class Logger : public SMGlobalClass
|
||||
{
|
||||
public:
|
||||
Logger() : m_Mode(LoggingMode_Daily), m_ErrMapStart(false),
|
||||
m_Active(false), m_DelayedStart(false), m_DailyPrintHdr(false),
|
||||
m_InitialState(true)
|
||||
{
|
||||
}
|
||||
public: //SMGlobalClass
|
||||
ConfigResult OnSourceModConfigChanged(const char *key,
|
||||
const char *value,
|
||||
ConfigSource source,
|
||||
char *error,
|
||||
size_t maxlength);
|
||||
void OnSourceModStartup(bool late);
|
||||
void OnSourceModAllShutdown();
|
||||
void OnSourceModLevelChange(const char *mapName);
|
||||
public:
|
||||
void InitLogger(LoggingMode mode);
|
||||
void CloseLogger();
|
||||
void EnableLogging();
|
||||
void DisableLogging();
|
||||
void LogMessage(const char *msg, ...);
|
||||
void LogMessageEx(const char *msg, va_list ap);
|
||||
void LogError(const char *msg, ...);
|
||||
void LogErrorEx(const char *msg, va_list ap);
|
||||
void LogFatal(const char *msg, ...);
|
||||
void LogFatalEx(const char *msg, va_list ap);
|
||||
void LogToOpenFile(FILE *fp, const char *msg, ...);
|
||||
void LogToOpenFileEx(FILE *fp, const char *msg, va_list ap);
|
||||
/* This version does not print to console, and is thus thread-safe */
|
||||
void LogToFileOnly(FILE *fp, const char *msg, ...);
|
||||
void LogToFileOnlyEx(FILE *fp, const char *msg, va_list ap);
|
||||
void MapChange(const char *mapname);
|
||||
const char *GetLogFileName(LogType type) const;
|
||||
LoggingMode GetLoggingMode() const;
|
||||
private:
|
||||
void _CloseFile();
|
||||
void _NewMapFile();
|
||||
void _PrintToGameLog(const char *fmt, va_list ap);
|
||||
private:
|
||||
String m_NrmFileName;
|
||||
String m_ErrFileName;
|
||||
String m_CurMapName;
|
||||
LoggingMode m_Mode;
|
||||
int m_NrmCurDay;
|
||||
int m_ErrCurDay;
|
||||
bool m_ErrMapStart;
|
||||
bool m_Active;
|
||||
bool m_DelayedStart;
|
||||
bool m_DailyPrintHdr;
|
||||
bool m_InitialState;
|
||||
};
|
||||
|
||||
void Engine_LogPrintWrapper(const char *msg);
|
||||
|
||||
extern bool g_in_game_log_hook;
|
||||
extern Logger g_Logger;
|
||||
|
||||
#endif // _INCLUDE_SOURCEMOD_CLOGGER_H_
|
||||
|
||||
@@ -261,6 +261,15 @@ CRadioDisplay *CRadioStyle::MakeRadioDisplay(CRadioMenu *menu)
|
||||
return display;
|
||||
}
|
||||
|
||||
IMenuPanel *CRadioStyle::MakeRadioDisplay(const char *str, int keys)
|
||||
{
|
||||
CRadioDisplay *pPanel = MakeRadioDisplay(NULL);
|
||||
|
||||
pPanel->DirectSet(str, keys);
|
||||
|
||||
return pPanel;
|
||||
}
|
||||
|
||||
void CRadioStyle::FreeRadioDisplay(CRadioDisplay *display)
|
||||
{
|
||||
m_FreeDisplays.push(display);
|
||||
@@ -327,12 +336,11 @@ void CRadioDisplay::Reset()
|
||||
keys = 0;
|
||||
}
|
||||
|
||||
bool CRadioDisplay::DirectSet(const char *str)
|
||||
void CRadioDisplay::DirectSet(const char *str, int keymap)
|
||||
{
|
||||
m_Title.clear();
|
||||
m_BufferText.assign(str);
|
||||
|
||||
return true;
|
||||
keys = keymap;
|
||||
}
|
||||
|
||||
unsigned int CRadioDisplay::GetCurrentKey()
|
||||
|
||||
@@ -101,6 +101,7 @@ public:
|
||||
CRadioDisplay *MakeRadioDisplay(CRadioMenu *menu=NULL);
|
||||
void FreeRadioDisplay(CRadioDisplay *display);
|
||||
CRadioMenuPlayer *GetRadioMenuPlayer(int client);
|
||||
IMenuPanel *MakeRadioDisplay(const char *str, int keys);
|
||||
private:
|
||||
CRadioMenuPlayer *m_players;
|
||||
CStack<CRadioDisplay *> m_FreeDisplays;
|
||||
@@ -128,7 +129,8 @@ public: //IMenuPanel
|
||||
bool SetCurrentKey(unsigned int key);
|
||||
int GetAmountRemaining();
|
||||
unsigned int GetApproxMemUsage();
|
||||
bool DirectSet(const char *str);
|
||||
public:
|
||||
void DirectSet(const char *str, int keymap);
|
||||
private:
|
||||
String m_BufferText;
|
||||
String m_Title;
|
||||
|
||||
@@ -75,7 +75,6 @@ public: //IMenuStyle
|
||||
IBaseMenu *CreateMenu(IMenuHandler *pHandler, IdentityToken_t *pOwner);
|
||||
unsigned int GetMaxPageItems();
|
||||
unsigned int GetApproxMemUsage();
|
||||
bool IsSupported() { return true; }
|
||||
private:
|
||||
void HookCreateMessage(edict_t *pEdict, DIALOG_TYPE type, KeyValues *kv, IServerPluginCallbacks *plugin);
|
||||
private:
|
||||
@@ -106,7 +105,6 @@ public:
|
||||
bool SetCurrentKey(unsigned int key);
|
||||
int GetAmountRemaining();
|
||||
unsigned int GetApproxMemUsage();
|
||||
bool DirectSet(const char *str) { return false; }
|
||||
private:
|
||||
KeyValues *m_pKv;
|
||||
unsigned int m_NextPos;
|
||||
|
||||
+2
-3
@@ -36,7 +36,6 @@
|
||||
#include "sm_stringutil.h"
|
||||
#include "sourcehook.h"
|
||||
#include "sm_srvcmds.h"
|
||||
#include "logic_bridge.h"
|
||||
|
||||
NextMapManager g_NextMap;
|
||||
|
||||
@@ -131,7 +130,7 @@ void NextMapManager::HookChangeLevel(const char *map, const char *unknown, const
|
||||
{
|
||||
if (g_forcedChange)
|
||||
{
|
||||
logger->LogMessage("[SM] Changed map to \"%s\"", map);
|
||||
g_Logger.LogMessage("[SM] Changed map to \"%s\"", map);
|
||||
RETURN_META(MRES_IGNORED);
|
||||
}
|
||||
|
||||
@@ -142,7 +141,7 @@ void NextMapManager::HookChangeLevel(const char *map, const char *unknown, const
|
||||
RETURN_META(MRES_IGNORED);
|
||||
}
|
||||
|
||||
logger->LogMessage("[SM] Changed map to \"%s\"", newmap);
|
||||
g_Logger.LogMessage("[SM] Changed map to \"%s\"", newmap);
|
||||
|
||||
UTIL_Format(m_tempChangeInfo.m_mapName, sizeof(m_tempChangeInfo.m_mapName), newmap);
|
||||
UTIL_Format(m_tempChangeInfo.m_changeReason, sizeof(m_tempChangeInfo.m_changeReason), "Normal level change");
|
||||
|
||||
+66
-235
@@ -403,9 +403,12 @@ void PlayerManager::RunAuthChecks()
|
||||
for (unsigned int i=1; i<=m_AuthQueue[0]; i++)
|
||||
{
|
||||
pPlayer = &m_Players[m_AuthQueue[i]];
|
||||
pPlayer->UpdateAuthIds();
|
||||
|
||||
authstr = pPlayer->m_AuthID.chars();
|
||||
#if SOURCE_ENGINE == SE_DOTA
|
||||
authstr = engine->GetPlayerNetworkIDString(pPlayer->m_iIndex - 1);
|
||||
#else
|
||||
authstr = engine->GetPlayerNetworkIDString(pPlayer->m_pEdict);
|
||||
#endif
|
||||
pPlayer->SetAuthString(authstr);
|
||||
|
||||
if (!pPlayer->IsAuthStringValidated())
|
||||
{
|
||||
@@ -422,8 +425,6 @@ void PlayerManager::RunAuthChecks()
|
||||
unsigned int client = m_AuthQueue[i];
|
||||
m_AuthQueue[i] = 0;
|
||||
removed++;
|
||||
|
||||
const char *steamId = pPlayer->GetSteam2Id();
|
||||
|
||||
/* Send to extensions */
|
||||
List<IClientListener *>::iterator iter;
|
||||
@@ -431,7 +432,7 @@ void PlayerManager::RunAuthChecks()
|
||||
for (iter=m_hooks.begin(); iter!=m_hooks.end(); iter++)
|
||||
{
|
||||
pListener = (*iter);
|
||||
pListener->OnClientAuthorized(client, steamId ? steamId : authstr);
|
||||
pListener->OnClientAuthorized(client, authstr);
|
||||
if (!pPlayer->IsConnected())
|
||||
{
|
||||
break;
|
||||
@@ -443,8 +444,7 @@ void PlayerManager::RunAuthChecks()
|
||||
{
|
||||
/* :TODO: handle the case of a player disconnecting in the middle */
|
||||
m_clauth->PushCell(client);
|
||||
/* For legacy reasons, people are expecting the Steam2 id here if using Steam auth */
|
||||
m_clauth->PushString(steamId ? steamId : authstr);
|
||||
m_clauth->PushString(authstr);
|
||||
m_clauth->Execute(NULL);
|
||||
}
|
||||
|
||||
@@ -502,9 +502,6 @@ bool PlayerManager::OnClientConnect(edict_t *pEntity, const char *pszName, const
|
||||
/* Get the client's language */
|
||||
if (m_QueryLang)
|
||||
{
|
||||
#if SOURCE_ENGINE == SE_CSGO
|
||||
pPlayer->m_LangId = translator->GetServerLanguage();
|
||||
#else
|
||||
const char *name;
|
||||
if (!pPlayer->IsFakeClient() && (name=engine->GetClientConVarValue(client, "cl_language")))
|
||||
{
|
||||
@@ -513,7 +510,6 @@ bool PlayerManager::OnClientConnect(edict_t *pEntity, const char *pszName, const
|
||||
} else {
|
||||
pPlayer->m_LangId = translator->GetServerLanguage();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
List<IClientListener *>::iterator iter;
|
||||
@@ -536,7 +532,7 @@ bool PlayerManager::OnClientConnect(edict_t *pEntity, const char *pszName, const
|
||||
|
||||
if (res)
|
||||
{
|
||||
if (!pPlayer->IsAuthorized() && !pPlayer->IsFakeClient())
|
||||
if (!pPlayer->IsAuthorized())
|
||||
{
|
||||
m_AuthQueue[++m_AuthQueue[0]] = client;
|
||||
}
|
||||
@@ -620,7 +616,14 @@ void PlayerManager::OnClientPutInServer(edict_t *pEntity, const char *playername
|
||||
{
|
||||
/* Run manual connection routines */
|
||||
char error[255];
|
||||
|
||||
const char *authid;
|
||||
#if SOURCE_ENGINE == SE_DOTA
|
||||
authid = engine->GetPlayerNetworkIDString(client - 1);
|
||||
#else
|
||||
authid = engine->GetPlayerNetworkIDString(pEntity);
|
||||
#endif
|
||||
pPlayer->SetAuthString(authid);
|
||||
pPlayer->Authorize();
|
||||
pPlayer->m_bFakeClient = true;
|
||||
|
||||
/*
|
||||
@@ -709,33 +712,21 @@ void PlayerManager::OnClientPutInServer(edict_t *pEntity, const char *playername
|
||||
m_clconnect_post->PushCell(client);
|
||||
m_clconnect_post->Execute(&res, NULL);
|
||||
|
||||
pPlayer->Authorize();
|
||||
|
||||
const char *steamId = pPlayer->GetSteam2Id();
|
||||
|
||||
/* Now do authorization */
|
||||
for (iter=m_hooks.begin(); iter!=m_hooks.end(); iter++)
|
||||
{
|
||||
pListener = (*iter);
|
||||
pListener->OnClientAuthorized(client, steamId ? steamId : pPlayer->m_AuthID.chars());
|
||||
pListener->OnClientAuthorized(client, authid);
|
||||
}
|
||||
/* Finally, tell plugins */
|
||||
if (m_clauth->GetFunctionCount())
|
||||
{
|
||||
m_clauth->PushCell(client);
|
||||
/* For legacy reasons, people are expecting the Steam2 id here if using Steam auth */
|
||||
m_clauth->PushString(steamId ? steamId : pPlayer->m_AuthID.chars());
|
||||
m_clauth->PushString(authid);
|
||||
m_clauth->Execute(NULL);
|
||||
}
|
||||
pPlayer->Authorize_Post();
|
||||
}
|
||||
#if SOURCE_ENGINE == SE_CSGO
|
||||
else
|
||||
{
|
||||
// Not a bot
|
||||
pPlayer->m_LanguageCookie = g_ConVarManager.QueryClientConVar(pEntity, "cl_language", NULL, 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (playerinfo)
|
||||
{
|
||||
@@ -1236,7 +1227,7 @@ void PlayerManager::OnClientSettingsChanged(edict_t *pEntity)
|
||||
if ((networkid_force = engine->GetClientConVarValue(client, "networkid_force")) && networkid_force[0] != '\0')
|
||||
{
|
||||
unsigned int accountId = pPlayer->GetSteamAccountID();
|
||||
logger->LogMessage("\"%s<%d><STEAM_1:%d:%d><>\" has bad networkid (id \"%s\") (ip \"%s\")",
|
||||
g_Logger.LogMessage("\"%s<%d><STEAM_1:%d:%d><>\" has bad networkid (id \"%s\") (ip \"%s\")",
|
||||
new_name, pPlayer->GetUserId(), accountId & 1, accountId >> 1, networkid_force, pPlayer->GetIPAddress());
|
||||
|
||||
pPlayer->Kick("NetworkID spoofing detected.");
|
||||
@@ -1550,47 +1541,22 @@ void PlayerManager::ProcessCommandTarget(cmd_target_info_t *info)
|
||||
}
|
||||
|
||||
/* Do we need to look for a steam id? */
|
||||
int steamIdType = 0;
|
||||
if (strncmp(&info->pattern[1], "STEAM_", 6) == 0)
|
||||
{
|
||||
steamIdType = 2;
|
||||
}
|
||||
else if (strncmp(&info->pattern[1], "[U:", 3) == 0)
|
||||
{
|
||||
steamIdType = 3;
|
||||
}
|
||||
|
||||
if (steamIdType > 0)
|
||||
{
|
||||
size_t p, len;
|
||||
char new_pattern[256];
|
||||
if (steamIdType == 2)
|
||||
{
|
||||
size_t p, len;
|
||||
|
||||
strcpy(new_pattern, "STEAM_");
|
||||
len = strlen(&info->pattern[7]);
|
||||
for (p = 0; p < len; p++)
|
||||
{
|
||||
new_pattern[6 + p] = info->pattern[7 + p];
|
||||
if (new_pattern[6 + p] == '_')
|
||||
{
|
||||
new_pattern[6 + p] = ':';
|
||||
}
|
||||
}
|
||||
new_pattern[6 + p] = '\0';
|
||||
}
|
||||
else
|
||||
strcpy(new_pattern, "STEAM_");
|
||||
len = strlen(&info->pattern[7]);
|
||||
for (p = 0; p < len; p++)
|
||||
{
|
||||
size_t p = 0;
|
||||
char c;
|
||||
while ((c = info->pattern[p + 1]) != '\0')
|
||||
new_pattern[6 + p] = info->pattern[7 + p];
|
||||
if (new_pattern[6 + p] == '_')
|
||||
{
|
||||
new_pattern[p] = (c == '_') ? ':' : c;
|
||||
++p;
|
||||
new_pattern[6 + p] = ':';
|
||||
}
|
||||
|
||||
new_pattern[p] = '\0';
|
||||
}
|
||||
new_pattern[6 + p] = '\0';
|
||||
|
||||
for (int i = 1; i <= max_clients; i++)
|
||||
{
|
||||
@@ -1602,10 +1568,8 @@ void PlayerManager::ProcessCommandTarget(cmd_target_info_t *info)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// We want to make it easy for people to be kicked/banned, so don't require validation for command targets.
|
||||
const char *steamId = steamIdType == 2 ? pTarget->GetSteam2Id(false) : pTarget->GetSteam3Id(false);
|
||||
if (steamId && strcmp(steamId, new_pattern) == 0)
|
||||
const char *authstr = pTarget->GetAuthString(false); // We want to make it easy for people to be kicked/banned, so don't require validation for command targets.
|
||||
if (authstr && strcmp(authstr, new_pattern) == 0)
|
||||
{
|
||||
if ((info->reason = FilterCommandTarget(pAdmin, pTarget, info->flags))
|
||||
== COMMAND_TARGET_VALID)
|
||||
@@ -1898,24 +1862,6 @@ void CmdMaxplayersCallback()
|
||||
g_Players.MaxPlayersChanged();
|
||||
}
|
||||
|
||||
#if SOURCE_ENGINE == SE_CSGO
|
||||
bool PlayerManager::HandleConVarQuery(QueryCvarCookie_t cookie, edict_t *pPlayer, EQueryCvarValueStatus result, const char *cvarName, const char *cvarValue)
|
||||
{
|
||||
for (int i = 1; i <= m_maxClients; i++)
|
||||
{
|
||||
if (m_Players[i].m_LanguageCookie == cookie)
|
||||
{
|
||||
unsigned int langid;
|
||||
m_Players[i].m_LangId = (translator->GetLanguageByName(cvarValue, &langid)) ? langid : translator->GetServerLanguage();
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/*******************
|
||||
*** PLAYER CODE ***
|
||||
@@ -1939,9 +1885,7 @@ CPlayer::CPlayer()
|
||||
m_bIsSourceTV = false;
|
||||
m_bIsReplay = false;
|
||||
m_Serial.value = -1;
|
||||
#if SOURCE_ENGINE == SE_CSGO
|
||||
m_LanguageCookie = InvalidQueryCvarCookie;
|
||||
#endif
|
||||
m_SteamAccountID = 0;
|
||||
}
|
||||
|
||||
void CPlayer::Initialize(const char *name, const char *ip, edict_t *pEntity)
|
||||
@@ -1963,8 +1907,6 @@ void CPlayer::Initialize(const char *name, const char *ip, edict_t *pEntity)
|
||||
*ptr = '\0';
|
||||
}
|
||||
m_IpNoPort.assign(ip2);
|
||||
|
||||
UpdateAuthIds();
|
||||
}
|
||||
|
||||
void CPlayer::Connect()
|
||||
@@ -1989,112 +1931,14 @@ void CPlayer::Connect()
|
||||
}
|
||||
}
|
||||
|
||||
void CPlayer::UpdateAuthIds()
|
||||
void CPlayer::SetAuthString(const char *steamid)
|
||||
{
|
||||
if (m_IsAuthorized)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// First cache engine networkid
|
||||
const char *authstr;
|
||||
#if SOURCE_ENGINE == SE_DOTA
|
||||
authstr = engine->GetPlayerNetworkIDString(m_iIndex - 1);
|
||||
#else
|
||||
authstr = engine->GetPlayerNetworkIDString(m_pEdict);
|
||||
#endif
|
||||
|
||||
if (!authstr)
|
||||
{
|
||||
// engine doesn't have the client's auth string just yet, we can't do anything
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_AuthID.compare(authstr) == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
m_AuthID = authstr;
|
||||
|
||||
// Then, cache SteamId
|
||||
if (IsFakeClient())
|
||||
{
|
||||
m_SteamId = k_steamIDNil;
|
||||
}
|
||||
else
|
||||
{
|
||||
#if SOURCE_ENGINE < SE_ORANGEBOX
|
||||
const char * pAuth = GetAuthString();
|
||||
/* STEAM_0:1:123123 | STEAM_ID_LAN | STEAM_ID_PENDING */
|
||||
if (pAuth && (strlen(pAuth) > 10) && pAuth[8] != '_')
|
||||
{
|
||||
m_SteamId = CSteamID(atoi(&pAuth[8]) | (atoi(&pAuth[10]) << 1),
|
||||
k_unSteamUserDesktopInstance, k_EUniversePublic, k_EAccountTypeIndividual);
|
||||
}
|
||||
#else
|
||||
const CSteamID *steamId;
|
||||
#if SOURCE_ENGINE == SE_DOTA
|
||||
steamId = engine->GetClientSteamID(m_iIndex);
|
||||
#else
|
||||
steamId = engine->GetClientSteamID(m_pEdict);
|
||||
#endif
|
||||
|
||||
if (steamId)
|
||||
{
|
||||
m_SteamId = (*steamId);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// Now cache Steam2/3 rendered ids
|
||||
if (IsFakeClient())
|
||||
{
|
||||
m_Steam2Id = "BOT";
|
||||
m_Steam3Id = "BOT";
|
||||
return;
|
||||
}
|
||||
|
||||
if (!m_SteamId.IsValid())
|
||||
{
|
||||
if (g_HL2.IsLANServer())
|
||||
{
|
||||
m_Steam2Id = "STEAM_ID_LAN";
|
||||
m_Steam3Id = "STEAM_ID_LAN";
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_Steam2Id = "STEAM_ID_PENDING";
|
||||
m_Steam3Id = "STEAM_ID_PENDING";
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
EUniverse steam2universe = m_SteamId.GetEUniverse();
|
||||
const char *keyUseInvalidUniverse = g_pGameConf->GetKeyValue("UseInvalidUniverseInSteam2IDs");
|
||||
if (keyUseInvalidUniverse && atoi(keyUseInvalidUniverse) == 1)
|
||||
{
|
||||
steam2universe = k_EUniverseInvalid;
|
||||
}
|
||||
|
||||
char szAuthBuffer[64];
|
||||
snprintf(szAuthBuffer, sizeof(szAuthBuffer), "STEAM_%u:%u:%u", steam2universe, m_SteamId.GetAccountID() & 1, m_SteamId.GetAccountID() >> 1);
|
||||
|
||||
m_Steam2Id = szAuthBuffer;
|
||||
|
||||
// TODO: make sure all hl2sdks' steamclientpublic.h have k_unSteamUserDesktopInstance.
|
||||
if (m_SteamId.GetUnAccountInstance() == 1 /* k_unSteamUserDesktopInstance */)
|
||||
{
|
||||
snprintf(szAuthBuffer, sizeof(szAuthBuffer), "[U:%u:%u]", m_SteamId.GetEUniverse(), m_SteamId.GetAccountID());
|
||||
}
|
||||
else
|
||||
{
|
||||
snprintf(szAuthBuffer, sizeof(szAuthBuffer), "[U:%u:%u:%u]", m_SteamId.GetEUniverse(), m_SteamId.GetAccountID(), m_SteamId.GetUnAccountInstance());
|
||||
}
|
||||
|
||||
m_Steam3Id = szAuthBuffer;
|
||||
m_AuthID.assign(steamid);
|
||||
}
|
||||
|
||||
// Ensure a valid AuthString is set before calling.
|
||||
@@ -2111,10 +1955,7 @@ void CPlayer::Disconnect()
|
||||
m_IsAuthorized = false;
|
||||
m_Name.clear();
|
||||
m_Ip.clear();
|
||||
m_AuthID = "";
|
||||
m_SteamId = k_steamIDNil;
|
||||
m_Steam2Id = "";
|
||||
m_Steam3Id = "";
|
||||
m_AuthID.clear();
|
||||
m_pEdict = NULL;
|
||||
m_Info = NULL;
|
||||
m_bAdminCheckSignalled = false;
|
||||
@@ -2124,9 +1965,7 @@ void CPlayer::Disconnect()
|
||||
m_bIsSourceTV = false;
|
||||
m_bIsReplay = false;
|
||||
m_Serial.value = -1;
|
||||
#if SOURCE_ENGINE == SE_CSGO
|
||||
m_LanguageCookie = InvalidQueryCvarCookie;
|
||||
#endif
|
||||
m_SteamAccountID = 0;
|
||||
}
|
||||
|
||||
void CPlayer::SetName(const char *name)
|
||||
@@ -2156,50 +1995,42 @@ const char *CPlayer::GetAuthString(bool validated)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return m_AuthID.chars();
|
||||
}
|
||||
|
||||
const CSteamID &CPlayer::GetSteamId(bool validated)
|
||||
{
|
||||
if (validated && !IsAuthStringValidated())
|
||||
{
|
||||
static const CSteamID invalidId = k_steamIDNil;
|
||||
return invalidId;
|
||||
}
|
||||
|
||||
return m_SteamId;
|
||||
}
|
||||
|
||||
const char *CPlayer::GetSteam2Id(bool validated)
|
||||
{
|
||||
if (!m_Steam2Id.length() || (validated && !IsAuthStringValidated()))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return m_Steam2Id.chars();
|
||||
}
|
||||
|
||||
const char *CPlayer::GetSteam3Id(bool validated)
|
||||
{
|
||||
if (!m_Steam3Id.length() || (validated && !IsAuthStringValidated()))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return m_Steam3Id.chars();
|
||||
return m_AuthID.c_str();
|
||||
}
|
||||
|
||||
unsigned int CPlayer::GetSteamAccountID(bool validated)
|
||||
{
|
||||
if (!IsFakeClient() && (!validated || IsAuthStringValidated()))
|
||||
if (IsFakeClient() || (validated && !IsAuthStringValidated()))
|
||||
{
|
||||
const CSteamID &id = GetSteamId();
|
||||
if (id.IsValid())
|
||||
return id.GetAccountID();
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
if (m_SteamAccountID != 0)
|
||||
{
|
||||
return m_SteamAccountID;
|
||||
}
|
||||
|
||||
#if SOURCE_ENGINE < SE_ORANGEBOX
|
||||
const char * pAuth = GetAuthString();
|
||||
/* STEAM_0:1:123123 | STEAM_ID_LAN | STEAM_ID_PENDING */
|
||||
if (pAuth && (strlen(pAuth) > 10) && pAuth[8] != '_')
|
||||
{
|
||||
m_SteamAccountID = (atoi(&pAuth[8]) | (atoi(&pAuth[10]) << 1));
|
||||
}
|
||||
#else
|
||||
unsigned long long *steamId;
|
||||
#if SOURCE_ENGINE == SE_DOTA
|
||||
steamId = (unsigned long long *)engine->GetClientSteamID(m_iIndex);
|
||||
#else
|
||||
steamId = (unsigned long long *)engine->GetClientSteamID(m_pEdict);
|
||||
#endif
|
||||
|
||||
if (steamId)
|
||||
{
|
||||
m_SteamAccountID = (*steamId & 0xFFFFFFFF);
|
||||
}
|
||||
#endif
|
||||
return m_SteamAccountID;
|
||||
}
|
||||
|
||||
edict_t *CPlayer::GetEdict()
|
||||
@@ -2465,7 +2296,7 @@ void CPlayer::DoBasicAdminChecks()
|
||||
}
|
||||
|
||||
/* Check steam id */
|
||||
if ((id = adminsys->FindAdminByIdentity("steam", m_AuthID.chars())) != INVALID_ADMIN_ID)
|
||||
if ((id = adminsys->FindAdminByIdentity("steam", m_AuthID.c_str())) != INVALID_ADMIN_ID)
|
||||
{
|
||||
if (g_Players.CheckSetAdmin(client, this, id))
|
||||
{
|
||||
|
||||
+3
-18
@@ -41,11 +41,8 @@
|
||||
#include <sh_string.h>
|
||||
#include <sh_list.h>
|
||||
#include <sh_vector.h>
|
||||
#include <am-string.h>
|
||||
#include "ConVarManager.h"
|
||||
|
||||
#include <steam/steamclientpublic.h>
|
||||
|
||||
using namespace SourceHook;
|
||||
|
||||
#define PLAYER_LIFE_UNKNOWN 0
|
||||
@@ -74,10 +71,6 @@ public:
|
||||
const char *GetIPAddress();
|
||||
const char *GetAuthString(bool validated = true);
|
||||
unsigned int GetSteamAccountID(bool validated = true);
|
||||
const CSteamID &GetSteamId(bool validated = true);
|
||||
uint64_t GetSteamId64(bool validated = true) { return GetSteamId(validated).ConvertToUint64(); }
|
||||
const char *GetSteam2Id(bool validated = true);
|
||||
const char *GetSteam3Id(bool validated = true);
|
||||
edict_t *GetEdict();
|
||||
bool IsInGame();
|
||||
bool WasCountedAsInGame();
|
||||
@@ -110,7 +103,7 @@ private:
|
||||
void Disconnect();
|
||||
void SetName(const char *name);
|
||||
void DumpAdmin(bool deleting);
|
||||
void UpdateAuthIds();
|
||||
void SetAuthString(const char *auth);
|
||||
void Authorize();
|
||||
void Authorize_Post();
|
||||
void DoPostConnectAuthorization();
|
||||
@@ -123,9 +116,7 @@ private:
|
||||
String m_Name;
|
||||
String m_Ip;
|
||||
String m_IpNoPort;
|
||||
ke::AString m_AuthID;
|
||||
ke::AString m_Steam2Id;
|
||||
ke::AString m_Steam3Id;
|
||||
String m_AuthID;
|
||||
AdminId m_Admin;
|
||||
bool m_TempAdmin;
|
||||
edict_t *m_pEdict;
|
||||
@@ -139,10 +130,7 @@ private:
|
||||
bool m_bIsSourceTV;
|
||||
bool m_bIsReplay;
|
||||
serial_t m_Serial;
|
||||
CSteamID m_SteamId;
|
||||
#if SOURCE_ENGINE == SE_CSGO
|
||||
QueryCvarCookie_t m_LanguageCookie;
|
||||
#endif
|
||||
unsigned int m_SteamAccountID;
|
||||
};
|
||||
|
||||
class PlayerManager :
|
||||
@@ -223,9 +211,6 @@ public:
|
||||
unsigned int GetReplyTo();
|
||||
unsigned int SetReplyTo(unsigned int reply);
|
||||
void MaxPlayersChanged(int newvalue = -1);
|
||||
#if SOURCE_ENGINE == SE_CSGO
|
||||
bool HandleConVarQuery(QueryCvarCookie_t cookie, edict_t *pPlayer, EQueryCvarValueStatus result, const char *cvarName, const char *cvarValue);
|
||||
#endif
|
||||
private:
|
||||
#if SOURCE_ENGINE == SE_DOTA
|
||||
void OnServerActivate();
|
||||
|
||||
+1
-10
@@ -19,12 +19,6 @@ if builder.target_platform == 'linux':
|
||||
elif builder.target_platform == 'mac':
|
||||
binary.compiler.cflags += ['-Wno-deprecated-declarations']
|
||||
binary.compiler.postlink += ['-framework', 'CoreServices']
|
||||
|
||||
if binary.compiler.vendor == 'gcc' or binary.compiler.vendor == 'clang':
|
||||
binary.compiler.cxxflags += ['-fno-rtti']
|
||||
elif binary.compiler.vendor == 'msvc':
|
||||
binary.compiler.cxxflags += ['/GR-']
|
||||
|
||||
binary.sources += [
|
||||
'common_logic.cpp',
|
||||
'smn_adt_array.cpp',
|
||||
@@ -39,6 +33,7 @@ binary.sources += [
|
||||
'TextParsers.cpp',
|
||||
'smn_textparse.cpp',
|
||||
'smn_adt_trie.cpp',
|
||||
'Profiler.cpp',
|
||||
'smn_functions.cpp',
|
||||
'smn_timers.cpp',
|
||||
'smn_players.cpp',
|
||||
@@ -71,10 +66,6 @@ binary.sources += [
|
||||
'AdminCache.cpp',
|
||||
'sm_trie.cpp',
|
||||
'smn_console.cpp',
|
||||
'ProfileTools.cpp',
|
||||
'Logger.cpp',
|
||||
'smn_core.cpp',
|
||||
'smn_menus.cpp',
|
||||
]
|
||||
if builder.target_platform == 'windows':
|
||||
binary.sources += ['thread/WinThreads.cpp']
|
||||
|
||||
+24
-98
@@ -39,16 +39,15 @@
|
||||
#include "AdminCache.h"
|
||||
#include "Translator.h"
|
||||
#include "common_logic.h"
|
||||
#include "stringutil.h"
|
||||
|
||||
#define LEVEL_STATE_NONE 0
|
||||
#define LEVEL_STATE_LEVELS 1
|
||||
#define LEVEL_STATE_FLAGS 2
|
||||
|
||||
AdminCache g_Admins;
|
||||
char g_ReverseFlags[AdminFlags_TOTAL];
|
||||
char g_ReverseFlags[26];
|
||||
AdminFlag g_FlagLetters[26];
|
||||
bool g_FlagCharSet[26];
|
||||
bool g_FlagSet[26];
|
||||
|
||||
/* Default flags */
|
||||
AdminFlag g_DefaultFlags[26] =
|
||||
@@ -72,9 +71,9 @@ public:
|
||||
memcpy(g_FlagLetters, g_DefaultFlags, sizeof(AdminFlag) * 26);
|
||||
for (unsigned int i=0; i<20; i++)
|
||||
{
|
||||
g_FlagCharSet[i] = true;
|
||||
g_FlagSet[i] = true;
|
||||
}
|
||||
g_FlagCharSet[25] = true;
|
||||
g_FlagSet[25] = true;
|
||||
}
|
||||
}
|
||||
private:
|
||||
@@ -104,7 +103,7 @@ private:
|
||||
{
|
||||
m_LevelState = LEVEL_STATE_NONE;
|
||||
m_IgnoreLevel = 0;
|
||||
memset(g_FlagCharSet, 0, sizeof(g_FlagCharSet));
|
||||
memset(g_FlagSet, 0, sizeof(g_FlagSet));
|
||||
}
|
||||
SMCResult ReadSMC_NewSection(const SMCStates *states, const char *name)
|
||||
{
|
||||
@@ -164,7 +163,7 @@ private:
|
||||
return SMCResult_Continue;
|
||||
}
|
||||
|
||||
g_FlagCharSet[c] = true;
|
||||
g_FlagSet[c] = true;
|
||||
|
||||
return SMCResult_Continue;
|
||||
}
|
||||
@@ -199,11 +198,11 @@ private:
|
||||
|
||||
if (!m_bFileNameLogged)
|
||||
{
|
||||
logger->LogError("[SM] Parse error(s) detected in file \"%s\":", m_File);
|
||||
smcore.LogError("[SM] Parse error(s) detected in file \"%s\":", m_File);
|
||||
m_bFileNameLogged = true;
|
||||
}
|
||||
|
||||
logger->LogError("[SM] (Line %d): %s", states ? states->line : 0, buffer);
|
||||
smcore.LogError("[SM] (Line %d): %s", states ? states->line : 0, buffer);
|
||||
}
|
||||
private:
|
||||
bool m_bFileNameLogged;
|
||||
@@ -1057,65 +1056,6 @@ bool AdminCache::GetMethodIndex(const char *name, unsigned int *_index)
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* Converts Steam2 id, Steam3 id, or SteamId64 to unified, legacy
|
||||
* admin identity format. (account id part of Steam2 format)
|
||||
*/
|
||||
bool AdminCache::GetUnifiedSteamIdentity(const char *ident, char *out, size_t maxlen)
|
||||
{
|
||||
int len = strlen(ident);
|
||||
if (!strcmp(ident, "BOT"))
|
||||
{
|
||||
// Bots
|
||||
strncopy(out, ident, maxlen);
|
||||
return true;
|
||||
}
|
||||
else if (len >= 11 && !strncmp(ident, "STEAM_", 6) && ident[8] != '_')
|
||||
{
|
||||
// non-bot/lan Steam2 Id, strip off the STEAM_* part
|
||||
snprintf(out, maxlen, "%s", &ident[8]);
|
||||
return true;
|
||||
}
|
||||
else if (len >= 7 && !strncmp(ident, "[U:", 3) && ident[len-1] == ']')
|
||||
{
|
||||
// Steam3 Id, replicate the Steam2 Post-"STEAM_" part
|
||||
uint32_t accountId = strtoul(&ident[5], nullptr, 10);
|
||||
snprintf(out, maxlen, "%u:%u", accountId & 1, accountId >> 1);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// 64-bit CSteamID, replicate the Steam2 Post-"STEAM_" part
|
||||
|
||||
// some constants from steamclientpublic.h
|
||||
static const uint32_t k_EAccountTypeIndividual = 1;
|
||||
static const int k_EUniverseInvalid = 0;
|
||||
static const int k_EUniverseMax = 5;
|
||||
static const unsigned int k_unSteamUserWebInstance = 4;
|
||||
|
||||
uint64_t steamId = strtoull(ident, nullptr, 10);
|
||||
if (steamId > 0)
|
||||
{
|
||||
// Make some attempt at being sure it's a valid id rather than other number,
|
||||
// even though we're only going to use the lower 32 bits.
|
||||
uint32_t accountId = steamId & 0xFFFFFFFF;
|
||||
uint32_t accountType = (steamId >> 52) & 0xF;
|
||||
int universe = steamId >> 56;
|
||||
uint32_t accountInstance = (steamId >> 32) & 0xFFFFF;
|
||||
if (accountId > 0
|
||||
&& universe > k_EUniverseInvalid && universe < k_EUniverseMax
|
||||
&& accountType == k_EAccountTypeIndividual && accountInstance <= k_unSteamUserWebInstance
|
||||
)
|
||||
{
|
||||
snprintf(out, maxlen, "%u:%u", accountId & 1, accountId >> 1);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool AdminCache::BindAdminIdentity(AdminId id, const char *auth, const char *ident)
|
||||
{
|
||||
if (ident[0] == '\0')
|
||||
@@ -1133,14 +1073,10 @@ bool AdminCache::BindAdminIdentity(AdminId id, const char *auth, const char *ide
|
||||
if (!m_AuthTables.retrieve(auth, &method))
|
||||
return false;
|
||||
|
||||
/* If the auth type is steam, the id could be in a number of formats. Unify it. */
|
||||
char steamIdent[16];
|
||||
if (strcmp(auth, "steam") == 0)
|
||||
/* If the id was a steam id strip off the STEAM_*: part */
|
||||
if (strcmp(auth, "steam") == 0 && strncmp(ident, "STEAM_", 6) == 0)
|
||||
{
|
||||
if (!GetUnifiedSteamIdentity(ident, steamIdent, sizeof(steamIdent)))
|
||||
return false;
|
||||
|
||||
ident = steamIdent;
|
||||
ident += 8;
|
||||
}
|
||||
|
||||
if (method->identities.contains(ident))
|
||||
@@ -1161,14 +1097,10 @@ AdminId AdminCache::FindAdminByIdentity(const char *auth, const char *identity)
|
||||
if (!m_AuthTables.retrieve(auth, &method))
|
||||
return INVALID_ADMIN_ID;
|
||||
|
||||
/* If the auth type is steam, the id could be in a number of formats. Unify it. */
|
||||
char steamIdent[16];
|
||||
if (strcmp(auth, "steam") == 0)
|
||||
/* If the id was a steam id strip off the STEAM_*: part */
|
||||
if (strcmp(auth, "steam") == 0 && strncmp(identity, "STEAM_", 6) == 0)
|
||||
{
|
||||
if (!GetUnifiedSteamIdentity(identity, steamIdent, sizeof(steamIdent)))
|
||||
return INVALID_ADMIN_ID;
|
||||
|
||||
identity = steamIdent;
|
||||
identity += 8;
|
||||
}
|
||||
|
||||
AdminId id;
|
||||
@@ -1585,7 +1517,7 @@ bool AdminCache::FindFlag(char c, AdminFlag *pAdmFlag)
|
||||
{
|
||||
if (c < 'a'
|
||||
|| c > 'z'
|
||||
|| !g_FlagCharSet[(unsigned)c - (unsigned)'a'])
|
||||
|| !g_FlagSet[(unsigned)c - (unsigned)'a'])
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@@ -1600,13 +1532,17 @@ bool AdminCache::FindFlag(char c, AdminFlag *pAdmFlag)
|
||||
|
||||
bool AdminCache::FindFlagChar(AdminFlag flag, char *c)
|
||||
{
|
||||
char flagchar = g_ReverseFlags[flag];
|
||||
if (c)
|
||||
if (!g_FlagSet[flag])
|
||||
{
|
||||
*c = flagchar;
|
||||
return false;
|
||||
}
|
||||
|
||||
return flagchar != '?';
|
||||
if (c)
|
||||
{
|
||||
*c = g_ReverseFlags[flag];
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
FlagBits AdminCache::ReadFlagString(const char *flags, const char **end)
|
||||
@@ -1766,7 +1702,7 @@ void iterator_group_grp_override(FILE *fp, const char *key, OverrideRule rule)
|
||||
fprintf(fp, "\t\t\t\"@%s\"\t\t\"%s\"\n", key, str);
|
||||
}
|
||||
|
||||
bool AdminCache::DumpCache(const char *filename)
|
||||
void AdminCache::DumpCache(FILE *fp)
|
||||
{
|
||||
int *itable;
|
||||
AdminId aid;
|
||||
@@ -1775,12 +1711,6 @@ bool AdminCache::DumpCache(const char *filename)
|
||||
unsigned int num;
|
||||
AdminUser *pAdmin;
|
||||
AdminGroup *pGroup;
|
||||
|
||||
FILE *fp;
|
||||
if ((fp = fopen(filename, "wt")) == NULL)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
fprintf(fp, "\"Groups\"\n{\n");
|
||||
|
||||
@@ -1911,10 +1841,6 @@ bool AdminCache::DumpCache(const char *filename)
|
||||
for (FlagMap::iterator iter = m_CmdOverrides.iter(); !iter.empty(); iter.next())
|
||||
iterator_glob_basic_override(fp, iter->key.chars(), iter->value);
|
||||
fprintf(fp, "}\n");
|
||||
|
||||
fclose(fp);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
AdminGroup *AdminCache::GetGroup(GroupId gid)
|
||||
|
||||
@@ -183,7 +183,7 @@ public: //IAdminSystem
|
||||
bool IsValidAdmin(AdminId id);
|
||||
bool CheckClientCommandAccess(int client, const char *cmd, FlagBits cmdflags);
|
||||
public:
|
||||
bool DumpCache(const char *filename);
|
||||
void DumpCache(FILE *fp);
|
||||
AdminGroup *GetGroup(GroupId gid);
|
||||
AdminUser *GetUser(AdminId id);
|
||||
const char *GetString(int idx);
|
||||
@@ -198,7 +198,6 @@ private:
|
||||
bool GetMethodIndex(const char *name, unsigned int *_index);
|
||||
const char *GetMethodName(unsigned int index);
|
||||
void NameFlag(const char *str, AdminFlag flag);
|
||||
bool GetUnifiedSteamIdentity(const char *ident, char *out, size_t maxlen);
|
||||
public:
|
||||
typedef StringHashMap<FlagBits> FlagMap;
|
||||
|
||||
|
||||
+3
-14
@@ -89,11 +89,11 @@ void DBManager::OnSourceModLevelChange(const char *mapName)
|
||||
ke::AutoLock lock(&m_ConfigLock);
|
||||
if ((err = textparsers->ParseFile_SMC(m_Filename, this, &states)) != SMCError_Okay)
|
||||
{
|
||||
logger->LogError("[SM] Detected parse error(s) in file \"%s\"", m_Filename);
|
||||
smcore.LogError("[SM] Detected parse error(s) in file \"%s\"", m_Filename);
|
||||
if (err != SMCError_Custom)
|
||||
{
|
||||
const char *txt = textparsers->GetSMCErrorString(err);
|
||||
logger->LogError("[SM] Line %d: %s", states.line, txt);
|
||||
smcore.LogError("[SM] Line %d: %s", states.line, txt);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -541,7 +541,7 @@ bool DBManager::AddToThreadQueue(IDBThreadOperation *op, PrioQueueLevel prio)
|
||||
{
|
||||
if (!s_OneTimeThreaderErrorMsg)
|
||||
{
|
||||
logger->LogError("[SM] Unable to create db threader (error unknown)");
|
||||
smcore.LogError("[SM] Unable to create db threader (error unknown)");
|
||||
s_OneTimeThreaderErrorMsg = true;
|
||||
}
|
||||
m_Worker = NULL;
|
||||
@@ -615,17 +615,6 @@ void DBManager::ThreadMain()
|
||||
ke::AutoLock lock(&m_ThinkLock);
|
||||
m_ThinkQueue.push(op);
|
||||
}
|
||||
|
||||
|
||||
if (!m_Terminate)
|
||||
{
|
||||
ke::AutoUnlock unlock(&m_QueueEvent);
|
||||
#ifdef _WIN32
|
||||
Sleep(20);
|
||||
#else
|
||||
usleep(20000);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
if (m_Terminate)
|
||||
|
||||
@@ -32,7 +32,6 @@
|
||||
#include <IPluginSys.h>
|
||||
#include <stdarg.h>
|
||||
#include "DebugReporter.h"
|
||||
#include "Logger.h"
|
||||
|
||||
DebugReport g_DbgReporter;
|
||||
|
||||
@@ -50,7 +49,7 @@ void DebugReport::OnDebugSpew(const char *msg, ...)
|
||||
smcore.FormatArgs(buffer, sizeof(buffer), msg, ap);
|
||||
va_end(ap);
|
||||
|
||||
g_Logger.LogMessage("[SM] %s", buffer);
|
||||
smcore.Log("[SM] %s", buffer);
|
||||
}
|
||||
|
||||
void DebugReport::GenerateError(IPluginContext *ctx, cell_t func_idx, int err, const char *message, ...)
|
||||
@@ -72,12 +71,12 @@ void DebugReport::GenerateErrorVA(IPluginContext *ctx, cell_t func_idx, int err,
|
||||
|
||||
if (error)
|
||||
{
|
||||
g_Logger.LogError("[SM] Plugin \"%s\" encountered error %d: %s", plname, err, error);
|
||||
smcore.LogError("[SM] Plugin \"%s\" encountered error %d: %s", plname, err, error);
|
||||
} else {
|
||||
g_Logger.LogError("[SM] Plugin \"%s\" encountered unknown error %d", plname, err);
|
||||
smcore.LogError("[SM] Plugin \"%s\" encountered unknown error %d", plname, err);
|
||||
}
|
||||
|
||||
g_Logger.LogError("[SM] %s", buffer);
|
||||
smcore.LogError("[SM] %s", buffer);
|
||||
|
||||
if (func_idx != -1)
|
||||
{
|
||||
@@ -87,7 +86,7 @@ void DebugReport::GenerateErrorVA(IPluginContext *ctx, cell_t func_idx, int err,
|
||||
sp_public_t *function;
|
||||
if (ctx->GetRuntime()->GetPublicByIndex(func_idx, &function) == SP_ERROR_NONE)
|
||||
{
|
||||
g_Logger.LogError("[SM] Unable to call function \"%s\" due to above error(s).", function->name);
|
||||
smcore.LogError("[SM] Unable to call function \"%s\" due to above error(s).", function->name);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -107,18 +106,18 @@ void DebugReport::GenerateCodeError(IPluginContext *pContext, uint32_t code_addr
|
||||
|
||||
if (error)
|
||||
{
|
||||
g_Logger.LogError("[SM] Plugin \"%s\" encountered error %d: %s", plname, err, error);
|
||||
smcore.LogError("[SM] Plugin \"%s\" encountered error %d: %s", plname, err, error);
|
||||
} else {
|
||||
g_Logger.LogError("[SM] Plugin \"%s\" encountered unknown error %d", plname, err);
|
||||
smcore.LogError("[SM] Plugin \"%s\" encountered unknown error %d", plname, err);
|
||||
}
|
||||
|
||||
g_Logger.LogError("[SM] %s", buffer);
|
||||
smcore.LogError("[SM] %s", buffer);
|
||||
|
||||
IPluginDebugInfo *pDebug;
|
||||
if ((pDebug = pContext->GetRuntime()->GetDebugInfo()) == NULL)
|
||||
{
|
||||
g_Logger.LogError("[SM] Debug mode is not enabled for \"%s\"", plname);
|
||||
g_Logger.LogError("[SM] To enable debug mode, edit plugin_settings.cfg, or type: sm plugins debug %d on",
|
||||
smcore.LogError("[SM] Debug mode is not enabled for \"%s\"", plname);
|
||||
smcore.LogError("[SM] To enable debug mode, edit plugin_settings.cfg, or type: sm plugins debug %d on",
|
||||
_GetPluginIndex(pContext));
|
||||
return;
|
||||
}
|
||||
@@ -126,9 +125,9 @@ void DebugReport::GenerateCodeError(IPluginContext *pContext, uint32_t code_addr
|
||||
const char *name;
|
||||
if (pDebug->LookupFunction(code_addr, &name) == SP_ERROR_NONE)
|
||||
{
|
||||
g_Logger.LogError("[SM] Unable to call function \"%s\" due to above error(s).", name);
|
||||
smcore.LogError("[SM] Unable to call function \"%s\" due to above error(s).", name);
|
||||
} else {
|
||||
g_Logger.LogError("[SM] Unable to call function (name unknown, address \"%x\").", code_addr);
|
||||
smcore.LogError("[SM] Unable to call function (name unknown, address \"%x\").", code_addr);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -140,7 +139,7 @@ void DebugReport::OnContextExecuteError(IPluginContext *ctx, IContextTrace *erro
|
||||
|
||||
if (n_err != SP_ERROR_NATIVE)
|
||||
{
|
||||
g_Logger.LogError("[SM] Plugin encountered error %d: %s",
|
||||
smcore.LogError("[SM] Plugin encountered error %d: %s",
|
||||
n_err,
|
||||
error->GetErrorString());
|
||||
}
|
||||
@@ -150,26 +149,26 @@ void DebugReport::OnContextExecuteError(IPluginContext *ctx, IContextTrace *erro
|
||||
const char *custerr;
|
||||
if ((custerr=error->GetCustomErrorString()) != NULL)
|
||||
{
|
||||
g_Logger.LogError("[SM] Native \"%s\" reported: %s", lastname, custerr);
|
||||
smcore.LogError("[SM] Native \"%s\" reported: %s", lastname, custerr);
|
||||
} else {
|
||||
g_Logger.LogError("[SM] Native \"%s\" encountered a generic error.", lastname);
|
||||
smcore.LogError("[SM] Native \"%s\" encountered a generic error.", lastname);
|
||||
}
|
||||
}
|
||||
|
||||
if (!error->DebugInfoAvailable())
|
||||
{
|
||||
g_Logger.LogError("[SM] Debug mode is not enabled for \"%s\"", plname);
|
||||
g_Logger.LogError("[SM] To enable debug mode, edit plugin_settings.cfg, or type: sm plugins debug %d on",
|
||||
smcore.LogError("[SM] Debug mode is not enabled for \"%s\"", plname);
|
||||
smcore.LogError("[SM] To enable debug mode, edit plugin_settings.cfg, or type: sm plugins debug %d on",
|
||||
_GetPluginIndex(ctx));
|
||||
return;
|
||||
}
|
||||
|
||||
CallStackInfo stk_info;
|
||||
int i = 0;
|
||||
g_Logger.LogError("[SM] Displaying call stack trace for plugin \"%s\":", plname);
|
||||
smcore.LogError("[SM] Displaying call stack trace for plugin \"%s\":", plname);
|
||||
while (error->GetTraceInfo(&stk_info))
|
||||
{
|
||||
g_Logger.LogError("[SM] [%d] Line %d, %s::%s()",
|
||||
smcore.LogError("[SM] [%d] Line %d, %s::%s()",
|
||||
i++,
|
||||
stk_info.line,
|
||||
stk_info.filename,
|
||||
|
||||
@@ -606,7 +606,7 @@ IExtension *CExtensionManager::LoadAutoExtension(const char *path, bool bErrorOn
|
||||
{
|
||||
if (bErrorOnMissing || libsys->IsPathFile(p->GetPath()))
|
||||
{
|
||||
logger->LogError("[SM] Unable to load extension \"%s\": %s", path, error);
|
||||
smcore.LogError("[SM] Unable to load extension \"%s\": %s", path, error);
|
||||
}
|
||||
|
||||
p->SetError(error);
|
||||
@@ -1360,24 +1360,6 @@ void CExtensionManager::CallOnCoreMapStart(edict_t *pEdictList, int edictCount,
|
||||
}
|
||||
}
|
||||
|
||||
void CExtensionManager::CallOnCoreMapEnd()
|
||||
{
|
||||
IExtensionInterface *pAPI;
|
||||
List<CExtension *>::iterator iter;
|
||||
|
||||
for (iter=m_Libs.begin(); iter!=m_Libs.end(); iter++)
|
||||
{
|
||||
if ((pAPI = (*iter)->GetAPI()) == NULL)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (pAPI->GetExtensionVersion() > 7)
|
||||
{
|
||||
pAPI->OnCoreMapEnd();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const CVector<IExtension *> *CExtensionManager::ListExtensions()
|
||||
{
|
||||
CVector<IExtension *> *list = new CVector<IExtension *>();
|
||||
|
||||
@@ -173,7 +173,6 @@ public:
|
||||
void AddLibrary(IExtension *pSource, const char *library);
|
||||
bool LibraryExists(const char *library);
|
||||
void CallOnCoreMapStart(edict_t *pEdictList, int edictCount, int clientMax);
|
||||
void CallOnCoreMapEnd();
|
||||
void AddRawDependency(IExtension *ext, IdentityToken_t *other, void *iface);
|
||||
const CVector<IExtension *> *ListExtensions();
|
||||
void FreeExtensionList(const CVector<IExtension *> *list);
|
||||
|
||||
+14
-15
@@ -301,8 +301,8 @@ SMCResult CGameConfig::ReadSMC_NewSection(const SMCStates *states, const char *n
|
||||
if (error[0] != '\0')
|
||||
{
|
||||
m_IgnoreLevel = 1;
|
||||
logger->LogError("[SM] Error while parsing CRC section for \"%s\" (%s):", m_Game, m_CurFile);
|
||||
logger->LogError("[SM] %s", error);
|
||||
smcore.LogError("[SM] Error while parsing CRC section for \"%s\" (%s):", m_Game, m_CurFile);
|
||||
smcore.LogError("[SM] %s", error);
|
||||
} else {
|
||||
m_ParseState = PSTATE_GAMEDEFS_CRC_BINARY;
|
||||
}
|
||||
@@ -335,8 +335,8 @@ SMCResult CGameConfig::ReadSMC_NewSection(const SMCStates *states, const char *n
|
||||
{
|
||||
if (strcmp(name, "linux") != 0 && strcmp(name, "windows") != 0 && strcmp(name, "mac") != 0)
|
||||
{
|
||||
logger->LogError("[SM] Error while parsing Address section for \"%s\" (%s):", m_Address, m_CurFile);
|
||||
logger->LogError("[SM] Unrecognized platform \"%s\"", name);
|
||||
smcore.LogError("[SM] Error while parsing Address section for \"%s\" (%s):", m_Address, m_CurFile);
|
||||
smcore.LogError("[SM] Unrecognized platform \"%s\"", name);
|
||||
}
|
||||
m_IgnoreLevel = 1;
|
||||
}
|
||||
@@ -435,7 +435,7 @@ SMCResult CGameConfig::ReadSMC_KeyValue(const SMCStates *states, const char *key
|
||||
}
|
||||
else
|
||||
{
|
||||
logger->LogError("[SM] Error parsing Address \"%s\", does not support more than %d read offsets (gameconf \"%s\")", m_Address, limit, m_CurFile);
|
||||
smcore.LogError("[SM] Error parsing Address \"%s\", does not support more than %d read offsets (gameconf \"%s\")", m_Address, limit, m_CurFile);
|
||||
}
|
||||
} else if (strcmp(key, "signature") == 0) {
|
||||
strncopy(m_AddressSignature, value, sizeof(m_AddressSignature));
|
||||
@@ -503,7 +503,7 @@ SMCResult CGameConfig::ReadSMC_LeavingSection(const SMCStates *states)
|
||||
if (((strcmp(m_Game, "*") != 0) && strcmp(m_Game, "#default") != 0)
|
||||
&& (!m_Offsets.retrieve(m_offset)))
|
||||
{
|
||||
logger->LogError("[SM] Unable to find property %s.%s (file \"%s\") (mod \"%s\")",
|
||||
smcore.LogError("[SM] Unable to find property %s.%s (file \"%s\") (mod \"%s\")",
|
||||
m_Class,
|
||||
m_Prop,
|
||||
m_CurFile,
|
||||
@@ -556,7 +556,7 @@ SMCResult CGameConfig::ReadSMC_LeavingSection(const SMCStates *states)
|
||||
void *final_addr = NULL;
|
||||
if (addrInBase == NULL)
|
||||
{
|
||||
logger->LogError("[SM] Unrecognized library \"%s\" (gameconf \"%s\")",
|
||||
smcore.LogError("[SM] Unrecognized library \"%s\" (gameconf \"%s\")",
|
||||
s_TempSig.library,
|
||||
m_CurFile);
|
||||
}
|
||||
@@ -570,7 +570,7 @@ SMCResult CGameConfig::ReadSMC_LeavingSection(const SMCStates *states)
|
||||
if (VirtualQuery(addrInBase, &mem, sizeof(mem)))
|
||||
final_addr = g_MemUtils.ResolveSymbol(mem.AllocationBase, &s_TempSig.sig[1]);
|
||||
else
|
||||
logger->LogError("[SM] Unable to find library \"%s\" in memory (gameconf \"%s\")", s_TempSig.library, m_File);
|
||||
smcore.LogError("[SM] Unable to find library \"%s\" in memory (gameconf \"%s\")", s_TempSig.library, m_File);
|
||||
#elif defined PLATFORM_POSIX
|
||||
Dl_info info;
|
||||
/* GNU only: returns 0 on error, inconsistent! >:[ */
|
||||
@@ -585,12 +585,12 @@ SMCResult CGameConfig::ReadSMC_LeavingSection(const SMCStates *states)
|
||||
final_addr = dlsym(handle, &s_TempSig.sig[1]);
|
||||
dlclose(handle);
|
||||
} else {
|
||||
logger->LogError("[SM] Unable to load library \"%s\" (gameconf \"%s\")",
|
||||
smcore.LogError("[SM] Unable to load library \"%s\" (gameconf \"%s\")",
|
||||
s_TempSig.library,
|
||||
m_File);
|
||||
}
|
||||
} else {
|
||||
logger->LogError("[SM] Unable to find library \"%s\" in memory (gameconf \"%s\")",
|
||||
smcore.LogError("[SM] Unable to find library \"%s\" in memory (gameconf \"%s\")",
|
||||
s_TempSig.library,
|
||||
m_File);
|
||||
}
|
||||
@@ -827,8 +827,8 @@ bool CGameConfig::Reparse(char *error, size_t maxlength)
|
||||
{
|
||||
const char *msg = textparsers->GetSMCErrorString(err);
|
||||
|
||||
logger->LogError("[SM] Error parsing master gameconf file \"%s\":", path);
|
||||
logger->LogError("[SM] Error %d on line %d, col %d: %s",
|
||||
smcore.LogError("[SM] Error parsing master gameconf file \"%s\":", path);
|
||||
smcore.LogError("[SM] Error %d on line %d, col %d: %s",
|
||||
err,
|
||||
state.line,
|
||||
state.col,
|
||||
@@ -915,8 +915,8 @@ bool CGameConfig::EnterFile(const char *file, char *error, size_t maxlength)
|
||||
{
|
||||
const char *msg = textparsers->GetSMCErrorString(err);
|
||||
|
||||
logger->LogError("[SM] Error parsing gameconfig file \"%s\":", m_CurFile);
|
||||
logger->LogError("[SM] Error %d on line %d, col %d: %s",
|
||||
smcore.LogError("[SM] Error parsing gameconfig file \"%s\":", m_CurFile);
|
||||
smcore.LogError("[SM] Error %d on line %d, col %d: %s",
|
||||
err,
|
||||
state.line,
|
||||
state.col,
|
||||
@@ -1082,7 +1082,6 @@ bool GameConfigManager::LoadGameConfigFile(const char *file, IGameConfig **_pCon
|
||||
}
|
||||
|
||||
pConfig = new CGameConfig(file);
|
||||
pConfig->AddRef();
|
||||
|
||||
/* :HACKHACK: Don't parse the main config file */
|
||||
bool retval = true;
|
||||
|
||||
@@ -957,8 +957,8 @@ bool HandleSystem::InitAccessDefaults(TypeAccess *pTypeAccess, HandleAccess *pHa
|
||||
}
|
||||
|
||||
#define HANDLE_LOG_VERY_BAD(message, ...) \
|
||||
logger->LogFatal(message, ##__VA_ARGS__); \
|
||||
logger->LogError(message, ##__VA_ARGS__);
|
||||
smcore.LogFatal(message, ##__VA_ARGS__); \
|
||||
smcore.LogError(message, ##__VA_ARGS__);
|
||||
|
||||
bool HandleSystem::TryAndFreeSomeHandles()
|
||||
{
|
||||
|
||||
@@ -38,7 +38,7 @@
|
||||
#include <am-string.h>
|
||||
#include "common_logic.h"
|
||||
|
||||
#define HANDLESYS_MAX_HANDLES (1<<15)
|
||||
#define HANDLESYS_MAX_HANDLES (1<<14)
|
||||
#define HANDLESYS_MAX_TYPES (1<<9)
|
||||
#define HANDLESYS_MAX_SUBTYPES 0xF
|
||||
#define HANDLESYS_SUBTYPE_MASK 0xF
|
||||
|
||||
@@ -1,551 +0,0 @@
|
||||
/**
|
||||
* vim: set ts=4 sw=4 :
|
||||
* =============================================================================
|
||||
* SourceMod
|
||||
* Copyright (C) 2004-2009 AlliedModders LLC. All rights reserved.
|
||||
* =============================================================================
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, version 3.0, as published by the
|
||||
* Free Software Foundation.
|
||||
*
|
||||
* 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/>.
|
||||
*
|
||||
* As a special exception, AlliedModders LLC gives you permission to link the
|
||||
* code of this program (as well as its derivative works) to "Half-Life 2," the
|
||||
* "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
|
||||
* by the Valve Corporation. You must obey the GNU General Public License in
|
||||
* all respects for all other code used. Additionally, AlliedModders LLC grants
|
||||
* this exception to all derivative works. AlliedModders LLC defines further
|
||||
* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
|
||||
* or <http://www.sourcemod.net/license.php>.
|
||||
*
|
||||
* Version: $Id$
|
||||
*/
|
||||
|
||||
#include <time.h>
|
||||
#include <cstdarg>
|
||||
#include "Logger.h"
|
||||
#include <sourcemod_version.h>
|
||||
#include <ISourceMod.h>
|
||||
|
||||
Logger g_Logger;
|
||||
|
||||
/**
|
||||
* :TODO: This should be creating the log folder if it doesn't exist
|
||||
*/
|
||||
|
||||
ConfigResult Logger::OnSourceModConfigChanged(const char *key,
|
||||
const char *value,
|
||||
ConfigSource source,
|
||||
char *error,
|
||||
size_t maxlength)
|
||||
{
|
||||
if (strcasecmp(key, "Logging") == 0)
|
||||
{
|
||||
bool state;
|
||||
|
||||
if (strcasecmp(value, "on") == 0)
|
||||
{
|
||||
state = true;
|
||||
} else if (strcasecmp(value, "off") == 0) {
|
||||
state = false;
|
||||
} else {
|
||||
smcore.Format(error, maxlength, "Invalid value: must be \"on\" or \"off\"");
|
||||
return ConfigResult_Reject;
|
||||
}
|
||||
|
||||
if (source == ConfigSource_Console)
|
||||
{
|
||||
state ? EnableLogging() : DisableLogging();
|
||||
} else {
|
||||
m_InitialState = state;
|
||||
}
|
||||
|
||||
return ConfigResult_Accept;
|
||||
} else if (strcasecmp(key, "LogMode") == 0) {
|
||||
if (strcasecmp(value, "daily") == 0)
|
||||
{
|
||||
m_Mode = LoggingMode_Daily;
|
||||
} else if (strcasecmp(value, "map") == 0) {
|
||||
m_Mode = LoggingMode_PerMap;
|
||||
} else if (strcasecmp(value, "game") == 0) {
|
||||
m_Mode = LoggingMode_Game;
|
||||
} else {
|
||||
smcore.Format(error, maxlength, "Invalid value: must be [daily|map|game]");
|
||||
return ConfigResult_Reject;
|
||||
}
|
||||
|
||||
return ConfigResult_Accept;
|
||||
}
|
||||
|
||||
return ConfigResult_Ignore;
|
||||
}
|
||||
|
||||
void Logger::OnSourceModStartup(bool late)
|
||||
{
|
||||
InitLogger(m_Mode);
|
||||
}
|
||||
|
||||
void Logger::OnSourceModAllShutdown()
|
||||
{
|
||||
CloseLogger();
|
||||
}
|
||||
|
||||
void Logger::OnSourceModLevelChange(const char *mapName)
|
||||
{
|
||||
MapChange(mapName);
|
||||
}
|
||||
|
||||
void Logger::_NewMapFile()
|
||||
{
|
||||
if (!m_Active)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/* Append "Log file closed" to previous log file */
|
||||
_CloseFile();
|
||||
|
||||
char _filename[256];
|
||||
int i = 0;
|
||||
|
||||
time_t t = g_pSM->GetAdjustedTime();
|
||||
tm *curtime = localtime(&t);
|
||||
|
||||
while (true)
|
||||
{
|
||||
g_pSM->BuildPath(Path_SM, _filename, sizeof(_filename), "logs/L%02d%02d%03d.log", curtime->tm_mon + 1, curtime->tm_mday, i);
|
||||
FILE *fp = fopen(_filename, "r");
|
||||
if (!fp)
|
||||
{
|
||||
break;
|
||||
}
|
||||
fclose(fp);
|
||||
i++;
|
||||
}
|
||||
m_NrmFileName.assign(_filename);
|
||||
|
||||
FILE *fp = fopen(m_NrmFileName.c_str(), "w");
|
||||
if (!fp)
|
||||
{
|
||||
char error[255];
|
||||
libsys->GetPlatformError(error, sizeof(error));
|
||||
LogFatal("[SM] Unexpected fatal logging error (file \"%s\")", m_NrmFileName.c_str());
|
||||
LogFatal("[SM] Platform returned error: \"%s\"", error);
|
||||
LogFatal("[SM] Logging has been disabled.");
|
||||
m_Active = false;
|
||||
return;
|
||||
} else {
|
||||
char date[32];
|
||||
strftime(date, sizeof(date), "%m/%d/%Y - %H:%M:%S", curtime);
|
||||
fprintf(fp, "L %s: SourceMod log file started (file \"L%02d%02d%03d.log\") (Version \"%s\")\n", date, curtime->tm_mon + 1, curtime->tm_mday, i, SOURCEMOD_VERSION);
|
||||
fclose(fp);
|
||||
}
|
||||
}
|
||||
|
||||
void Logger::_CloseFile()
|
||||
{
|
||||
if (!m_Active)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
FILE *fp = NULL;
|
||||
if (!m_NrmFileName.empty())
|
||||
{
|
||||
fp = fopen(m_NrmFileName.c_str(), "r+");
|
||||
if (fp)
|
||||
{
|
||||
fseek(fp, 0, SEEK_END);
|
||||
LogMessage("Log file closed.");
|
||||
fclose(fp);
|
||||
}
|
||||
m_NrmFileName.clear();
|
||||
}
|
||||
|
||||
if (!m_ErrMapStart)
|
||||
{
|
||||
return;
|
||||
}
|
||||
fp = fopen(m_ErrFileName.c_str(), "r+");
|
||||
if (fp)
|
||||
{
|
||||
fseek(fp, 0, SEEK_END);
|
||||
LogError("Error log file session closed.");
|
||||
fclose(fp);
|
||||
}
|
||||
m_ErrFileName.clear();
|
||||
}
|
||||
|
||||
void Logger::InitLogger(LoggingMode mode)
|
||||
{
|
||||
m_Mode = mode;
|
||||
m_Active = m_InitialState;
|
||||
|
||||
time_t t = g_pSM->GetAdjustedTime();
|
||||
tm *curtime = localtime(&t);
|
||||
m_NrmCurDay = curtime->tm_mday;
|
||||
m_ErrCurDay = curtime->tm_mday;
|
||||
|
||||
char _filename[256];
|
||||
g_pSM->BuildPath(Path_SM, _filename, sizeof(_filename), "logs/errors_%04d%02d%02d.log", curtime->tm_year + 1900, curtime->tm_mon + 1, curtime->tm_mday);
|
||||
m_ErrFileName.assign(_filename);
|
||||
|
||||
switch (m_Mode)
|
||||
{
|
||||
case LoggingMode_PerMap:
|
||||
{
|
||||
if (!m_Active)
|
||||
{
|
||||
m_DelayedStart = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case LoggingMode_Daily:
|
||||
{
|
||||
g_pSM->BuildPath(Path_SM, _filename, sizeof(_filename), "logs/L%04d%02d%02d.log", curtime->tm_year + 1900, curtime->tm_mon + 1, curtime->tm_mday);
|
||||
m_NrmFileName.assign(_filename);
|
||||
m_DailyPrintHdr = true;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
/* do nothing... */
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Logger::CloseLogger()
|
||||
{
|
||||
_CloseFile();
|
||||
}
|
||||
|
||||
void Logger::LogToOpenFile(FILE *fp, const char *msg, ...)
|
||||
{
|
||||
if (!m_Active)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
va_list ap;
|
||||
va_start(ap, msg);
|
||||
LogToOpenFileEx(fp, msg, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
void Logger::LogToFileOnly(FILE *fp, const char *msg, ...)
|
||||
{
|
||||
if (!m_Active)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
va_list ap;
|
||||
va_start(ap, msg);
|
||||
LogToFileOnlyEx(fp, msg, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
void Logger::LogToOpenFileEx(FILE *fp, const char *msg, va_list ap)
|
||||
{
|
||||
if (!m_Active)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
static ConVar *sv_logecho = smcore.FindConVar("sv_logecho");
|
||||
|
||||
char buffer[3072];
|
||||
smcore.FormatArgs(buffer, sizeof(buffer), msg, ap);
|
||||
|
||||
char date[32];
|
||||
time_t t = g_pSM->GetAdjustedTime();
|
||||
tm *curtime = localtime(&t);
|
||||
strftime(date, sizeof(date), "%m/%d/%Y - %H:%M:%S", curtime);
|
||||
|
||||
fprintf(fp, "L %s: %s\n", date, buffer);
|
||||
|
||||
if (!sv_logecho || smcore.GetCvarBool(sv_logecho))
|
||||
{
|
||||
static char conBuffer[4096];
|
||||
smcore.Format(conBuffer, sizeof(conBuffer), "L %s: %s\n", date, buffer);
|
||||
smcore.ConPrint(conBuffer);
|
||||
}
|
||||
}
|
||||
|
||||
void Logger::LogToFileOnlyEx(FILE *fp, const char *msg, va_list ap)
|
||||
{
|
||||
if (!m_Active)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
char buffer[3072];
|
||||
smcore.FormatArgs(buffer, sizeof(buffer), msg, ap);
|
||||
|
||||
char date[32];
|
||||
time_t t = g_pSM->GetAdjustedTime();
|
||||
tm *curtime = localtime(&t);
|
||||
strftime(date, sizeof(date), "%m/%d/%Y - %H:%M:%S", curtime);
|
||||
|
||||
fprintf(fp, "L %s: %s\n", date, buffer);
|
||||
fflush(fp);
|
||||
}
|
||||
|
||||
void Logger::LogMessage(const char *vafmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
va_start(ap, vafmt);
|
||||
LogMessageEx(vafmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
void Logger::LogMessageEx(const char *vafmt, va_list ap)
|
||||
{
|
||||
if (!m_Active)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_Mode == LoggingMode_Game)
|
||||
{
|
||||
_PrintToGameLog(vafmt, ap);
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_DelayedStart)
|
||||
{
|
||||
m_DelayedStart = false;
|
||||
_NewMapFile();
|
||||
}
|
||||
|
||||
time_t t = g_pSM->GetAdjustedTime();
|
||||
tm *curtime = localtime(&t);
|
||||
|
||||
FILE *fp = NULL;
|
||||
if (m_Mode == LoggingMode_PerMap)
|
||||
{
|
||||
fp = fopen(m_NrmFileName.c_str(), "a+");
|
||||
if (!fp)
|
||||
{
|
||||
_NewMapFile();
|
||||
fp = fopen(m_NrmFileName.c_str(), "a+");
|
||||
if (!fp)
|
||||
{
|
||||
goto print_error;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (m_NrmCurDay != curtime->tm_mday)
|
||||
{
|
||||
char _filename[256];
|
||||
g_pSM->BuildPath(Path_SM, _filename, sizeof(_filename), "logs/L%04d%02d%02d.log", curtime->tm_year + 1900, curtime->tm_mon + 1, curtime->tm_mday);
|
||||
m_NrmFileName.assign(_filename);
|
||||
m_NrmCurDay = curtime->tm_mday;
|
||||
m_DailyPrintHdr = true;
|
||||
}
|
||||
fp = fopen(m_NrmFileName.c_str(), "a+");
|
||||
}
|
||||
|
||||
if (fp)
|
||||
{
|
||||
if (m_DailyPrintHdr)
|
||||
{
|
||||
char date[32];
|
||||
m_DailyPrintHdr = false;
|
||||
strftime(date, sizeof(date), "%m/%d/%Y - %H:%M:%S", curtime);
|
||||
fprintf(fp, "L %s: SourceMod log file session started (file \"L%04d%02d%02d.log\") (Version \"%s\")\n", date, curtime->tm_year + 1900, curtime->tm_mon + 1, curtime->tm_mday, SOURCEMOD_VERSION);
|
||||
}
|
||||
LogToOpenFileEx(fp, vafmt, ap);
|
||||
fclose(fp);
|
||||
} else {
|
||||
goto print_error;
|
||||
}
|
||||
|
||||
return;
|
||||
print_error:
|
||||
char error[255];
|
||||
libsys->GetPlatformError(error, sizeof(error));
|
||||
LogFatal("[SM] Unexpected fatal logging error (file \"%s\")", m_NrmFileName.c_str());
|
||||
LogFatal("[SM] Platform returned error: \"%s\"", error);
|
||||
LogFatal("[SM] Logging has been disabled.");
|
||||
m_Active = false;
|
||||
}
|
||||
|
||||
void Logger::LogError(const char *vafmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
va_start(ap, vafmt);
|
||||
LogErrorEx(vafmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
void Logger::LogErrorEx(const char *vafmt, va_list ap)
|
||||
{
|
||||
if (!m_Active)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
time_t t = g_pSM->GetAdjustedTime();
|
||||
tm *curtime = localtime(&t);
|
||||
|
||||
if (curtime->tm_mday != m_ErrCurDay)
|
||||
{
|
||||
char _filename[256];
|
||||
g_pSM->BuildPath(Path_SM, _filename, sizeof(_filename), "logs/errors_%04d%02d%02d.log", curtime->tm_year + 1900, curtime->tm_mon + 1, curtime->tm_mday);
|
||||
m_ErrFileName.assign(_filename);
|
||||
m_ErrCurDay = curtime->tm_mday;
|
||||
m_ErrMapStart = false;
|
||||
}
|
||||
|
||||
FILE *fp = fopen(m_ErrFileName.c_str(), "a+");
|
||||
if (fp)
|
||||
{
|
||||
if (!m_ErrMapStart)
|
||||
{
|
||||
char date[32];
|
||||
strftime(date, sizeof(date), "%m/%d/%Y - %H:%M:%S", curtime);
|
||||
fprintf(fp, "L %s: SourceMod error session started\n", date);
|
||||
fprintf(fp, "L %s: Info (map \"%s\") (file \"errors_%04d%02d%02d.log\")\n", date, m_CurMapName.c_str(), curtime->tm_year + 1900, curtime->tm_mon + 1, curtime->tm_mday);
|
||||
m_ErrMapStart = true;
|
||||
}
|
||||
LogToOpenFileEx(fp, vafmt, ap);
|
||||
fclose(fp);
|
||||
}
|
||||
else
|
||||
{
|
||||
char error[255];
|
||||
libsys->GetPlatformError(error, sizeof(error));
|
||||
LogFatal("[SM] Unexpected fatal logging error (file \"%s\")", m_NrmFileName.c_str());
|
||||
LogFatal("[SM] Platform returned error: \"%s\"", error);
|
||||
LogFatal("[SM] Logging has been disabled.");
|
||||
m_Active = false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void Logger::MapChange(const char *mapname)
|
||||
{
|
||||
m_CurMapName.assign(mapname);
|
||||
|
||||
switch (m_Mode)
|
||||
{
|
||||
case LoggingMode_Daily:
|
||||
{
|
||||
LogMessage("-------- Mapchange to %s --------", mapname);
|
||||
break;
|
||||
}
|
||||
case LoggingMode_PerMap:
|
||||
{
|
||||
_NewMapFile();
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
/* Do nothing... */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (m_ErrMapStart)
|
||||
{
|
||||
LogError("Error log file session closed.");
|
||||
}
|
||||
m_ErrMapStart = false;
|
||||
}
|
||||
|
||||
void Logger::_PrintToGameLog(const char *fmt, va_list ap)
|
||||
{
|
||||
char msg[3072];
|
||||
size_t len;
|
||||
|
||||
len = vsnprintf(msg, sizeof(msg)-2, fmt, ap);
|
||||
len = (len >= sizeof(msg)) ? (sizeof(msg) - 2) : len;
|
||||
|
||||
msg[len++] = '\n';
|
||||
msg[len] = '\0';
|
||||
|
||||
smcore.LogToGame(msg);
|
||||
}
|
||||
|
||||
const char *Logger::GetLogFileName(LogType type) const
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case LogType_Normal:
|
||||
{
|
||||
return m_NrmFileName.c_str();
|
||||
}
|
||||
case LogType_Error:
|
||||
{
|
||||
return m_ErrFileName.c_str();
|
||||
}
|
||||
default:
|
||||
{
|
||||
return "";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LoggingMode Logger::GetLoggingMode() const
|
||||
{
|
||||
return m_Mode;
|
||||
}
|
||||
|
||||
void Logger::EnableLogging()
|
||||
{
|
||||
if (m_Active)
|
||||
{
|
||||
return;
|
||||
}
|
||||
m_Active = true;
|
||||
LogMessage("[SM] Logging enabled manually by user.");
|
||||
}
|
||||
|
||||
void Logger::DisableLogging()
|
||||
{
|
||||
if (!m_Active)
|
||||
{
|
||||
return;
|
||||
}
|
||||
LogMessage("[SM] Logging disabled manually by user.");
|
||||
m_Active = false;
|
||||
}
|
||||
|
||||
void Logger::LogFatal(const char *msg, ...)
|
||||
{
|
||||
va_list ap;
|
||||
va_start(ap, msg);
|
||||
LogFatalEx(msg, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
void Logger::LogFatalEx(const char *msg, va_list ap)
|
||||
{
|
||||
/* :TODO: make this print all pretty-like
|
||||
* In fact, the pretty log printing function should be abstracted.
|
||||
* It's already implemented twice which is bad.
|
||||
*/
|
||||
|
||||
char path[PLATFORM_MAX_PATH];
|
||||
|
||||
g_pSM->BuildPath(Path_Game, path, sizeof(path), "sourcemod_fatal.log");
|
||||
|
||||
FILE *fp = fopen(path, "at");
|
||||
if (fp)
|
||||
{
|
||||
m_Active = true;
|
||||
LogToOpenFileEx(fp, msg, ap);
|
||||
m_Active = false;
|
||||
fclose(fp);
|
||||
}
|
||||
}
|
||||
@@ -1,111 +0,0 @@
|
||||
/**
|
||||
* vim: set ts=4 :
|
||||
* =============================================================================
|
||||
* SourceMod
|
||||
* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
|
||||
* =============================================================================
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, version 3.0, as published by the
|
||||
* Free Software Foundation.
|
||||
*
|
||||
* 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/>.
|
||||
*
|
||||
* As a special exception, AlliedModders LLC gives you permission to link the
|
||||
* code of this program (as well as its derivative works) to "Half-Life 2," the
|
||||
* "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
|
||||
* by the Valve Corporation. You must obey the GNU General Public License in
|
||||
* all respects for all other code used. Additionally, AlliedModders LLC grants
|
||||
* this exception to all derivative works. AlliedModders LLC defines further
|
||||
* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
|
||||
* or <http://www.sourcemod.net/license.php>.
|
||||
*
|
||||
* Version: $Id$
|
||||
*/
|
||||
|
||||
#ifndef _INCLUDE_SOURCEMOD_CLOGGER_H_
|
||||
#define _INCLUDE_SOURCEMOD_CLOGGER_H_
|
||||
|
||||
#include <stdio.h>
|
||||
#include <sh_string.h>
|
||||
|
||||
#include "common_logic.h"
|
||||
|
||||
using namespace SourceHook;
|
||||
|
||||
enum LogType
|
||||
{
|
||||
LogType_Normal,
|
||||
LogType_Error
|
||||
};
|
||||
|
||||
enum LoggingMode
|
||||
{
|
||||
LoggingMode_Daily,
|
||||
LoggingMode_PerMap,
|
||||
LoggingMode_Game
|
||||
};
|
||||
|
||||
class Logger : public SMGlobalClass, public ILogger
|
||||
{
|
||||
public:
|
||||
Logger() : m_Mode(LoggingMode_Daily), m_ErrMapStart(false),
|
||||
m_Active(false), m_DelayedStart(false), m_DailyPrintHdr(false),
|
||||
m_InitialState(true)
|
||||
{
|
||||
}
|
||||
public: //SMGlobalClass
|
||||
ConfigResult OnSourceModConfigChanged(const char *key,
|
||||
const char *value,
|
||||
ConfigSource source,
|
||||
char *error,
|
||||
size_t maxlength);
|
||||
void OnSourceModStartup(bool late);
|
||||
void OnSourceModAllShutdown();
|
||||
void OnSourceModLevelChange(const char *mapName);
|
||||
public:
|
||||
void InitLogger(LoggingMode mode);
|
||||
void CloseLogger();
|
||||
void EnableLogging();
|
||||
void DisableLogging();
|
||||
void LogMessage(const char *msg, ...);
|
||||
void LogMessageEx(const char *msg, va_list ap);
|
||||
void LogError(const char *msg, ...);
|
||||
void LogErrorEx(const char *msg, va_list ap);
|
||||
void LogFatal(const char *msg, ...);
|
||||
void LogFatalEx(const char *msg, va_list ap);
|
||||
void LogToOpenFile(FILE *fp, const char *msg, ...);
|
||||
void LogToOpenFileEx(FILE *fp, const char *msg, va_list ap);
|
||||
/* This version does not print to console, and is thus thread-safe */
|
||||
void LogToFileOnly(FILE *fp, const char *msg, ...);
|
||||
void LogToFileOnlyEx(FILE *fp, const char *msg, va_list ap);
|
||||
void MapChange(const char *mapname);
|
||||
const char *GetLogFileName(LogType type) const;
|
||||
LoggingMode GetLoggingMode() const;
|
||||
private:
|
||||
void _CloseFile();
|
||||
void _NewMapFile();
|
||||
void _PrintToGameLog(const char *fmt, va_list ap);
|
||||
private:
|
||||
String m_NrmFileName;
|
||||
String m_ErrFileName;
|
||||
String m_CurMapName;
|
||||
LoggingMode m_Mode;
|
||||
int m_NrmCurDay;
|
||||
int m_ErrCurDay;
|
||||
bool m_ErrMapStart;
|
||||
bool m_Active;
|
||||
bool m_DelayedStart;
|
||||
bool m_DailyPrintHdr;
|
||||
bool m_InitialState;
|
||||
};
|
||||
|
||||
extern Logger g_Logger;
|
||||
|
||||
#endif // _INCLUDE_SOURCEMOD_CLOGGER_H_
|
||||
@@ -42,7 +42,6 @@
|
||||
#include "GameConfigs.h"
|
||||
#include "common_logic.h"
|
||||
#include "Translator.h"
|
||||
#include "Logger.h"
|
||||
|
||||
CPluginManager g_PluginSys;
|
||||
HandleType_t g_PluginType = 0;
|
||||
@@ -845,8 +844,8 @@ void CPluginManager::LoadPluginsFromDir(const char *basedir, const char *localpa
|
||||
{
|
||||
char error[256];
|
||||
libsys->GetPlatformError(error, sizeof(error));
|
||||
g_Logger.LogError("[SM] Failure reading from plugins path: %s", localpath);
|
||||
g_Logger.LogError("[SM] Platform returned error: %s", error);
|
||||
smcore.LogError("[SM] Failure reading from plugins path: %s", localpath);
|
||||
smcore.LogError("[SM] Platform returned error: %s", error);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -991,9 +990,9 @@ LoadRes CPluginManager::_LoadPlugin(CPlugin **aResult, const char *path, bool de
|
||||
} else {
|
||||
if (bulletinUrl[0] != '\0')
|
||||
{
|
||||
g_Logger.LogMessage("%s: Known malware detected. See %s for more info, blocking disabled in core.cfg", pPlugin->GetFilename(), bulletinUrl);
|
||||
smcore.Log("%s: Known malware detected. See %s for more info, blocking disabled in core.cfg", pPlugin->GetFilename(), bulletinUrl);
|
||||
} else {
|
||||
g_Logger.LogMessage("%s: Possible malware or illegal plugin detected, blocking disabled in core.cfg", pPlugin->GetFilename());
|
||||
smcore.Log("%s: Possible malware or illegal plugin detected, blocking disabled in core.cfg", pPlugin->GetFilename());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1095,7 +1094,7 @@ void CPluginManager::LoadAutoPlugin(const char *plugin)
|
||||
|
||||
if ((res=_LoadPlugin(&pl, plugin, false, PluginType_MapUpdated, error, sizeof(error))) == LoadRes_Failure)
|
||||
{
|
||||
g_Logger.LogError("[SM] Failed to load plugin \"%s\": %s.", plugin, error);
|
||||
smcore.LogError("[SM] Failed to load plugin \"%s\": %s.", plugin, error);
|
||||
pl->SetErrorState(
|
||||
pl->GetStatus() <= Plugin_Created ? Plugin_BadLoad : pl->GetStatus(),
|
||||
"%s",
|
||||
@@ -1137,7 +1136,7 @@ void CPluginManager::LoadAll_SecondPass()
|
||||
error[0] = '\0';
|
||||
if (!RunSecondPass(pPlugin, error, sizeof(error)))
|
||||
{
|
||||
g_Logger.LogError("[SM] Unable to load plugin \"%s\": %s", pPlugin->GetFilename(), error);
|
||||
smcore.LogError("[SM] Unable to load plugin \"%s\": %s", pPlugin->GetFilename(), error);
|
||||
pPlugin->SetErrorState(Plugin_Failed, "%s", error);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,190 +0,0 @@
|
||||
// vim: set ts=4 sw=4 tw=99 noet :
|
||||
// =============================================================================
|
||||
// SourceMod
|
||||
// Copyright (C) 2004-2014 AlliedModders LLC. All rights reserved.
|
||||
// =============================================================================
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify it under
|
||||
// the terms of the GNU General Public License, version 3.0, as published by the
|
||||
// Free Software Foundation.
|
||||
//
|
||||
// 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/>.
|
||||
//
|
||||
// As a special exception, AlliedModders LLC gives you permission to link the
|
||||
// code of this program (as well as its derivative works) to "Half-Life 2," the
|
||||
// "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
|
||||
// by the Valve Corporation. You must obey the GNU General Public License in
|
||||
// all respects for all other code used. Additionally, AlliedModders LLC grants
|
||||
// this exception to all derivative works. AlliedModders LLC defines further
|
||||
// exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
|
||||
// or <http://www.sourcemod.net/license.php>.
|
||||
|
||||
#include "ProfileTools.h"
|
||||
#include <stdarg.h>
|
||||
|
||||
ProfileToolManager g_ProfileToolManager;
|
||||
|
||||
ProfileToolManager::ProfileToolManager()
|
||||
: active_(nullptr),
|
||||
default_(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
ProfileToolManager::OnSourceModAllInitialized()
|
||||
{
|
||||
rootmenu->AddRootConsoleCommand2("prof", "Profiling", this);
|
||||
}
|
||||
|
||||
void
|
||||
ProfileToolManager::OnSourceModShutdown()
|
||||
{
|
||||
rootmenu->RemoveRootConsoleCommand("prof", this);
|
||||
}
|
||||
|
||||
IProfilingTool *
|
||||
ProfileToolManager::FindToolByName(const char *name)
|
||||
{
|
||||
for (size_t i = 0; i < tools_.length(); i++) {
|
||||
if (strcmp(tools_[i]->Name(), name) == 0)
|
||||
return tools_[i];
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
static void
|
||||
render_help(const char *fmt, ...)
|
||||
{
|
||||
char buffer[2048];
|
||||
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
smcore.FormatArgs(buffer, sizeof(buffer), fmt, ap);
|
||||
va_end(ap);
|
||||
|
||||
rootmenu->ConsolePrint("%s", buffer);
|
||||
}
|
||||
|
||||
void
|
||||
ProfileToolManager::StartFromConsole(IProfilingTool *tool)
|
||||
{
|
||||
if (active_) {
|
||||
rootmenu->ConsolePrint("A profile is already active using %s.", active_->Name());
|
||||
return;
|
||||
}
|
||||
|
||||
active_ = tool;
|
||||
if (!active_->Start()) {
|
||||
rootmenu->ConsolePrint("Failed to attach to or start %s.", active_->Name());
|
||||
active_ = nullptr;
|
||||
return;
|
||||
}
|
||||
|
||||
g_pSourcePawn2->SetProfilingTool(active_);
|
||||
g_pSourcePawn2->EnableProfiling();
|
||||
rootmenu->ConsolePrint("Started profiling with %s.", active_->Name());
|
||||
|
||||
default_ = active_;
|
||||
}
|
||||
|
||||
void
|
||||
ProfileToolManager::OnRootConsoleCommand2(const char *cmdname, const ICommandArgs *args)
|
||||
{
|
||||
if (tools_.length() == 0) {
|
||||
rootmenu->ConsolePrint("No profiling tools are enabled.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (args->ArgC() >= 3) {
|
||||
cmdname = args->Arg(2);
|
||||
|
||||
if (strcmp(cmdname, "list") == 0) {
|
||||
rootmenu->ConsolePrint("Profiling tools:");
|
||||
for (size_t i = 0; i < tools_.length(); i++) {
|
||||
rootmenu->DrawGenericOption(tools_[i]->Name(), tools_[i]->Description());
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (strcmp(cmdname, "stop") == 0) {
|
||||
if (!active_) {
|
||||
rootmenu->ConsolePrint("No profiler is active.");
|
||||
return;
|
||||
}
|
||||
g_pSourcePawn2->DisableProfiling();
|
||||
g_pSourcePawn2->SetProfilingTool(nullptr);
|
||||
active_->Stop(render_help);
|
||||
active_ = nullptr;
|
||||
return;
|
||||
}
|
||||
if (strcmp(cmdname, "dump") == 0) {
|
||||
if (active_) {
|
||||
// if we have an active profiler, dump it
|
||||
active_->Dump();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (args->ArgC() < 4) {
|
||||
if (strcmp(cmdname, "start") == 0) {
|
||||
if (!default_) {
|
||||
default_ = FindToolByName("vprof");
|
||||
if (!default_ && tools_.length() > 0)
|
||||
default_ = tools_[0];
|
||||
if (!default_) {
|
||||
rootmenu->ConsolePrint("Could not find any profiler to use.");
|
||||
return;
|
||||
}
|
||||
}
|
||||
StartFromConsole(default_);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (args->ArgC() < 4) {
|
||||
rootmenu->ConsolePrint("You must specify a profiling tool name.");
|
||||
return;
|
||||
}
|
||||
|
||||
const char *toolname = args->Arg(3);
|
||||
if (strcmp(cmdname, "start") == 0) {
|
||||
IProfilingTool *tool = FindToolByName(toolname);
|
||||
if (!tool) {
|
||||
rootmenu->ConsolePrint("No tool with the name \"%s\" was found.", toolname);
|
||||
return;
|
||||
}
|
||||
StartFromConsole(tool);
|
||||
return;
|
||||
}
|
||||
if (strcmp(cmdname, "dump") == 0) {
|
||||
IProfilingTool *tool = FindToolByName(toolname);
|
||||
if (!tool) {
|
||||
rootmenu->ConsolePrint("No tool with the name \"%s\" was found.", toolname);
|
||||
return;
|
||||
}
|
||||
tool->Dump();
|
||||
return;
|
||||
}
|
||||
if (strcmp(cmdname, "help") == 0) {
|
||||
IProfilingTool *tool = FindToolByName(toolname);
|
||||
if (!tool) {
|
||||
rootmenu->ConsolePrint("No tool with the name \"%s\" was found.", toolname);
|
||||
return;
|
||||
}
|
||||
tool->RenderHelp(render_help);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
rootmenu->ConsolePrint("Profiling commands:");
|
||||
rootmenu->DrawGenericOption("list", "List all available profiling tools.");
|
||||
rootmenu->DrawGenericOption("start", "Start a profile with a given tool.");
|
||||
rootmenu->DrawGenericOption("stop", "Stop the current profile session.");
|
||||
rootmenu->DrawGenericOption("dump", "Dumps output from the current profile session.");
|
||||
rootmenu->DrawGenericOption("help", "Display help text for a profiler.");
|
||||
}
|
||||
@@ -1,87 +0,0 @@
|
||||
// vim: set ts=4 sw=4 tw=99 noet :
|
||||
// =============================================================================
|
||||
// SourceMod
|
||||
// Copyright (C) 2004-2014 AlliedModders LLC. All rights reserved.
|
||||
// =============================================================================
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify it under
|
||||
// the terms of the GNU General Public License, version 3.0, as published by the
|
||||
// Free Software Foundation.
|
||||
//
|
||||
// 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/>.
|
||||
//
|
||||
// As a special exception, AlliedModders LLC gives you permission to link the
|
||||
// code of this program (as well as its derivative works) to "Half-Life 2," the
|
||||
// "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
|
||||
// by the Valve Corporation. You must obey the GNU General Public License in
|
||||
// all respects for all other code used. Additionally, AlliedModders LLC grants
|
||||
// this exception to all derivative works. AlliedModders LLC defines further
|
||||
// exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
|
||||
// or <http://www.sourcemod.net/license.php>.
|
||||
|
||||
#ifndef _include_sourcemod_logic_profile_tool_manager_h_
|
||||
#define _include_sourcemod_logic_profile_tool_manager_h_
|
||||
|
||||
#include <sp_vm_api.h>
|
||||
#include <am-vector.h>
|
||||
#include <IShareSys.h>
|
||||
#include <IRootConsoleMenu.h>
|
||||
#include "common_logic.h"
|
||||
|
||||
using namespace SourcePawn;
|
||||
|
||||
class ProfileToolManager
|
||||
: public SMGlobalClass,
|
||||
public IRootConsoleCommand
|
||||
{
|
||||
public:
|
||||
ProfileToolManager();
|
||||
|
||||
// SMGlobalClass
|
||||
void OnSourceModAllInitialized() KE_OVERRIDE;
|
||||
void OnSourceModShutdown() KE_OVERRIDE;
|
||||
|
||||
// IRootConsoleCommand
|
||||
void OnRootConsoleCommand2(const char *cmdname, const ICommandArgs *args) KE_OVERRIDE;
|
||||
|
||||
void RegisterTool(IProfilingTool *tool) {
|
||||
tools_.append(tool);
|
||||
}
|
||||
|
||||
bool IsActive() const {
|
||||
return !!active_;
|
||||
}
|
||||
|
||||
// If we get problems with plugins not being able to balance the profile
|
||||
// scopes, we should add a safety net that automatically clears any pending
|
||||
// scopes.
|
||||
void EnterScope(const char *group, const char *name) {
|
||||
if (active_)
|
||||
active_->EnterScope(group, name);
|
||||
}
|
||||
void LeaveScope() {
|
||||
if (active_)
|
||||
active_->LeaveScope();
|
||||
}
|
||||
|
||||
IProfilingTool *FindToolByName(const char *name);
|
||||
|
||||
private:
|
||||
void StartFromConsole(IProfilingTool *tool);
|
||||
|
||||
private:
|
||||
ke::Vector<IProfilingTool *> tools_;
|
||||
IProfilingTool *active_;
|
||||
IProfilingTool *default_;
|
||||
bool enabled_;
|
||||
};
|
||||
|
||||
extern ProfileToolManager g_ProfileToolManager;
|
||||
|
||||
#endif // _include_sourcemod_logic_profile_tool_manager_h_
|
||||
@@ -0,0 +1,516 @@
|
||||
/**
|
||||
* vim: set ts=4 sw=4 tw=99 noet :
|
||||
* =============================================================================
|
||||
* SourceMod
|
||||
* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
|
||||
* =============================================================================
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, version 3.0, as published by the
|
||||
* Free Software Foundation.
|
||||
*
|
||||
* 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/>.
|
||||
*
|
||||
* As a special exception, AlliedModders LLC gives you permission to link the
|
||||
* code of this program (as well as its derivative works) to "Half-Life 2," the
|
||||
* "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
|
||||
* by the Valve Corporation. You must obey the GNU General Public License in
|
||||
* all respects for all other code used. Additionally, AlliedModders LLC grants
|
||||
* this exception to all derivative works. AlliedModders LLC defines further
|
||||
* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
|
||||
* or <http://www.sourcemod.net/license.php>.
|
||||
*
|
||||
* Version: $Id$
|
||||
*/
|
||||
|
||||
#include "Profiler.h"
|
||||
#include <ISourceMod.h>
|
||||
#if defined PLATFORM_POSIX
|
||||
#include <sys/time.h>
|
||||
#include <time.h>
|
||||
#endif
|
||||
#include <IPluginSys.h>
|
||||
#include "stringutil.h"
|
||||
|
||||
ProfileEngine g_Profiler;
|
||||
IProfiler *sm_profiler = &g_Profiler;
|
||||
|
||||
#if defined PLATFORM_WINDOWS
|
||||
double WINDOWS_PERFORMANCE_FREQUENCY;
|
||||
#endif
|
||||
|
||||
class EmptyProfiler : public IProfiler
|
||||
{
|
||||
public:
|
||||
void OnNativeBegin(IPluginContext *pContext, sp_native_t *native)
|
||||
{
|
||||
}
|
||||
void OnNativeEnd()
|
||||
{
|
||||
}
|
||||
void OnFunctionBegin(IPluginContext *pContext, const char *name)
|
||||
{
|
||||
}
|
||||
void OnFunctionEnd()
|
||||
{
|
||||
}
|
||||
int OnCallbackBegin(IPluginContext *pContext, sp_public_t *pubfunc)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
void OnCallbackEnd(int serial)
|
||||
{
|
||||
}
|
||||
} s_EmptyProfiler;
|
||||
|
||||
inline void InitProfPoint(prof_point_t &pt)
|
||||
{
|
||||
#if defined PLATFORM_WINDOWS
|
||||
QueryPerformanceCounter(&pt.value);
|
||||
#elif defined PLATFORM_POSIX
|
||||
gettimeofday(&pt.value, NULL);
|
||||
#endif
|
||||
pt.is_set = true;
|
||||
}
|
||||
|
||||
ProfileEngine::ProfileEngine()
|
||||
{
|
||||
m_serial = 0;
|
||||
|
||||
#if defined PLATFORM_WINDOWS
|
||||
LARGE_INTEGER pf;
|
||||
|
||||
if (QueryPerformanceFrequency(&pf))
|
||||
{
|
||||
WINDOWS_PERFORMANCE_FREQUENCY = 1.0 / (double)(pf.QuadPart);
|
||||
}
|
||||
else
|
||||
{
|
||||
WINDOWS_PERFORMANCE_FREQUENCY = -1.0;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (IsEnabled())
|
||||
{
|
||||
InitProfPoint(m_ProfStart);
|
||||
}
|
||||
else
|
||||
{
|
||||
sm_profiler = &s_EmptyProfiler;
|
||||
}
|
||||
}
|
||||
|
||||
bool ProfileEngine::IsEnabled()
|
||||
{
|
||||
#if defined PLATFORM_WINDOWS
|
||||
return (WINDOWS_PERFORMANCE_FREQUENCY > 0.0);
|
||||
#elif defined PLATFORM_POSIX
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
|
||||
inline double DiffProfPoints(const prof_point_t &start, const prof_point_t &end)
|
||||
{
|
||||
double seconds;
|
||||
|
||||
#if defined PLATFORM_WINDOWS
|
||||
LONGLONG diff;
|
||||
|
||||
diff = end.value.QuadPart - start.value.QuadPart;
|
||||
seconds = diff * WINDOWS_PERFORMANCE_FREQUENCY;
|
||||
#elif defined PLATFORM_POSIX
|
||||
seconds = (double)(end.value.tv_sec - start.value.tv_sec);
|
||||
|
||||
if (start.value.tv_usec > end.value.tv_usec)
|
||||
{
|
||||
seconds -= 1.0;
|
||||
seconds += (double)(1000000 - (start.value.tv_usec - end.value.tv_usec)) / 1000000.0;
|
||||
}
|
||||
else
|
||||
{
|
||||
seconds += (double)(end.value.tv_usec - start.value.tv_usec) / 1000000.0;
|
||||
}
|
||||
#endif
|
||||
|
||||
return seconds;
|
||||
}
|
||||
|
||||
inline double CalcAtomTime(const prof_atom_t &atom)
|
||||
{
|
||||
if (!atom.end.is_set)
|
||||
{
|
||||
return atom.base_time;
|
||||
}
|
||||
|
||||
return atom.base_time + DiffProfPoints(atom.start, atom.end);
|
||||
}
|
||||
|
||||
void ProfileEngine::OnNativeBegin(IPluginContext *pContext, sp_native_t *native)
|
||||
{
|
||||
PushProfileStack(pContext, SP_PROF_NATIVES, native->name);
|
||||
}
|
||||
|
||||
void ProfileEngine::OnNativeEnd()
|
||||
{
|
||||
assert(!m_AtomStack.empty());
|
||||
assert(m_AtomStack.front().atom_type == SP_PROF_NATIVES);
|
||||
|
||||
PopProfileStack(&m_Natives);
|
||||
}
|
||||
|
||||
void ProfileEngine::OnFunctionBegin(IPluginContext *pContext, const char *name)
|
||||
{
|
||||
PushProfileStack(pContext, SP_PROF_FUNCTIONS, name);
|
||||
}
|
||||
|
||||
void ProfileEngine::OnFunctionEnd()
|
||||
{
|
||||
assert(!m_AtomStack.empty());
|
||||
assert(m_AtomStack.front().atom_type == SP_PROF_FUNCTIONS);
|
||||
|
||||
PopProfileStack(&m_Functions);
|
||||
}
|
||||
|
||||
int ProfileEngine::OnCallbackBegin(IPluginContext *pContext, sp_public_t *pubfunc)
|
||||
{
|
||||
PushProfileStack(pContext, SP_PROF_CALLBACKS, pubfunc->name);
|
||||
|
||||
return m_serial;
|
||||
}
|
||||
|
||||
void ProfileEngine::OnCallbackEnd(int serial)
|
||||
{
|
||||
assert(!m_AtomStack.empty());
|
||||
|
||||
/**
|
||||
* Account for the situation where the JIT discards the
|
||||
* stack because there was an RTE of sorts.
|
||||
*/
|
||||
if (m_AtomStack.front().atom_type != SP_PROF_CALLBACKS
|
||||
&& m_AtomStack.front().atom_serial != serial)
|
||||
{
|
||||
prof_atom_t atom;
|
||||
double total_time;
|
||||
|
||||
/* There was an error, and we need to discard things. */
|
||||
total_time = 0.0;
|
||||
while (!m_AtomStack.empty()
|
||||
&& m_AtomStack.front().atom_type != SP_PROF_CALLBACKS
|
||||
&& m_AtomStack.front().atom_serial != serial)
|
||||
{
|
||||
total_time += CalcAtomTime(m_AtomStack.front());
|
||||
m_AtomStack.pop();
|
||||
}
|
||||
|
||||
/**
|
||||
* Now we can end and discard ourselves, without saving the data.
|
||||
* Since this data is all erroneous anyway, we don't care if it's
|
||||
* not totally accurate.
|
||||
*/
|
||||
|
||||
assert(!m_AtomStack.empty());
|
||||
atom = m_AtomStack.front();
|
||||
m_AtomStack.pop();
|
||||
|
||||
/* Note: We don't need to resume ourselves because end is set by Pause(). */
|
||||
total_time += CalcAtomTime(atom);
|
||||
|
||||
ResumeParent(total_time);
|
||||
return;
|
||||
}
|
||||
|
||||
PopProfileStack(&m_Callbacks);
|
||||
}
|
||||
|
||||
void ProfileEngine::PushProfileStack(IPluginContext *ctx, int type, const char *name)
|
||||
{
|
||||
prof_atom_t atom;
|
||||
|
||||
PauseParent();
|
||||
|
||||
atom.atom_type = type;
|
||||
atom.base_time = 0.0;
|
||||
atom.ctx = ctx->GetContext();
|
||||
atom.name = name;
|
||||
atom.end.is_set = false;
|
||||
|
||||
if (type == SP_PROF_CALLBACKS)
|
||||
{
|
||||
atom.atom_serial = ++m_serial;
|
||||
}
|
||||
else
|
||||
{
|
||||
atom.atom_serial = 0;
|
||||
}
|
||||
|
||||
m_AtomStack.push(atom);
|
||||
|
||||
/* Note: We do this after because the stack could grow and skew results */
|
||||
InitProfPoint(m_AtomStack.front().start);
|
||||
}
|
||||
|
||||
void ProfileEngine::PopProfileStack(ProfileReport *reporter)
|
||||
{
|
||||
double total_time;
|
||||
|
||||
prof_atom_t &atom = m_AtomStack.front();
|
||||
|
||||
/* We're okay to cache our used time. */
|
||||
InitProfPoint(atom.end);
|
||||
total_time = CalcAtomTime(atom);
|
||||
|
||||
/* Now it's time to save this! This may do a lot of computations which
|
||||
* is why we've cached the time beforehand.
|
||||
*/
|
||||
reporter->SaveAtom(atom);
|
||||
m_AtomStack.pop();
|
||||
|
||||
/* Finally, tell our parent how much time we used. */
|
||||
ResumeParent(total_time);
|
||||
}
|
||||
|
||||
void ProfileEngine::PauseParent()
|
||||
{
|
||||
if (m_AtomStack.empty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
InitProfPoint(m_AtomStack.front().end);
|
||||
}
|
||||
|
||||
void ProfileEngine::ResumeParent(double addTime)
|
||||
{
|
||||
if (m_AtomStack.empty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
prof_atom_t &atom = m_AtomStack.front();
|
||||
|
||||
/* Move its "paused time" to its base (known) time,
|
||||
* then reset the start/end. Note that since CalcAtomTime()
|
||||
* reads the base time, we SHOULD NOT use += to add.
|
||||
*/
|
||||
atom.base_time = CalcAtomTime(atom);
|
||||
atom.base_time += addTime;
|
||||
InitProfPoint(atom.start);
|
||||
atom.end.is_set = false;
|
||||
}
|
||||
|
||||
void ProfileEngine::Clear()
|
||||
{
|
||||
m_Natives.Clear();
|
||||
m_Callbacks.Clear();
|
||||
m_Functions.Clear();
|
||||
InitProfPoint(m_ProfStart);
|
||||
}
|
||||
|
||||
void ProfileEngine::OnSourceModAllInitialized()
|
||||
{
|
||||
rootmenu->AddRootConsoleCommand2("profiler", "Profiler commands", this);
|
||||
}
|
||||
|
||||
void ProfileEngine::OnSourceModShutdown()
|
||||
{
|
||||
rootmenu->RemoveRootConsoleCommand("profiler", this);
|
||||
}
|
||||
|
||||
void ProfileEngine::OnRootConsoleCommand2(const char *cmdname, const ICommandArgs *command)
|
||||
{
|
||||
if (command->ArgC() >= 3)
|
||||
{
|
||||
if (strcmp(command->Arg(2), "flush") == 0)
|
||||
{
|
||||
FILE *fp;
|
||||
char path[256];
|
||||
|
||||
g_pSM->BuildPath(Path_SM, path, sizeof(path), "logs/profile_%d.xml", (int)time(NULL));
|
||||
|
||||
if ((fp = fopen(path, "wt")) == NULL)
|
||||
{
|
||||
rootmenu->ConsolePrint("Failed, could not open file for writing: %s", path);
|
||||
return;
|
||||
}
|
||||
|
||||
GenerateReport(fp);
|
||||
|
||||
fclose(fp);
|
||||
|
||||
Clear();
|
||||
|
||||
rootmenu->ConsolePrint("Profiler report generated as: %s\n", path);
|
||||
|
||||
return;
|
||||
}
|
||||
else if (strcmp(command->Arg(2), "report") == 0)
|
||||
{
|
||||
FILE *fp;
|
||||
char path[256];
|
||||
|
||||
g_pSM->BuildPath(Path_SM, path, sizeof(path), "logs/profile_%d.xml", (int)time(NULL));
|
||||
|
||||
if ((fp = fopen(path, "wt")) == NULL)
|
||||
{
|
||||
rootmenu->ConsolePrint("Failed, could not open file for writing: %s", path);
|
||||
return;
|
||||
}
|
||||
|
||||
GenerateReport(fp);
|
||||
|
||||
fclose(fp);
|
||||
|
||||
rootmenu->ConsolePrint("Profiler report generated as: %s\n", path);
|
||||
return;
|
||||
}
|
||||
else if (strcmp(command->Arg(2), "clear") == 0)
|
||||
{
|
||||
Clear();
|
||||
|
||||
rootmenu->ConsolePrint("Profiler statistics cleared.\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
rootmenu->ConsolePrint("Profiler commands:");
|
||||
rootmenu->DrawGenericOption("flush", "Flushes statistics to disk and starts over");
|
||||
rootmenu->DrawGenericOption("report", "Flushes statistics to disk");
|
||||
rootmenu->DrawGenericOption("clear", "Clears statistics");
|
||||
}
|
||||
|
||||
bool ProfileEngine::GenerateReport(FILE *fp)
|
||||
{
|
||||
time_t t;
|
||||
double total_time;
|
||||
prof_point_t end_time;
|
||||
|
||||
InitProfPoint(end_time);
|
||||
total_time = DiffProfPoints(m_ProfStart, end_time);
|
||||
|
||||
t = time(NULL);
|
||||
|
||||
fprintf(fp, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\n");
|
||||
fprintf(fp, "<profile time=\"%d\" uptime=\"%f\">\n", (int)t, total_time);
|
||||
WriteReport(fp, &m_Natives, "natives");
|
||||
WriteReport(fp, &m_Callbacks, "callbacks");
|
||||
WriteReport(fp, &m_Functions, "functions");
|
||||
fprintf(fp, "</profile>\n");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void ProfileEngine::WriteReport(FILE *fp, ProfileReport *report, const char *name)
|
||||
{
|
||||
size_t i, num;
|
||||
prof_atom_report_t *ar;
|
||||
char new_name[512];
|
||||
|
||||
fprintf(fp, " <report name=\"%s\">\n", name);
|
||||
|
||||
num = report->GetNumReports();
|
||||
for (i = 0; i < num; i++)
|
||||
{
|
||||
ar = report->GetReport(i);
|
||||
|
||||
strncopy(new_name, ar->atom_name, sizeof(new_name));
|
||||
UTIL_ReplaceAll(new_name, sizeof(new_name), "<", "<", true);
|
||||
UTIL_ReplaceAll(new_name, sizeof(new_name), ">", ">", true);
|
||||
|
||||
fprintf(fp, " <item name=\"%s\" numcalls=\"%d\" mintime=\"%f\" maxtime=\"%f\" totaltime=\"%f\"/>\n",
|
||||
new_name,
|
||||
ar->num_calls,
|
||||
ar->min_time,
|
||||
ar->max_time,
|
||||
ar->total_time);
|
||||
}
|
||||
|
||||
fprintf(fp, " </report>\n");
|
||||
}
|
||||
|
||||
ProfileReport::~ProfileReport()
|
||||
{
|
||||
for (size_t i = 0; i < m_Reports.size(); i++)
|
||||
{
|
||||
delete m_Reports[i];
|
||||
}
|
||||
}
|
||||
|
||||
void ProfileReport::Clear()
|
||||
{
|
||||
m_ReportLookup.clear();
|
||||
for (size_t i = 0; i < m_Reports.size(); i++)
|
||||
{
|
||||
delete m_Reports[i];
|
||||
}
|
||||
m_Reports.clear();
|
||||
}
|
||||
|
||||
size_t ProfileReport::GetNumReports()
|
||||
{
|
||||
return m_Reports.size();
|
||||
}
|
||||
|
||||
prof_atom_report_t *ProfileReport::GetReport(size_t i)
|
||||
{
|
||||
return m_Reports[i];
|
||||
}
|
||||
|
||||
void ProfileReport::SaveAtom(const prof_atom_t &atom)
|
||||
{
|
||||
double atom_time;
|
||||
char full_name[256];
|
||||
prof_atom_report_t *report;
|
||||
|
||||
if (atom.atom_type == SP_PROF_NATIVES)
|
||||
{
|
||||
smcore.strncopy(full_name, atom.name, sizeof(full_name));
|
||||
}
|
||||
else
|
||||
{
|
||||
IPlugin *pl;
|
||||
const char *file;
|
||||
|
||||
file = "unknown";
|
||||
if ((pl = pluginsys->FindPluginByContext(atom.ctx)) != NULL)
|
||||
{
|
||||
file = pl->GetFilename();
|
||||
}
|
||||
|
||||
smcore.Format(full_name, sizeof(full_name), "%s!%s", file, atom.name);
|
||||
}
|
||||
|
||||
atom_time = CalcAtomTime(atom);
|
||||
|
||||
if (!m_ReportLookup.retrieve(full_name, &report))
|
||||
{
|
||||
report = new prof_atom_report_t;
|
||||
|
||||
smcore.strncopy(report->atom_name, full_name, sizeof(report->atom_name));
|
||||
report->max_time = atom_time;
|
||||
report->min_time = atom_time;
|
||||
report->num_calls = 1;
|
||||
report->total_time = atom_time;
|
||||
|
||||
m_ReportLookup.insert(full_name, report);
|
||||
m_Reports.push_back(report);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (atom_time > report->max_time)
|
||||
{
|
||||
report->max_time = atom_time;
|
||||
}
|
||||
if (atom_time < report->min_time)
|
||||
{
|
||||
report->min_time = atom_time;
|
||||
}
|
||||
report->num_calls++;
|
||||
report->total_time += atom_time;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,136 @@
|
||||
/**
|
||||
* vim: set ts=4 sw=4 tw=99 noet :
|
||||
* =============================================================================
|
||||
* SourceMod
|
||||
* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
|
||||
* =============================================================================
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, version 3.0, as published by the
|
||||
* Free Software Foundation.
|
||||
*
|
||||
* 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/>.
|
||||
*
|
||||
* As a special exception, AlliedModders LLC gives you permission to link the
|
||||
* code of this program (as well as its derivative works) to "Half-Life 2," the
|
||||
* "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
|
||||
* by the Valve Corporation. You must obey the GNU General Public License in
|
||||
* all respects for all other code used. Additionally, AlliedModders LLC grants
|
||||
* this exception to all derivative works. AlliedModders LLC defines further
|
||||
* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
|
||||
* or <http://www.sourcemod.net/license.php>.
|
||||
*
|
||||
* Version: $Id$
|
||||
*/
|
||||
|
||||
#ifndef _INCLUDE_SOURCEMOD_PLUGIN_PROFILER_H_
|
||||
#define _INCLUDE_SOURCEMOD_PLUGIN_PROFILER_H_
|
||||
|
||||
#include <sp_vm_api.h>
|
||||
#include <sm_platform.h>
|
||||
#include <sh_vector.h>
|
||||
#include <sh_stack.h>
|
||||
#include <sm_namehashset.h>
|
||||
#include <stdio.h>
|
||||
#include "common_logic.h"
|
||||
#include <IRootConsoleMenu.h>
|
||||
|
||||
using namespace SourcePawn;
|
||||
using namespace SourceHook;
|
||||
|
||||
struct prof_point_t
|
||||
{
|
||||
#if defined PLATFORM_WINDOWS
|
||||
LARGE_INTEGER value;
|
||||
#elif defined PLATFORM_POSIX
|
||||
struct timeval value;
|
||||
#endif
|
||||
bool is_set;
|
||||
};
|
||||
|
||||
struct prof_atom_t
|
||||
{
|
||||
int atom_type; /* Type of object we're profiling */
|
||||
int atom_serial; /* Serial number, if appropriate */
|
||||
sp_context_t *ctx; /* Plugin context. */
|
||||
const char *name; /* Name of the function */
|
||||
prof_point_t start; /* Start time */
|
||||
prof_point_t end; /* End time */
|
||||
double base_time; /* Known time from children or pausing. */
|
||||
};
|
||||
|
||||
struct prof_atom_report_t
|
||||
{
|
||||
char atom_name[256]; /* Full name to shove to logs */
|
||||
double total_time; /* Total time spent executing, in s */
|
||||
unsigned int num_calls; /* Number of invocations */
|
||||
double min_time; /* Min time spent in one call, in s */
|
||||
double max_time; /* Max time spent in one call, in s */
|
||||
|
||||
static inline bool matches(const char *name, const prof_atom_report_t *report)
|
||||
{
|
||||
return strcmp(report->atom_name, name) == 0;
|
||||
}
|
||||
};
|
||||
|
||||
class ProfileReport
|
||||
{
|
||||
public:
|
||||
~ProfileReport();
|
||||
public:
|
||||
void SaveAtom(const prof_atom_t &atom);
|
||||
size_t GetNumReports();
|
||||
prof_atom_report_t *GetReport(size_t i);
|
||||
void Clear();
|
||||
private:
|
||||
NameHashSet<prof_atom_report_t *> m_ReportLookup;
|
||||
CVector<prof_atom_report_t *> m_Reports;
|
||||
};
|
||||
|
||||
class ProfileEngine :
|
||||
public SMGlobalClass,
|
||||
public IRootConsoleCommand,
|
||||
public IProfiler
|
||||
{
|
||||
public:
|
||||
ProfileEngine();
|
||||
public:
|
||||
bool IsEnabled();
|
||||
bool GenerateReport(FILE *fp);
|
||||
void Clear();
|
||||
public: //SMGlobalClass
|
||||
void OnSourceModAllInitialized();
|
||||
void OnSourceModShutdown();
|
||||
public: //IRootConsoleCommand
|
||||
void OnRootConsoleCommand2(const char *cmdname, const ICommandArgs *command);
|
||||
public: //IProfiler
|
||||
void OnNativeBegin(IPluginContext *pContext, sp_native_t *native);
|
||||
void OnNativeEnd() ;
|
||||
void OnFunctionBegin(IPluginContext *pContext, const char *name);
|
||||
void OnFunctionEnd();
|
||||
int OnCallbackBegin(IPluginContext *pContext, sp_public_t *pubfunc);
|
||||
void OnCallbackEnd(int serial);
|
||||
private:
|
||||
void PushProfileStack(IPluginContext *ctx, int type, const char *name);
|
||||
void PopProfileStack(ProfileReport *reporter);
|
||||
void PauseParent();
|
||||
void ResumeParent(double addTime);
|
||||
void WriteReport(FILE *fp, ProfileReport *report, const char *name);
|
||||
private:
|
||||
CStack<prof_atom_t> m_AtomStack;
|
||||
ProfileReport m_Callbacks;
|
||||
ProfileReport m_Functions;
|
||||
ProfileReport m_Natives;
|
||||
int m_serial;
|
||||
prof_point_t m_ProfStart;
|
||||
};
|
||||
|
||||
extern IProfiler *sm_profiler;
|
||||
|
||||
#endif //_INCLUDE_SOURCEMOD_PLUGIN_PROFILER_H_
|
||||
@@ -375,7 +375,7 @@ PassRef<Native> ShareSystem::AddNativeToCache(CNativeOwner *pOwner, const sp_nat
|
||||
if (i.found())
|
||||
return NULL;
|
||||
|
||||
Ref<Native> entry = new Native(pOwner, ntv);
|
||||
Ref<Native> entry = Newborn<Native>(new Native(pOwner, ntv));
|
||||
m_NtvCache.insert(ntv->name, entry);
|
||||
return entry;
|
||||
}
|
||||
@@ -415,7 +415,7 @@ PassRef<Native> ShareSystem::AddFakeNative(IPluginFunction *pFunc, const char *n
|
||||
|
||||
CNativeOwner *owner = g_PluginSys.GetPluginByCtx(fake->ctx->GetContext());
|
||||
|
||||
entry = new Native(owner, fake.take());
|
||||
entry = Newborn<Native>(new Native(owner, fake.take()));
|
||||
m_NtvCache.insert(name, entry);
|
||||
|
||||
return entry;
|
||||
|
||||
@@ -1077,7 +1077,7 @@ const char *TextParsers::GetSMCErrorString(SMCError err)
|
||||
NULL,
|
||||
"Stream failed to open",
|
||||
"Stream returned read error",
|
||||
"Callback error",
|
||||
NULL,
|
||||
"Un-quoted section has invalid tokens",
|
||||
"Section declared without header",
|
||||
"Section declared with unknown tokens",
|
||||
|
||||
+13
-21
@@ -96,11 +96,11 @@ void CPhraseFile::ParseWarning(const char *message, ...)
|
||||
|
||||
if (!m_FileLogged)
|
||||
{
|
||||
logger->LogError("[SM] Warning(s) encountered in translation file \"%s\"", m_File.c_str());
|
||||
smcore.LogError("[SM] Warning(s) encountered in translation file \"%s\"", m_File.c_str());
|
||||
m_FileLogged = true;
|
||||
}
|
||||
|
||||
logger->LogError("[SM] %s", buffer);
|
||||
smcore.LogError("[SM] %s", buffer);
|
||||
}
|
||||
|
||||
void CPhraseFile::ReparseFile()
|
||||
@@ -142,8 +142,8 @@ void CPhraseFile::ReparseFile()
|
||||
msg = m_ParseError.c_str();
|
||||
}
|
||||
|
||||
logger->LogError("[SM] Fatal error encountered parsing translation file \"%s\"", m_File.c_str());
|
||||
logger->LogError("[SM] Error (line %d, column %d): %s", states.line, states.col, msg);
|
||||
smcore.LogError("[SM] Fatal error encountered parsing translation file \"%s\"", m_File.c_str());
|
||||
smcore.LogError("[SM] Error (line %d, column %d): %s", states.line, states.col, msg);
|
||||
}
|
||||
|
||||
const char *code;
|
||||
@@ -175,10 +175,10 @@ void CPhraseFile::ReparseFile()
|
||||
msg = m_ParseError.c_str();
|
||||
}
|
||||
|
||||
logger->LogError("[SM] Fatal error encountered parsing translation file \"%s/%s\"",
|
||||
smcore.LogError("[SM] Fatal error encountered parsing translation file \"%s/%s\"",
|
||||
code,
|
||||
m_File.c_str());
|
||||
logger->LogError("[SM] Error (line %d, column %d): %s",
|
||||
smcore.LogError("[SM] Error (line %d, column %d): %s",
|
||||
states.line,
|
||||
states.col,
|
||||
msg);
|
||||
@@ -831,13 +831,13 @@ void Translator::RebuildLanguageDatabase()
|
||||
str_err = m_CustomError.c_str();
|
||||
}
|
||||
|
||||
logger->LogError("[SM] Failed to parse language header file: \"%s\"", path);
|
||||
logger->LogError("[SM] Parse error (line %d, column %d): %s", states.line, states.col, str_err);
|
||||
smcore.LogError("[SM] Failed to parse language header file: \"%s\"", path);
|
||||
smcore.LogError("[SM] Parse error (line %d, column %d): %s", states.line, states.col, str_err);
|
||||
}
|
||||
|
||||
if (!m_LCodeLookup.retrieve(m_InitialLang, &m_ServerLang))
|
||||
{
|
||||
logger->LogError("Server language was set to bad language \"%s\" -- reverting to English", m_InitialLang);
|
||||
smcore.LogError("Server language was set to bad language \"%s\" -- reverting to English", m_InitialLang);
|
||||
|
||||
smcore.strncopy(m_InitialLang, "en", sizeof(m_InitialLang));
|
||||
m_ServerLang = SOURCEMOD_LANGUAGE_ENGLISH;
|
||||
@@ -845,7 +845,7 @@ void Translator::RebuildLanguageDatabase()
|
||||
|
||||
if (!m_Languages.size())
|
||||
{
|
||||
logger->LogError("[SM] Fatal error, no languages found! Translation will not work.");
|
||||
smcore.LogError("[SM] Fatal error, no languages found! Translation will not work.");
|
||||
}
|
||||
|
||||
for (size_t i=0; i<m_Files.size(); i++)
|
||||
@@ -872,7 +872,7 @@ SMCResult Translator::ReadSMC_NewSection(const SMCStates *states, const char *na
|
||||
|
||||
if (!m_InLanguageSection)
|
||||
{
|
||||
logger->LogError("[SM] Warning: Unrecognized section \"%s\" in languages.cfg", name);
|
||||
smcore.LogError("[SM] Warning: Unrecognized section \"%s\" in languages.cfg", name);
|
||||
}
|
||||
|
||||
return SMCResult_Continue;
|
||||
@@ -887,14 +887,6 @@ SMCResult Translator::ReadSMC_LeavingSection(const SMCStates *states)
|
||||
|
||||
SMCResult Translator::ReadSMC_KeyValue(const SMCStates *states, const char *key, const char *value)
|
||||
{
|
||||
size_t len = strlen(key);
|
||||
|
||||
if (len >= sizeof(((Language *)0)->m_code2))
|
||||
{
|
||||
logger->LogError("[SM] Warning encountered parsing languages.cfg file.");
|
||||
logger->LogError("[SM] Invalid language code \"%s\" is too long.", key);
|
||||
}
|
||||
|
||||
AddLanguage(key, value);
|
||||
|
||||
return SMCResult_Continue;
|
||||
@@ -1033,11 +1025,11 @@ bool CoreTranslate(char *buffer, size_t maxlength, const char *format, unsigned
|
||||
{
|
||||
if (fail_phrase != NULL)
|
||||
{
|
||||
logger->LogError("[SM] Could not find core phrase: %s", fail_phrase);
|
||||
smcore.LogError("[SM] Could not find core phrase: %s", fail_phrase);
|
||||
}
|
||||
else
|
||||
{
|
||||
logger->LogError("[SM] Unknown fatal error while translating a core phrase.");
|
||||
smcore.LogError("[SM] Unknown fatal error while translating a core phrase.");
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
@@ -54,7 +54,7 @@ enum PhraseParseState
|
||||
|
||||
struct Language
|
||||
{
|
||||
char m_code2[32];
|
||||
char m_code2[4];
|
||||
int m_CanonicalName;
|
||||
};
|
||||
|
||||
|
||||
@@ -35,6 +35,7 @@
|
||||
#include <stdarg.h>
|
||||
#include "common_logic.h"
|
||||
#include "TextParsers.h"
|
||||
#include "Profiler.h"
|
||||
#include "sm_crc32.h"
|
||||
#include "MemoryUtils.h"
|
||||
#include "stringutil.h"
|
||||
@@ -49,8 +50,6 @@
|
||||
#include "ExtensionSys.h"
|
||||
#include "ForwardSys.h"
|
||||
#include "AdminCache.h"
|
||||
#include "ProfileTools.h"
|
||||
#include "Logger.h"
|
||||
|
||||
sm_core_t smcore;
|
||||
IHandleSys *handlesys = &g_HandleSys;
|
||||
@@ -73,9 +72,6 @@ ISourcePawnEngine *g_pSourcePawn;
|
||||
ISourcePawnEngine2 *g_pSourcePawn2;
|
||||
CNativeOwner g_CoreNatives;
|
||||
IScriptManager *scripts = &g_PluginSys;
|
||||
IExtensionSys *extsys = &g_Extensions;
|
||||
ILogger *logger = &g_Logger;
|
||||
IMenuManager *menus;
|
||||
|
||||
static void AddCorePhraseFile(const char *filename)
|
||||
{
|
||||
@@ -108,20 +104,16 @@ static void DumpHandles(void (*dumpfn)(const char *fmt, ...))
|
||||
g_HandleSys.Dump(dumpfn);
|
||||
}
|
||||
|
||||
static bool DumpAdminCache(const char *filename)
|
||||
static void DumpAdminCache(FILE *f)
|
||||
{
|
||||
return g_Admins.DumpCache(filename);
|
||||
}
|
||||
|
||||
static void RegisterProfiler(IProfilingTool *tool)
|
||||
{
|
||||
g_ProfileToolManager.RegisterTool(tool);
|
||||
g_Admins.DumpCache(f);
|
||||
}
|
||||
|
||||
static sm_logic_t logic =
|
||||
{
|
||||
NULL,
|
||||
g_pThreader,
|
||||
sm_profiler,
|
||||
&g_Translator,
|
||||
stristr,
|
||||
CoreTranslate,
|
||||
@@ -136,7 +128,6 @@ static sm_logic_t logic =
|
||||
AddNatives,
|
||||
DumpHandles,
|
||||
DumpAdminCache,
|
||||
RegisterProfiler,
|
||||
&g_PluginSys,
|
||||
&g_ShareSys,
|
||||
&g_Extensions,
|
||||
@@ -144,7 +135,6 @@ static sm_logic_t logic =
|
||||
&g_Forwards,
|
||||
&g_Admins,
|
||||
NULL,
|
||||
&g_Logger,
|
||||
-1.0f
|
||||
};
|
||||
|
||||
@@ -163,7 +153,6 @@ static void logic_init(const sm_core_t* core, sm_logic_t* _logic)
|
||||
timersys = core->timersys;
|
||||
playerhelpers = core->playerhelpers;
|
||||
gamehelpers = core->gamehelpers;
|
||||
menus = core->menus;
|
||||
g_pSourcePawn = *core->spe1;
|
||||
g_pSourcePawn2 = *core->spe2;
|
||||
SMGlobalClass::head = core->listeners;
|
||||
|
||||
@@ -53,9 +53,6 @@ extern IPlayerManager *playerhelpers;
|
||||
extern IAdminSystem *adminsys;
|
||||
extern IGameHelpers *gamehelpers;
|
||||
extern IScriptManager *scripts;
|
||||
extern IExtensionSys *extsys;
|
||||
extern ILogger *logger;
|
||||
extern IMenuManager *menus;
|
||||
|
||||
#endif /* _INCLUDE_SOURCEMOD_COMMON_LOGIC_H_ */
|
||||
|
||||
|
||||
@@ -1,95 +0,0 @@
|
||||
/**
|
||||
* vim: set ts=4 sw=4 tw=99 noet :
|
||||
* =============================================================================
|
||||
* SourceMod
|
||||
* Copyright (C) 2004-2014 AlliedModders LLC. All rights reserved.
|
||||
* =============================================================================
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, version 3.0, as published by the
|
||||
* Free Software Foundation.
|
||||
*
|
||||
* 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/>.
|
||||
*
|
||||
* As a special exception, AlliedModders LLC gives you permission to link the
|
||||
* code of this program (as well as its derivative works) to "Half-Life 2," the
|
||||
* "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
|
||||
* by the Valve Corporation. You must obey the GNU General Public License in
|
||||
* all respects for all other code used. Additionally, AlliedModders LLC grants
|
||||
* this exception to all derivative works. AlliedModders LLC defines further
|
||||
* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
|
||||
* or <http://www.sourcemod.net/license.php>.
|
||||
*
|
||||
* Version: $Id$
|
||||
*/
|
||||
#ifndef _include_sourcemod_handle_helpers_h_
|
||||
#define _include_sourcemod_handle_helpers_h_
|
||||
|
||||
#include "common_logic.h"
|
||||
|
||||
// T must be a pointer type.
|
||||
template <typename T>
|
||||
class OpenHandle
|
||||
{
|
||||
public:
|
||||
OpenHandle()
|
||||
: t_(),
|
||||
error_(HandleError_None)
|
||||
{}
|
||||
explicit OpenHandle(T *t)
|
||||
: t_(t),
|
||||
error_(HandleError_None)
|
||||
{}
|
||||
OpenHandle(const OpenHandle &other)
|
||||
: t_(other.t_),
|
||||
error_(other.error_)
|
||||
{}
|
||||
OpenHandle(IPluginContext *cx, Handle_t handle, HandleType_t type)
|
||||
: t_(NULL)
|
||||
{
|
||||
HandleSecurity sec(cx->GetIdentity(), g_pCoreIdent);
|
||||
error_ = handlesys->ReadHandle(handle, type, &sec, (void **)&t_);
|
||||
if (error_ != HandleError_None)
|
||||
cx->ThrowNativeError("invalid handle %x (error: %d)", handle, error_);
|
||||
}
|
||||
|
||||
bool Ok() const {
|
||||
return t_ && error_ == HandleError_None;
|
||||
}
|
||||
|
||||
operator T *() const {
|
||||
assert(Ok());
|
||||
return t_;
|
||||
}
|
||||
T *operator *() const {
|
||||
assert(Ok());
|
||||
return t_;
|
||||
}
|
||||
T *operator ->() const {
|
||||
assert(Ok());
|
||||
return t_;
|
||||
}
|
||||
|
||||
OpenHandle &operator =(T *t) {
|
||||
t_ = t;
|
||||
error_ = HandleError_None;
|
||||
return *this;
|
||||
}
|
||||
OpenHandle &operator =(const OpenHandle &other) {
|
||||
t_ = other.t_;
|
||||
error_ = other.error_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
private:
|
||||
T *t_;
|
||||
HandleError error_;
|
||||
};
|
||||
|
||||
#endif // _include_sourcemod_handle_helpers_h_
|
||||
+8
-29
@@ -52,7 +52,7 @@ using namespace SourceHook;
|
||||
* Add 1 to the RHS of this expression to bump the intercom file
|
||||
* This is to prevent mismatching core/logic binaries
|
||||
*/
|
||||
#define SM_LOGIC_MAGIC (0x0F47C0DE - 29)
|
||||
#define SM_LOGIC_MAGIC (0x0F47C0DE - 28)
|
||||
|
||||
#if defined SM_LOGIC
|
||||
class IVEngineServer
|
||||
@@ -83,7 +83,6 @@ class IFileSystem_Logic
|
||||
public:
|
||||
virtual const char *FindFirstEx(const char *pWildCard, const char *pPathID, FileFindHandle_t *pHandle) = 0;
|
||||
virtual const char *FindNext(FileFindHandle_t handle) = 0;
|
||||
virtual bool FindIsDirectory(FileFindHandle_t handle) = 0;
|
||||
virtual void FindClose(FileFindHandle_t handle) = 0;
|
||||
virtual FileHandle_t Open(const char *pFileName, const char *pOptions, const char *pathID = 0) = 0;
|
||||
virtual void Close(FileHandle_t file) = 0;
|
||||
@@ -91,17 +90,6 @@ public:
|
||||
virtual bool EndOfFile(FileHandle_t file) = 0;
|
||||
virtual bool FileExists(const char *pFileName, const char *pPathID = 0) = 0;
|
||||
virtual unsigned int Size(const char *pFileName, const char *pPathID = 0) = 0;
|
||||
virtual int Read(void* pOutput, int size, FileHandle_t file) = 0;
|
||||
virtual int Write(void const* pInput, int size, FileHandle_t file) = 0;
|
||||
virtual void Seek(FileHandle_t file, int post, int seekType) = 0;
|
||||
virtual unsigned int Tell(FileHandle_t file) = 0;
|
||||
virtual int FPrint(FileHandle_t file, const char *pData) = 0;
|
||||
virtual void Flush(FileHandle_t file) = 0;
|
||||
virtual bool IsOk(FileHandle_t file) = 0;
|
||||
virtual void RemoveFile(const char *pRelativePath, const char *pathID = 0) = 0;
|
||||
virtual void RenameFile(char const *pOldPath, char const *pNewPath, const char *pathID = 0) = 0;
|
||||
virtual bool IsDirectory(const char *pFileName, const char *pathID = 0) = 0;
|
||||
virtual void CreateDirHierarchy(const char *path, const char *pathID = 0) = 0;
|
||||
};
|
||||
|
||||
namespace SourceMod
|
||||
@@ -120,7 +108,6 @@ namespace SourceMod
|
||||
class IPhraseCollection;
|
||||
class ITranslator;
|
||||
class IGameConfig;
|
||||
class IMenuManager;
|
||||
}
|
||||
|
||||
class IVEngineServer;
|
||||
@@ -224,15 +211,6 @@ public:
|
||||
virtual void AddRawDependency(IExtension *myself, IdentityToken_t *token, void *iface) = 0;
|
||||
virtual const CVector<IExtension *> *ListExtensions() = 0;
|
||||
virtual void FreeExtensionList(const CVector<IExtension *> *list) = 0;
|
||||
virtual void CallOnCoreMapEnd() = 0;
|
||||
};
|
||||
|
||||
class ILogger
|
||||
{
|
||||
public:
|
||||
virtual void LogMessage(const char *msg, ...) = 0;
|
||||
virtual void LogError(const char *msg, ...) = 0;
|
||||
virtual void LogFatal(const char *msg, ...) = 0;
|
||||
};
|
||||
|
||||
class AutoPluginList
|
||||
@@ -289,17 +267,19 @@ struct sm_core_t
|
||||
ITimerSystem *timersys;
|
||||
IPlayerManager *playerhelpers;
|
||||
IGameHelpers *gamehelpers;
|
||||
IMenuManager *menus;
|
||||
ISourcePawnEngine **spe1;
|
||||
ISourcePawnEngine2 **spe2;
|
||||
/* Functions */
|
||||
ConVar * (*FindConVar)(const char*);
|
||||
unsigned int (*strncopy)(char*, const char*, size_t);
|
||||
char * (*TrimWhitespace)(char *, size_t &);
|
||||
void (*LogError)(const char*, ...);
|
||||
void (*LogFatal)(const char*, ...);
|
||||
void (*Log)(const char*, ...);
|
||||
void (*LogToFile)(FILE *fp, const char*, ...);
|
||||
void (*LogToGame)(const char *message);
|
||||
void (*ConPrint)(const char *message);
|
||||
const char * (*GetCvarString)(ConVar*);
|
||||
bool (*GetCvarBool)(ConVar*);
|
||||
size_t (*Format)(char*, size_t, const char*, ...);
|
||||
size_t (*FormatArgs)(char*, size_t, const char*,va_list ap);
|
||||
bool (*gnprintf)(char *, size_t, const char *, IPhraseCollection *, void **,
|
||||
@@ -337,6 +317,7 @@ struct sm_logic_t
|
||||
{
|
||||
SMGlobalClass *head;
|
||||
IThreader *threader;
|
||||
IProfiler *profiler;
|
||||
ITranslator *translator;
|
||||
const char *(*stristr)(const char *, const char *);
|
||||
bool (*CoreTranslate)(char *, size_t, const char *, unsigned int, size_t *, ...);
|
||||
@@ -345,13 +326,12 @@ struct sm_logic_t
|
||||
char *(*ReplaceEx)(char *, size_t, const char *, size_t, const char *, size_t, bool);
|
||||
size_t (*DecodeHexString)(unsigned char *, size_t, const char *);
|
||||
IGameConfig * (*GetCoreGameConfig)();
|
||||
bool (*OnLogPrint)(const char *msg); // true to supersede
|
||||
bool (*OnLogPrint)(const char *msg); // true to supercede
|
||||
IDebugListener *debugger;
|
||||
void (*GenerateError)(IPluginContext *, cell_t, int, const char *, ...);
|
||||
void (*AddNatives)(sp_nativeinfo_t *natives);
|
||||
void (*DumpHandles)(void (*dumpfn)(const char *fmt, ...));
|
||||
bool (*DumpAdminCache)(const char *filename);
|
||||
void (*RegisterProfiler)(IProfilingTool *tool);
|
||||
void (*DumpAdminCache)(FILE *);
|
||||
IScriptManager *scripts;
|
||||
IShareSys *sharesys;
|
||||
IExtensionSys *extsys;
|
||||
@@ -359,7 +339,6 @@ struct sm_logic_t
|
||||
IForwardManager *forwardsys;
|
||||
IAdminSystem *adminsys;
|
||||
IdentityToken_t *core_ident;
|
||||
ILogger *logger;
|
||||
float sentinel;
|
||||
};
|
||||
|
||||
|
||||
@@ -582,27 +582,5 @@ REGISTER_NATIVES(cellArrayNatives)
|
||||
{"CloneArray", CloneArray},
|
||||
{"FindStringInArray", FindStringInArray},
|
||||
{"FindValueInArray", FindValueInArray},
|
||||
|
||||
// Transitional syntax support.
|
||||
{"ArrayList.ArrayList", CreateArray},
|
||||
{"ArrayList.Clear", ClearArray},
|
||||
{"ArrayList.Length.get", GetArraySize},
|
||||
{"ArrayList.Resize", ResizeArray},
|
||||
{"ArrayList.Get", GetArrayCell},
|
||||
{"ArrayList.GetString", GetArrayString},
|
||||
{"ArrayList.GetArray", GetArrayArray},
|
||||
{"ArrayList.Push", PushArrayCell},
|
||||
{"ArrayList.PushString", PushArrayString},
|
||||
{"ArrayList.PushArray", PushArrayArray},
|
||||
{"ArrayList.Set", SetArrayCell},
|
||||
{"ArrayList.SetString", SetArrayString},
|
||||
{"ArrayList.SetArray", SetArrayArray},
|
||||
{"ArrayList.Erase", RemoveFromArray},
|
||||
{"ArrayList.ShiftUp", ShiftArrayUp},
|
||||
{"ArrayList.SwapAt", SwapArrayItems},
|
||||
{"ArrayList.Clone", CloneArray},
|
||||
{"ArrayList.FindString", FindStringInArray},
|
||||
{"ArrayList.FindValue", FindValueInArray},
|
||||
|
||||
{NULL, NULL},
|
||||
};
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/**
|
||||
* vim: set ts=4 sw=4 tw=99 noet :
|
||||
* vim: set ts=4 :
|
||||
* =============================================================================
|
||||
* SourceMod
|
||||
* Copyright (C) 2004-2014 AlliedModders LLC. All rights reserved.
|
||||
* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
|
||||
* =============================================================================
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under
|
||||
@@ -32,7 +32,6 @@
|
||||
#include <stdlib.h>
|
||||
#include "common_logic.h"
|
||||
#include "CellArray.h"
|
||||
#include "handle_helpers.h"
|
||||
|
||||
HandleType_t htCellStack;
|
||||
|
||||
@@ -294,79 +293,6 @@ static cell_t IsStackEmpty(IPluginContext *pContext, const cell_t *params)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static cell_t ArrayStack_Pop(IPluginContext *pContext, const cell_t *params)
|
||||
{
|
||||
OpenHandle<CellArray> array(pContext, params[1], htCellStack);
|
||||
if (!array.Ok())
|
||||
return 0;
|
||||
|
||||
if (array->size() == 0)
|
||||
return pContext->ThrowNativeError("stack is empty");
|
||||
|
||||
cell_t *blk = array->at(array->size() - 1);
|
||||
cell_t idx = (size_t)params[2];
|
||||
|
||||
cell_t rval;
|
||||
if (params[3] == 0) {
|
||||
if (idx >= array->blocksize())
|
||||
return pContext->ThrowNativeError("Invalid block %d (blocksize: %d)", idx, array->blocksize());
|
||||
rval = blk[idx];
|
||||
} else {
|
||||
if (idx >= array->blocksize() * 4)
|
||||
return pContext->ThrowNativeError("Invalid byte %d (blocksize: %d bytes)", idx, array->blocksize() * 4);
|
||||
rval = (cell_t)*((char *)blk + idx);
|
||||
}
|
||||
|
||||
array->remove(array->size() - 1);
|
||||
return rval;
|
||||
}
|
||||
|
||||
static cell_t ArrayStack_PopString(IPluginContext *pContext, const cell_t *params)
|
||||
{
|
||||
OpenHandle<CellArray> array(pContext, params[1], htCellStack);
|
||||
if (!array.Ok())
|
||||
return 0;
|
||||
|
||||
if (array->size() == 0)
|
||||
return pContext->ThrowNativeError("stack is empty");
|
||||
|
||||
size_t idx = array->size() - 1;
|
||||
cell_t *blk = array->at(idx);
|
||||
|
||||
cell_t *pWritten;
|
||||
pContext->LocalToPhysAddr(params[4], &pWritten);
|
||||
|
||||
size_t numWritten;
|
||||
pContext->StringToLocalUTF8(params[2], params[3], (char *)blk, &numWritten);
|
||||
*pWritten = (cell_t)numWritten;
|
||||
array->remove(idx);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static cell_t ArrayStack_PopArray(IPluginContext *pContext, const cell_t *params)
|
||||
{
|
||||
OpenHandle<CellArray> array(pContext, params[1], htCellStack);
|
||||
if (!array.Ok())
|
||||
return 0;
|
||||
|
||||
if (array->size() == 0)
|
||||
return pContext->ThrowNativeError("stack is empty");
|
||||
|
||||
cell_t *addr;
|
||||
pContext->LocalToPhysAddr(params[2], &addr);
|
||||
|
||||
size_t idx = array->size() - 1;
|
||||
cell_t *blk = array->at(idx);
|
||||
size_t indexes = array->blocksize();
|
||||
|
||||
if (params[3] != -1 && (size_t)params[3] <= array->blocksize())
|
||||
indexes = params[3];
|
||||
|
||||
memcpy(addr, blk, sizeof(cell_t) * indexes);
|
||||
array->remove(idx);
|
||||
return 0;
|
||||
}
|
||||
|
||||
REGISTER_NATIVES(cellStackNatives)
|
||||
{
|
||||
{"CreateStack", CreateStack},
|
||||
@@ -377,16 +303,5 @@ REGISTER_NATIVES(cellStackNatives)
|
||||
{"PushStackArray", PushStackArray},
|
||||
{"PushStackCell", PushStackCell},
|
||||
{"PushStackString", PushStackString},
|
||||
|
||||
// Transitional syntax support.
|
||||
{"ArrayStack.ArrayStack", CreateStack},
|
||||
{"ArrayStack.Pop", ArrayStack_Pop},
|
||||
{"ArrayStack.PopString", ArrayStack_PopString},
|
||||
{"ArrayStack.PopArray", ArrayStack_PopArray},
|
||||
{"ArrayStack.Push", PushStackCell},
|
||||
{"ArrayStack.PushString", PushStackString},
|
||||
{"ArrayStack.PushArray", PushStackArray},
|
||||
{"ArrayStack.Empty.get", IsStackEmpty},
|
||||
|
||||
{NULL, NULL},
|
||||
};
|
||||
|
||||
+3
-144
@@ -37,7 +37,6 @@
|
||||
#include "sm_memtable.h"
|
||||
|
||||
HandleType_t htCellTrie;
|
||||
HandleType_t htSnapshot;
|
||||
|
||||
enum EntryType
|
||||
{
|
||||
@@ -163,27 +162,11 @@ private:
|
||||
cell_t data_;
|
||||
};
|
||||
|
||||
struct CellTrie
|
||||
struct CellTrie : public ke::Refcounted<CellTrie>
|
||||
{
|
||||
StringHashMap<Entry> map;
|
||||
};
|
||||
|
||||
struct TrieSnapshot
|
||||
{
|
||||
TrieSnapshot()
|
||||
: strings(128)
|
||||
{ }
|
||||
|
||||
size_t mem_usage()
|
||||
{
|
||||
return length * sizeof(int) + strings.GetMemTable()->GetMemUsage();
|
||||
}
|
||||
|
||||
size_t length;
|
||||
ke::AutoArray<int> keys;
|
||||
BaseStringTable strings;
|
||||
};
|
||||
|
||||
class TrieHelpers :
|
||||
public SMGlobalClass,
|
||||
public IHandleTypeDispatch
|
||||
@@ -192,11 +175,9 @@ public: //SMGlobalClass
|
||||
void OnSourceModAllInitialized()
|
||||
{
|
||||
htCellTrie = handlesys->CreateType("Trie", this, 0, NULL, NULL, g_pCoreIdent, NULL);
|
||||
htSnapshot = handlesys->CreateType("TrieSnapshot", this, 0, NULL, NULL, g_pCoreIdent, NULL);
|
||||
}
|
||||
void OnSourceModShutdown()
|
||||
{
|
||||
handlesys->RemoveType(htSnapshot, g_pCoreIdent);
|
||||
handlesys->RemoveType(htCellTrie, g_pCoreIdent);
|
||||
}
|
||||
public: //IHandleTypeDispatch
|
||||
@@ -204,10 +185,8 @@ public: //IHandleTypeDispatch
|
||||
{
|
||||
if (type == htCellTrie)
|
||||
{
|
||||
delete (CellTrie *)object;
|
||||
} else {
|
||||
TrieSnapshot *snapshot = (TrieSnapshot *)object;
|
||||
delete snapshot;
|
||||
CellTrie *pTrie = (CellTrie *)object;
|
||||
pTrie->Release();
|
||||
}
|
||||
}
|
||||
bool GetHandleApproxSize(HandleType_t type, void *object, unsigned int *pSize)
|
||||
@@ -216,9 +195,6 @@ public: //IHandleTypeDispatch
|
||||
{
|
||||
CellTrie *pArray = (CellTrie *)object;
|
||||
*pSize = sizeof(CellTrie) + pArray->map.mem_usage();
|
||||
} else {
|
||||
TrieSnapshot *snapshot = (TrieSnapshot *)object;
|
||||
*pSize = sizeof(TrieSnapshot) + snapshot->mem_usage();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -539,100 +515,6 @@ static cell_t GetTrieSize(IPluginContext *pContext, const cell_t *params)
|
||||
return pTrie->map.elements();
|
||||
}
|
||||
|
||||
static cell_t CreateTrieSnapshot(IPluginContext *pContext, const cell_t *params)
|
||||
{
|
||||
HandleError err;
|
||||
HandleSecurity sec = HandleSecurity(pContext->GetIdentity(), g_pCoreIdent);
|
||||
|
||||
Handle_t hndl = params[1];
|
||||
|
||||
CellTrie *pTrie;
|
||||
if ((err = handlesys->ReadHandle(hndl, htCellTrie, &sec, (void **)&pTrie))
|
||||
!= HandleError_None)
|
||||
{
|
||||
return pContext->ThrowNativeError("Invalid Handle %x (error %d)", hndl, err);
|
||||
}
|
||||
|
||||
TrieSnapshot *snapshot = new TrieSnapshot;
|
||||
snapshot->length = pTrie->map.elements();
|
||||
snapshot->keys = new int[snapshot->length];
|
||||
size_t i = 0;
|
||||
for (StringHashMap<Entry>::iterator iter = pTrie->map.iter(); !iter.empty(); iter.next(), i++)
|
||||
snapshot->keys[i] = snapshot->strings.AddString(iter->key.chars(), iter->key.length());
|
||||
assert(i == snapshot->length);
|
||||
|
||||
if ((hndl = handlesys->CreateHandle(htSnapshot, snapshot, pContext->GetIdentity(), g_pCoreIdent, NULL))
|
||||
== BAD_HANDLE)
|
||||
{
|
||||
delete snapshot;
|
||||
return BAD_HANDLE;
|
||||
}
|
||||
|
||||
return hndl;
|
||||
}
|
||||
|
||||
static cell_t TrieSnapshotLength(IPluginContext *pContext, const cell_t *params)
|
||||
{
|
||||
HandleError err;
|
||||
HandleSecurity sec = HandleSecurity(pContext->GetIdentity(), g_pCoreIdent);
|
||||
|
||||
Handle_t hndl = params[1];
|
||||
|
||||
TrieSnapshot *snapshot;
|
||||
if ((err = handlesys->ReadHandle(hndl, htSnapshot, &sec, (void **)&snapshot))
|
||||
!= HandleError_None)
|
||||
{
|
||||
return pContext->ThrowNativeError("Invalid Handle %x (error %d)", hndl, err);
|
||||
}
|
||||
|
||||
return snapshot->length;
|
||||
}
|
||||
|
||||
static cell_t TrieSnapshotKeyBufferSize(IPluginContext *pContext, const cell_t *params)
|
||||
{
|
||||
HandleError err;
|
||||
HandleSecurity sec = HandleSecurity(pContext->GetIdentity(), g_pCoreIdent);
|
||||
|
||||
Handle_t hndl = params[1];
|
||||
|
||||
TrieSnapshot *snapshot;
|
||||
if ((err = handlesys->ReadHandle(hndl, htSnapshot, &sec, (void **)&snapshot))
|
||||
!= HandleError_None)
|
||||
{
|
||||
return pContext->ThrowNativeError("Invalid Handle %x (error %d)", hndl, err);
|
||||
}
|
||||
|
||||
unsigned index = params[2];
|
||||
if (index >= snapshot->length)
|
||||
return pContext->ThrowNativeError("Invalid index %d", index);
|
||||
|
||||
return strlen(snapshot->strings.GetString(snapshot->keys[index])) + 1;
|
||||
}
|
||||
|
||||
static cell_t GetTrieSnapshotKey(IPluginContext *pContext, const cell_t *params)
|
||||
{
|
||||
HandleError err;
|
||||
HandleSecurity sec = HandleSecurity(pContext->GetIdentity(), g_pCoreIdent);
|
||||
|
||||
Handle_t hndl = params[1];
|
||||
|
||||
TrieSnapshot *snapshot;
|
||||
if ((err = handlesys->ReadHandle(hndl, htSnapshot, &sec, (void **)&snapshot))
|
||||
!= HandleError_None)
|
||||
{
|
||||
return pContext->ThrowNativeError("Invalid Handle %x (error %d)", hndl, err);
|
||||
}
|
||||
|
||||
unsigned index = params[2];
|
||||
if (index >= snapshot->length)
|
||||
return pContext->ThrowNativeError("Invalid index %d", index);
|
||||
|
||||
size_t written;
|
||||
const char *str = snapshot->strings.GetString(snapshot->keys[index]);
|
||||
pContext->StringToLocalUTF8(params[3], params[4], str, &written);
|
||||
return written;
|
||||
}
|
||||
|
||||
REGISTER_NATIVES(trieNatives)
|
||||
{
|
||||
{"ClearTrie", ClearTrie},
|
||||
@@ -645,28 +527,5 @@ REGISTER_NATIVES(trieNatives)
|
||||
{"SetTrieString", SetTrieString},
|
||||
{"SetTrieValue", SetTrieValue},
|
||||
{"GetTrieSize", GetTrieSize},
|
||||
|
||||
{"CreateTrieSnapshot", CreateTrieSnapshot},
|
||||
{"TrieSnapshotLength", TrieSnapshotLength},
|
||||
{"TrieSnapshotKeyBufferSize", TrieSnapshotKeyBufferSize},
|
||||
{"GetTrieSnapshotKey", GetTrieSnapshotKey},
|
||||
|
||||
// Transitional syntax support.
|
||||
{"StringMap.StringMap", CreateTrie},
|
||||
{"StringMap.Clear", ClearTrie},
|
||||
{"StringMap.GetArray", GetTrieArray},
|
||||
{"StringMap.GetString", GetTrieString},
|
||||
{"StringMap.GetValue", GetTrieValue},
|
||||
{"StringMap.Remove", RemoveFromTrie},
|
||||
{"StringMap.SetArray", SetTrieArray},
|
||||
{"StringMap.SetString", SetTrieString},
|
||||
{"StringMap.SetValue", SetTrieValue},
|
||||
{"StringMap.Size.get", GetTrieSize},
|
||||
{"StringMap.Snapshot", CreateTrieSnapshot},
|
||||
|
||||
{"StringMapSnapshot.Length.get", TrieSnapshotLength},
|
||||
{"StringMapSnapshot.KeyBufferSize", TrieSnapshotKeyBufferSize},
|
||||
{"StringMapSnapshot.GetKey", GetTrieSnapshotKey},
|
||||
|
||||
{NULL, NULL},
|
||||
};
|
||||
|
||||
@@ -289,20 +289,14 @@ private:
|
||||
Handle_t m_MyHandle;
|
||||
};
|
||||
|
||||
enum AsyncCallbackMode {
|
||||
ACM_Old,
|
||||
ACM_New
|
||||
};
|
||||
|
||||
class TConnectOp : public IDBThreadOperation
|
||||
{
|
||||
public:
|
||||
TConnectOp(IPluginFunction *func, IDBDriver *driver, const char *_dbname, AsyncCallbackMode acm, cell_t data)
|
||||
TConnectOp(IPluginFunction *func, IDBDriver *driver, const char *_dbname, cell_t data)
|
||||
{
|
||||
m_pFunction = func;
|
||||
m_pDriver = driver;
|
||||
m_pDatabase = NULL;
|
||||
m_ACM = acm;
|
||||
m_Data = data;
|
||||
error[0] = '\0';
|
||||
strncopy(dbname, _dbname, sizeof(dbname));
|
||||
@@ -334,8 +328,7 @@ public:
|
||||
{
|
||||
m_pDatabase->Close();
|
||||
}
|
||||
if (m_ACM == ACM_Old)
|
||||
m_pFunction->PushCell(BAD_HANDLE);
|
||||
m_pFunction->PushCell(BAD_HANDLE);
|
||||
m_pFunction->PushCell(BAD_HANDLE);
|
||||
m_pFunction->PushString("Driver is unloading");
|
||||
m_pFunction->PushCell(m_Data);
|
||||
@@ -355,8 +348,7 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
if (m_ACM == ACM_Old)
|
||||
m_pFunction->PushCell(m_pDriver->GetHandle());
|
||||
m_pFunction->PushCell(m_pDriver->GetHandle());
|
||||
m_pFunction->PushCell(hndl);
|
||||
m_pFunction->PushString(hndl == BAD_HANDLE ? error : "");
|
||||
m_pFunction->PushCell(m_Data);
|
||||
@@ -371,7 +363,6 @@ private:
|
||||
IPluginFunction *m_pFunction;
|
||||
IDBDriver *m_pDriver;
|
||||
IDatabase *m_pDatabase;
|
||||
AsyncCallbackMode m_ACM;
|
||||
char dbname[64];
|
||||
char error[255];
|
||||
cell_t m_Data;
|
||||
@@ -410,7 +401,7 @@ static cell_t SQL_Connect(IPluginContext *pContext, const cell_t *params)
|
||||
return hndl;
|
||||
}
|
||||
|
||||
static cell_t ConnectToDbAsync(IPluginContext *pContext, const cell_t *params, AsyncCallbackMode acm)
|
||||
static cell_t SQL_TConnect(IPluginContext *pContext, const cell_t *params)
|
||||
{
|
||||
IPluginFunction *pf = pContext->GetFunctionById(params[1]);
|
||||
if (!pf)
|
||||
@@ -451,8 +442,7 @@ static cell_t ConnectToDbAsync(IPluginContext *pContext, const cell_t *params, A
|
||||
if (!pInfo || !driver)
|
||||
{
|
||||
pf->PushCell(BAD_HANDLE);
|
||||
if (acm == ACM_Old)
|
||||
pf->PushCell(BAD_HANDLE);
|
||||
pf->PushCell(BAD_HANDLE);
|
||||
pf->PushString(error);
|
||||
pf->PushCell(0);
|
||||
pf->Execute(NULL);
|
||||
@@ -467,7 +457,7 @@ static cell_t ConnectToDbAsync(IPluginContext *pContext, const cell_t *params, A
|
||||
}
|
||||
|
||||
/* Finally, add to the thread if we can */
|
||||
TConnectOp *op = new TConnectOp(pf, driver, conf, acm, params[3]);
|
||||
TConnectOp *op = new TConnectOp(pf, driver, conf, params[3]);
|
||||
IPlugin *pPlugin = scripts->FindPluginByContext(pContext->GetContext());
|
||||
if (pPlugin->GetProperty("DisallowDBThreads", NULL)
|
||||
|| !g_DBMan.AddToThreadQueue(op, PrioQueue_High))
|
||||
@@ -481,16 +471,6 @@ static cell_t ConnectToDbAsync(IPluginContext *pContext, const cell_t *params, A
|
||||
return 1;
|
||||
}
|
||||
|
||||
static cell_t SQL_TConnect(IPluginContext *pContext, const cell_t *params)
|
||||
{
|
||||
return ConnectToDbAsync(pContext, params, ACM_Old);
|
||||
}
|
||||
|
||||
static cell_t Database_Connect(IPluginContext *pContext, const cell_t *params)
|
||||
{
|
||||
return ConnectToDbAsync(pContext, params, ACM_New);
|
||||
}
|
||||
|
||||
static cell_t SQL_ConnectEx(IPluginContext *pContext, const cell_t *params)
|
||||
{
|
||||
IDBDriver *driver;
|
||||
@@ -1370,20 +1350,6 @@ static cell_t SQL_ReadDriver(IPluginContext *pContext, const cell_t *params)
|
||||
return driver->GetHandle();
|
||||
}
|
||||
|
||||
static cell_t Database_Driver_get(IPluginContext *pContext, const cell_t *params)
|
||||
{
|
||||
IDatabase *db1=NULL;
|
||||
HandleError err;
|
||||
|
||||
if ((err = g_DBMan.ReadHandle(params[1], DBHandle_Database, (void **)&db1))
|
||||
!= HandleError_None)
|
||||
{
|
||||
return pContext->ThrowNativeError("Invalid database Handle 1/%x (error: %d)", params[1], err);
|
||||
}
|
||||
|
||||
return db1->GetDriver()->GetHandle();
|
||||
}
|
||||
|
||||
static cell_t SQL_CheckConfig(IPluginContext *pContext, const cell_t *params)
|
||||
{
|
||||
char *name;
|
||||
@@ -1777,48 +1743,9 @@ static cell_t SQL_ExecuteTransaction(IPluginContext *pContext, const cell_t *par
|
||||
|
||||
REGISTER_NATIVES(dbNatives)
|
||||
{
|
||||
// Transitional syntax support.
|
||||
{"DBDriver.Find", SQL_GetDriver},
|
||||
{"DBDriver.GetIdentifier", SQL_GetDriverIdent},
|
||||
{"DBDriver.GetProduct", SQL_GetDriverProduct},
|
||||
|
||||
{"DBResultSet.FetchMoreResults", SQL_FetchMoreResults},
|
||||
{"DBResultSet.HasResults.get", SQL_HasResultSet},
|
||||
{"DBResultSet.RowCount.get", SQL_GetRowCount},
|
||||
{"DBResultSet.FieldCount.get", SQL_GetFieldCount},
|
||||
{"DBResultSet.AffectedRows.get", SQL_GetAffectedRows},
|
||||
{"DBResultSet.InsertId.get", SQL_GetInsertId},
|
||||
{"DBResultSet.FieldNameToNum", SQL_FieldNameToNum},
|
||||
{"DBResultSet.FieldNumToName", SQL_FieldNumToName},
|
||||
{"DBResultSet.FetchRow", SQL_FetchRow},
|
||||
{"DBResultSet.MoreRows.get", SQL_MoreRows},
|
||||
{"DBResultSet.Rewind", SQL_Rewind},
|
||||
{"DBResultSet.FetchString", SQL_FetchString},
|
||||
{"DBResultSet.FetchFloat", SQL_FetchFloat},
|
||||
{"DBResultSet.FetchInt", SQL_FetchInt},
|
||||
{"DBResultSet.IsFieldNull", SQL_IsFieldNull},
|
||||
{"DBResultSet.FetchSize", SQL_FetchSize},
|
||||
|
||||
{"Transaction.Transaction", SQL_CreateTransaction},
|
||||
{"Transaction.AddQuery", SQL_AddQuery},
|
||||
|
||||
{"DBStatement.BindInt", SQL_BindParamInt},
|
||||
{"DBStatement.BindFloat", SQL_BindParamFloat},
|
||||
{"DBStatement.BindString", SQL_BindParamString},
|
||||
|
||||
{"Database.Connect", Database_Connect},
|
||||
{"Database.Driver.get", Database_Driver_get},
|
||||
{"Database.SetCharset", SQL_SetCharset},
|
||||
{"Database.Escape", SQL_QuoteString},
|
||||
{"Database.IsSameConnection", SQL_IsSameConnection},
|
||||
{"Database.Execute", SQL_ExecuteTransaction},
|
||||
|
||||
// Note: The callback is ABI compatible so we can re-use the native.
|
||||
{"Database.Query", SQL_TQuery},
|
||||
|
||||
{"SQL_BindParamInt", SQL_BindParamInt},
|
||||
{"SQL_BindParamFloat", SQL_BindParamFloat},
|
||||
{"SQL_BindParamString", SQL_BindParamString},
|
||||
{"SQL_BindParamString", SQL_BindParamString},\
|
||||
{"SQL_CheckConfig", SQL_CheckConfig},
|
||||
{"SQL_Connect", SQL_Connect},
|
||||
{"SQL_ConnectEx", SQL_ConnectEx},
|
||||
|
||||
@@ -148,27 +148,6 @@ static cell_t smn_WritePackString(IPluginContext *pContext, const cell_t *params
|
||||
return 1;
|
||||
}
|
||||
|
||||
static cell_t smn_WritePackFunction(IPluginContext *pContext, const cell_t *params)
|
||||
{
|
||||
Handle_t hndl = static_cast<Handle_t>(params[1]);
|
||||
HandleError herr;
|
||||
HandleSecurity sec;
|
||||
IDataPack *pDataPack;
|
||||
|
||||
sec.pOwner = pContext->GetIdentity();
|
||||
sec.pIdentity = g_pCoreIdent;
|
||||
|
||||
if ((herr = handlesys->ReadHandle(hndl, g_DataPackType, &sec, (void **)&pDataPack))
|
||||
!= HandleError_None)
|
||||
{
|
||||
return pContext->ThrowNativeError("Invalid data pack handle %x (error %d)", hndl, herr);
|
||||
}
|
||||
|
||||
pDataPack->PackFunction(params[2]);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static cell_t smn_ReadPackCell(IPluginContext *pContext, const cell_t *params)
|
||||
{
|
||||
Handle_t hndl = static_cast<Handle_t>(params[1]);
|
||||
@@ -185,7 +164,7 @@ static cell_t smn_ReadPackCell(IPluginContext *pContext, const cell_t *params)
|
||||
return pContext->ThrowNativeError("Invalid data pack handle %x (error %d)", hndl, herr);
|
||||
}
|
||||
|
||||
if (!pDataPack->IsReadable(sizeof(char) + sizeof(size_t) + sizeof(cell_t)))
|
||||
if (!pDataPack->IsReadable(sizeof(size_t) + sizeof(cell_t)))
|
||||
{
|
||||
return pContext->ThrowNativeError("DataPack operation is out of bounds.");
|
||||
}
|
||||
@@ -209,7 +188,7 @@ static cell_t smn_ReadPackFloat(IPluginContext *pContext, const cell_t *params)
|
||||
return pContext->ThrowNativeError("Invalid data pack handle %x (error %d)", hndl, herr);
|
||||
}
|
||||
|
||||
if (!pDataPack->IsReadable(sizeof(char) + sizeof(size_t) + sizeof(float)))
|
||||
if (!pDataPack->IsReadable(sizeof(size_t) + sizeof(float)))
|
||||
{
|
||||
return pContext->ThrowNativeError("DataPack operation is out of bounds.");
|
||||
}
|
||||
@@ -244,30 +223,6 @@ static cell_t smn_ReadPackString(IPluginContext *pContext, const cell_t *params)
|
||||
return 1;
|
||||
}
|
||||
|
||||
static cell_t smn_ReadPackFunction(IPluginContext *pContext, const cell_t *params)
|
||||
{
|
||||
Handle_t hndl = static_cast<Handle_t>(params[1]);
|
||||
HandleError herr;
|
||||
HandleSecurity sec;
|
||||
IDataPack *pDataPack;
|
||||
|
||||
sec.pOwner = pContext->GetIdentity();
|
||||
sec.pIdentity = g_pCoreIdent;
|
||||
|
||||
if ((herr = handlesys->ReadHandle(hndl, g_DataPackType, &sec, (void **)&pDataPack))
|
||||
!= HandleError_None)
|
||||
{
|
||||
return pContext->ThrowNativeError("Invalid data pack handle %x (error %d)", hndl, herr);
|
||||
}
|
||||
|
||||
if (!pDataPack->IsReadable(sizeof(char) + sizeof(size_t) + sizeof(cell_t)))
|
||||
{
|
||||
return pContext->ThrowNativeError("DataPack operation is out of bounds.");
|
||||
}
|
||||
|
||||
return pDataPack->ReadFunction();
|
||||
}
|
||||
|
||||
static cell_t smn_ResetPack(IPluginContext *pContext, const cell_t *params)
|
||||
{
|
||||
Handle_t hndl = static_cast<Handle_t>(params[1]);
|
||||
@@ -363,11 +318,9 @@ REGISTER_NATIVES(datapacknatives)
|
||||
{"WritePackCell", smn_WritePackCell},
|
||||
{"WritePackFloat", smn_WritePackFloat},
|
||||
{"WritePackString", smn_WritePackString},
|
||||
{"WritePackFunction", smn_WritePackFunction},
|
||||
{"ReadPackCell", smn_ReadPackCell},
|
||||
{"ReadPackFloat", smn_ReadPackFloat},
|
||||
{"ReadPackString", smn_ReadPackString},
|
||||
{"ReadPackFunction", smn_ReadPackFunction},
|
||||
{"ResetPack", smn_ResetPack},
|
||||
{"GetPackPosition", smn_GetPackPosition},
|
||||
{"SetPackPosition", smn_SetPackPosition},
|
||||
|
||||
@@ -441,7 +441,6 @@ REGISTER_NATIVES(nativeNatives)
|
||||
{"GetNativeArray", GetNativeArray},
|
||||
{"GetNativeCell", GetNativeCell},
|
||||
{"GetNativeCellRef", GetNativeCellRef},
|
||||
{"GetNativeFunction", GetNativeCell},
|
||||
{"GetNativeString", GetNativeString},
|
||||
{"GetNativeStringLength", GetNativeStringLength},
|
||||
{"FormatNativeString", FormatNativeString},
|
||||
|
||||
+403
-616
File diff suppressed because it is too large
Load Diff
@@ -36,7 +36,6 @@
|
||||
#include "MersenneTwister.h"
|
||||
#include <IPluginSys.h>
|
||||
#include <am-utility.h>
|
||||
#include <am-float.h>
|
||||
|
||||
/****************************************
|
||||
* *
|
||||
|
||||
@@ -53,10 +53,6 @@ static cell_t sm_IsValidHandle(IPluginContext *pContext, const cell_t *params)
|
||||
static cell_t sm_CloseHandle(IPluginContext *pContext, const cell_t *params)
|
||||
{
|
||||
Handle_t hndl = static_cast<Handle_t>(params[1]);
|
||||
|
||||
if (!hndl)
|
||||
return 0;
|
||||
|
||||
HandleSecurity sec;
|
||||
|
||||
sec.pIdentity = NULL;
|
||||
|
||||
@@ -202,8 +202,8 @@ public:
|
||||
{
|
||||
errmsg = "Unknown error";
|
||||
}
|
||||
logger->LogError("[SM] Could not parse file \"%s\"", m_ConfigFile);
|
||||
logger->LogError("[SM] Error on line %d (col %d): %s", states.line, states.col, errmsg);
|
||||
smcore.LogError("[SM] Could not parse file \"%s\"", m_ConfigFile);
|
||||
smcore.LogError("[SM] Error on line %d (col %d): %s", states.line, states.col, errmsg);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
+17
-89
@@ -37,21 +37,12 @@
|
||||
#include <ITranslator.h>
|
||||
#include <sh_string.h>
|
||||
#include <sh_list.h>
|
||||
#include "GameConfigs.h"
|
||||
#include "CellArray.h"
|
||||
#include "AutoHandleRooter.h"
|
||||
|
||||
using namespace SourceHook;
|
||||
using namespace SourceMod;
|
||||
|
||||
#ifndef PRIu64
|
||||
#ifdef _WIN32
|
||||
#define PRIu64 "I64u"
|
||||
#else
|
||||
#define PRIu64 "llu"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
static const int kActivityNone = 0;
|
||||
static const int kActivityNonAdmins = 1; // Show admin activity to non-admins anonymously.
|
||||
static const int kActivityNonAdminsNames = 2; // If 1 is specified, admin names will be shown.
|
||||
@@ -129,7 +120,7 @@ public: //ICommandTargetProcessor
|
||||
Handle_t hndl = handlesys->CreateHandleEx(htCellArray, array, &sec, NULL, NULL);
|
||||
AutoHandleCloner ahc(hndl, sec);
|
||||
if (ahc.getClone() == BAD_HANDLE) {
|
||||
logger->LogError("[SM] Could not allocate a handle (%s, %d)", __FILE__, __LINE__);
|
||||
smcore.LogError("[SM] Could not allocate a handle (%s, %d)", __FILE__, __LINE__);
|
||||
delete array;
|
||||
return false;
|
||||
}
|
||||
@@ -331,17 +322,9 @@ static cell_t sm_GetClientIP(IPluginContext *pCtx, const cell_t *params)
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Must match clients.inc
|
||||
enum class AuthIdType
|
||||
{
|
||||
Engine = 0,
|
||||
Steam2,
|
||||
Steam3,
|
||||
SteamId64,
|
||||
};
|
||||
|
||||
static cell_t SteamIdToLocal(IPluginContext *pCtx, int index, AuthIdType authType, cell_t local_addr, size_t bytes, bool validate)
|
||||
static cell_t sm_GetClientAuthStr(IPluginContext *pCtx, const cell_t *params)
|
||||
{
|
||||
int index = params[1];
|
||||
if ((index < 1) || (index > playerhelpers->GetMaxClients()))
|
||||
{
|
||||
return pCtx->ThrowNativeError("Client index %d is invalid", index);
|
||||
@@ -352,79 +335,25 @@ static cell_t SteamIdToLocal(IPluginContext *pCtx, int index, AuthIdType authTyp
|
||||
{
|
||||
return pCtx->ThrowNativeError("Client %d is not connected", index);
|
||||
}
|
||||
|
||||
const char *authstr;
|
||||
|
||||
switch (authType)
|
||||
{
|
||||
case AuthIdType::Engine:
|
||||
authstr = pPlayer->GetAuthString(validate);
|
||||
if (!authstr || authstr[0] == '\0')
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
pCtx->StringToLocal(local_addr, bytes, authstr);
|
||||
break;
|
||||
case AuthIdType::Steam2:
|
||||
authstr = pPlayer->GetSteam2Id(validate);
|
||||
if (!authstr || authstr[0] == '\0')
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
pCtx->StringToLocal(local_addr, bytes, authstr);
|
||||
break;
|
||||
case AuthIdType::Steam3:
|
||||
authstr = pPlayer->GetSteam3Id(validate);
|
||||
if (!authstr || authstr[0] == '\0')
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
pCtx->StringToLocal(local_addr, bytes, authstr);
|
||||
break;
|
||||
|
||||
case AuthIdType::SteamId64:
|
||||
{
|
||||
if (pPlayer->IsFakeClient() || gamehelpers->IsLANServer())
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint64_t steamId = pPlayer->GetSteamId64(validate);
|
||||
if (steamId == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
char szAuth[64];
|
||||
snprintf(szAuth, sizeof(szAuth), "%" PRIu64, steamId);
|
||||
|
||||
pCtx->StringToLocal(local_addr, bytes, szAuth);
|
||||
}
|
||||
break;
|
||||
}
|
||||
bool validate = true;
|
||||
if (params[0] > 3)
|
||||
{
|
||||
validate = !!params[4];
|
||||
}
|
||||
|
||||
const char *authstr = pPlayer->GetAuthString(validate);
|
||||
|
||||
if (!authstr || authstr[0] == '\0')
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
pCtx->StringToLocal(params[2], static_cast<size_t>(params[3]), authstr);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static cell_t sm_GetClientAuthStr(IPluginContext *pCtx, const cell_t *params)
|
||||
{
|
||||
bool validate = true;
|
||||
if (params[0] >= 4)
|
||||
{
|
||||
validate = !!params[4];
|
||||
}
|
||||
|
||||
return SteamIdToLocal(pCtx, params[1], AuthIdType::Steam2, params[2], (size_t)params[3], validate);
|
||||
}
|
||||
|
||||
static cell_t sm_GetClientAuthId(IPluginContext *pCtx, const cell_t *params)
|
||||
{
|
||||
return SteamIdToLocal(pCtx, params[1], (AuthIdType)params[2], params[3], (size_t)params[4], params[5] != 0);
|
||||
}
|
||||
|
||||
static cell_t sm_GetSteamAccountID(IPluginContext *pCtx, const cell_t *params)
|
||||
{
|
||||
int index = params[1];
|
||||
@@ -1611,7 +1540,6 @@ REGISTER_NATIVES(playernatives)
|
||||
{ "CanUserTarget", CanUserTarget },
|
||||
{ "ChangeClientTeam", ChangeClientTeam },
|
||||
{ "GetClientAuthString", sm_GetClientAuthStr },
|
||||
{ "GetClientAuthId", sm_GetClientAuthId },
|
||||
{ "GetSteamAccountID", sm_GetSteamAccountID },
|
||||
{ "GetClientCount", sm_GetClientCount },
|
||||
{ "GetClientInfo", sm_GetClientInfo },
|
||||
|
||||
@@ -36,7 +36,6 @@
|
||||
#include <stdint.h>
|
||||
#include <sys/time.h>
|
||||
#endif
|
||||
#include "ProfileTools.h"
|
||||
|
||||
struct Profiler
|
||||
{
|
||||
@@ -186,42 +185,12 @@ static cell_t GetProfilerTime(IPluginContext *pContext, const cell_t *params)
|
||||
return sp_ftoc(fTime);
|
||||
}
|
||||
|
||||
static cell_t EnterProfilingEvent(IPluginContext *pContext, const cell_t *params)
|
||||
{
|
||||
char *group;
|
||||
pContext->LocalToString(params[1], &group);
|
||||
|
||||
char *name;
|
||||
pContext->LocalToString(params[2], &name);
|
||||
|
||||
const char *groupname = NULL;
|
||||
if (strcmp(group, "all") != 0)
|
||||
groupname = group;
|
||||
|
||||
g_ProfileToolManager.EnterScope(groupname, name);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static cell_t LeaveProfilingEvent(IPluginContext *pContext, const cell_t *params)
|
||||
{
|
||||
g_ProfileToolManager.LeaveScope();
|
||||
return 1;
|
||||
}
|
||||
|
||||
static cell_t IsProfilingActive(IPluginContext *pContext, const cell_t *params)
|
||||
{
|
||||
return g_ProfileToolManager.IsActive() ? 1 : 0;
|
||||
}
|
||||
|
||||
REGISTER_NATIVES(profilerNatives)
|
||||
{
|
||||
{"CreateProfiler", CreateProfiler},
|
||||
{"GetProfilerTime", GetProfilerTime},
|
||||
{"StartProfiling", StartProfiling},
|
||||
{"StopProfiling", StopProfiling},
|
||||
{"EnterProfilingEvent", EnterProfilingEvent},
|
||||
{"LeaveProfilingEvent", LeaveProfilingEvent},
|
||||
{"IsProfilingActive", IsProfilingActive},
|
||||
{NULL, NULL},
|
||||
};
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/**
|
||||
* vim: set ts=4 sw=4 tw=99 noet :
|
||||
* vim: set ts=4 :
|
||||
* =============================================================================
|
||||
* SourceMod
|
||||
* Copyright (C) 2004-2014 AlliedModders LLC. All rights reserved.
|
||||
* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
|
||||
* =============================================================================
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under
|
||||
@@ -32,7 +32,6 @@
|
||||
#include "common_logic.h"
|
||||
#include <ITextParsers.h>
|
||||
#include <ISourceMod.h>
|
||||
#include "handle_helpers.h"
|
||||
|
||||
HandleType_t g_TypeSMC = 0;
|
||||
|
||||
@@ -200,51 +199,90 @@ static cell_t SMC_CreateParser(IPluginContext *pContext, const cell_t *params)
|
||||
|
||||
static cell_t SMC_SetParseStart(IPluginContext *pContext, const cell_t *params)
|
||||
{
|
||||
OpenHandle<ParseInfo> parse(pContext, params[1], g_TypeSMC);
|
||||
if (!parse.Ok())
|
||||
return 0;
|
||||
Handle_t hndl = (Handle_t)params[1];
|
||||
HandleError err;
|
||||
ParseInfo *parse;
|
||||
HandleSecurity sec(pContext->GetIdentity(), g_pCoreIdent);
|
||||
|
||||
if ((err=handlesys->ReadHandle(hndl, g_TypeSMC, &sec, (void **)&parse))
|
||||
!= HandleError_None)
|
||||
{
|
||||
return pContext->ThrowNativeError("Invalid SMC Parse Handle %x (error %d)", hndl, err);
|
||||
}
|
||||
|
||||
parse->parse_start = pContext->GetFunctionById((funcid_t)params[2]);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static cell_t SMC_SetParseEnd(IPluginContext *pContext, const cell_t *params)
|
||||
{
|
||||
OpenHandle<ParseInfo> parse(pContext, params[1], g_TypeSMC);
|
||||
if (!parse.Ok())
|
||||
return 0;
|
||||
Handle_t hndl = (Handle_t)params[1];
|
||||
HandleError err;
|
||||
ParseInfo *parse;
|
||||
HandleSecurity sec(pContext->GetIdentity(), g_pCoreIdent);
|
||||
|
||||
if ((err=handlesys->ReadHandle(hndl, g_TypeSMC, &sec, (void **)&parse))
|
||||
!= HandleError_None)
|
||||
{
|
||||
return pContext->ThrowNativeError("Invalid SMC Parse Handle %x (error %d)", hndl, err);
|
||||
}
|
||||
|
||||
parse->parse_end = pContext->GetFunctionById((funcid_t)params[2]);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static cell_t SMC_SetReaders(IPluginContext *pContext, const cell_t *params)
|
||||
{
|
||||
OpenHandle<ParseInfo> parse(pContext, params[1], g_TypeSMC);
|
||||
if (!parse.Ok())
|
||||
return 0;
|
||||
Handle_t hndl = (Handle_t)params[1];
|
||||
HandleError err;
|
||||
ParseInfo *parse;
|
||||
HandleSecurity sec(pContext->GetIdentity(), g_pCoreIdent);
|
||||
|
||||
if ((err=handlesys->ReadHandle(hndl, g_TypeSMC, &sec, (void **)&parse))
|
||||
!= HandleError_None)
|
||||
{
|
||||
return pContext->ThrowNativeError("Invalid SMC Parse Handle %x (error %d)", hndl, err);
|
||||
}
|
||||
|
||||
parse->new_section = pContext->GetFunctionById((funcid_t)params[2]);
|
||||
parse->key_value = pContext->GetFunctionById((funcid_t)params[3]);
|
||||
parse->end_section = pContext->GetFunctionById((funcid_t)params[4]);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static cell_t SMC_SetRawLine(IPluginContext *pContext, const cell_t *params)
|
||||
{
|
||||
OpenHandle<ParseInfo> parse(pContext, params[1], g_TypeSMC);
|
||||
if (!parse.Ok())
|
||||
return 0;
|
||||
Handle_t hndl = (Handle_t)params[1];
|
||||
HandleError err;
|
||||
ParseInfo *parse;
|
||||
HandleSecurity sec(pContext->GetIdentity(), g_pCoreIdent);
|
||||
|
||||
if ((err=handlesys->ReadHandle(hndl, g_TypeSMC, &sec, (void **)&parse))
|
||||
!= HandleError_None)
|
||||
{
|
||||
return pContext->ThrowNativeError("Invalid SMC Parse Handle %x (error %d)", hndl, err);
|
||||
}
|
||||
|
||||
parse->raw_line = pContext->GetFunctionById((funcid_t)params[2]);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static cell_t SMC_ParseFile(IPluginContext *pContext, const cell_t *params)
|
||||
{
|
||||
OpenHandle<ParseInfo> parse(pContext, params[1], g_TypeSMC);
|
||||
if (!parse.Ok())
|
||||
return 0;
|
||||
Handle_t hndl = (Handle_t)params[1];
|
||||
HandleError err;
|
||||
ParseInfo *parse;
|
||||
HandleSecurity sec(pContext->GetIdentity(), g_pCoreIdent);
|
||||
|
||||
if ((err=handlesys->ReadHandle(hndl, g_TypeSMC, &sec, (void **)&parse))
|
||||
!= HandleError_None)
|
||||
{
|
||||
return pContext->ThrowNativeError("Invalid SMC Parse Handle %x (error %d)", hndl, err);
|
||||
}
|
||||
|
||||
char *file;
|
||||
pContext->LocalToString(params[2], &file);
|
||||
@@ -261,63 +299,21 @@ static cell_t SMC_ParseFile(IPluginContext *pContext, const cell_t *params)
|
||||
|
||||
*c_line = states.line;
|
||||
*c_col = states.col;
|
||||
|
||||
return (cell_t)p_err;
|
||||
}
|
||||
|
||||
static cell_t SMC_GetErrorString(IPluginContext *pContext, const cell_t *params)
|
||||
{
|
||||
const char *str = textparsers->GetSMCErrorString((SMCError)params[1]);
|
||||
|
||||
if (!str)
|
||||
{
|
||||
return 0;
|
||||
|
||||
pContext->StringToLocal(params[2], params[3], str);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static cell_t SMCParser_OnEnterSection_set(IPluginContext *pContext, const cell_t *params)
|
||||
{
|
||||
OpenHandle<ParseInfo> parse(pContext, params[1], g_TypeSMC);
|
||||
if (!parse.Ok())
|
||||
return 0;
|
||||
|
||||
parse->new_section = pContext->GetFunctionById((funcid_t)params[2]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static cell_t SMCParser_OnLeaveSection_set(IPluginContext *pContext, const cell_t *params)
|
||||
{
|
||||
OpenHandle<ParseInfo> parse(pContext, params[1], g_TypeSMC);
|
||||
if (!parse.Ok())
|
||||
return 0;
|
||||
|
||||
parse->end_section = pContext->GetFunctionById((funcid_t)params[2]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static cell_t SMCParser_OnKeyValue_set(IPluginContext *pContext, const cell_t *params)
|
||||
{
|
||||
OpenHandle<ParseInfo> parse(pContext, params[1], g_TypeSMC);
|
||||
if (!parse.Ok())
|
||||
return 0;
|
||||
|
||||
parse->key_value = pContext->GetFunctionById((funcid_t)params[2]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static cell_t SMCParser_GetErrorString(IPluginContext *pContext, const cell_t *params)
|
||||
{
|
||||
OpenHandle<ParseInfo> parse(pContext, params[1], g_TypeSMC);
|
||||
if (!parse.Ok())
|
||||
return 0;
|
||||
|
||||
const char *str = "no error";
|
||||
if (params[2]) {
|
||||
str = textparsers->GetSMCErrorString((SMCError)params[2]);
|
||||
if (!str)
|
||||
str = "unknown error";
|
||||
}
|
||||
|
||||
pContext->StringToLocal(params[3], params[4], str);
|
||||
pContext->StringToLocal(params[2], params[3], str);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -330,17 +326,5 @@ REGISTER_NATIVES(textNatives)
|
||||
{"SMC_SetParseEnd", SMC_SetParseEnd},
|
||||
{"SMC_SetReaders", SMC_SetReaders},
|
||||
{"SMC_SetRawLine", SMC_SetRawLine},
|
||||
|
||||
// Transitional syntax support.
|
||||
{"SMCParser.SMCParser", SMC_CreateParser},
|
||||
{"SMCParser.ParseFile", SMC_ParseFile},
|
||||
{"SMCParser.OnStart.set", SMC_SetParseStart},
|
||||
{"SMCParser.OnEnd.set", SMC_SetParseEnd},
|
||||
{"SMCParser.OnEnterSection.set", SMCParser_OnEnterSection_set},
|
||||
{"SMCParser.OnLeaveSection.set", SMCParser_OnLeaveSection_set},
|
||||
{"SMCParser.OnKeyValue.set", SMCParser_OnKeyValue_set},
|
||||
{"SMCParser.OnRawLine.set", SMC_SetRawLine},
|
||||
{"SMCParser.GetErrorString", SMCParser_GetErrorString},
|
||||
|
||||
{NULL, NULL},
|
||||
};
|
||||
|
||||
+39
-59
@@ -43,7 +43,6 @@
|
||||
#include "logic_bridge.h"
|
||||
#include "PlayerManager.h"
|
||||
#include "HalfLife2.h"
|
||||
#include "MenuManager.h"
|
||||
#include "CoreConfig.h"
|
||||
#include "ConCmdManager.h"
|
||||
#include "IDBDriver.h"
|
||||
@@ -87,7 +86,6 @@ IExtensionSys *extsys;
|
||||
IHandleSys *handlesys;
|
||||
IForwardManager *forwardsys;
|
||||
IAdminSystem *adminsys;
|
||||
ILogger *logger;
|
||||
|
||||
class VEngineServer_Logic : public IVEngineServer_Logic
|
||||
{
|
||||
@@ -148,10 +146,6 @@ public:
|
||||
{
|
||||
return filesystem->FindNext(handle);
|
||||
}
|
||||
bool FindIsDirectory(FileFindHandle_t handle)
|
||||
{
|
||||
return filesystem->FindIsDirectory(handle);
|
||||
}
|
||||
void FindClose(FileFindHandle_t handle)
|
||||
{
|
||||
filesystem->FindClose(handle);
|
||||
@@ -180,50 +174,6 @@ public:
|
||||
{
|
||||
return filesystem->Size(pFileName, pPathID);
|
||||
}
|
||||
int Read(void* pOutput, int size, FileHandle_t file)
|
||||
{
|
||||
return filesystem->Read(pOutput, size, file);
|
||||
}
|
||||
int Write(void const* pInput, int size, FileHandle_t file)
|
||||
{
|
||||
return filesystem->Write(pInput, size, file);
|
||||
}
|
||||
void Seek(FileHandle_t file, int pos, int seekType)
|
||||
{
|
||||
filesystem->Seek(file, pos, (FileSystemSeek_t) seekType);
|
||||
}
|
||||
unsigned int Tell(FileHandle_t file)
|
||||
{
|
||||
return filesystem->Tell(file);
|
||||
}
|
||||
int FPrint(FileHandle_t file, const char *pData)
|
||||
{
|
||||
return filesystem->FPrintf(file, "%s", pData);
|
||||
}
|
||||
void Flush(FileHandle_t file)
|
||||
{
|
||||
filesystem->Flush(file);
|
||||
}
|
||||
bool IsOk(FileHandle_t file)
|
||||
{
|
||||
return filesystem->IsOk(file);
|
||||
}
|
||||
void RemoveFile(const char *pRelativePath, const char *pathID)
|
||||
{
|
||||
filesystem->RemoveFile(pRelativePath, pathID);
|
||||
}
|
||||
void RenameFile(char const *pOldPath, char const *pNewPath, const char *pathID)
|
||||
{
|
||||
filesystem->RenameFile(pOldPath, pNewPath, pathID);
|
||||
}
|
||||
bool IsDirectory(const char *pFileName, const char *pathID)
|
||||
{
|
||||
return filesystem->IsDirectory(pFileName, pathID);
|
||||
}
|
||||
void CreateDirHierarchy(const char *path, const char *pathID)
|
||||
{
|
||||
filesystem->CreateDirHierarchy(path, pathID);
|
||||
}
|
||||
};
|
||||
|
||||
static VFileSystem_Logic logic_filesystem;
|
||||
@@ -301,13 +251,46 @@ static VPlayerInfo_Logic logic_playerinfo;
|
||||
|
||||
static ConVar sm_show_activity("sm_show_activity", "13", FCVAR_SPONLY, "Activity display setting (see sourcemod.cfg)");
|
||||
static ConVar sm_immunity_mode("sm_immunity_mode", "1", FCVAR_SPONLY, "Mode for deciding immunity protection");
|
||||
static ConVar sm_datetime_format("sm_datetime_format", "%m/%d/%Y - %H:%M:%S", 0, "Default formatting time rules");
|
||||
|
||||
static ConVar *find_convar(const char *name)
|
||||
{
|
||||
return icvar->FindVar(name);
|
||||
}
|
||||
|
||||
static void log_error(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, fmt);
|
||||
g_Logger.LogErrorEx(fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
static void log_fatal(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, fmt);
|
||||
g_Logger.LogFatalEx(fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
static void log_message(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
g_Logger.LogMessageEx(fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
static void log_to_file(FILE *fp, const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
g_Logger.LogToOpenFileEx(fp, fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
static void log_to_game(const char *message)
|
||||
{
|
||||
Engine_LogPrintWrapper(message);
|
||||
@@ -323,11 +306,6 @@ static const char *get_cvar_string(ConVar* cvar)
|
||||
return cvar->GetString();
|
||||
}
|
||||
|
||||
static bool get_cvar_bool(ConVar* cvar)
|
||||
{
|
||||
return cvar->GetBool();
|
||||
}
|
||||
|
||||
static bool get_game_name(char *buffer, size_t maxlength)
|
||||
{
|
||||
KeyValues *pGameInfo = new KeyValues("GameInfo");
|
||||
@@ -577,17 +555,19 @@ static sm_core_t core_bridge =
|
||||
&g_Timers,
|
||||
&g_Players,
|
||||
&g_HL2,
|
||||
&g_Menus,
|
||||
&g_pSourcePawn,
|
||||
&g_pSourcePawn2,
|
||||
/* Functions */
|
||||
find_convar,
|
||||
strncopy,
|
||||
UTIL_TrimWhitespace,
|
||||
log_error,
|
||||
log_fatal,
|
||||
log_message,
|
||||
log_to_file,
|
||||
log_to_game,
|
||||
conprint,
|
||||
get_cvar_string,
|
||||
get_cvar_bool,
|
||||
UTIL_Format,
|
||||
UTIL_FormatArgs,
|
||||
gnprintf,
|
||||
@@ -648,6 +628,7 @@ void InitLogicBridge()
|
||||
glob->m_pGlobalClassNext = logicore.head;
|
||||
|
||||
g_pThreader = logicore.threader;
|
||||
g_pSourcePawn2->SetProfiler(logicore.profiler);
|
||||
translator = logicore.translator;
|
||||
scripts = logicore.scripts;
|
||||
sharesys = logicore.sharesys;
|
||||
@@ -656,7 +637,6 @@ void InitLogicBridge()
|
||||
handlesys = logicore.handlesys;
|
||||
forwardsys = logicore.forwardsys;
|
||||
adminsys = logicore.adminsys;
|
||||
logger = logicore.logger;
|
||||
}
|
||||
|
||||
bool StartLogicBridge(char *error, size_t maxlength)
|
||||
|
||||
@@ -48,6 +48,5 @@ extern IExtensionSys *extsys;
|
||||
extern IHandleSys *handlesys;
|
||||
extern IForwardManager *forwardsys;
|
||||
extern IAdminSystem *adminsys;
|
||||
extern ILogger *logger;
|
||||
|
||||
#endif /* _INCLUDE_SOURCEMOD_LOGIC_BRIDGE_H_ */
|
||||
|
||||
+7
-1
@@ -424,15 +424,21 @@ CON_COMMAND(sm_reload_translations, "Reparses all loaded translation files")
|
||||
|
||||
CON_COMMAND(sm_dump_admcache, "Dumps the admin cache for debugging")
|
||||
{
|
||||
FILE *fp;
|
||||
char buffer[PLATFORM_MAX_PATH];
|
||||
|
||||
g_SourceMod.BuildPath(Path_SM, buffer, sizeof(buffer), "data/admin_cache_dump.txt");
|
||||
|
||||
if (!logicore.DumpAdminCache(buffer))
|
||||
if ((fp = fopen(buffer, "wt")) == NULL)
|
||||
{
|
||||
g_RootMenu.ConsolePrint("Could not open file for writing: %s", buffer);
|
||||
return;
|
||||
}
|
||||
|
||||
logicore.DumpAdminCache(fp);
|
||||
|
||||
g_RootMenu.ConsolePrint("Admin cache dumped to: %s", buffer);
|
||||
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
|
||||
@@ -39,7 +39,6 @@
|
||||
#include "logic_bridge.h"
|
||||
#include "sourcemod.h"
|
||||
#include <am-utility.h>
|
||||
#include <am-float.h>
|
||||
|
||||
#define LADJUST 0x00000004 /* left adjustment */
|
||||
#define ZEROPAD 0x00000080 /* zero (as opposed to blank) pad */
|
||||
|
||||
@@ -717,39 +717,6 @@ REGISTER_NATIVES(bitbufnatives)
|
||||
{"BfReadVecNormal", smn_BfReadVecNormal},
|
||||
{"BfReadAngles", smn_BfReadAngles},
|
||||
{"BfGetNumBytesLeft", smn_BfGetNumBytesLeft},
|
||||
|
||||
// Transitional syntax support.
|
||||
{"BfWrite.WriteBool", smn_BfWriteBool},
|
||||
{"BfWrite.WriteByte", smn_BfWriteByte},
|
||||
{"BfWrite.WriteChar", smn_BfWriteChar},
|
||||
{"BfWrite.WriteShort", smn_BfWriteShort},
|
||||
{"BfWrite.WriteWord", smn_BfWriteWord},
|
||||
{"BfWrite.WriteNum", smn_BfWriteNum},
|
||||
{"BfWrite.WriteFloat", smn_BfWriteFloat},
|
||||
{"BfWrite.WriteString", smn_BfWriteString},
|
||||
{"BfWrite.WriteEntity", smn_BfWriteEntity},
|
||||
{"BfWrite.WriteAngle", smn_BfWriteAngle},
|
||||
{"BfWrite.WriteCoord", smn_BfWriteCoord},
|
||||
{"BfWrite.WriteVecCoord", smn_BfWriteVecCoord},
|
||||
{"BfWrite.WriteVecNormal", smn_BfWriteVecNormal},
|
||||
{"BfWrite.WriteAngles", smn_BfWriteAngles},
|
||||
|
||||
{"BfRead.ReadBool", smn_BfReadBool},
|
||||
{"BfRead.ReadByte", smn_BfReadByte},
|
||||
{"BfRead.ReadChar", smn_BfReadChar},
|
||||
{"BfRead.ReadShort", smn_BfReadShort},
|
||||
{"BfRead.ReadWord", smn_BfReadWord},
|
||||
{"BfRead.ReadNum", smn_BfReadNum},
|
||||
{"BfRead.ReadFloat", smn_BfReadFloat},
|
||||
{"BfRead.ReadString", smn_BfReadString},
|
||||
{"BfRead.ReadEntity", smn_BfReadEntity},
|
||||
{"BfRead.ReadAngle", smn_BfReadAngle},
|
||||
{"BfRead.ReadCoord", smn_BfReadCoord},
|
||||
{"BfRead.ReadVecCoord", smn_BfReadVecCoord},
|
||||
{"BfRead.ReadVecNormal", smn_BfReadVecNormal},
|
||||
{"BfRead.ReadAngles", smn_BfReadAngles},
|
||||
{"BfRead.BytesLeft.get", smn_BfGetNumBytesLeft},
|
||||
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
||||
|
||||
@@ -1,131 +0,0 @@
|
||||
/**
|
||||
* vim: set ts=4 :
|
||||
* =============================================================================
|
||||
* SourceMod
|
||||
* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
|
||||
* =============================================================================
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, version 3.0, as published by the
|
||||
* Free Software Foundation.
|
||||
*
|
||||
* 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/>.
|
||||
*
|
||||
* As a special exception, AlliedModders LLC gives you permission to link the
|
||||
* code of this program (as well as its derivative works) to "Half-Life 2," the
|
||||
* "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
|
||||
* by the Valve Corporation. You must obey the GNU General Public License in
|
||||
* all respects for all other code used. Additionally, AlliedModders LLC grants
|
||||
* this exception to all derivative works. AlliedModders LLC defines further
|
||||
* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
|
||||
* or <http://www.sourcemod.net/license.php>.
|
||||
*
|
||||
* Version: $Id$
|
||||
*/
|
||||
|
||||
#include "HalfLife2.h"
|
||||
|
||||
static cell_t sm_GetCommandLine(IPluginContext *pCtx, const cell_t *params)
|
||||
{
|
||||
ICommandLine *pCmdLine = g_HL2.GetValveCommandLine();
|
||||
|
||||
if (pCmdLine == NULL)
|
||||
{
|
||||
return pCtx->ThrowNativeError("Unable to get valve command line");
|
||||
}
|
||||
|
||||
const char *commandLine = pCmdLine->GetCmdLine();
|
||||
|
||||
if (commandLine == NULL)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
pCtx->StringToLocal(params[1], params[2], commandLine);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static cell_t sm_GetCommandLineParam(IPluginContext *pCtx, const cell_t *params)
|
||||
{
|
||||
ICommandLine *pCmdLine = g_HL2.GetValveCommandLine();
|
||||
|
||||
if (pCmdLine == NULL)
|
||||
{
|
||||
return pCtx->ThrowNativeError("Unable to get valve command line");
|
||||
}
|
||||
|
||||
char *param = NULL;
|
||||
char *defValue = NULL;
|
||||
pCtx->LocalToString(params[1], ¶m);
|
||||
pCtx->LocalToString(params[4], ¶m);
|
||||
|
||||
const char *value = pCmdLine->ParmValue(param, defValue);
|
||||
|
||||
pCtx->StringToLocal(params[2], params[3], value);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static cell_t sm_GetCommandLineParamInt(IPluginContext *pCtx, const cell_t *params)
|
||||
{
|
||||
ICommandLine *pCmdLine = g_HL2.GetValveCommandLine();
|
||||
|
||||
if (pCmdLine == NULL)
|
||||
{
|
||||
return pCtx->ThrowNativeError("Unable to get valve command line");
|
||||
}
|
||||
|
||||
char *param = NULL;
|
||||
pCtx->LocalToString(params[1], ¶m);
|
||||
|
||||
return pCmdLine->ParmValue(param, params[2]);
|
||||
}
|
||||
|
||||
static cell_t sm_GetCommandLineParamFloat(IPluginContext *pCtx, const cell_t *params)
|
||||
{
|
||||
ICommandLine *pCmdLine = g_HL2.GetValveCommandLine();
|
||||
|
||||
if (pCmdLine == NULL)
|
||||
{
|
||||
return pCtx->ThrowNativeError("Unable to get valve command line");
|
||||
}
|
||||
|
||||
char *param = NULL;
|
||||
pCtx->LocalToString(params[1], ¶m);
|
||||
|
||||
float value = pCmdLine->ParmValue(param, sp_ctof(params[2]));
|
||||
|
||||
return sp_ftoc(value);
|
||||
}
|
||||
|
||||
static cell_t sm_FindCommandLineParam(IPluginContext *pCtx, const cell_t *params)
|
||||
{
|
||||
ICommandLine *pCmdLine = g_HL2.GetValveCommandLine();
|
||||
|
||||
if (pCmdLine == NULL)
|
||||
{
|
||||
return pCtx->ThrowNativeError("Unable to get valve command line");
|
||||
}
|
||||
|
||||
char *param = NULL;
|
||||
pCtx->LocalToString(params[1], ¶m);
|
||||
|
||||
return pCmdLine->FindParm(param);
|
||||
}
|
||||
|
||||
REGISTER_NATIVES(commandlinenatives)
|
||||
{
|
||||
{"GetCommandLine", sm_GetCommandLine},
|
||||
{"GetCommandLineParam", sm_GetCommandLineParam},
|
||||
{"GetCommandLineParamInt", sm_GetCommandLineParamInt},
|
||||
{"GetCommandLineParamFloat", sm_GetCommandLineParamFloat},
|
||||
{"FindCommandLineParam", sm_FindCommandLineParam},
|
||||
{NULL, NULL},
|
||||
};
|
||||
+10
-78
@@ -1182,19 +1182,28 @@ static cell_t SendConVarValue(IPluginContext *pContext, const cell_t *params)
|
||||
CPlayer *pPlayer = g_Players.GetPlayerByIndex(params[1]);
|
||||
|
||||
if (!pPlayer)
|
||||
{
|
||||
return pContext->ThrowNativeError("Client index %d is invalid", params[1]);
|
||||
}
|
||||
|
||||
if (!pPlayer->IsConnected())
|
||||
{
|
||||
return pContext->ThrowNativeError("Client %d is not connected", params[1]);
|
||||
}
|
||||
|
||||
if (pPlayer->IsFakeClient())
|
||||
{
|
||||
return pContext->ThrowNativeError("Client %d is fake and cannot be targeted", params[1]);
|
||||
}
|
||||
|
||||
INetChannel *netchan = static_cast<INetChannel *>(engine->GetPlayerNetInfo(params[1]));
|
||||
if (netchan == NULL)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
netchan->SendData(buffer);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -1207,7 +1216,7 @@ static cell_t AddCommandListener(IPluginContext *pContext, const cell_t *params)
|
||||
|
||||
if (strcasecmp(name, "sm") == 0)
|
||||
{
|
||||
logger->LogError("Request to register \"sm\" command denied.");
|
||||
g_Logger.LogError("Request to register \"sm\" command denied.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1238,59 +1247,6 @@ static cell_t RemoveCommandListener(IPluginContext *pContext, const cell_t *para
|
||||
return 1;
|
||||
}
|
||||
|
||||
static cell_t ConVar_BoolValue_set(IPluginContext *pContext, const cell_t *params)
|
||||
{
|
||||
static cell_t new_params[5] = {
|
||||
4,
|
||||
params[1],
|
||||
params[2],
|
||||
0, /* Default replicate setting. */
|
||||
0, /* Default replicate setting. */
|
||||
};
|
||||
|
||||
return sm_SetConVarNum(pContext, new_params);
|
||||
}
|
||||
|
||||
static cell_t ConVar_IntValue_set(IPluginContext *pContext, const cell_t *params)
|
||||
{
|
||||
static cell_t new_params[5] = {
|
||||
4,
|
||||
params[1],
|
||||
params[2],
|
||||
0, /* Default replicate setting. */
|
||||
0, /* Default replicate setting. */
|
||||
};
|
||||
|
||||
return sm_SetConVarNum(pContext, new_params);
|
||||
}
|
||||
|
||||
static cell_t ConVar_FloatValue_set(IPluginContext *pContext, const cell_t *params)
|
||||
{
|
||||
static cell_t new_params[5] = {
|
||||
4,
|
||||
params[1],
|
||||
params[2],
|
||||
0, /* Default replicate setting. */
|
||||
0, /* Default replicate setting. */
|
||||
};
|
||||
|
||||
return sm_SetConVarFloat(pContext, new_params);
|
||||
}
|
||||
|
||||
static cell_t ConVar_ReplicateToClient(IPluginContext *pContext, const cell_t *params)
|
||||
{
|
||||
// Old version is (client, handle, value).
|
||||
// New version is (handle, client, value).
|
||||
static cell_t new_params[4] = {
|
||||
3,
|
||||
params[2],
|
||||
params[1],
|
||||
params[3],
|
||||
};
|
||||
|
||||
return SendConVarValue(pContext, new_params);
|
||||
}
|
||||
|
||||
REGISTER_NATIVES(consoleNatives)
|
||||
{
|
||||
{"CreateConVar", sm_CreateConVar},
|
||||
@@ -1331,29 +1287,5 @@ REGISTER_NATIVES(consoleNatives)
|
||||
{"SendConVarValue", SendConVarValue},
|
||||
{"AddCommandListener", AddCommandListener},
|
||||
{"RemoveCommandListener", RemoveCommandListener},
|
||||
|
||||
// Transitional syntax support.
|
||||
{"ConVar.BoolValue.get", sm_GetConVarBool},
|
||||
{"ConVar.BoolValue.set", ConVar_BoolValue_set},
|
||||
{"ConVar.FloatValue.get", sm_GetConVarFloat},
|
||||
{"ConVar.FloatValue.set", ConVar_FloatValue_set},
|
||||
{"ConVar.IntValue.get", sm_GetConVarInt},
|
||||
{"ConVar.IntValue.set", ConVar_IntValue_set},
|
||||
{"ConVar.Flags.get", sm_GetConVarFlags},
|
||||
{"ConVar.Flags.set", sm_SetConVarFlags},
|
||||
{"ConVar.SetBool", sm_SetConVarNum},
|
||||
{"ConVar.SetInt", sm_SetConVarNum},
|
||||
{"ConVar.SetFloat", sm_SetConVarFloat},
|
||||
{"ConVar.GetString", sm_GetConVarString},
|
||||
{"ConVar.SetString", sm_SetConVarString},
|
||||
{"ConVar.RestoreDefault", sm_ResetConVar},
|
||||
{"ConVar.GetDefault", GetConVarDefault},
|
||||
{"ConVar.GetBounds", sm_GetConVarBounds},
|
||||
{"ConVar.SetBounds", sm_SetConVarBounds},
|
||||
{"ConVar.GetName", sm_GetConVarName},
|
||||
{"ConVar.ReplicateToClient", ConVar_ReplicateToClient},
|
||||
{"ConVar.AddChangeHook", sm_HookConVarChange},
|
||||
{"ConVar.RemoveChangeHook", sm_UnhookConVarChange},
|
||||
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
||||
@@ -32,14 +32,14 @@
|
||||
#include <time.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include "common_logic.h"
|
||||
#include "sm_stringutil.h"
|
||||
#include "sm_globals.h"
|
||||
#include "sourcemod.h"
|
||||
#include "LibrarySys.h"
|
||||
#include "TimerSys.h"
|
||||
#include "Logger.h"
|
||||
|
||||
#include <ISourceMod.h>
|
||||
#include <ITranslator.h>
|
||||
|
||||
#include <sourcehook.h>
|
||||
#include <sh_memory.h>
|
||||
#include "logic_bridge.h"
|
||||
|
||||
#if defined PLATFORM_WINDOWS
|
||||
#include <windows.h>
|
||||
@@ -50,11 +50,9 @@
|
||||
#endif
|
||||
|
||||
HandleType_t g_PlIter;
|
||||
|
||||
ConVar sm_datetime_format("sm_datetime_format", "%m/%d/%Y - %H:%M:%S", 0, "Default formatting time rules");
|
||||
IForward *g_OnLogAction = NULL;
|
||||
|
||||
static ConVar *sm_datetime_format = NULL;
|
||||
|
||||
class CoreNativeHelpers :
|
||||
public SMGlobalClass,
|
||||
public IHandleTypeDispatch
|
||||
@@ -77,8 +75,6 @@ public:
|
||||
Param_Cell,
|
||||
Param_Cell,
|
||||
Param_String);
|
||||
|
||||
sm_datetime_format = smcore.FindConVar("sm_datetime_format");
|
||||
}
|
||||
void OnHandleDestroy(HandleType_t type, void *object)
|
||||
{
|
||||
@@ -123,14 +119,14 @@ void LogAction(Handle_t hndl, int type, int client, int target, const char *mess
|
||||
|
||||
g_Logger.LogMessage("[%s] %s", logtag, message);
|
||||
}
|
||||
|
||||
static cell_t ThrowError(IPluginContext *pContext, const cell_t *params)
|
||||
|
||||
static cell_t ThrowError(IPluginContext *pContext, const cell_t *params)
|
||||
{
|
||||
char buffer[512];
|
||||
|
||||
g_pSM->SetGlobalTarget(SOURCEMOD_SERVER_LANGUAGE);
|
||||
g_SourceMod.SetGlobalTarget(SOURCEMOD_SERVER_LANGUAGE);
|
||||
|
||||
g_pSM->FormatString(buffer, sizeof(buffer), pContext, params, 1);
|
||||
g_SourceMod.FormatString(buffer, sizeof(buffer), pContext, params, 1);
|
||||
|
||||
if (pContext->GetLastNativeError() == SP_ERROR_NONE)
|
||||
{
|
||||
@@ -142,7 +138,7 @@ void LogAction(Handle_t hndl, int type, int client, int target, const char *mess
|
||||
|
||||
static cell_t GetTime(IPluginContext *pContext, const cell_t *params)
|
||||
{
|
||||
time_t t = g_pSM->GetAdjustedTime();
|
||||
time_t t = GetAdjustedTime();
|
||||
cell_t *addr;
|
||||
pContext->LocalToPhysAddr(params[1], &addr);
|
||||
|
||||
@@ -172,14 +168,14 @@ static cell_t FormatTime(IPluginContext *pContext, const cell_t *params)
|
||||
|
||||
if (format == NULL)
|
||||
{
|
||||
format = const_cast<char *>(smcore.GetCvarString(sm_datetime_format));
|
||||
format = const_cast<char *>(sm_datetime_format.GetString());
|
||||
}
|
||||
|
||||
#if defined SUBPLATFORM_SECURECRT
|
||||
_invalid_parameter_handler handler = _set_invalid_parameter_handler(_ignore_invalid_parameter);
|
||||
#endif
|
||||
|
||||
time_t t = (params[4] == -1) ? g_pSM->GetAdjustedTime() : (time_t)params[4];
|
||||
time_t t = (params[4] == -1) ? GetAdjustedTime() : (time_t)params[4];
|
||||
size_t written = strftime(buffer, params[2], format, localtime(&t));
|
||||
|
||||
#if defined SUBPLATFORM_SECURECRT
|
||||
@@ -388,7 +384,7 @@ static cell_t SetFailState(IPluginContext *pContext, const cell_t *params)
|
||||
{
|
||||
char buffer[2048];
|
||||
|
||||
g_pSM->FormatString(buffer, sizeof(buffer), pContext, params, 1);
|
||||
g_SourceMod.FormatString(buffer, sizeof(buffer), pContext, params, 1);
|
||||
if (pContext->GetLastNativeError() != SP_ERROR_NONE)
|
||||
{
|
||||
pPlugin->SetErrorState(Plugin_Error, "%s", str);
|
||||
@@ -437,14 +433,14 @@ static cell_t AutoExecConfig(IPluginContext *pContext, const cell_t *params)
|
||||
static char temp_file[PLATFORM_MAX_PATH];
|
||||
char *ptr;
|
||||
|
||||
libsys->GetFileFromPath(temp_str, sizeof(temp_str), plugin->GetFilename());
|
||||
g_LibSys.GetFileFromPath(temp_str, sizeof(temp_str), plugin->GetFilename());
|
||||
if ((ptr = strstr(temp_str, ".smx")) != NULL)
|
||||
{
|
||||
*ptr = '\0';
|
||||
}
|
||||
|
||||
/* We have the raw filename! */
|
||||
g_pSM->Format(temp_file, sizeof(temp_file), "plugin.%s", temp_str);
|
||||
UTIL_Format(temp_file, sizeof(temp_file), "plugin.%s", temp_str);
|
||||
cfg = temp_file;
|
||||
}
|
||||
|
||||
@@ -510,8 +506,8 @@ static cell_t LibraryExists(IPluginContext *pContext, const cell_t *params)
|
||||
static cell_t sm_LogAction(IPluginContext *pContext, const cell_t *params)
|
||||
{
|
||||
char buffer[2048];
|
||||
g_pSM->SetGlobalTarget(SOURCEMOD_SERVER_LANGUAGE);
|
||||
g_pSM->FormatString(buffer, sizeof(buffer), pContext, params, 3);
|
||||
g_SourceMod.SetGlobalTarget(SOURCEMOD_SERVER_LANGUAGE);
|
||||
g_SourceMod.FormatString(buffer, sizeof(buffer), pContext, params, 3);
|
||||
|
||||
if (pContext->GetLastNativeError() != SP_ERROR_NONE)
|
||||
{
|
||||
@@ -531,7 +527,7 @@ static cell_t LogToFile(IPluginContext *pContext, const cell_t *params)
|
||||
pContext->LocalToString(params[1], &file);
|
||||
|
||||
char path[PLATFORM_MAX_PATH];
|
||||
g_pSM->BuildPath(Path_Game, path, sizeof(path), "%s", file);
|
||||
g_SourceMod.BuildPath(Path_Game, path, sizeof(path), "%s", file);
|
||||
|
||||
FILE *fp = fopen(path, "at");
|
||||
if (!fp)
|
||||
@@ -540,8 +536,8 @@ static cell_t LogToFile(IPluginContext *pContext, const cell_t *params)
|
||||
}
|
||||
|
||||
char buffer[2048];
|
||||
g_pSM->SetGlobalTarget(SOURCEMOD_SERVER_LANGUAGE);
|
||||
g_pSM->FormatString(buffer, sizeof(buffer), pContext, params, 2);
|
||||
g_SourceMod.SetGlobalTarget(SOURCEMOD_SERVER_LANGUAGE);
|
||||
g_SourceMod.FormatString(buffer, sizeof(buffer), pContext, params, 2);
|
||||
|
||||
if (pContext->GetLastNativeError() != SP_ERROR_NONE)
|
||||
{
|
||||
@@ -564,7 +560,7 @@ static cell_t LogToFileEx(IPluginContext *pContext, const cell_t *params)
|
||||
pContext->LocalToString(params[1], &file);
|
||||
|
||||
char path[PLATFORM_MAX_PATH];
|
||||
g_pSM->BuildPath(Path_Game, path, sizeof(path), "%s", file);
|
||||
g_SourceMod.BuildPath(Path_Game, path, sizeof(path), "%s", file);
|
||||
|
||||
FILE *fp = fopen(path, "at");
|
||||
if (!fp)
|
||||
@@ -573,8 +569,8 @@ static cell_t LogToFileEx(IPluginContext *pContext, const cell_t *params)
|
||||
}
|
||||
|
||||
char buffer[2048];
|
||||
g_pSM->SetGlobalTarget(SOURCEMOD_SERVER_LANGUAGE);
|
||||
g_pSM->FormatString(buffer, sizeof(buffer), pContext, params, 2);
|
||||
g_SourceMod.SetGlobalTarget(SOURCEMOD_SERVER_LANGUAGE);
|
||||
g_SourceMod.FormatString(buffer, sizeof(buffer), pContext, params, 2);
|
||||
|
||||
if (pContext->GetLastNativeError() != SP_ERROR_NONE)
|
||||
{
|
||||
@@ -657,10 +653,10 @@ static cell_t RequireFeature(IPluginContext *pContext, const cell_t *params)
|
||||
char default_message[255];
|
||||
SMPlugin *pPlugin = scripts->FindPluginByContext(pContext->GetContext());
|
||||
|
||||
g_pSM->FormatString(buffer, sizeof(buffer), pContext, params, 3);
|
||||
g_SourceMod.FormatString(buffer, sizeof(buffer), pContext, params, 3);
|
||||
if (pContext->GetLastNativeError() != SP_ERROR_NONE || buffer[0] == '\0')
|
||||
{
|
||||
g_pSM->Format(default_message, sizeof(default_message), "Feature \"%s\" not available", name);
|
||||
UTIL_Format(default_message, sizeof(default_message), "Feature \"%s\" not available", name);
|
||||
msg = default_message;
|
||||
}
|
||||
pPlugin->SetErrorState(Plugin_Error, "%s", msg);
|
||||
@@ -747,19 +743,19 @@ static cell_t StoreToAddress(IPluginContext *pContext, const cell_t *params)
|
||||
|
||||
REGISTER_NATIVES(coreNatives)
|
||||
{
|
||||
{"ThrowError", ThrowError},
|
||||
{"GetTime", GetTime},
|
||||
{"FormatTime", FormatTime},
|
||||
{"AutoExecConfig", AutoExecConfig},
|
||||
{"GetPluginFilename", GetPluginFilename},
|
||||
{"GetPluginInfo", GetPluginInfo},
|
||||
{"GetPluginIterator", GetPluginIterator},
|
||||
{"GetPluginStatus", GetPluginStatus},
|
||||
{"GetSysTickCount", GetSysTickCount},
|
||||
{"GetTime", GetTime},
|
||||
{"IsPluginDebugging", IsPluginDebugging},
|
||||
{"MorePlugins", MorePlugins},
|
||||
{"ReadPlugin", ReadPlugin},
|
||||
{"GetPluginStatus", GetPluginStatus},
|
||||
{"GetPluginFilename", GetPluginFilename},
|
||||
{"IsPluginDebugging", IsPluginDebugging},
|
||||
{"GetPluginInfo", GetPluginInfo},
|
||||
{"ThrowError", ThrowError},
|
||||
{"SetFailState", SetFailState},
|
||||
{"GetSysTickCount", GetSysTickCount},
|
||||
{"AutoExecConfig", AutoExecConfig},
|
||||
{"FormatTime", FormatTime},
|
||||
{"MarkNativeAsOptional", MarkNativeAsOptional},
|
||||
{"RegPluginLibrary", RegPluginLibrary},
|
||||
{"LibraryExists", LibraryExists},
|
||||
@@ -774,4 +770,5 @@ REGISTER_NATIVES(coreNatives)
|
||||
{"LoadFromAddress", LoadFromAddress},
|
||||
{"StoreToAddress", StoreToAddress},
|
||||
{NULL, NULL},
|
||||
};
|
||||
};
|
||||
|
||||
+31
-113
@@ -1519,13 +1519,6 @@ static cell_t SetEntPropFloat(IPluginContext *pContext, const cell_t *params)
|
||||
return 1;
|
||||
}
|
||||
|
||||
enum PropEntType
|
||||
{
|
||||
PropEnt_Handle,
|
||||
PropEnt_Entity,
|
||||
PropEnt_Edict,
|
||||
};
|
||||
|
||||
static cell_t GetEntPropEnt(IPluginContext *pContext, const cell_t *params)
|
||||
{
|
||||
CBaseEntity *pEntity;
|
||||
@@ -1533,7 +1526,6 @@ static cell_t GetEntPropEnt(IPluginContext *pContext, const cell_t *params)
|
||||
int offset;
|
||||
int bit_count;
|
||||
edict_t *pEdict;
|
||||
PropEntType type;
|
||||
|
||||
int element = 0;
|
||||
if (params[0] >= 4)
|
||||
@@ -1556,23 +1548,12 @@ static cell_t GetEntPropEnt(IPluginContext *pContext, const cell_t *params)
|
||||
|
||||
FIND_PROP_DATA(td);
|
||||
|
||||
switch (td->fieldType)
|
||||
if (td->fieldType != FIELD_EHANDLE)
|
||||
{
|
||||
case FIELD_EHANDLE:
|
||||
type = PropEnt_Handle;
|
||||
break;
|
||||
case FIELD_CLASSPTR:
|
||||
type = PropEnt_Entity;
|
||||
break;
|
||||
#if SOURCE_ENGINE != SE_DOTA
|
||||
case FIELD_EDICT:
|
||||
type = PropEnt_Edict;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
return pContext->ThrowNativeError("Data field %s is not an entity nor edict (%d)",
|
||||
return pContext->ThrowNativeError("Data field %s is not an entity (%d != %d)",
|
||||
prop,
|
||||
td->fieldType);
|
||||
td->fieldType,
|
||||
FIELD_EHANDLE);
|
||||
}
|
||||
|
||||
CHECK_SET_PROP_DATA_OFFSET();
|
||||
@@ -1581,7 +1562,6 @@ static cell_t GetEntPropEnt(IPluginContext *pContext, const cell_t *params)
|
||||
}
|
||||
case Prop_Send:
|
||||
{
|
||||
type = PropEnt_Handle;
|
||||
FIND_PROP_SEND(DPT_Int, "integer");
|
||||
break;
|
||||
}
|
||||
@@ -1591,34 +1571,13 @@ static cell_t GetEntPropEnt(IPluginContext *pContext, const cell_t *params)
|
||||
}
|
||||
}
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case PropEnt_Handle:
|
||||
{
|
||||
CBaseHandle &hndl = *(CBaseHandle *) ((uint8_t *) pEntity + offset);
|
||||
CBaseEntity *pHandleEntity = g_HL2.ReferenceToEntity(hndl.GetEntryIndex());
|
||||
CBaseHandle &hndl = *(CBaseHandle *)((uint8_t *)pEntity + offset);
|
||||
CBaseEntity *pHandleEntity = g_HL2.ReferenceToEntity(hndl.GetEntryIndex());
|
||||
|
||||
if (!pHandleEntity || hndl != reinterpret_cast<IHandleEntity *>(pHandleEntity)->GetRefEHandle())
|
||||
return -1;
|
||||
if (!pHandleEntity || hndl != reinterpret_cast<IHandleEntity *>(pHandleEntity)->GetRefEHandle())
|
||||
return -1;
|
||||
|
||||
return g_HL2.EntityToBCompatRef(pHandleEntity);
|
||||
}
|
||||
case PropEnt_Entity:
|
||||
{
|
||||
CBaseEntity *pPropEntity = *(CBaseEntity **) ((uint8_t *) pEntity + offset);
|
||||
return g_HL2.EntityToBCompatRef(pPropEntity);
|
||||
}
|
||||
case PropEnt_Edict:
|
||||
{
|
||||
edict_t *pEdict = *(edict_t **) ((uint8_t *) pEntity + offset);
|
||||
if (!pEdict || pEdict->IsFree())
|
||||
return -1;
|
||||
|
||||
return IndexOfEdict(pEdict);
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
return g_HL2.EntityToBCompatRef(pHandleEntity);
|
||||
}
|
||||
|
||||
static cell_t SetEntPropEnt(IPluginContext *pContext, const cell_t *params)
|
||||
@@ -1628,7 +1587,6 @@ static cell_t SetEntPropEnt(IPluginContext *pContext, const cell_t *params)
|
||||
int offset;
|
||||
int bit_count;
|
||||
edict_t *pEdict;
|
||||
PropEntType type;
|
||||
|
||||
int element = 0;
|
||||
if (params[0] >= 5)
|
||||
@@ -1651,25 +1609,12 @@ static cell_t SetEntPropEnt(IPluginContext *pContext, const cell_t *params)
|
||||
|
||||
FIND_PROP_DATA(td);
|
||||
|
||||
switch (td->fieldType)
|
||||
if (td->fieldType != FIELD_EHANDLE)
|
||||
{
|
||||
case FIELD_EHANDLE:
|
||||
type = PropEnt_Handle;
|
||||
break;
|
||||
case FIELD_CLASSPTR:
|
||||
type = PropEnt_Entity;
|
||||
break;
|
||||
#if SOURCE_ENGINE != SE_DOTA
|
||||
case FIELD_EDICT:
|
||||
type = PropEnt_Edict;
|
||||
if (!pEdict)
|
||||
return pContext->ThrowNativeError("Edict %d is invalid", params[1]);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
return pContext->ThrowNativeError("Data field %s is not an entity nor edict (%d)",
|
||||
return pContext->ThrowNativeError("Data field %s is not an entity (%d != %d)",
|
||||
prop,
|
||||
td->fieldType);
|
||||
td->fieldType,
|
||||
FIELD_EHANDLE);
|
||||
}
|
||||
|
||||
CHECK_SET_PROP_DATA_OFFSET();
|
||||
@@ -1678,7 +1623,6 @@ static cell_t SetEntPropEnt(IPluginContext *pContext, const cell_t *params)
|
||||
}
|
||||
case Prop_Send:
|
||||
{
|
||||
type = PropEnt_Handle;
|
||||
FIND_PROP_SEND(DPT_Int, "integer");
|
||||
break;
|
||||
}
|
||||
@@ -1688,54 +1632,28 @@ static cell_t SetEntPropEnt(IPluginContext *pContext, const cell_t *params)
|
||||
}
|
||||
}
|
||||
|
||||
CBaseEntity *pOther = GetEntity(params[4]);
|
||||
if (!pOther && params[4] != -1)
|
||||
CBaseHandle &hndl = *(CBaseHandle *)((uint8_t *)pEntity + offset);
|
||||
|
||||
if (params[4] == -1)
|
||||
{
|
||||
return pContext->ThrowNativeError("Entity %d (%d) is invalid", g_HL2.ReferenceToIndex(params[4]), params[4]);
|
||||
hndl.Set(NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
CBaseEntity *pOther = GetEntity(params[4]);
|
||||
|
||||
if (!pOther)
|
||||
{
|
||||
return pContext->ThrowNativeError("Entity %d (%d) is invalid", g_HL2.ReferenceToIndex(params[4]), params[4]);
|
||||
}
|
||||
|
||||
IHandleEntity *pHandleEnt = (IHandleEntity *)pOther;
|
||||
hndl.Set(pHandleEnt);
|
||||
}
|
||||
|
||||
switch (type)
|
||||
if (params[2] == Prop_Send && (pEdict != NULL))
|
||||
{
|
||||
case PropEnt_Handle:
|
||||
{
|
||||
CBaseHandle &hndl = *(CBaseHandle *) ((uint8_t *) pEntity + offset);
|
||||
hndl.Set((IHandleEntity *) pOther);
|
||||
|
||||
if (params[2] == Prop_Send && (pEdict != NULL))
|
||||
{
|
||||
g_HL2.SetEdictStateChanged(pEdict, offset);
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case PropEnt_Entity:
|
||||
{
|
||||
*(CBaseEntity **) ((uint8_t *) pEntity + offset) = pOther;
|
||||
break;
|
||||
}
|
||||
|
||||
case PropEnt_Edict:
|
||||
{
|
||||
edict_t *pOtherEdict = NULL;
|
||||
if (pOther)
|
||||
{
|
||||
IServerNetworkable *pNetworkable = ((IServerUnknown *) pOther)->GetNetworkable();
|
||||
if (!pNetworkable)
|
||||
{
|
||||
return pContext->ThrowNativeError("Entity %d (%d) does not have a valid edict", g_HL2.ReferenceToIndex(params[4]), params[4]);
|
||||
}
|
||||
|
||||
pOtherEdict = pNetworkable->GetEdict();
|
||||
if (!pOtherEdict || pOtherEdict->IsFree())
|
||||
{
|
||||
return pContext->ThrowNativeError("Entity %d (%d) does not have a valid edict", g_HL2.ReferenceToIndex(params[4]), params[4]);
|
||||
}
|
||||
}
|
||||
|
||||
*(edict_t **) ((uint8_t *) pEntity + offset) = pOtherEdict;
|
||||
break;
|
||||
}
|
||||
g_HL2.SetEdictStateChanged(pEdict, offset);
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
||||
+4
-44
@@ -207,13 +207,7 @@ static cell_t sm_GetEventBool(IPluginContext *pContext, const cell_t *params)
|
||||
char *key;
|
||||
pContext->LocalToString(params[2], &key);
|
||||
|
||||
bool defValue = false;
|
||||
if (params[0] > 2)
|
||||
{
|
||||
defValue = !!params[3];
|
||||
}
|
||||
|
||||
return pInfo->pEvent->GetBool(key, defValue);
|
||||
return pInfo->pEvent->GetBool(key);
|
||||
}
|
||||
|
||||
static cell_t sm_GetEventInt(IPluginContext *pContext, const cell_t *params)
|
||||
@@ -232,13 +226,7 @@ static cell_t sm_GetEventInt(IPluginContext *pContext, const cell_t *params)
|
||||
char *key;
|
||||
pContext->LocalToString(params[2], &key);
|
||||
|
||||
int defValue = 0;
|
||||
if (params[0] > 2)
|
||||
{
|
||||
defValue = params[3];
|
||||
}
|
||||
|
||||
return pInfo->pEvent->GetInt(key, defValue);
|
||||
return pInfo->pEvent->GetInt(key);
|
||||
}
|
||||
|
||||
static cell_t sm_GetEventFloat(IPluginContext *pContext, const cell_t *params)
|
||||
@@ -257,13 +245,7 @@ static cell_t sm_GetEventFloat(IPluginContext *pContext, const cell_t *params)
|
||||
char *key;
|
||||
pContext->LocalToString(params[2], &key);
|
||||
|
||||
float defValue = 0.0f;
|
||||
if (params[0] > 2)
|
||||
{
|
||||
defValue = sp_ctof(params[3]);
|
||||
}
|
||||
|
||||
float value = pInfo->pEvent->GetFloat(key, defValue);
|
||||
float value = pInfo->pEvent->GetFloat(key);
|
||||
|
||||
return sp_ftoc(value);
|
||||
}
|
||||
@@ -284,14 +266,7 @@ static cell_t sm_GetEventString(IPluginContext *pContext, const cell_t *params)
|
||||
char *key;
|
||||
pContext->LocalToString(params[2], &key);
|
||||
|
||||
char *defValue = NULL;
|
||||
if (params[0] > 4)
|
||||
{
|
||||
pContext->LocalToString(params[5], &defValue);
|
||||
}
|
||||
|
||||
const char *value = pInfo->pEvent->GetString(key, defValue ? defValue : "");
|
||||
pContext->StringToLocalUTF8(params[3], params[4], value, NULL);
|
||||
pContext->StringToLocalUTF8(params[3], params[4], pInfo->pEvent->GetString(key), NULL);
|
||||
|
||||
return 1;
|
||||
}
|
||||
@@ -418,21 +393,6 @@ REGISTER_NATIVES(gameEventNatives)
|
||||
{"SetEventFloat", sm_SetEventFloat},
|
||||
{"SetEventString", sm_SetEventString},
|
||||
{"SetEventBroadcast", sm_SetEventBroadcast},
|
||||
|
||||
// Transitional syntax support.
|
||||
{"Event.Fire", sm_FireEvent},
|
||||
{"Event.Cancel", sm_CancelCreatedEvent},
|
||||
{"Event.GetName", sm_GetEventName},
|
||||
{"Event.GetBool", sm_GetEventBool},
|
||||
{"Event.GetInt", sm_GetEventInt},
|
||||
{"Event.GetFloat", sm_GetEventFloat},
|
||||
{"Event.GetString", sm_GetEventString},
|
||||
{"Event.SetBool", sm_SetEventBool},
|
||||
{"Event.SetInt", sm_SetEventInt},
|
||||
{"Event.SetFloat", sm_SetEventFloat},
|
||||
{"Event.SetString", sm_SetEventString},
|
||||
{"Event.BroadcastDisabled.set", sm_SetEventBroadcast},
|
||||
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
||||
|
||||
+3
-47
@@ -35,11 +35,9 @@
|
||||
#include "PlayerManager.h"
|
||||
#include "HalfLife2.h"
|
||||
|
||||
#include <vstdlib/random.h>
|
||||
|
||||
static cell_t SetRandomSeed(IPluginContext *pContext, const cell_t *params)
|
||||
{
|
||||
::RandomSeed(params[1]);
|
||||
engrandom->SetSeed(params[1]);
|
||||
|
||||
return 1;
|
||||
}
|
||||
@@ -49,14 +47,14 @@ static cell_t GetRandomFloat(IPluginContext *pContext, const cell_t *params)
|
||||
float fMin = sp_ctof(params[1]);
|
||||
float fMax = sp_ctof(params[2]);
|
||||
|
||||
float fRandom = ::RandomFloat(fMin, fMax);
|
||||
float fRandom = engrandom->RandomFloat(fMin, fMax);
|
||||
|
||||
return sp_ftoc(fRandom);
|
||||
}
|
||||
|
||||
static cell_t GetRandomInt(IPluginContext *pContext, const cell_t *params)
|
||||
{
|
||||
return ::RandomInt(params[1], params[2]);
|
||||
return engrandom->RandomInt(params[1], params[2]);
|
||||
}
|
||||
|
||||
static cell_t IsMapValid(IPluginContext *pContext, const cell_t *params)
|
||||
@@ -572,47 +570,6 @@ static cell_t ReferenceToBCompatRef(IPluginContext *pContext, const cell_t *para
|
||||
return g_HL2.ReferenceToBCompatRef(params[1]);
|
||||
}
|
||||
|
||||
// Must match ClientRangeType enum in halflife.inc
|
||||
enum class ClientRangeType : cell_t
|
||||
{
|
||||
Visibility = 0,
|
||||
Audibility,
|
||||
};
|
||||
|
||||
static cell_t GetClientsInRange(IPluginContext *pContext, const cell_t *params)
|
||||
{
|
||||
cell_t *origin;
|
||||
pContext->LocalToPhysAddr(params[1], &origin);
|
||||
|
||||
Vector vOrigin(sp_ctof(origin[0]), sp_ctof(origin[1]), sp_ctof(origin[2]));
|
||||
|
||||
ClientRangeType rangeType = (ClientRangeType) params[2];
|
||||
|
||||
CBitVec<ABSOLUTE_PLAYER_LIMIT> players;
|
||||
engine->Message_DetermineMulticastRecipients(rangeType == ClientRangeType::Audibility, vOrigin, players);
|
||||
|
||||
cell_t *outPlayers;
|
||||
pContext->LocalToPhysAddr(params[3], &outPlayers);
|
||||
|
||||
int maxPlayers = params[4];
|
||||
int curPlayers = 0;
|
||||
|
||||
int index = players.FindNextSetBit(0);
|
||||
while (index > -1 && curPlayers < maxPlayers)
|
||||
{
|
||||
int entidx = index + 1;
|
||||
CPlayer *pPlayer = g_Players.GetPlayerByIndex(entidx);
|
||||
if (pPlayer && pPlayer->IsInGame())
|
||||
{
|
||||
outPlayers[curPlayers++] = entidx;
|
||||
}
|
||||
|
||||
index = players.FindNextSetBit(index + 1);
|
||||
}
|
||||
|
||||
return curPlayers;
|
||||
}
|
||||
|
||||
REGISTER_NATIVES(halflifeNatives)
|
||||
{
|
||||
{"CreateFakeClient", CreateFakeClient},
|
||||
@@ -648,6 +605,5 @@ REGISTER_NATIVES(halflifeNatives)
|
||||
{"EntIndexToEntRef", IndexToReference},
|
||||
{"EntRefToEntIndex", ReferenceToIndex},
|
||||
{"MakeCompatEntRef", ReferenceToBCompatRef},
|
||||
{"GetClientsInRange", GetClientsInRange},
|
||||
{NULL, NULL},
|
||||
};
|
||||
|
||||
@@ -797,32 +797,6 @@ static cell_t smn_FileToKeyValues(IPluginContext *pCtx, const cell_t *params)
|
||||
return g_HL2.KVLoadFromFile(kv, basefilesystem, path);
|
||||
}
|
||||
|
||||
static cell_t smn_StringToKeyValues(IPluginContext *pCtx, const cell_t *params)
|
||||
{
|
||||
Handle_t hndl = static_cast<Handle_t>(params[1]);
|
||||
HandleError herr;
|
||||
HandleSecurity sec;
|
||||
KeyValueStack *pStk;
|
||||
KeyValues *kv;
|
||||
|
||||
sec.pOwner = NULL;
|
||||
sec.pIdentity = g_pCoreIdent;
|
||||
|
||||
if ((herr=handlesys->ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
|
||||
!= HandleError_None)
|
||||
{
|
||||
return pCtx->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
|
||||
}
|
||||
|
||||
char *buffer;
|
||||
char *resourceName;
|
||||
pCtx->LocalToString(params[2], &buffer);
|
||||
pCtx->LocalToString(params[3], &resourceName);
|
||||
|
||||
kv = pStk->pCurRoot.front();
|
||||
return kv->LoadFromBuffer(resourceName, buffer);
|
||||
}
|
||||
|
||||
static cell_t smn_KvSetEscapeSequences(IPluginContext *pCtx, const cell_t *params)
|
||||
{
|
||||
Handle_t hndl = static_cast<Handle_t>(params[1]);
|
||||
@@ -1101,18 +1075,6 @@ static cell_t smn_KvGetSectionSymbol(IPluginContext *pCtx, const cell_t *params)
|
||||
return 1;
|
||||
}
|
||||
|
||||
static cell_t KeyValues_Import(IPluginContext *pContext, const cell_t *params)
|
||||
{
|
||||
// This version takes (dest, src). The original is (src, dest).
|
||||
cell_t new_params[3] = {
|
||||
2,
|
||||
params[2],
|
||||
params[1],
|
||||
};
|
||||
|
||||
return smn_CopySubkeys(pContext, new_params);
|
||||
}
|
||||
|
||||
static KeyValueNatives s_KeyValueNatives;
|
||||
|
||||
REGISTER_NATIVES(keyvaluenatives)
|
||||
@@ -1139,7 +1101,6 @@ REGISTER_NATIVES(keyvaluenatives)
|
||||
{"KvGetDataType", smn_KvGetDataType},
|
||||
{"KeyValuesToFile", smn_KeyValuesToFile},
|
||||
{"FileToKeyValues", smn_FileToKeyValues},
|
||||
{"StringToKeyValues", smn_StringToKeyValues},
|
||||
{"KvSetEscapeSequences", smn_KvSetEscapeSequences},
|
||||
{"KvDeleteThis", smn_KvDeleteThis},
|
||||
{"KvDeleteKey", smn_KvDeleteKey},
|
||||
@@ -1151,42 +1112,5 @@ REGISTER_NATIVES(keyvaluenatives)
|
||||
{"KvGetSectionSymbol", smn_KvGetSectionSymbol},
|
||||
{"KvGetVector", smn_KvGetVector},
|
||||
{"KvSetVector", smn_KvSetVector},
|
||||
|
||||
// Transitional syntax support.
|
||||
{"KeyValues.KeyValues", smn_CreateKeyValues},
|
||||
{"KeyValues.SetString", smn_KvSetString},
|
||||
{"KeyValues.SetNum", smn_KvSetNum},
|
||||
{"KeyValues.SetUInt64", smn_KvSetUInt64},
|
||||
{"KeyValues.SetFloat", smn_KvSetFloat},
|
||||
{"KeyValues.SetColor", smn_KvSetColor},
|
||||
{"KeyValues.GetString", smn_KvGetString},
|
||||
{"KeyValues.GetNum", smn_KvGetNum},
|
||||
{"KeyValues.GetFloat", smn_KvGetFloat},
|
||||
{"KeyValues.GetColor", smn_KvGetColor},
|
||||
{"KeyValues.GetUInt64", smn_KvGetUInt64},
|
||||
{"KeyValues.JumpToKey", smn_KvJumpToKey},
|
||||
{"KeyValues.JumpToKeySymbol", smn_KvJumpToKeySymbol},
|
||||
{"KeyValues.GotoNextKey", smn_KvGotoNextKey},
|
||||
{"KeyValues.GotoFirstSubKey", smn_KvGotoFirstSubKey},
|
||||
{"KeyValues.GoBack", smn_KvGoBack},
|
||||
{"KeyValues.Rewind", smn_KvRewind},
|
||||
{"KeyValues.GetSectionName", smn_KvGetSectionName},
|
||||
{"KeyValues.SetSectionName", smn_KvSetSectionName},
|
||||
{"KeyValues.GetDataType", smn_KvGetDataType},
|
||||
{"KeyValues.SetEscapeSequences", smn_KvSetEscapeSequences},
|
||||
{"KeyValues.DeleteThis", smn_KvDeleteThis},
|
||||
{"KeyValues.DeleteKey", smn_KvDeleteKey},
|
||||
{"KeyValues.NodesInStack", smn_KvNodesInStack},
|
||||
{"KeyValues.SavePosition", smn_KvSavePosition},
|
||||
{"KeyValues.FindKeyById", smn_FindKeyById},
|
||||
{"KeyValues.GetNameSymbol", smn_GetNameSymbol},
|
||||
{"KeyValues.GetSectionSymbol", smn_KvGetSectionSymbol},
|
||||
{"KeyValues.GetVector", smn_KvGetVector},
|
||||
{"KeyValues.SetVector", smn_KvSetVector},
|
||||
{"KeyValues.Import", KeyValues_Import},
|
||||
{"KeyValues.ImportFromFile", smn_FileToKeyValues},
|
||||
{"KeyValues.ImportFromString", smn_StringToKeyValues},
|
||||
{"KeyValues.ExportToFile", smn_KeyValuesToFile},
|
||||
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
||||
@@ -29,16 +29,20 @@
|
||||
* Version: $Id$
|
||||
*/
|
||||
|
||||
#include "common_logic.h"
|
||||
#include "sm_globals.h"
|
||||
#include <sh_stack.h>
|
||||
#include <IMenuManager.h>
|
||||
#include <IPlayerHelpers.h>
|
||||
#include "DebugReporter.h"
|
||||
#include "MenuManager.h"
|
||||
#include "MenuStyle_Valve.h"
|
||||
#include "MenuStyle_Radio.h"
|
||||
#include "PlayerManager.h"
|
||||
#include "sm_stringutil.h"
|
||||
#include "sourcemm_api.h"
|
||||
#if defined MENU_DEBUG
|
||||
#include "Logger.h"
|
||||
#endif
|
||||
#include <ISourceMod.h>
|
||||
#include <stdlib.h>
|
||||
#include "ChatTriggers.h"
|
||||
#include "logic_bridge.h"
|
||||
#include "sourcemod.h"
|
||||
|
||||
#if defined CreateMenu
|
||||
#undef CreateMenu
|
||||
@@ -64,50 +68,6 @@ enum MenuAction
|
||||
MenuAction_DisplayItem = (1<<9), /**< the odd duck */
|
||||
};
|
||||
|
||||
static HandleError ReadMenuHandle(Handle_t handle, IBaseMenu **menu)
|
||||
{
|
||||
static HandleType_t menuType = NO_HANDLE_TYPE;
|
||||
if (menuType == NO_HANDLE_TYPE && !handlesys->FindHandleType("IBaseMenu", &menuType))
|
||||
{
|
||||
// This should never happen so exact error doesn't matter.
|
||||
return HandleError_Index;
|
||||
}
|
||||
|
||||
HandleSecurity sec;
|
||||
sec.pIdentity = g_pCoreIdent;
|
||||
sec.pOwner = NULL;
|
||||
return handlesys->ReadHandle(handle, menuType, &sec, (void **)menu);
|
||||
}
|
||||
|
||||
static HandleError ReadStyleHandle(Handle_t handle, IMenuStyle **style)
|
||||
{
|
||||
static HandleType_t styleType = NO_HANDLE_TYPE;
|
||||
if (styleType == NO_HANDLE_TYPE && !handlesys->FindHandleType("IMenuStyle", &styleType))
|
||||
{
|
||||
// This should never happen so exact error doesn't matter.
|
||||
return HandleError_Index;
|
||||
}
|
||||
|
||||
HandleSecurity sec;
|
||||
|
||||
sec.pIdentity = g_pCoreIdent;
|
||||
sec.pOwner = g_pCoreIdent;
|
||||
|
||||
return handlesys->ReadHandle(handle, styleType, &sec, (void **)style);
|
||||
}
|
||||
|
||||
static IMenuStyle &ValveMenuStyle()
|
||||
{
|
||||
static IMenuStyle *valveMenuStyle = menus->FindStyleByName("valve");
|
||||
return *valveMenuStyle;
|
||||
}
|
||||
|
||||
static IMenuStyle &RadioMenuStyle()
|
||||
{
|
||||
static IMenuStyle *radioMenuStyle = menus->FindStyleByName("radio");
|
||||
return *radioMenuStyle;
|
||||
}
|
||||
|
||||
class CPanelHandler : public IMenuHandler
|
||||
{
|
||||
friend class MenuNativeHelpers;
|
||||
@@ -309,13 +269,13 @@ void CPanelHandler::OnMenuSelect(IBaseMenu *menu, int client, unsigned int item)
|
||||
{
|
||||
if (m_pFunc)
|
||||
{
|
||||
unsigned int old_reply = playerhelpers->SetReplyTo(SM_REPLY_CHAT);
|
||||
unsigned int old_reply = g_ChatTriggers.SetReplyTo(SM_REPLY_CHAT);
|
||||
m_pFunc->PushCell(BAD_HANDLE);
|
||||
m_pFunc->PushCell(MenuAction_Select);
|
||||
m_pFunc->PushCell(client);
|
||||
m_pFunc->PushCell(item);
|
||||
m_pFunc->Execute(NULL);
|
||||
playerhelpers->SetReplyTo(old_reply);
|
||||
g_ChatTriggers.SetReplyTo(old_reply);
|
||||
}
|
||||
g_MenuHelpers.FreePanelHandler(this);
|
||||
}
|
||||
@@ -370,18 +330,18 @@ void CMenuHandler::OnMenuSelect2(IBaseMenu *menu, int client, unsigned int item,
|
||||
|
||||
s_CurSelectPosition = &first_item;
|
||||
|
||||
unsigned int old_reply = playerhelpers->SetReplyTo(SM_REPLY_CHAT);
|
||||
unsigned int old_reply = g_ChatTriggers.SetReplyTo(SM_REPLY_CHAT);
|
||||
DoAction(menu, MenuAction_Select, client, item);
|
||||
playerhelpers->SetReplyTo(old_reply);
|
||||
g_ChatTriggers.SetReplyTo(old_reply);
|
||||
|
||||
s_CurSelectPosition = old_pos;
|
||||
}
|
||||
|
||||
void CMenuHandler::OnMenuCancel(IBaseMenu *menu, int client, MenuCancelReason reason)
|
||||
{
|
||||
unsigned int old_reply = playerhelpers->SetReplyTo(SM_REPLY_CHAT);
|
||||
unsigned int old_reply = g_ChatTriggers.SetReplyTo(SM_REPLY_CHAT);
|
||||
DoAction(menu, MenuAction_Cancel, client, (cell_t)reason);
|
||||
playerhelpers->SetReplyTo(old_reply);
|
||||
g_ChatTriggers.SetReplyTo(old_reply);
|
||||
}
|
||||
|
||||
void CMenuHandler::OnMenuEnd(IBaseMenu *menu, MenuEndReason reason)
|
||||
@@ -510,7 +470,7 @@ void CMenuHandler::OnMenuVoteResults(IBaseMenu *menu, const menu_vote_result_t *
|
||||
if ((err = pContext->HeapAlloc(client_array_size, &client_array_address, &client_array_base))
|
||||
!= SP_ERROR_NONE)
|
||||
{
|
||||
g_DbgReporter.GenerateError(pContext, m_fnVoteResult, err, "Menu callback could not allocate %d bytes for client list.", client_array_size * sizeof(cell_t));
|
||||
logicore.GenerateError(pContext, m_fnVoteResult, err, "Menu callback could not allocate %d bytes for client list.", client_array_size * sizeof(cell_t));
|
||||
no_call = true;
|
||||
} else {
|
||||
cell_t target_offs = sizeof(cell_t) * results->num_clients;
|
||||
@@ -543,7 +503,7 @@ void CMenuHandler::OnMenuVoteResults(IBaseMenu *menu, const menu_vote_result_t *
|
||||
if ((err = pContext->HeapAlloc(item_array_size, &item_array_address, &item_array_base))
|
||||
!= SP_ERROR_NONE)
|
||||
{
|
||||
g_DbgReporter.GenerateError(pContext, m_fnVoteResult, err, "Menu callback could not allocate %d bytes for item list.", item_array_size);
|
||||
logicore.GenerateError(pContext, m_fnVoteResult, err, "Menu callback could not allocate %d bytes for item list.", item_array_size);
|
||||
no_call = true;
|
||||
} else {
|
||||
cell_t target_offs = sizeof(cell_t) * results->num_items;
|
||||
@@ -632,14 +592,14 @@ inline IMenuStyle *GetStyleFromCell(cell_t cell)
|
||||
|
||||
if (cell == MenuStyle_Valve)
|
||||
{
|
||||
return &ValveMenuStyle();
|
||||
return &g_ValveMenuStyle;
|
||||
} else if (cell == MenuStyle_Radio
|
||||
&& RadioMenuStyle().IsSupported())
|
||||
&& g_RadioMenuStyle.IsSupported())
|
||||
{
|
||||
return &RadioMenuStyle();
|
||||
return &g_RadioMenuStyle;
|
||||
}
|
||||
|
||||
return menus->GetDefaultStyle();
|
||||
return g_Menus.GetDefaultStyle();
|
||||
}
|
||||
|
||||
/***********************************
|
||||
@@ -648,7 +608,7 @@ inline IMenuStyle *GetStyleFromCell(cell_t cell)
|
||||
|
||||
static cell_t CreateMenu(IPluginContext *pContext, const cell_t *params)
|
||||
{
|
||||
IMenuStyle *style = menus->GetDefaultStyle();
|
||||
IMenuStyle *style = g_Menus.GetDefaultStyle();
|
||||
IPluginFunction *pFunction;
|
||||
|
||||
if ((pFunction=pContext->GetFunctionById(params[1])) == NULL)
|
||||
@@ -675,7 +635,7 @@ static cell_t DisplayMenu(IPluginContext *pContext, const cell_t *params)
|
||||
HandleError err;
|
||||
IBaseMenu *menu;
|
||||
|
||||
if ((err = ReadMenuHandle(params[1], &menu)) != HandleError_None)
|
||||
if ((err=g_Menus.ReadMenuHandle(params[1], &menu)) != HandleError_None)
|
||||
{
|
||||
return pContext->ThrowNativeError("Menu handle %x is invalid (error %d)", hndl, err);
|
||||
}
|
||||
@@ -689,7 +649,7 @@ static cell_t DisplayMenuAtItem(IPluginContext *pContext, const cell_t *params)
|
||||
HandleError err;
|
||||
IBaseMenu *menu;
|
||||
|
||||
if ((err = ReadMenuHandle(params[1], &menu)) != HandleError_None)
|
||||
if ((err=g_Menus.ReadMenuHandle(params[1], &menu)) != HandleError_None)
|
||||
{
|
||||
return pContext->ThrowNativeError("Menu handle %x is invalid (error %d)", hndl, err);
|
||||
}
|
||||
@@ -699,7 +659,7 @@ static cell_t DisplayMenuAtItem(IPluginContext *pContext, const cell_t *params)
|
||||
|
||||
static cell_t VoteMenu(IPluginContext *pContext, const cell_t *params)
|
||||
{
|
||||
if (menus->IsVoteInProgress())
|
||||
if (g_Menus.IsVoteInProgress())
|
||||
{
|
||||
return pContext->ThrowNativeError("A vote is already in progress");
|
||||
}
|
||||
@@ -708,7 +668,7 @@ static cell_t VoteMenu(IPluginContext *pContext, const cell_t *params)
|
||||
HandleError err;
|
||||
IBaseMenu *menu;
|
||||
|
||||
if ((err = ReadMenuHandle(params[1], &menu)) != HandleError_None)
|
||||
if ((err=g_Menus.ReadMenuHandle(params[1], &menu)) != HandleError_None)
|
||||
{
|
||||
return pContext->ThrowNativeError("Menu handle %x is invalid (error %d)", hndl, err);
|
||||
}
|
||||
@@ -722,7 +682,7 @@ static cell_t VoteMenu(IPluginContext *pContext, const cell_t *params)
|
||||
flags = params[5];
|
||||
}
|
||||
|
||||
if (!menus->StartVote(menu, params[3], addr, params[4], flags))
|
||||
if (!g_Menus.StartVote(menu, params[3], addr, params[4], flags))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
@@ -736,7 +696,7 @@ static cell_t AddMenuItem(IPluginContext *pContext, const cell_t *params)
|
||||
HandleError err;
|
||||
IBaseMenu *menu;
|
||||
|
||||
if ((err = ReadMenuHandle(params[1], &menu)) != HandleError_None)
|
||||
if ((err=g_Menus.ReadMenuHandle(params[1], &menu)) != HandleError_None)
|
||||
{
|
||||
return pContext->ThrowNativeError("Menu handle %x is invalid (error %d)", hndl, err);
|
||||
}
|
||||
@@ -757,7 +717,7 @@ static cell_t InsertMenuItem(IPluginContext *pContext, const cell_t *params)
|
||||
HandleError err;
|
||||
IBaseMenu *menu;
|
||||
|
||||
if ((err = ReadMenuHandle(params[1], &menu)) != HandleError_None)
|
||||
if ((err=g_Menus.ReadMenuHandle(params[1], &menu)) != HandleError_None)
|
||||
{
|
||||
return pContext->ThrowNativeError("Menu handle %x is invalid (error %d)", hndl, err);
|
||||
}
|
||||
@@ -778,7 +738,7 @@ static cell_t RemoveMenuItem(IPluginContext *pContext, const cell_t *params)
|
||||
HandleError err;
|
||||
IBaseMenu *menu;
|
||||
|
||||
if ((err = ReadMenuHandle(params[1], &menu)) != HandleError_None)
|
||||
if ((err=g_Menus.ReadMenuHandle(params[1], &menu)) != HandleError_None)
|
||||
{
|
||||
return pContext->ThrowNativeError("Menu handle %x is invalid (error %d)", hndl, err);
|
||||
}
|
||||
@@ -792,7 +752,7 @@ static cell_t RemoveAllMenuItems(IPluginContext *pContext, const cell_t *params)
|
||||
HandleError err;
|
||||
IBaseMenu *menu;
|
||||
|
||||
if ((err = ReadMenuHandle(params[1], &menu)) != HandleError_None)
|
||||
if ((err=g_Menus.ReadMenuHandle(params[1], &menu)) != HandleError_None)
|
||||
{
|
||||
return pContext->ThrowNativeError("Menu handle %x is invalid (error %d)", hndl, err);
|
||||
}
|
||||
@@ -808,7 +768,7 @@ static cell_t GetMenuItem(IPluginContext *pContext, const cell_t *params)
|
||||
HandleError err;
|
||||
IBaseMenu *menu;
|
||||
|
||||
if ((err = ReadMenuHandle(params[1], &menu)) != HandleError_None)
|
||||
if ((err=g_Menus.ReadMenuHandle(params[1], &menu)) != HandleError_None)
|
||||
{
|
||||
return pContext->ThrowNativeError("Menu handle %x is invalid (error %d)", hndl, err);
|
||||
}
|
||||
@@ -837,7 +797,7 @@ static cell_t SetMenuPagination(IPluginContext *pContext, const cell_t *params)
|
||||
HandleError err;
|
||||
IBaseMenu *menu;
|
||||
|
||||
if ((err = ReadMenuHandle(params[1], &menu)) != HandleError_None)
|
||||
if ((err=g_Menus.ReadMenuHandle(params[1], &menu)) != HandleError_None)
|
||||
{
|
||||
return pContext->ThrowNativeError("Menu handle %x is invalid (error %d)", hndl, err);
|
||||
}
|
||||
@@ -851,7 +811,7 @@ static cell_t GetMenuPagination(IPluginContext *pContext, const cell_t *params)
|
||||
HandleError err;
|
||||
IBaseMenu *menu;
|
||||
|
||||
if ((err = ReadMenuHandle(params[1], &menu)) != HandleError_None)
|
||||
if ((err=g_Menus.ReadMenuHandle(params[1], &menu)) != HandleError_None)
|
||||
{
|
||||
return pContext->ThrowNativeError("Menu handle %x is invalid (error %d)", hndl, err);
|
||||
}
|
||||
@@ -865,7 +825,7 @@ static cell_t GetMenuItemCount(IPluginContext *pContext, const cell_t *params)
|
||||
HandleError err;
|
||||
IBaseMenu *menu;
|
||||
|
||||
if ((err = ReadMenuHandle(params[1], &menu)) != HandleError_None)
|
||||
if ((err=g_Menus.ReadMenuHandle(params[1], &menu)) != HandleError_None)
|
||||
{
|
||||
return pContext->ThrowNativeError("Menu handle %x is invalid (error %d)", hndl, err);
|
||||
}
|
||||
@@ -879,13 +839,13 @@ static cell_t SetMenuTitle(IPluginContext *pContext, const cell_t *params)
|
||||
HandleError err;
|
||||
IBaseMenu *menu;
|
||||
|
||||
if ((err = ReadMenuHandle(params[1], &menu)) != HandleError_None)
|
||||
if ((err=g_Menus.ReadMenuHandle(params[1], &menu)) != HandleError_None)
|
||||
{
|
||||
return pContext->ThrowNativeError("Menu handle %x is invalid (error %d)", hndl, err);
|
||||
}
|
||||
|
||||
char buffer[1024];
|
||||
g_pSM->FormatString(buffer, sizeof(buffer), pContext, params, 2);
|
||||
g_SourceMod.FormatString(buffer, sizeof(buffer), pContext, params, 2);
|
||||
|
||||
menu->SetDefaultTitle(buffer);
|
||||
|
||||
@@ -898,7 +858,7 @@ static cell_t GetMenuTitle(IPluginContext *pContext, const cell_t *params)
|
||||
HandleError err;
|
||||
IBaseMenu *menu;
|
||||
|
||||
if ((err = ReadMenuHandle(params[1], &menu)) != HandleError_None)
|
||||
if ((err=g_Menus.ReadMenuHandle(params[1], &menu)) != HandleError_None)
|
||||
{
|
||||
return pContext->ThrowNativeError("Menu handle %x is invalid (error %d)", hndl, err);
|
||||
}
|
||||
@@ -917,7 +877,7 @@ static cell_t CreatePanelFromMenu(IPluginContext *pContext, const cell_t *params
|
||||
HandleError err;
|
||||
IBaseMenu *menu;
|
||||
|
||||
if ((err = ReadMenuHandle(params[1], &menu)) != HandleError_None)
|
||||
if ((err=g_Menus.ReadMenuHandle(params[1], &menu)) != HandleError_None)
|
||||
{
|
||||
return pContext->ThrowNativeError("Menu handle %x is invalid (error %d)", hndl, err);
|
||||
}
|
||||
@@ -938,7 +898,7 @@ static cell_t GetMenuExitButton(IPluginContext *pContext, const cell_t *params)
|
||||
HandleError err;
|
||||
IBaseMenu *menu;
|
||||
|
||||
if ((err = ReadMenuHandle(params[1], &menu)) != HandleError_None)
|
||||
if ((err=g_Menus.ReadMenuHandle(params[1], &menu)) != HandleError_None)
|
||||
{
|
||||
return pContext->ThrowNativeError("Menu handle %x is invalid (error %d)", hndl, err);
|
||||
}
|
||||
@@ -952,7 +912,7 @@ static cell_t GetMenuExitBackButton(IPluginContext *pContext, const cell_t *para
|
||||
HandleError err;
|
||||
IBaseMenu *menu;
|
||||
|
||||
if ((err = ReadMenuHandle(params[1], &menu)) != HandleError_None)
|
||||
if ((err=g_Menus.ReadMenuHandle(params[1], &menu)) != HandleError_None)
|
||||
{
|
||||
return pContext->ThrowNativeError("Menu handle %x is invalid (error %d)", hndl, err);
|
||||
}
|
||||
@@ -966,7 +926,7 @@ static cell_t SetMenuExitButton(IPluginContext *pContext, const cell_t *params)
|
||||
HandleError err;
|
||||
IBaseMenu *menu;
|
||||
|
||||
if ((err = ReadMenuHandle(params[1], &menu)) != HandleError_None)
|
||||
if ((err=g_Menus.ReadMenuHandle(params[1], &menu)) != HandleError_None)
|
||||
{
|
||||
return pContext->ThrowNativeError("Menu handle %x is invalid (error %d)", hndl, err);
|
||||
}
|
||||
@@ -992,7 +952,7 @@ static cell_t SetMenuNoVoteButton(IPluginContext *pContext, const cell_t *params
|
||||
HandleError err;
|
||||
IBaseMenu *menu;
|
||||
|
||||
if ((err = ReadMenuHandle(params[1], &menu)) != HandleError_None)
|
||||
if ((err=g_Menus.ReadMenuHandle(params[1], &menu)) != HandleError_None)
|
||||
{
|
||||
return pContext->ThrowNativeError("Menu handle %x is invalid (error %d)", hndl, err);
|
||||
}
|
||||
@@ -1018,7 +978,7 @@ static cell_t SetMenuExitBackButton(IPluginContext *pContext, const cell_t *para
|
||||
HandleError err;
|
||||
IBaseMenu *menu;
|
||||
|
||||
if ((err = ReadMenuHandle(params[1], &menu)) != HandleError_None)
|
||||
if ((err=g_Menus.ReadMenuHandle(params[1], &menu)) != HandleError_None)
|
||||
{
|
||||
return pContext->ThrowNativeError("Menu handle %x is invalid (error %d)", hndl, err);
|
||||
}
|
||||
@@ -1043,19 +1003,19 @@ static cell_t CancelMenu(IPluginContext *pContext, const cell_t *params)
|
||||
HandleError err;
|
||||
IBaseMenu *menu;
|
||||
|
||||
if ((err = ReadMenuHandle(params[1], &menu)) != HandleError_None)
|
||||
if ((err=g_Menus.ReadMenuHandle(params[1], &menu)) != HandleError_None)
|
||||
{
|
||||
return pContext->ThrowNativeError("Menu handle %x is invalid (error %d)", hndl, err);
|
||||
}
|
||||
|
||||
menus->CancelMenu(menu);
|
||||
g_Menus.CancelMenu(menu);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static cell_t IsVoteInProgress(IPluginContext *pContext, const cell_t *params)
|
||||
{
|
||||
return menus->IsVoteInProgress() ? 1 : 0;
|
||||
return g_Menus.IsVoteInProgress() ? 1 : 0;
|
||||
}
|
||||
|
||||
static cell_t GetMenuStyle(IPluginContext *pContext, const cell_t *params)
|
||||
@@ -1064,7 +1024,7 @@ static cell_t GetMenuStyle(IPluginContext *pContext, const cell_t *params)
|
||||
HandleError err;
|
||||
IBaseMenu *menu;
|
||||
|
||||
if ((err = ReadMenuHandle(params[1], &menu)) != HandleError_None)
|
||||
if ((err=g_Menus.ReadMenuHandle(params[1], &menu)) != HandleError_None)
|
||||
{
|
||||
return pContext->ThrowNativeError("Menu handle %x is invalid (error %d)", hndl, err);
|
||||
}
|
||||
@@ -1091,12 +1051,12 @@ static cell_t CreatePanel(IPluginContext *pContext, const cell_t *params)
|
||||
|
||||
if (hndl != 0)
|
||||
{
|
||||
if ((err = ReadStyleHandle(params[1], &style)) != HandleError_None)
|
||||
if ((err=g_Menus.ReadStyleHandle(params[1], &style)) != HandleError_None)
|
||||
{
|
||||
return pContext->ThrowNativeError("MenuStyle handle %x is invalid (error %d)", hndl, err);
|
||||
}
|
||||
} else {
|
||||
style = menus->GetDefaultStyle();
|
||||
style = g_Menus.GetDefaultStyle();
|
||||
}
|
||||
|
||||
IMenuPanel *panel = style->CreatePanel();
|
||||
@@ -1119,12 +1079,12 @@ static cell_t CreateMenuEx(IPluginContext *pContext, const cell_t *params)
|
||||
|
||||
if (hndl != 0)
|
||||
{
|
||||
if ((err = ReadStyleHandle(params[1], &style)) != HandleError_None)
|
||||
if ((err=g_Menus.ReadStyleHandle(params[1], &style)) != HandleError_None)
|
||||
{
|
||||
return pContext->ThrowNativeError("MenuStyle handle %x is invalid (error %d)", hndl, err);
|
||||
}
|
||||
} else {
|
||||
style = menus->GetDefaultStyle();
|
||||
style = g_Menus.GetDefaultStyle();
|
||||
}
|
||||
|
||||
IPluginFunction *pFunction;
|
||||
@@ -1154,12 +1114,12 @@ static cell_t GetClientMenu(IPluginContext *pContext, const cell_t *params)
|
||||
|
||||
if (hndl != 0)
|
||||
{
|
||||
if ((err = ReadStyleHandle(params[1], &style)) != HandleError_None)
|
||||
if ((err=g_Menus.ReadStyleHandle(params[1], &style)) != HandleError_None)
|
||||
{
|
||||
return pContext->ThrowNativeError("MenuStyle handle %x is invalid (error %d)", hndl, err);
|
||||
}
|
||||
} else {
|
||||
style = menus->GetDefaultStyle();
|
||||
style = g_Menus.GetDefaultStyle();
|
||||
}
|
||||
|
||||
return style->GetClientMenu(params[1], NULL);
|
||||
@@ -1173,12 +1133,12 @@ static cell_t CancelClientMenu(IPluginContext *pContext, const cell_t *params)
|
||||
|
||||
if (hndl != 0)
|
||||
{
|
||||
if ((err = ReadStyleHandle(params[1], &style)) != HandleError_None)
|
||||
if ((err=g_Menus.ReadStyleHandle(params[1], &style)) != HandleError_None)
|
||||
{
|
||||
return pContext->ThrowNativeError("MenuStyle handle %x is invalid (error %d)", hndl, err);
|
||||
}
|
||||
} else {
|
||||
style = menus->GetDefaultStyle();
|
||||
style = g_Menus.GetDefaultStyle();
|
||||
}
|
||||
|
||||
return style->CancelClientMenu(params[1], params[2] ? true : false) ? 1 : 0;
|
||||
@@ -1192,12 +1152,12 @@ static cell_t GetMaxPageItems(IPluginContext *pContext, const cell_t *params)
|
||||
|
||||
if (hndl != 0)
|
||||
{
|
||||
if ((err = ReadStyleHandle(params[1], &style)) != HandleError_None)
|
||||
if ((err=g_Menus.ReadStyleHandle(params[1], &style)) != HandleError_None)
|
||||
{
|
||||
return pContext->ThrowNativeError("MenuStyle handle %x is invalid (error %d)", hndl, err);
|
||||
}
|
||||
} else {
|
||||
style = menus->GetDefaultStyle();
|
||||
style = g_Menus.GetDefaultStyle();
|
||||
}
|
||||
|
||||
return style->GetMaxPageItems();
|
||||
@@ -1394,7 +1354,7 @@ static cell_t GetMenuOptionFlags(IPluginContext *pContext, const cell_t *params)
|
||||
HandleError err;
|
||||
IBaseMenu *menu;
|
||||
|
||||
if ((err = ReadMenuHandle(params[1], &menu)) != HandleError_None)
|
||||
if ((err=g_Menus.ReadMenuHandle(params[1], &menu)) != HandleError_None)
|
||||
{
|
||||
return pContext->ThrowNativeError("Menu handle %x is invalid (error %d)", hndl, err);
|
||||
}
|
||||
@@ -1408,7 +1368,7 @@ static cell_t SetMenuOptionFlags(IPluginContext *pContext, const cell_t *params)
|
||||
HandleError err;
|
||||
IBaseMenu *menu;
|
||||
|
||||
if ((err = ReadMenuHandle(params[1], &menu)) != HandleError_None)
|
||||
if ((err=g_Menus.ReadMenuHandle(params[1], &menu)) != HandleError_None)
|
||||
{
|
||||
return pContext->ThrowNativeError("Menu handle %x is invalid (error %d)", hndl, err);
|
||||
}
|
||||
@@ -1420,12 +1380,12 @@ static cell_t SetMenuOptionFlags(IPluginContext *pContext, const cell_t *params)
|
||||
|
||||
static cell_t CancelVote(IPluginContext *pContxt, const cell_t *params)
|
||||
{
|
||||
if (!menus->IsVoteInProgress())
|
||||
if (!g_Menus.IsVoteInProgress())
|
||||
{
|
||||
return pContxt->ThrowNativeError("No vote is in progress");
|
||||
}
|
||||
|
||||
menus->CancelVoting();
|
||||
g_Menus.CancelVoting();
|
||||
|
||||
return 1;
|
||||
}
|
||||
@@ -1436,7 +1396,7 @@ static cell_t SetVoteResultCallback(IPluginContext *pContext, const cell_t *para
|
||||
HandleError err;
|
||||
IBaseMenu *menu;
|
||||
|
||||
if ((err = ReadMenuHandle(params[1], &menu)) != HandleError_None)
|
||||
if ((err=g_Menus.ReadMenuHandle(params[1], &menu)) != HandleError_None)
|
||||
{
|
||||
return pContext->ThrowNativeError("Menu handle %x is invalid (error %d)", hndl, err);
|
||||
}
|
||||
@@ -1462,7 +1422,7 @@ static cell_t SetVoteResultCallback(IPluginContext *pContext, const cell_t *para
|
||||
|
||||
static cell_t CheckVoteDelay(IPluginContext *pContext, const cell_t *params)
|
||||
{
|
||||
return menus->GetRemainingVoteDelay();
|
||||
return g_Menus.GetRemainingVoteDelay();
|
||||
}
|
||||
|
||||
static cell_t GetMenuSelectionPosition(IPluginContext *pContext, const cell_t *params)
|
||||
@@ -1481,17 +1441,17 @@ static cell_t IsClientInVotePool(IPluginContext *pContext, const cell_t *params)
|
||||
IGamePlayer *pPlayer;
|
||||
|
||||
client = params[1];
|
||||
if ((pPlayer = playerhelpers->GetGamePlayer(client)) == NULL)
|
||||
if ((pPlayer = g_Players.GetPlayerByIndex(client)) == NULL)
|
||||
{
|
||||
return pContext->ThrowNativeError("Invalid client index %d", client);
|
||||
}
|
||||
|
||||
if (!menus->IsVoteInProgress())
|
||||
if (!g_Menus.IsVoteInProgress())
|
||||
{
|
||||
return pContext->ThrowNativeError("No vote is in progress");
|
||||
}
|
||||
|
||||
return menus->IsClientInVotePool(client) ? 1 : 0;
|
||||
return g_Menus.IsClientInVotePool(client) ? 1 : 0;
|
||||
}
|
||||
|
||||
static cell_t RedrawClientVoteMenu(IPluginContext *pContext, const cell_t *params)
|
||||
@@ -1500,17 +1460,17 @@ static cell_t RedrawClientVoteMenu(IPluginContext *pContext, const cell_t *param
|
||||
IGamePlayer *pPlayer;
|
||||
|
||||
client = params[1];
|
||||
if ((pPlayer = playerhelpers->GetGamePlayer(client)) == NULL)
|
||||
if ((pPlayer = g_Players.GetPlayerByIndex(client)) == NULL)
|
||||
{
|
||||
return pContext->ThrowNativeError("Invalid client index %d", client);
|
||||
}
|
||||
|
||||
if (!menus->IsVoteInProgress())
|
||||
if (!g_Menus.IsVoteInProgress())
|
||||
{
|
||||
return pContext->ThrowNativeError("No vote is in progress");
|
||||
}
|
||||
|
||||
if (!menus->IsClientInVotePool(client))
|
||||
if (!g_Menus.IsClientInVotePool(client))
|
||||
{
|
||||
return pContext->ThrowNativeError("Client is not in the voting pool");
|
||||
}
|
||||
@@ -1521,7 +1481,7 @@ static cell_t RedrawClientVoteMenu(IPluginContext *pContext, const cell_t *param
|
||||
revote = false;
|
||||
}
|
||||
|
||||
return menus->RedrawClientVoteMenu2(client, revote) ? 1 : 0;
|
||||
return g_Menus.RedrawClientVoteMenu2(client, revote) ? 1 : 0;
|
||||
}
|
||||
|
||||
class EmptyMenuHandler : public IMenuHandler
|
||||
@@ -1532,7 +1492,7 @@ public:
|
||||
static cell_t InternalShowMenu(IPluginContext *pContext, const cell_t *params)
|
||||
{
|
||||
int client = params[1];
|
||||
IGamePlayer *pPlayer = playerhelpers->GetGamePlayer(client);
|
||||
CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
|
||||
|
||||
if (pPlayer == NULL)
|
||||
{
|
||||
@@ -1543,7 +1503,7 @@ static cell_t InternalShowMenu(IPluginContext *pContext, const cell_t *params)
|
||||
return pContext->ThrowNativeError("Client %d is not in game", client);
|
||||
}
|
||||
|
||||
if (!RadioMenuStyle().IsSupported())
|
||||
if (!g_RadioMenuStyle.IsSupported())
|
||||
{
|
||||
return pContext->ThrowNativeError("Radio menus are not supported on this mod");
|
||||
}
|
||||
@@ -1551,16 +1511,13 @@ static cell_t InternalShowMenu(IPluginContext *pContext, const cell_t *params)
|
||||
char *str;
|
||||
pContext->LocalToString(params[2], &str);
|
||||
|
||||
IMenuPanel *pPanel = RadioMenuStyle().CreatePanel();
|
||||
IMenuPanel *pPanel = g_RadioMenuStyle.MakeRadioDisplay(str, params[4]);
|
||||
|
||||
if (pPanel == NULL)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
pPanel->DirectSet(str);
|
||||
pPanel->SetSelectableKeys(params[4]);
|
||||
|
||||
IMenuHandler *pHandler;
|
||||
CPanelHandler *pActualHandler = NULL;
|
||||
if (params[5] != -1)
|
||||
@@ -1645,47 +1602,6 @@ REGISTER_NATIVES(menuNatives)
|
||||
{"SetVoteResultCallback", SetVoteResultCallback},
|
||||
{"VoteMenu", VoteMenu},
|
||||
{"SetMenuNoVoteButton", SetMenuNoVoteButton},
|
||||
|
||||
// Transitional syntax support.
|
||||
{"Panel.Panel", CreatePanel},
|
||||
{"Panel.TextRemaining.get", GetPanelTextRemaining},
|
||||
{"Panel.CurrentKey.get", GetPanelCurrentKey},
|
||||
{"Panel.CurrentKey.set", SetPanelCurrentKey},
|
||||
{"Panel.Style", GetPanelStyle},
|
||||
{"Panel.CanDrawFlags", CanPanelDrawFlags},
|
||||
{"Panel.SetTitle", SetPanelTitle},
|
||||
{"Panel.SetKeys", SetPanelKeys},
|
||||
{"Panel.Send", SendPanelToClient},
|
||||
{"Panel.DrawItem", DrawPanelItem},
|
||||
{"Panel.DrawText", DrawPanelText},
|
||||
|
||||
{"Menu.Menu", CreateMenu},
|
||||
{"Menu.Display", DisplayMenu},
|
||||
{"Menu.DisplayAt", DisplayMenuAtItem},
|
||||
{"Menu.AddItem", AddMenuItem},
|
||||
{"Menu.InsertItem", InsertMenuItem},
|
||||
{"Menu.RemoveItem", RemoveMenuItem},
|
||||
{"Menu.RemoveAllItems", RemoveAllMenuItems},
|
||||
{"Menu.GetItem", GetMenuItem},
|
||||
{"Menu.GetTitle", GetMenuTitle},
|
||||
{"Menu.SetTitle", SetMenuTitle},
|
||||
{"Menu.ToPanel", CreatePanelFromMenu},
|
||||
{"Menu.Cancel", CancelMenu},
|
||||
{"Menu.DisplayVote", VoteMenu},
|
||||
{"Menu.Pagination.get", GetMenuPagination},
|
||||
{"Menu.Pagination.set", SetMenuPagination},
|
||||
{"Menu.OptionFlags.get", GetMenuOptionFlags},
|
||||
{"Menu.OptionFlags.set", SetMenuOptionFlags},
|
||||
{"Menu.ExitButton.get", GetMenuExitButton},
|
||||
{"Menu.ExitButton.set", SetMenuExitButton},
|
||||
{"Menu.ExitBackButton.get", GetMenuExitBackButton},
|
||||
{"Menu.ExitBackButton.set", SetMenuExitBackButton},
|
||||
{"Menu.NoVoteButton.set", SetMenuNoVoteButton},
|
||||
{"Menu.VoteResultCallback.set", SetVoteResultCallback},
|
||||
{"Menu.ItemCount.get", GetMenuItemCount},
|
||||
{"Menu.Style.get", GetMenuStyle},
|
||||
{"Menu.Selection.get", GetMenuSelectionPosition},
|
||||
|
||||
{NULL, NULL},
|
||||
};
|
||||
|
||||
+1
-33
@@ -811,38 +811,6 @@ REGISTER_NATIVES(protobufnatives)
|
||||
{"PbReadMessage", smn_PbReadMessage},
|
||||
{"PbReadRepeatedMessage", smn_PbReadRepeatedMessage},
|
||||
{"PbAddMessage", smn_PbAddMessage},
|
||||
|
||||
// Transitional syntax.
|
||||
{"Protobuf.ReadInt", smn_PbReadInt},
|
||||
{"Protobuf.ReadFloat", smn_PbReadFloat},
|
||||
{"Protobuf.ReadBool", smn_PbReadBool},
|
||||
{"Protobuf.ReadString", smn_PbReadString},
|
||||
{"Protobuf.ReadColor", smn_PbReadColor},
|
||||
{"Protobuf.ReadAngle", smn_PbReadAngle},
|
||||
{"Protobuf.ReadVector", smn_PbReadVector},
|
||||
{"Protobuf.ReadVector2D", smn_PbReadVector2D},
|
||||
{"Protobuf.GetRepeatedFieldCount", smn_PbGetRepeatedFieldCount},
|
||||
{"Protobuf.SetInt", smn_PbSetInt},
|
||||
{"Protobuf.SetFloat", smn_PbSetFloat},
|
||||
{"Protobuf.SetBool", smn_PbSetBool},
|
||||
{"Protobuf.SetString", smn_PbSetString},
|
||||
{"Protobuf.SetColor", smn_PbSetColor},
|
||||
{"Protobuf.SetAngle", smn_PbSetAngle},
|
||||
{"Protobuf.SetVector", smn_PbSetVector},
|
||||
{"Protobuf.SetVector2D", smn_PbSetVector2D},
|
||||
{"Protobuf.AddInt", smn_PbAddInt},
|
||||
{"Protobuf.AddFloat", smn_PbAddFloat},
|
||||
{"Protobuf.AddBool", smn_PbAddBool},
|
||||
{"Protobuf.AddString", smn_PbAddString},
|
||||
{"Protobuf.AddColor", smn_PbAddColor},
|
||||
{"Protobuf.AddAngle", smn_PbAddAngle},
|
||||
{"Protobuf.AddVector", smn_PbAddVector},
|
||||
{"Protobuf.AddVector2D", smn_PbAddVector2D},
|
||||
{"Protobuf.RemoveRepeatedFieldValue", smn_PbRemoveRepeatedFieldValue},
|
||||
{"Protobuf.ReadMessage", smn_PbReadMessage},
|
||||
{"Protobuf.ReadRepeatedMessage", smn_PbReadRepeatedMessage},
|
||||
{"Protobuf.AddMessage", smn_PbAddMessage},
|
||||
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
||||
@@ -852,7 +820,7 @@ REGISTER_NATIVES(protobufnatives)
|
||||
@@@@@@@@@@@@@@@@@@@@@
|
||||
@@@@@@@@@@@@@@@@@@@@@@@@
|
||||
@@@@@@@@ @@@@@@@@@@@@@
|
||||
@@@@@@@@ o @@@@@@@@@@@@@
|
||||
@@@@@@@@ @@@@@@@@@@@@@
|
||||
@@@@@@ @@@@@@@@@@@@@@@
|
||||
0000 @@@@@@@@@@@@@@@@@@@@@
|
||||
000000000 @@@@@@@@@@@@@@@@@@@
|
||||
|
||||
@@ -45,15 +45,13 @@ ISmmPluginManager *g_pMMPlugins = NULL;
|
||||
CGlobalVars *gpGlobals = NULL;
|
||||
ICvar *icvar = NULL;
|
||||
IGameEventManager2 *gameevents = NULL;
|
||||
IUniformRandomStream *engrandom = NULL;
|
||||
CallClass<IVEngineServer> *enginePatch = NULL;
|
||||
CallClass<IServerGameDLL> *gamedllPatch = NULL;
|
||||
IPlayerInfoManager *playerinfo = NULL;
|
||||
IBaseFileSystem *basefilesystem = NULL;
|
||||
IFileSystem *filesystem = NULL;
|
||||
IEngineSound *enginesound = NULL;
|
||||
#if SOURCE_ENGINE >= SE_ORANGEBOX
|
||||
IServerTools *servertools = NULL;
|
||||
#endif
|
||||
IServerPluginHelpers *serverpluginhelpers = NULL;
|
||||
IServerPluginCallbacks *vsp_interface = NULL;
|
||||
int vsp_version = 0;
|
||||
@@ -69,12 +67,10 @@ bool SourceMod_Core::Load(PluginId id, ISmmAPI *ismm, char *error, size_t maxlen
|
||||
GET_V_IFACE_CURRENT(GetServerFactory, serverClients, IServerGameClients, INTERFACEVERSION_SERVERGAMECLIENTS);
|
||||
GET_V_IFACE_CURRENT(GetEngineFactory, icvar, ICvar, CVAR_INTERFACE_VERSION);
|
||||
GET_V_IFACE_CURRENT(GetEngineFactory, gameevents, IGameEventManager2, INTERFACEVERSION_GAMEEVENTSMANAGER2);
|
||||
GET_V_IFACE_CURRENT(GetEngineFactory, engrandom, IUniformRandomStream, VENGINE_SERVER_RANDOM_INTERFACE_VERSION);
|
||||
GET_V_IFACE_CURRENT(GetFileSystemFactory, basefilesystem, IBaseFileSystem, BASEFILESYSTEM_INTERFACE_VERSION);
|
||||
GET_V_IFACE_CURRENT(GetFileSystemFactory, filesystem, IFileSystem, FILESYSTEM_INTERFACE_VERSION);
|
||||
GET_V_IFACE_CURRENT(GetEngineFactory, enginesound, IEngineSound, IENGINESOUND_SERVER_INTERFACE_VERSION);
|
||||
#if SOURCE_ENGINE >= SE_ORANGEBOX
|
||||
GET_V_IFACE_CURRENT(GetServerFactory, servertools, IServerTools, VSERVERTOOLS_INTERFACE_VERSION);
|
||||
#endif
|
||||
#if SOURCE_ENGINE != SE_DOTA
|
||||
GET_V_IFACE_CURRENT(GetEngineFactory, serverpluginhelpers, IServerPluginHelpers, INTERFACEVERSION_ISERVERPLUGINHELPERS);
|
||||
#endif
|
||||
@@ -171,7 +167,7 @@ void SourceMod_Core::OnVSPListening(IServerPluginCallbacks *iface)
|
||||
/* This shouldn't happen */
|
||||
if (!iface)
|
||||
{
|
||||
logger->LogFatal("Metamod:Source version is out of date. SourceMod requires 1.4.2 or greater.");
|
||||
g_Logger.LogFatal("Metamod:Source version is out of date. SourceMod requires 1.4.2 or greater.");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
+2
-4
@@ -47,9 +47,9 @@
|
||||
#include <eiface.h>
|
||||
#include <igameevents.h>
|
||||
#include <iplayerinfo.h>
|
||||
#include <random.h>
|
||||
#include <filesystem.h>
|
||||
#include <IEngineSound.h>
|
||||
#include <toolframework/itoolentity.h>
|
||||
|
||||
#ifndef METAMOD_PLAPI_VERSION
|
||||
#include <metamod_wrappers.h>
|
||||
@@ -98,13 +98,11 @@ extern CGlobalVars *gpGlobals;
|
||||
extern IGameEventManager2 *gameevents;
|
||||
extern SourceHook::CallClass<IVEngineServer> *enginePatch;
|
||||
extern SourceHook::CallClass<IServerGameDLL> *gamedllPatch;
|
||||
extern IUniformRandomStream *engrandom;
|
||||
extern IPlayerInfoManager *playerinfo;
|
||||
extern IBaseFileSystem *basefilesystem;
|
||||
extern IFileSystem *filesystem;
|
||||
extern IEngineSound *enginesound;
|
||||
#if SOURCE_ENGINE >= SE_ORANGEBOX
|
||||
extern IServerTools *servertools;
|
||||
#endif
|
||||
extern IServerPluginHelpers *serverpluginhelpers;
|
||||
extern IServerPluginCallbacks *vsp_interface;
|
||||
extern int vsp_version;
|
||||
|
||||
+4
-5
@@ -395,7 +395,6 @@ void SourceModBase::LevelShutdown()
|
||||
{
|
||||
g_pOnMapEnd->Execute(NULL);
|
||||
}
|
||||
extsys->CallOnCoreMapEnd();
|
||||
|
||||
g_Timers.RemoveMapChangeTimers();
|
||||
|
||||
@@ -573,9 +572,9 @@ void SourceModBase::LogMessage(IExtension *pExt, const char *format, ...)
|
||||
|
||||
if (tag)
|
||||
{
|
||||
logger->LogMessage("[%s] %s", tag, buffer);
|
||||
g_Logger.LogMessage("[%s] %s", tag, buffer);
|
||||
} else {
|
||||
logger->LogMessage("%s", buffer);
|
||||
g_Logger.LogMessage("%s", buffer);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -592,9 +591,9 @@ void SourceModBase::LogError(IExtension *pExt, const char *format, ...)
|
||||
|
||||
if (tag)
|
||||
{
|
||||
logger->LogError("[%s] %s", tag, buffer);
|
||||
g_Logger.LogError("[%s] %s", tag, buffer);
|
||||
} else {
|
||||
logger->LogError("%s", buffer);
|
||||
g_Logger.LogError("%s", buffer);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,117 +0,0 @@
|
||||
// vim: set ts=4 sw=4 tw=99 noet :
|
||||
// =============================================================================
|
||||
// SourceMod
|
||||
// Copyright (C) 2004-2014 AlliedModders LLC. All rights reserved.
|
||||
// =============================================================================
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify it under
|
||||
// the terms of the GNU General Public License, version 3.0, as published by the
|
||||
// Free Software Foundation.
|
||||
//
|
||||
// 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/>.
|
||||
//
|
||||
// As a special exception, AlliedModders LLC gives you permission to link the
|
||||
// code of this program (as well as its derivative works) to "Half-Life 2," the
|
||||
// "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
|
||||
// by the Valve Corporation. You must obey the GNU General Public License in
|
||||
// all respects for all other code used. Additionally, AlliedModders LLC grants
|
||||
// this exception to all derivative works. AlliedModders LLC defines further
|
||||
// exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
|
||||
// or <http://www.sourcemod.net/license.php>.
|
||||
|
||||
#include "vprof_tool.h"
|
||||
#include "logic_bridge.h"
|
||||
#include "sourcemod.h"
|
||||
#include "sourcemm_api.h"
|
||||
|
||||
#define VPROF_ENABLED
|
||||
#define RAD_TELEMETRY_DISABLED
|
||||
#include <tier0/vprof.h>
|
||||
|
||||
VProfTool sVProfTool;
|
||||
|
||||
VProfTool::VProfTool()
|
||||
: active_(false)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
VProfTool::OnSourceModAllInitialized()
|
||||
{
|
||||
logicore.RegisterProfiler(this);
|
||||
}
|
||||
|
||||
const char *
|
||||
VProfTool::Name()
|
||||
{
|
||||
return "vprof";
|
||||
}
|
||||
|
||||
const char *
|
||||
VProfTool::Description()
|
||||
{
|
||||
return "Valve built-in profiler";
|
||||
}
|
||||
|
||||
bool
|
||||
VProfTool::Start()
|
||||
{
|
||||
g_VProfCurrentProfile.Start();
|
||||
return IsActive();
|
||||
}
|
||||
|
||||
void
|
||||
VProfTool::Stop(void (*render)(const char *fmt, ...))
|
||||
{
|
||||
g_VProfCurrentProfile.Stop();
|
||||
RenderHelp(render);
|
||||
}
|
||||
|
||||
void
|
||||
VProfTool::Dump()
|
||||
{
|
||||
g_VProfCurrentProfile.Pause();
|
||||
g_VProfCurrentProfile.OutputReport(VPRT_FULL);
|
||||
g_VProfCurrentProfile.Resume();
|
||||
}
|
||||
|
||||
bool
|
||||
VProfTool::IsActive()
|
||||
{
|
||||
return g_VProfCurrentProfile.IsEnabled();
|
||||
}
|
||||
|
||||
bool
|
||||
VProfTool::IsAttached()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
VProfTool::EnterScope(const char *group, const char *name)
|
||||
{
|
||||
if (IsActive()) {
|
||||
if (!group)
|
||||
group = VPROF_BUDGETGROUP_OTHER_UNACCOUNTED;
|
||||
g_VProfCurrentProfile.EnterScope(name, 1, group, false, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
VProfTool::LeaveScope()
|
||||
{
|
||||
if (IsActive())
|
||||
g_VProfCurrentProfile.ExitScope();
|
||||
}
|
||||
|
||||
void
|
||||
VProfTool::RenderHelp(void (*render)(const char *fmt, ...))
|
||||
{
|
||||
render("Use 'sm prof dump vprof' or one of the vprof_generate_report commands in your console to analyze a profile session.");
|
||||
}
|
||||
@@ -1,61 +0,0 @@
|
||||
// vim: set ts=4 sw=4 tw=99 noet :
|
||||
// =============================================================================
|
||||
// SourceMod
|
||||
// Copyright (C) 2004-2014 AlliedModders LLC. All rights reserved.
|
||||
// =============================================================================
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify it under
|
||||
// the terms of the GNU General Public License, version 3.0, as published by the
|
||||
// Free Software Foundation.
|
||||
//
|
||||
// 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/>.
|
||||
//
|
||||
// As a special exception, AlliedModders LLC gives you permission to link the
|
||||
// code of this program (as well as its derivative works) to "Half-Life 2," the
|
||||
// "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
|
||||
// by the Valve Corporation. You must obey the GNU General Public License in
|
||||
// all respects for all other code used. Additionally, AlliedModders LLC grants
|
||||
// this exception to all derivative works. AlliedModders LLC defines further
|
||||
// exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
|
||||
// or <http://www.sourcemod.net/license.php>.
|
||||
|
||||
#ifndef _include_sourcemod_core_vprof_bridge_h_
|
||||
#define _include_sourcemod_core_vprof_bridge_h_
|
||||
|
||||
#include <sp_vm_api.h>
|
||||
#include "sm_globals.h"
|
||||
#include <am-utility.h>
|
||||
|
||||
class VProfTool
|
||||
: public IProfilingTool,
|
||||
public SMGlobalClass
|
||||
{
|
||||
public:
|
||||
VProfTool();
|
||||
|
||||
// IProfilingTool
|
||||
const char *Name() KE_OVERRIDE;
|
||||
const char *Description() KE_OVERRIDE;
|
||||
bool Start() KE_OVERRIDE;
|
||||
void Stop(void (*render)(const char *fmt, ...)) KE_OVERRIDE;
|
||||
void Dump() KE_OVERRIDE;
|
||||
bool IsActive() KE_OVERRIDE;
|
||||
bool IsAttached() KE_OVERRIDE;
|
||||
void EnterScope(const char *group, const char *name) KE_OVERRIDE;
|
||||
void LeaveScope() KE_OVERRIDE;
|
||||
void RenderHelp(void (*render)(const char *fmt, ...)) KE_OVERRIDE;
|
||||
|
||||
// SMGlobalClass
|
||||
void OnSourceModAllInitialized() KE_OVERRIDE;
|
||||
|
||||
private:
|
||||
bool active_;
|
||||
};
|
||||
|
||||
#endif // _include_sourcemod_core_vprof_bridge_h_
|
||||
@@ -8,10 +8,6 @@ binary.compiler.cxxincludes += [
|
||||
os.path.join(builder.sourcePath, 'public', 'jit'),
|
||||
os.path.join(builder.sourcePath, 'public', 'jit', 'x86'),
|
||||
]
|
||||
if binary.compiler.vendor == 'gcc' or binary.compiler.vendor == 'clang':
|
||||
binary.compiler.cxxflags += ['-fno-rtti']
|
||||
elif binary.compiler.vendor == 'msvc':
|
||||
binary.compiler.cxxflags += ['/GR-']
|
||||
|
||||
binary.sources += [
|
||||
'extension.cpp',
|
||||
|
||||
@@ -5,10 +5,6 @@ binary = SM.ExtLibrary(builder, 'clientprefs.ext')
|
||||
binary.compiler.cxxincludes += [
|
||||
os.path.join(SM.mms_root, 'core', 'sourcehook'),
|
||||
]
|
||||
if binary.compiler.vendor == 'gcc' or binary.compiler.vendor == 'clang':
|
||||
binary.compiler.cxxflags += ['-fno-rtti']
|
||||
elif binary.compiler.vendor == 'msvc':
|
||||
binary.compiler.cxxflags += ['/GR-']
|
||||
|
||||
binary.sources += [
|
||||
'extension.cpp',
|
||||
|
||||
@@ -159,7 +159,7 @@ void CookieManager::OnClientAuthorized(int client, const char *authstring)
|
||||
g_ClientPrefs.AttemptReconnection();
|
||||
|
||||
TQueryOp *op = new TQueryOp(Query_SelectData, player->GetSerial());
|
||||
UTIL_strncpy(op->m_params.steamId, GetPlayerCompatAuthId(player), MAX_NAME_LENGTH);
|
||||
UTIL_strncpy(op->m_params.steamId, authstring, MAX_NAME_LENGTH);
|
||||
|
||||
g_ClientPrefs.AddQueryToQueue(op);
|
||||
}
|
||||
@@ -181,7 +181,7 @@ void CookieManager::OnClientDisconnecting(int client)
|
||||
|
||||
if (player)
|
||||
{
|
||||
pAuth = GetPlayerCompatAuthId(player);
|
||||
pAuth = player->GetAuthString();
|
||||
g_ClientPrefs.ClearQueryCache(player->GetSerial());
|
||||
}
|
||||
|
||||
|
||||
@@ -219,7 +219,7 @@ void ClientPrefs::DatabaseConnect()
|
||||
char error[256];
|
||||
int errCode = 0;
|
||||
|
||||
Database = AdoptRef(Driver->Connect(DBInfo, true, error, sizeof(error)));
|
||||
Database = Newborn<IDatabase>(Driver->Connect(DBInfo, true, error, sizeof(error)));
|
||||
|
||||
if (!Database)
|
||||
{
|
||||
@@ -349,11 +349,32 @@ void ClientPrefs::ProcessQueryCache()
|
||||
cachedQueries.clear();
|
||||
}
|
||||
|
||||
const char *GetPlayerCompatAuthId(IGamePlayer *pPlayer)
|
||||
size_t IsAuthIdConnected(char *authID)
|
||||
{
|
||||
/* For legacy reasons, OnClientAuthorized gives the Steam2 id here if using Steam auth */
|
||||
const char *steamId = pPlayer->GetSteam2Id();
|
||||
return steamId ? steamId : pPlayer->GetAuthString();
|
||||
IGamePlayer *player;
|
||||
const char *authString;
|
||||
|
||||
for (int playerIndex = playerhelpers->GetMaxClients()+1; --playerIndex > 0;)
|
||||
{
|
||||
player = playerhelpers->GetGamePlayer(playerIndex);
|
||||
if (player == NULL || !player->IsConnected())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
authString = player->GetAuthString();
|
||||
|
||||
if (authString == NULL || authString[0] == '\0')
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (strcmp(authString, authID) == 0)
|
||||
{
|
||||
return playerIndex;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ClientPrefs::CatchLateLoadClients()
|
||||
@@ -373,7 +394,7 @@ void ClientPrefs::CatchLateLoadClients()
|
||||
continue;
|
||||
}
|
||||
|
||||
g_CookieManager.OnClientAuthorized(i, GetPlayerCompatAuthId(pPlayer));
|
||||
g_CookieManager.OnClientAuthorized(i, pPlayer->GetAuthString());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -181,7 +181,7 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
const char *GetPlayerCompatAuthId(IGamePlayer *pPlayer);
|
||||
size_t IsAuthIdConnected(char *authID);
|
||||
|
||||
extern sp_nativeinfo_t g_ClientPrefNatives[];
|
||||
|
||||
|
||||
@@ -83,31 +83,6 @@ cell_t FindClientPrefCookie(IPluginContext *pContext, const cell_t *params)
|
||||
NULL);
|
||||
}
|
||||
|
||||
size_t IsAuthIdConnected(char *authID)
|
||||
{
|
||||
IGamePlayer *player;
|
||||
const char *authString;
|
||||
|
||||
for (int playerIndex = playerhelpers->GetMaxClients()+1; --playerIndex > 0;)
|
||||
{
|
||||
player = playerhelpers->GetGamePlayer(playerIndex);
|
||||
if (player == NULL || !player->IsAuthorized())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!strcmp(player->GetAuthString(), authID)
|
||||
|| !strcmp(player->GetSteam2Id(), authID)
|
||||
|| !strcmp(player->GetSteam3Id(), authID)
|
||||
)
|
||||
{
|
||||
return playerIndex;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
cell_t SetAuthIdCookie(IPluginContext *pContext, const cell_t *params)
|
||||
{
|
||||
g_ClientPrefs.AttemptReconnection();
|
||||
|
||||
@@ -61,21 +61,9 @@ DETOUR_DECL_MEMBER1(DetourHandleBuy, int, const char *, weapon)
|
||||
|
||||
#if SOURCE_ENGINE != SE_CSGO
|
||||
DETOUR_DECL_MEMBER0(DetourWeaponPrice, int)
|
||||
#elif defined(WIN32)
|
||||
DETOUR_DECL_MEMBER2(DetourWeaponPrice, int, CEconItemView *, pEconItem, int, iUnknown)
|
||||
#else
|
||||
DETOUR_DECL_MEMBER3(DetourWeaponPrice, int, CEconItemView *, pEconItem, int, iUnknown, float, fUnknown)
|
||||
#endif
|
||||
{
|
||||
|
||||
#if SOURCE_ENGINE != SE_CSGO
|
||||
int price = DETOUR_MEMBER_CALL(DetourWeaponPrice)();
|
||||
#elif defined(WIN32)
|
||||
int price = DETOUR_MEMBER_CALL(DetourWeaponPrice)(pEconItem, iUnknown);
|
||||
#else
|
||||
int price = DETOUR_MEMBER_CALL(DetourWeaponPrice)(pEconItem, iUnknown, fUnknown);
|
||||
#endif
|
||||
|
||||
|
||||
if (lastclient == -1)
|
||||
return price;
|
||||
|
||||
@@ -83,6 +71,19 @@ DETOUR_DECL_MEMBER3(DetourWeaponPrice, int, CEconItemView *, pEconItem, int, iUn
|
||||
|
||||
return CallPriceForward(lastclient, weapon_name, price);
|
||||
}
|
||||
#else
|
||||
DETOUR_DECL_MEMBER2(DetourWeaponPrice, int, const char *, szAttribute, CEconItemView *, pEconItem)
|
||||
{
|
||||
int price = DETOUR_MEMBER_CALL(DetourWeaponPrice)(szAttribute, pEconItem);
|
||||
|
||||
if(lastclient == -1 || strcmp(szAttribute, "in game price") != 0)
|
||||
return price;
|
||||
|
||||
const char *weapon_name = reinterpret_cast<char *>(this+weaponNameOffset);
|
||||
|
||||
return CallPriceForward(lastclient, weapon_name, price);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if SOURCE_ENGINE != SE_CSGO || !defined(WIN32)
|
||||
DETOUR_DECL_MEMBER2(DetourTerminateRound, void, float, delay, int, reason)
|
||||
@@ -200,15 +201,8 @@ bool CreateWeaponPriceDetour()
|
||||
}
|
||||
}
|
||||
|
||||
#if SOURCE_ENGINE == SE_CSGO && defined(WIN32)
|
||||
void *pGetWeaponPriceAddress = GetWeaponPriceFunction();
|
||||
|
||||
if(!pGetWeaponPriceAddress)
|
||||
{
|
||||
g_pSM->LogError(myself, "GetWeaponPrice detour could not be initialized - Disabled OnGetWeaponPrice forward.");
|
||||
}
|
||||
|
||||
DWeaponPrice = DETOUR_CREATE_MEMBER(DetourWeaponPrice, pGetWeaponPriceAddress);
|
||||
#if SOURCE_ENGINE == SE_CSGO
|
||||
DWeaponPrice = DETOUR_CREATE_MEMBER(DetourWeaponPrice, "GetAttributeInt");
|
||||
#else
|
||||
DWeaponPrice = DETOUR_CREATE_MEMBER(DetourWeaponPrice, "GetWeaponPrice");
|
||||
#endif
|
||||
|
||||
@@ -372,10 +372,12 @@ static cell_t CS_TerminateRound(IPluginContext *pContext, const cell_t *params)
|
||||
|
||||
float delay = sp_ctof(params[1]);
|
||||
int reason = params[2];
|
||||
signed int unknown = 1;//We might want to find what this is?
|
||||
__asm
|
||||
{
|
||||
push reason
|
||||
movss xmm1, delay
|
||||
mov edi, unknown
|
||||
mov ecx, gamerules
|
||||
call addr
|
||||
}
|
||||
@@ -419,7 +421,6 @@ static cell_t CS_GetTranslatedWeaponAlias(IPluginContext *pContext, const cell_t
|
||||
|
||||
static cell_t CS_GetWeaponPrice(IPluginContext *pContext, const cell_t *params)
|
||||
{
|
||||
|
||||
if (!IsValidWeaponID(params[2]))
|
||||
return pContext->ThrowNativeError("Invalid WeaponID passed for this game");
|
||||
|
||||
@@ -427,7 +428,6 @@ static cell_t CS_GetWeaponPrice(IPluginContext *pContext, const cell_t *params)
|
||||
|
||||
//Hard code return values for weapons that dont call GetWeaponPrice and always use default value.
|
||||
#if SOURCE_ENGINE == SE_CSGO
|
||||
|
||||
if (id == WEAPON_C4 || id == WEAPON_KNIFE || id == WEAPON_KNIFE_GG)
|
||||
return 0;
|
||||
#else
|
||||
@@ -460,49 +460,23 @@ static cell_t CS_GetWeaponPrice(IPluginContext *pContext, const cell_t *params)
|
||||
#if SOURCE_ENGINE == SE_CSGO
|
||||
static ICallWrapper *pWrapper = NULL;
|
||||
|
||||
#if defined(WIN32)
|
||||
if(!pWrapper)
|
||||
{
|
||||
void *pGetWeaponPrice = GetWeaponPriceFunction();
|
||||
if(!pGetWeaponPrice)
|
||||
{
|
||||
return pContext->ThrowNativeError("Failed to locate function");
|
||||
}
|
||||
|
||||
PassInfo pass[2];
|
||||
PassInfo ret;
|
||||
pass[0].flags = PASSFLAG_BYVAL;
|
||||
pass[0].type = PassType_Basic;
|
||||
pass[0].size = sizeof(CEconItemView *);
|
||||
pass[1].flags = PASSFLAG_BYVAL;
|
||||
pass[1].type = PassType_Basic;
|
||||
pass[1].size = sizeof(int);
|
||||
ret.flags = PASSFLAG_BYVAL;
|
||||
ret.type = PassType_Basic;
|
||||
ret.size = sizeof(int);
|
||||
pWrapper = g_pBinTools->CreateCall(pGetWeaponPrice, CallConv_ThisCall, &ret, pass, 2);
|
||||
}
|
||||
#else
|
||||
if (!pWrapper)
|
||||
{
|
||||
REGISTER_NATIVE_ADDR("GetWeaponPrice",
|
||||
PassInfo pass[3]; \
|
||||
REGISTER_NATIVE_ADDR("GetAttributeInt",
|
||||
PassInfo pass[2]; \
|
||||
PassInfo ret; \
|
||||
pass[0].flags = PASSFLAG_BYVAL; \
|
||||
pass[0].type = PassType_Basic; \
|
||||
pass[0].size = sizeof(CEconItemView *); \
|
||||
pass[0].size = sizeof(char *); \
|
||||
pass[1].flags = PASSFLAG_BYVAL; \
|
||||
pass[1].type = PassType_Basic; \
|
||||
pass[1].size = sizeof(int); \
|
||||
pass[2].flags = PASSFLAG_BYVAL; \
|
||||
pass[2].type = PassType_Float; \
|
||||
pass[2].size = sizeof(float); \
|
||||
pass[1].size = sizeof(CEconItemView *); \
|
||||
ret.flags = PASSFLAG_BYVAL; \
|
||||
ret.type = PassType_Basic; \
|
||||
ret.size = sizeof(int); \
|
||||
pWrapper = g_pBinTools->CreateCall(addr, CallConv_ThisCall, &ret, pass, 3))
|
||||
pWrapper = g_pBinTools->CreateCall(addr, CallConv_ThisCall, &ret, pass, 2))
|
||||
}
|
||||
#endif
|
||||
|
||||
// Get a CEconItemView for the m4
|
||||
// Found in CCSPlayer::HandleCommand_Buy_Internal
|
||||
// Linux a1 - CCSPlayer *pEntity, v5 - Player Team, a3 - ItemLoadoutSlot -1 use default loadoutslot:
|
||||
@@ -580,22 +554,14 @@ static cell_t CS_GetWeaponPrice(IPluginContext *pContext, const cell_t *params)
|
||||
pGetView->Execute(vstk_view, &view);
|
||||
}
|
||||
|
||||
#if defined(WIN32)
|
||||
unsigned char vstk[sizeof(void *) * 2 + sizeof(int)];
|
||||
#else
|
||||
unsigned char vstk[sizeof(void *) * 2 + sizeof(int) + sizeof(float)];
|
||||
#endif
|
||||
unsigned char vstk[sizeof(void *) * 2 + sizeof(char *)];
|
||||
unsigned char *vptr = vstk;
|
||||
|
||||
*(void **)vptr = info;
|
||||
vptr += sizeof(void *);
|
||||
*(const char **)vptr = "in game price";
|
||||
vptr += sizeof(const char *);
|
||||
*(CEconItemView **)vptr = view;
|
||||
vptr += sizeof(CEconItemView *);
|
||||
*(int *)vptr = 0;
|
||||
#if !defined(WIN32)
|
||||
vptr += sizeof(int);
|
||||
*(float *)vptr = 1.0;
|
||||
#endif
|
||||
|
||||
int price = 0;
|
||||
pWrapper->Execute(vstk, &price);
|
||||
|
||||
@@ -229,56 +229,6 @@ const char *WeaponIDToAlias(int weaponID)
|
||||
#endif
|
||||
return alias;
|
||||
}
|
||||
|
||||
#if SOURCE_ENGINE == SE_CSGO && defined(WIN32)
|
||||
void *GetWeaponPriceFunction()
|
||||
{
|
||||
static void *pGetWeaponPriceAddress = NULL;
|
||||
|
||||
if(pGetWeaponPriceAddress == NULL)
|
||||
{
|
||||
void *pAddress = NULL;
|
||||
int offset = 0;
|
||||
int callOffset = 0;
|
||||
const char* byteCheck = NULL;
|
||||
|
||||
if(!g_pGameConf->GetMemSig("GetWeaponPrice", &pAddress) || pAddress == NULL)
|
||||
{
|
||||
g_pSM->LogError(myself, "Failed to get GetWeaponPrice address.");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if(!g_pGameConf->GetOffset("GetWeaponPriceFunc", &offset))
|
||||
{
|
||||
g_pSM->LogError(myself, "Failed to get GetWeaponPriceFunc offset.");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
byteCheck = g_pGameConf->GetKeyValue("GetWeaponPriceByteCheck");
|
||||
|
||||
if(byteCheck == NULL)
|
||||
{
|
||||
g_pSM->LogError(myself, "Failed to get GetWeaponPriceByteCheck keyvalue.");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
uint8_t iByte = strtoul(byteCheck, NULL, 16);
|
||||
|
||||
if(iByte != *(uint8_t *)((intptr_t)pAddress + (offset-1)))
|
||||
{
|
||||
g_pSM->LogError(myself, "GetWeaponPrice Byte check failed.");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
callOffset = *(uint32_t *)((intptr_t)pAddress + offset);
|
||||
|
||||
pGetWeaponPriceAddress = (void *)((intptr_t)pAddress + offset + callOffset + sizeof(int));
|
||||
}
|
||||
|
||||
return pGetWeaponPriceAddress;
|
||||
}
|
||||
#endif
|
||||
|
||||
int GetRealWeaponID(int weaponId)
|
||||
{
|
||||
#if SOURCE_ENGINE == SE_CSGO
|
||||
|
||||
@@ -165,6 +165,4 @@ int GetFakeWeaponID(int weaponId);
|
||||
|
||||
bool IsValidWeaponID(int weaponId);
|
||||
|
||||
void *GetWeaponPriceFunction();
|
||||
|
||||
#endif
|
||||
|
||||
@@ -8,10 +8,6 @@ binary.compiler.includes += [
|
||||
os.path.join(builder.sourcePath, 'extensions', 'curl', 'curl-src', 'include')
|
||||
]
|
||||
binary.compiler.defines += ['CURL_STATICLIB']
|
||||
if binary.compiler.vendor == 'gcc' or binary.compiler.vendor == 'clang':
|
||||
binary.compiler.cxxflags += ['-fno-rtti']
|
||||
elif binary.compiler.vendor == 'msvc':
|
||||
binary.compiler.cxxflags += ['/GR-']
|
||||
binary.compiler.postlink += [libcurl.binary]
|
||||
if builder.target_platform == 'linux':
|
||||
binary.compiler.postlink += ['-lrt']
|
||||
|
||||
@@ -2,10 +2,6 @@
|
||||
import os
|
||||
|
||||
binary = SM.ExtLibrary(builder, 'geoip.ext')
|
||||
if binary.compiler.vendor == 'gcc' or binary.compiler.vendor == 'clang':
|
||||
binary.compiler.cxxflags += ['-fno-rtti']
|
||||
elif binary.compiler.vendor == 'msvc':
|
||||
binary.compiler.cxxflags += ['/GR-']
|
||||
if builder.target_platform == 'windows':
|
||||
binary.compiler.postlink += ['wsock32.lib']
|
||||
|
||||
|
||||
@@ -7,20 +7,14 @@ if SM.mysql_root:
|
||||
os.path.join(SM.mysql_root, 'include'),
|
||||
os.path.join(SM.mms_root, 'core', 'sourcehook')
|
||||
]
|
||||
if binary.compiler.vendor == 'gcc' or binary.compiler.vendor == 'clang':
|
||||
binary.compiler.cxxflags += ['-fno-rtti']
|
||||
elif binary.compiler.vendor == 'msvc':
|
||||
binary.compiler.cxxflags += ['/GR-']
|
||||
|
||||
if builder.target_platform == 'linux' or builder.target_platform == 'mac':
|
||||
binary.compiler.postlink += [
|
||||
os.path.join(SM.mysql_root, 'lib', 'libmysqlclient_r.a'),
|
||||
'-lz',
|
||||
'-lpthread',
|
||||
'-lm',
|
||||
'-lm'
|
||||
]
|
||||
if builder.target_platform == 'linux':
|
||||
binary.compiler.postlink += ['-lrt']
|
||||
elif builder.target_platform == 'windows':
|
||||
binary.compiler.postlink += [
|
||||
os.path.join(SM.mysql_root, 'lib', 'opt', 'mysqlclient.lib'),
|
||||
|
||||
@@ -101,9 +101,6 @@ MyDatabase::MyDatabase(MYSQL *mysql, const DatabaseInfo *info, bool persistent)
|
||||
m_Info.driver = NULL;
|
||||
m_Info.maxTimeout = info->maxTimeout;
|
||||
m_Info.port = info->port;
|
||||
|
||||
// DBI, for historical reasons, guarantees an initial refcount of 1.
|
||||
AddRef();
|
||||
}
|
||||
|
||||
MyDatabase::~MyDatabase()
|
||||
|
||||
@@ -96,16 +96,11 @@ MYSQL *Connect(const DatabaseInfo *info, char *error, size_t maxlength)
|
||||
MYSQL *mysql = mysql_init(NULL);
|
||||
const char *host = NULL, *socket = NULL;
|
||||
|
||||
decltype(info->maxTimeout) timeout = 60;
|
||||
if (info->maxTimeout > 0)
|
||||
{
|
||||
timeout = info->maxTimeout;
|
||||
mysql_options(mysql, MYSQL_OPT_CONNECT_TIMEOUT, (const char *)&(info->maxTimeout));
|
||||
}
|
||||
|
||||
mysql_options(mysql, MYSQL_OPT_CONNECT_TIMEOUT, (const char *)&timeout);
|
||||
mysql_options(mysql, MYSQL_OPT_READ_TIMEOUT, (const char *)&timeout);
|
||||
mysql_options(mysql, MYSQL_OPT_WRITE_TIMEOUT, (const char *)&timeout);
|
||||
|
||||
/* Have MySQL automatically reconnect if it times out or loses connection.
|
||||
* This will prevent "MySQL server has gone away" errors after a while.
|
||||
*/
|
||||
|
||||
@@ -5,10 +5,6 @@ binary = SM.ExtLibrary(builder, 'regex.ext')
|
||||
binary.compiler.cxxincludes += [
|
||||
os.path.join(SM.mms_root, 'core', 'sourcehook'),
|
||||
]
|
||||
if binary.compiler.vendor == 'gcc' or binary.compiler.vendor == 'clang':
|
||||
binary.compiler.cxxflags += ['-fno-rtti']
|
||||
elif binary.compiler.vendor == 'msvc':
|
||||
binary.compiler.cxxflags += ['/GR-']
|
||||
|
||||
if builder.target_platform == 'linux':
|
||||
path = os.path.join(builder.sourcePath, 'extensions', 'regex', 'lib_linux', 'libpcre.a')
|
||||
|
||||
@@ -106,7 +106,7 @@ static cell_t MatchRegex(IPluginContext *pCtx, const cell_t *params)
|
||||
|
||||
if ((err=g_pHandleSys->ReadHandle(hndl, g_RegexHandle, &sec, (void **)&x)) != HandleError_None)
|
||||
{
|
||||
return pCtx->ThrowNativeError("Invalid regex handle %x (error %d)", hndl, err);
|
||||
return pCtx->ThrowNativeError("Invalid file handle %x (error %d)", hndl, err);
|
||||
}
|
||||
|
||||
if (!x)
|
||||
@@ -159,7 +159,7 @@ static cell_t GetRegexSubString(IPluginContext *pCtx, const cell_t *params)
|
||||
|
||||
if ((err=g_pHandleSys->ReadHandle(hndl, g_RegexHandle, &sec, (void **)&x)) != HandleError_None)
|
||||
{
|
||||
return pCtx->ThrowNativeError("Invalid regex handle %x (error %d)", hndl, err);
|
||||
return pCtx->ThrowNativeError("Invalid file handle %x (error %d)", hndl, err);
|
||||
}
|
||||
|
||||
if (!x)
|
||||
|
||||
+145
-162
@@ -88,10 +88,6 @@ HookTypeData g_HookTypes[SDKHook_MAXHOOKS] =
|
||||
{"Reload", "DT_BaseCombatWeapon", false},
|
||||
{"ReloadPost", "DT_BaseCombatWeapon", false},
|
||||
{"GetMaxHealth", "", false},
|
||||
{"Blocked", "", false},
|
||||
{"BlockedPost", "", false},
|
||||
{"OnTakeDamageAlive", "DT_BaseCombatCharacter", false},
|
||||
{"OnTakeDamageAlivePost", "DT_BaseCombatCharacter", false},
|
||||
};
|
||||
|
||||
SDKHooks g_Interface;
|
||||
@@ -170,7 +166,6 @@ SH_DECL_MANUALHOOK0(GetMaxHealth, 0, 0, 0, int);
|
||||
#endif
|
||||
SH_DECL_MANUALHOOK1_void(GroundEntChanged, 0, 0, 0, void *);
|
||||
SH_DECL_MANUALHOOK1(OnTakeDamage, 0, 0, 0, int, CTakeDamageInfoHack &);
|
||||
SH_DECL_MANUALHOOK1(OnTakeDamage_Alive, 0, 0, 0, int, CTakeDamageInfoHack &);
|
||||
SH_DECL_MANUALHOOK0_void(PreThink, 0, 0, 0);
|
||||
SH_DECL_MANUALHOOK0_void(PostThink, 0, 0, 0);
|
||||
SH_DECL_MANUALHOOK0(Reload, 0, 0, 0, bool);
|
||||
@@ -196,7 +191,6 @@ SH_DECL_MANUALHOOK1(Weapon_CanUse, 0, 0, 0, bool, CBaseCombatWeapon *);
|
||||
SH_DECL_MANUALHOOK3_void(Weapon_Drop, 0, 0, 0, CBaseCombatWeapon *, const Vector *, const Vector *);
|
||||
SH_DECL_MANUALHOOK1_void(Weapon_Equip, 0, 0, 0, CBaseCombatWeapon *);
|
||||
SH_DECL_MANUALHOOK2(Weapon_Switch, 0, 0, 0, bool, CBaseCombatWeapon *, int);
|
||||
SH_DECL_MANUALHOOK1_void(Blocked, 0, 0, 0, CBaseEntity *);
|
||||
|
||||
|
||||
/**
|
||||
@@ -219,26 +213,6 @@ bool SDKHooks::SDK_OnLoad(char *error, size_t maxlength, bool late)
|
||||
return false;
|
||||
}
|
||||
|
||||
buffer[0] = '\0';
|
||||
if (!gameconfs->LoadGameConfigFile("sdkhooks.games", &g_pGameConf, buffer, sizeof(buffer)))
|
||||
{
|
||||
if (buffer[0])
|
||||
{
|
||||
g_pSM->Format(error, maxlength, "Could not read sdkhooks.games gamedata: %s", buffer);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
CUtlVector<IEntityListener *> *entListeners = EntListeners();
|
||||
if (!entListeners)
|
||||
{
|
||||
g_pSM->Format(error, maxlength, "Failed to setup entity listeners");
|
||||
return false;
|
||||
}
|
||||
|
||||
entListeners->AddToTail(this);
|
||||
|
||||
sharesys->AddDependency(myself, "bintools.ext", true, true);
|
||||
sharesys->AddNatives(myself, g_Natives);
|
||||
sharesys->RegisterLibrary(myself, "sdkhooks");
|
||||
@@ -257,6 +231,26 @@ bool SDKHooks::SDK_OnLoad(char *error, size_t maxlength, bool late)
|
||||
#endif
|
||||
g_pOnLevelInit = forwards->CreateForward("OnLevelInit", ET_Hook, 2, NULL, Param_String, Param_String);
|
||||
|
||||
buffer[0] = '\0';
|
||||
if (!gameconfs->LoadGameConfigFile("sdkhooks.games", &g_pGameConf, buffer, sizeof(buffer)))
|
||||
{
|
||||
if (buffer[0])
|
||||
{
|
||||
g_pSM->Format(error, maxlength, "Could not read sdkhooks.games gamedata: %s", buffer);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
CUtlVector<IEntityListener *> *entListeners = EntListeners();
|
||||
if (!entListeners)
|
||||
{
|
||||
g_pSM->Format(error, maxlength, "Failed to setup entity listeners");
|
||||
return false;
|
||||
}
|
||||
|
||||
entListeners->AddToTail(this);
|
||||
|
||||
SetupHooks();
|
||||
|
||||
#if SOURCE_ENGINE >= SE_ORANGEBOX
|
||||
@@ -444,21 +438,6 @@ FeatureStatus SDKHooks::GetFeatureStatus(FeatureType type, const char *name)
|
||||
/**
|
||||
* Functions
|
||||
*/
|
||||
|
||||
static void PopulateCallbackList(const ke::Vector<HookList> &source, ke::Vector<IPluginFunction *> &destination, int entity)
|
||||
{
|
||||
destination.ensure(8); /* Skip trivial allocations as AMTL uses length<<1. */
|
||||
for (size_t iter = 0; iter < source.length(); ++iter)
|
||||
{
|
||||
if (source[iter].entity != entity)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
destination.append(source[iter].callback);
|
||||
}
|
||||
}
|
||||
|
||||
cell_t SDKHooks::Call(int entity, SDKHookType type, int other)
|
||||
{
|
||||
return Call(gamehelpers->ReferenceToEntity(entity), type, gamehelpers->ReferenceToEntity(other));
|
||||
@@ -482,14 +461,17 @@ cell_t SDKHooks::Call(CBaseEntity *pEnt, SDKHookType type, CBaseEntity *pOther)
|
||||
continue;
|
||||
}
|
||||
|
||||
ke::Vector<HookList> &pawnlist = vtablehooklist[entry]->hooks;
|
||||
int entity = gamehelpers->EntityToBCompatRef(pEnt);
|
||||
int other = gamehelpers->EntityToBCompatRef(pOther);
|
||||
|
||||
ke::Vector<IPluginFunction *> callbackList;
|
||||
PopulateCallbackList(vtablehooklist[entry]->hooks, callbackList, entity);
|
||||
for (entry = 0; entry < callbackList.length(); ++entry)
|
||||
for (entry = 0; entry < pawnlist.length(); ++entry)
|
||||
{
|
||||
IPluginFunction *callback = callbackList[entry];
|
||||
if (entity != pawnlist[entry].entity)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
IPluginFunction *callback = pawnlist[entry].callback;
|
||||
callback->PushCell(entity);
|
||||
callback->PushCell(other);
|
||||
|
||||
@@ -518,7 +500,6 @@ void SDKHooks::SetupHooks()
|
||||
CHECKOFFSET(FireBullets, false, true);
|
||||
CHECKOFFSET(GroundEntChanged, false, true);
|
||||
CHECKOFFSET(OnTakeDamage, true, true);
|
||||
CHECKOFFSET(OnTakeDamage_Alive,true, true);
|
||||
CHECKOFFSET(PreThink, true, true);
|
||||
CHECKOFFSET(PostThink, true, true);
|
||||
CHECKOFFSET(Reload, true, true);
|
||||
@@ -536,7 +517,6 @@ void SDKHooks::SetupHooks()
|
||||
CHECKOFFSET_W(Equip, true, true);
|
||||
CHECKOFFSET_W(Switch, true, true);
|
||||
CHECKOFFSET(VPhysicsUpdate, true, true);
|
||||
CHECKOFFSET(Blocked, true, true);
|
||||
|
||||
// this one is in a class all its own -_-
|
||||
offset = 0;
|
||||
@@ -611,12 +591,6 @@ HookReturn SDKHooks::Hook(int entity, SDKHookType type, IPluginFunction *callbac
|
||||
case SDKHook_OnTakeDamagePost:
|
||||
hookid = SH_ADD_MANUALVPHOOK(OnTakeDamage, pEnt, SH_MEMBER(&g_Interface, &SDKHooks::Hook_OnTakeDamagePost), true);
|
||||
break;
|
||||
case SDKHook_OnTakeDamage_Alive:
|
||||
hookid = SH_ADD_MANUALVPHOOK(OnTakeDamage_Alive, pEnt, SH_MEMBER(&g_Interface, &SDKHooks::Hook_OnTakeDamage_Alive), false);
|
||||
break;
|
||||
case SDKHook_OnTakeDamage_AlivePost:
|
||||
hookid = SH_ADD_MANUALVPHOOK(OnTakeDamage_Alive, pEnt, SH_MEMBER(&g_Interface, &SDKHooks::Hook_OnTakeDamage_AlivePost), true);
|
||||
break;
|
||||
case SDKHook_PreThink:
|
||||
hookid = SH_ADD_MANUALVPHOOK(PreThink, pEnt, SH_MEMBER(&g_Interface, &SDKHooks::Hook_PreThink), false);
|
||||
break;
|
||||
@@ -713,12 +687,6 @@ HookReturn SDKHooks::Hook(int entity, SDKHookType type, IPluginFunction *callbac
|
||||
case SDKHook_ShouldCollide:
|
||||
hookid = SH_ADD_MANUALVPHOOK(ShouldCollide, pEnt, SH_MEMBER(&g_Interface, &SDKHooks::Hook_ShouldCollide), false);
|
||||
break;
|
||||
case SDKHook_Blocked:
|
||||
hookid = SH_ADD_MANUALVPHOOK(Blocked, pEnt, SH_MEMBER(&g_Interface, &SDKHooks::Hook_Blocked), false);
|
||||
break;
|
||||
case SDKHook_BlockedPost:
|
||||
hookid = SH_ADD_MANUALVPHOOK(Blocked, pEnt, SH_MEMBER(&g_Interface, &SDKHooks::Hook_BlockedPost), true);
|
||||
break;
|
||||
}
|
||||
|
||||
vhook.SetHookID(hookid);
|
||||
@@ -894,6 +862,9 @@ bool SDKHooks::Hook_LevelInit(char const *pMapName, char const *pMapEntities, ch
|
||||
g_pOnLevelInit->PushStringEx(g_szMapEntities, sizeof(g_szMapEntities), SM_PARAM_STRING_COPY, SM_PARAM_COPYBACK);
|
||||
g_pOnLevelInit->Execute(&result);
|
||||
|
||||
if(result >= Pl_Handled)
|
||||
RETURN_META_VALUE(MRES_SUPERCEDE, false);
|
||||
|
||||
if(result == Pl_Changed)
|
||||
RETURN_META_VALUE_NEWPARAMS(MRES_HANDLED, true, &IServerGameDLL::LevelInit, (pMapName, g_szMapEntities, pOldLevel, pLandmarkName, loadGame, background));
|
||||
|
||||
@@ -943,11 +914,15 @@ void SDKHooks::Hook_FireBulletsPost(const FireBulletsInfo_t &info)
|
||||
|
||||
const char *weapon = pInfo->GetWeaponName();
|
||||
|
||||
ke::Vector<IPluginFunction *> callbackList;
|
||||
PopulateCallbackList(vtablehooklist[entry]->hooks, callbackList, entity);
|
||||
for (entry = 0; entry < callbackList.length(); ++entry)
|
||||
ke::Vector<HookList> &pawnlist = vtablehooklist[entry]->hooks;
|
||||
for (entry = 0; entry < pawnlist.length(); ++entry)
|
||||
{
|
||||
IPluginFunction *callback = callbackList[entry];
|
||||
if (entity != pawnlist[entry].entity)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
IPluginFunction *callback = pawnlist[entry].callback;
|
||||
callback->PushCell(entity);
|
||||
callback->PushCell(info.m_iShots);
|
||||
callback->PushString(weapon?weapon:"");
|
||||
@@ -981,11 +956,15 @@ int SDKHooks::Hook_GetMaxHealth()
|
||||
|
||||
cell_t res = Pl_Continue;
|
||||
|
||||
ke::Vector<IPluginFunction *> callbackList;
|
||||
PopulateCallbackList(vtablehooklist[entry]->hooks, callbackList, entity);
|
||||
for (entry = 0; entry < callbackList.length(); ++entry)
|
||||
ke::Vector<HookList> &pawnlist = vtablehooklist[entry]->hooks;
|
||||
for (entry = 0; entry < pawnlist.length(); ++entry)
|
||||
{
|
||||
IPluginFunction *callback = callbackList[entry];
|
||||
if (entity != pawnlist[entry].entity)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
IPluginFunction *callback = pawnlist[entry].callback;
|
||||
callback->PushCell(entity);
|
||||
callback->PushCellByRef(&new_max);
|
||||
callback->Execute(&res);
|
||||
@@ -1006,12 +985,12 @@ void SDKHooks::Hook_GroundEntChangedPost(void *pVar)
|
||||
Call(META_IFACEPTR(CBaseEntity), SDKHook_GroundEntChangedPost);
|
||||
}
|
||||
|
||||
int SDKHooks::HandleOnTakeDamageHook(CTakeDamageInfoHack &info, SDKHookType hookType)
|
||||
int SDKHooks::Hook_OnTakeDamage(CTakeDamageInfoHack &info)
|
||||
{
|
||||
CBaseEntity *pEntity = META_IFACEPTR(CBaseEntity);
|
||||
|
||||
CVTableHook vhook(pEntity);
|
||||
ke::Vector<CVTableList *> &vtablehooklist = g_HookList[hookType];
|
||||
ke::Vector<CVTableList *> &vtablehooklist = g_HookList[SDKHook_OnTakeDamage];
|
||||
for (size_t entry = 0; entry < vtablehooklist.length(); ++entry)
|
||||
{
|
||||
if (vhook != vtablehooklist[entry]->vtablehook)
|
||||
@@ -1027,18 +1006,22 @@ int SDKHooks::HandleOnTakeDamageHook(CTakeDamageInfoHack &info, SDKHookType hook
|
||||
int weapon = info.GetWeapon();
|
||||
|
||||
Vector force = info.GetDamageForce();
|
||||
cell_t damageForce[3] = { sp_ftoc(force.x), sp_ftoc(force.y), sp_ftoc(force.z) };
|
||||
cell_t damageForce[3] = {sp_ftoc(force.x), sp_ftoc(force.y), sp_ftoc(force.z)};
|
||||
|
||||
Vector pos = info.GetDamagePosition();
|
||||
cell_t damagePosition[3] = { sp_ftoc(pos.x), sp_ftoc(pos.y), sp_ftoc(pos.z) };
|
||||
cell_t damagePosition[3] = {sp_ftoc(pos.x), sp_ftoc(pos.y), sp_ftoc(pos.z)};
|
||||
|
||||
cell_t res, ret = Pl_Continue;
|
||||
|
||||
ke::Vector<IPluginFunction *> callbackList;
|
||||
PopulateCallbackList(vtablehooklist[entry]->hooks, callbackList, entity);
|
||||
for (entry = 0; entry < callbackList.length(); ++entry)
|
||||
ke::Vector<HookList> &pawnlist = vtablehooklist[entry]->hooks;
|
||||
for (entry = 0; entry < pawnlist.length(); ++entry)
|
||||
{
|
||||
IPluginFunction *callback = callbackList[entry];
|
||||
if (entity != pawnlist[entry].entity)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
IPluginFunction *callback = pawnlist[entry].callback;
|
||||
callback->PushCell(entity);
|
||||
callback->PushCellByRef(&attacker);
|
||||
callback->PushCellByRef(&inflictor);
|
||||
@@ -1046,23 +1029,23 @@ int SDKHooks::HandleOnTakeDamageHook(CTakeDamageInfoHack &info, SDKHookType hook
|
||||
callback->PushCellByRef(&damagetype);
|
||||
callback->PushCellByRef(&weapon);
|
||||
callback->PushArray(damageForce, 3, SM_PARAM_COPYBACK);
|
||||
callback->PushArray(damagePosition, 3, SM_PARAM_COPYBACK);
|
||||
callback->PushArray(damagePosition, 3, SM_PARAM_COPYBACK);
|
||||
callback->PushCell(info.GetDamageCustom());
|
||||
callback->Execute(&res);
|
||||
|
||||
if (res >= ret)
|
||||
if(res >= ret)
|
||||
{
|
||||
ret = res;
|
||||
if (ret == Pl_Changed)
|
||||
if(ret == Pl_Changed)
|
||||
{
|
||||
CBaseEntity *pEntAttacker = gamehelpers->ReferenceToEntity(attacker);
|
||||
if (!pEntAttacker)
|
||||
if(!pEntAttacker)
|
||||
{
|
||||
callback->GetParentRuntime()->GetDefaultContext()->ThrowNativeError("Entity %d for attacker is invalid", attacker);
|
||||
RETURN_META_VALUE(MRES_IGNORED, 0);
|
||||
}
|
||||
CBaseEntity *pEntInflictor = gamehelpers->ReferenceToEntity(inflictor);
|
||||
if (!pEntInflictor)
|
||||
if(!pEntInflictor)
|
||||
{
|
||||
callback->GetParentRuntime()->GetDefaultContext()->ThrowNativeError("Entity %d for inflictor is invalid", inflictor);
|
||||
RETURN_META_VALUE(MRES_IGNORED, 0);
|
||||
@@ -1084,12 +1067,12 @@ int SDKHooks::HandleOnTakeDamageHook(CTakeDamageInfoHack &info, SDKHookType hook
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (ret >= Pl_Handled)
|
||||
|
||||
if(ret >= Pl_Handled)
|
||||
RETURN_META_VALUE(MRES_SUPERCEDE, 1);
|
||||
|
||||
if (ret == Pl_Changed)
|
||||
RETURN_META_VALUE(MRES_HANDLED, 1);
|
||||
if(ret == Pl_Changed)
|
||||
RETURN_META_VALUE(MRES_HANDLED, 1);
|
||||
|
||||
break;
|
||||
}
|
||||
@@ -1097,12 +1080,12 @@ int SDKHooks::HandleOnTakeDamageHook(CTakeDamageInfoHack &info, SDKHookType hook
|
||||
RETURN_META_VALUE(MRES_IGNORED, 0);
|
||||
}
|
||||
|
||||
int SDKHooks::HandleOnTakeDamageHookPost(CTakeDamageInfoHack &info, SDKHookType hookType)
|
||||
int SDKHooks::Hook_OnTakeDamagePost(CTakeDamageInfoHack &info)
|
||||
{
|
||||
CBaseEntity *pEntity = META_IFACEPTR(CBaseEntity);
|
||||
|
||||
CVTableHook vhook(pEntity);
|
||||
ke::Vector<CVTableList *> &vtablehooklist = g_HookList[hookType];
|
||||
ke::Vector<CVTableList *> &vtablehooklist = g_HookList[SDKHook_OnTakeDamagePost];
|
||||
for (size_t entry = 0; entry < vtablehooklist.length(); ++entry)
|
||||
{
|
||||
if (vhook != vtablehooklist[entry]->vtablehook)
|
||||
@@ -1112,11 +1095,15 @@ int SDKHooks::HandleOnTakeDamageHookPost(CTakeDamageInfoHack &info, SDKHookType
|
||||
|
||||
int entity = gamehelpers->EntityToBCompatRef(pEntity);
|
||||
|
||||
ke::Vector<IPluginFunction *> callbackList;
|
||||
PopulateCallbackList(vtablehooklist[entry]->hooks, callbackList, entity);
|
||||
for (entry = 0; entry < callbackList.length(); ++entry)
|
||||
ke::Vector<HookList> &pawnlist = vtablehooklist[entry]->hooks;
|
||||
for (entry = 0; entry < pawnlist.length(); ++entry)
|
||||
{
|
||||
IPluginFunction *callback = callbackList[entry];
|
||||
if (entity != pawnlist[entry].entity)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
IPluginFunction *callback = pawnlist[entry].callback;
|
||||
callback->PushCell(entity);
|
||||
callback->PushCell(info.GetAttacker());
|
||||
callback->PushCell(info.GetInflictor());
|
||||
@@ -1125,11 +1112,11 @@ int SDKHooks::HandleOnTakeDamageHookPost(CTakeDamageInfoHack &info, SDKHookType
|
||||
callback->PushCell(info.GetWeapon());
|
||||
|
||||
Vector force = info.GetDamageForce();
|
||||
cell_t damageForce[3] = { sp_ftoc(force.x), sp_ftoc(force.y), sp_ftoc(force.z) };
|
||||
cell_t damageForce[3] = {sp_ftoc(force.x), sp_ftoc(force.y), sp_ftoc(force.z)};
|
||||
callback->PushArray(damageForce, 3);
|
||||
|
||||
Vector pos = info.GetDamagePosition();
|
||||
cell_t damagePosition[3] = { sp_ftoc(pos.x), sp_ftoc(pos.y), sp_ftoc(pos.z) };
|
||||
cell_t damagePosition[3] = {sp_ftoc(pos.x), sp_ftoc(pos.y), sp_ftoc(pos.z)};
|
||||
callback->PushArray(damagePosition, 3);
|
||||
|
||||
callback->PushCell(info.GetDamageCustom());
|
||||
@@ -1143,26 +1130,6 @@ int SDKHooks::HandleOnTakeDamageHookPost(CTakeDamageInfoHack &info, SDKHookType
|
||||
RETURN_META_VALUE(MRES_IGNORED, 0);
|
||||
}
|
||||
|
||||
int SDKHooks::Hook_OnTakeDamage(CTakeDamageInfoHack &info)
|
||||
{
|
||||
return HandleOnTakeDamageHook(info, SDKHook_OnTakeDamage);
|
||||
}
|
||||
|
||||
int SDKHooks::Hook_OnTakeDamagePost(CTakeDamageInfoHack &info)
|
||||
{
|
||||
return HandleOnTakeDamageHookPost(info, SDKHook_OnTakeDamagePost);
|
||||
}
|
||||
|
||||
int SDKHooks::Hook_OnTakeDamage_Alive(CTakeDamageInfoHack &info)
|
||||
{
|
||||
return HandleOnTakeDamageHook(info, SDKHook_OnTakeDamage_Alive);
|
||||
}
|
||||
|
||||
int SDKHooks::Hook_OnTakeDamage_AlivePost(CTakeDamageInfoHack &info)
|
||||
{
|
||||
return HandleOnTakeDamageHookPost(info, SDKHook_OnTakeDamage_AlivePost);
|
||||
}
|
||||
|
||||
void SDKHooks::Hook_PreThink()
|
||||
{
|
||||
Call(META_IFACEPTR(CBaseEntity), SDKHook_PreThink);
|
||||
@@ -1201,11 +1168,15 @@ bool SDKHooks::Hook_Reload()
|
||||
int entity = gamehelpers->EntityToBCompatRef(pEntity);
|
||||
cell_t res = Pl_Continue;
|
||||
|
||||
ke::Vector<IPluginFunction *> callbackList;
|
||||
PopulateCallbackList(vtablehooklist[entry]->hooks, callbackList, entity);
|
||||
for (entry = 0; entry < callbackList.length(); ++entry)
|
||||
ke::Vector<HookList> &pawnlist = vtablehooklist[entry]->hooks;
|
||||
for (entry = 0; entry < pawnlist.length(); ++entry)
|
||||
{
|
||||
IPluginFunction *callback = callbackList[entry];
|
||||
if (entity != pawnlist[entry].entity)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
IPluginFunction *callback = pawnlist[entry].callback;
|
||||
callback->PushCell(entity);
|
||||
callback->Execute(&res);
|
||||
}
|
||||
@@ -1224,7 +1195,7 @@ bool SDKHooks::Hook_ReloadPost()
|
||||
CBaseEntity *pEntity = META_IFACEPTR(CBaseEntity);
|
||||
|
||||
CVTableHook vhook(pEntity);
|
||||
ke::Vector<CVTableList *> &vtablehooklist = g_HookList[SDKHook_ReloadPost];
|
||||
ke::Vector<CVTableList *> &vtablehooklist = g_HookList[SDKHook_Reload];
|
||||
for (size_t entry = 0; entry < vtablehooklist.length(); ++entry)
|
||||
{
|
||||
if (vhook != vtablehooklist[entry]->vtablehook)
|
||||
@@ -1235,11 +1206,15 @@ bool SDKHooks::Hook_ReloadPost()
|
||||
int entity = gamehelpers->EntityToBCompatRef(pEntity);
|
||||
cell_t origreturn = META_RESULT_ORIG_RET(bool) ? 1 : 0;
|
||||
|
||||
ke::Vector<IPluginFunction *> callbackList;
|
||||
PopulateCallbackList(vtablehooklist[entry]->hooks, callbackList, entity);
|
||||
for (entry = 0; entry < callbackList.length(); ++entry)
|
||||
ke::Vector<HookList> &pawnlist = vtablehooklist[entry]->hooks;
|
||||
for (entry = 0; entry < pawnlist.length(); ++entry)
|
||||
{
|
||||
IPluginFunction *callback = callbackList[entry];
|
||||
if (entity != pawnlist[entry].entity)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
IPluginFunction *callback = pawnlist[entry].callback;
|
||||
callback->PushCell(entity);
|
||||
callback->PushCell(origreturn);
|
||||
callback->Execute(NULL);
|
||||
@@ -1278,11 +1253,15 @@ bool SDKHooks::Hook_ShouldCollide(int collisionGroup, int contentsMask)
|
||||
cell_t origRet = ((META_RESULT_STATUS >= MRES_OVERRIDE)?(META_RESULT_OVERRIDE_RET(bool)):(META_RESULT_ORIG_RET(bool))) ? 1 : 0;
|
||||
cell_t res = 0;
|
||||
|
||||
ke::Vector<IPluginFunction *> callbackList;
|
||||
PopulateCallbackList(vtablehooklist[entry]->hooks, callbackList, entity);
|
||||
for (entry = 0; entry < callbackList.length(); ++entry)
|
||||
ke::Vector<HookList> &pawnlist = vtablehooklist[entry]->hooks;
|
||||
for (entry = 0; entry < pawnlist.length(); ++entry)
|
||||
{
|
||||
IPluginFunction *callback = callbackList[entry];
|
||||
if (entity != pawnlist[entry].entity)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
IPluginFunction *callback = pawnlist[entry].callback;
|
||||
callback->PushCell(entity);
|
||||
callback->PushCell(collisionGroup);
|
||||
callback->PushCell(contentsMask);
|
||||
@@ -1322,11 +1301,15 @@ void SDKHooks::Hook_Spawn()
|
||||
int entity = gamehelpers->EntityToBCompatRef(pEntity);
|
||||
cell_t res = Pl_Continue;
|
||||
|
||||
ke::Vector<IPluginFunction *> callbackList;
|
||||
PopulateCallbackList(vtablehooklist[entry]->hooks, callbackList, entity);
|
||||
for (entry = 0; entry < callbackList.length(); ++entry)
|
||||
ke::Vector<HookList> &pawnlist = vtablehooklist[entry]->hooks;
|
||||
for (entry = 0; entry < pawnlist.length(); ++entry)
|
||||
{
|
||||
IPluginFunction *callback = callbackList[entry];
|
||||
if (entity != pawnlist[entry].entity)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
IPluginFunction *callback = pawnlist[entry].callback;
|
||||
callback->PushCell(entity);
|
||||
callback->Execute(&res);
|
||||
}
|
||||
@@ -1416,11 +1399,15 @@ void SDKHooks::Hook_TraceAttack(CTakeDamageInfoHack &info, const Vector &vecDir,
|
||||
int ammotype = info.GetAmmoType();
|
||||
cell_t res, ret = Pl_Continue;
|
||||
|
||||
ke::Vector<IPluginFunction *> callbackList;
|
||||
PopulateCallbackList(vtablehooklist[entry]->hooks, callbackList, entity);
|
||||
for (entry = 0; entry < callbackList.length(); ++entry)
|
||||
ke::Vector<HookList> &pawnlist = vtablehooklist[entry]->hooks;
|
||||
for (entry = 0; entry < pawnlist.length(); ++entry)
|
||||
{
|
||||
IPluginFunction *callback = callbackList[entry];
|
||||
if (entity != pawnlist[entry].entity)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
IPluginFunction *callback = pawnlist[entry].callback;
|
||||
callback->PushCell(entity);
|
||||
callback->PushCellByRef(&attacker);
|
||||
callback->PushCellByRef(&inflictor);
|
||||
@@ -1490,11 +1477,15 @@ void SDKHooks::Hook_TraceAttackPost(CTakeDamageInfoHack &info, const Vector &vec
|
||||
|
||||
int entity = gamehelpers->EntityToBCompatRef(pEntity);
|
||||
|
||||
ke::Vector<IPluginFunction *> callbackList;
|
||||
PopulateCallbackList(vtablehooklist[entry]->hooks, callbackList, entity);
|
||||
for (entry = 0; entry < callbackList.length(); ++entry)
|
||||
ke::Vector<HookList> &pawnlist = vtablehooklist[entry]->hooks;
|
||||
for (entry = 0; entry < pawnlist.length(); ++entry)
|
||||
{
|
||||
IPluginFunction *callback = callbackList[entry];
|
||||
if (entity != pawnlist[entry].entity)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
IPluginFunction *callback = pawnlist[entry].callback;
|
||||
callback->PushCell(entity);
|
||||
callback->PushCell(info.GetAttacker());
|
||||
callback->PushCell(info.GetInflictor());
|
||||
@@ -1530,11 +1521,15 @@ void SDKHooks::Hook_Use(CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE
|
||||
int caller = gamehelpers->EntityToBCompatRef(pCaller);
|
||||
cell_t ret = Pl_Continue;
|
||||
|
||||
ke::Vector<IPluginFunction *> callbackList;
|
||||
PopulateCallbackList(vtablehooklist[entry]->hooks, callbackList, entity);
|
||||
for (entry = 0; entry < callbackList.length(); ++entry)
|
||||
ke::Vector<HookList> &pawnlist = vtablehooklist[entry]->hooks;
|
||||
for (entry = 0; entry < pawnlist.length(); ++entry)
|
||||
{
|
||||
IPluginFunction *callback = callbackList[entry];
|
||||
if (entity != pawnlist[entry].entity)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
IPluginFunction *callback = pawnlist[entry].callback;
|
||||
callback->PushCell(entity);
|
||||
callback->PushCell(activator);
|
||||
callback->PushCell(caller);
|
||||
@@ -1569,11 +1564,15 @@ void SDKHooks::Hook_UsePost(CBaseEntity *pActivator, CBaseEntity *pCaller, USE_T
|
||||
int activator = gamehelpers->EntityToBCompatRef(pActivator);
|
||||
int caller = gamehelpers->EntityToBCompatRef(pCaller);
|
||||
|
||||
ke::Vector<IPluginFunction *> callbackList;
|
||||
PopulateCallbackList(vtablehooklist[entry]->hooks, callbackList, entity);
|
||||
for (entry = 0; entry < callbackList.length(); ++entry)
|
||||
ke::Vector<HookList> &pawnlist = vtablehooklist[entry]->hooks;
|
||||
for (entry = 0; entry < pawnlist.length(); ++entry)
|
||||
{
|
||||
IPluginFunction *callback = callbackList[entry];
|
||||
if (entity != pawnlist[entry].entity)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
IPluginFunction *callback = pawnlist[entry].callback;
|
||||
callback->PushCell(entity);
|
||||
callback->PushCell(activator);
|
||||
callback->PushCell(caller);
|
||||
@@ -1613,22 +1612,6 @@ void SDKHooks::Hook_VPhysicsUpdatePost(IPhysicsObject *pPhysics)
|
||||
Call(META_IFACEPTR(CBaseEntity), SDKHook_VPhysicsUpdatePost);
|
||||
}
|
||||
|
||||
void SDKHooks::Hook_Blocked(CBaseEntity *pOther)
|
||||
{
|
||||
cell_t result = Call(META_IFACEPTR(CBaseEntity), SDKHook_Blocked, pOther);
|
||||
|
||||
if(result >= Pl_Handled)
|
||||
RETURN_META(MRES_SUPERCEDE);
|
||||
|
||||
RETURN_META(MRES_IGNORED);
|
||||
}
|
||||
|
||||
void SDKHooks::Hook_BlockedPost(CBaseEntity *pOther)
|
||||
{
|
||||
Call(META_IFACEPTR(CBaseEntity), SDKHook_BlockedPost, pOther);
|
||||
RETURN_META(MRES_IGNORED);
|
||||
}
|
||||
|
||||
bool SDKHooks::Hook_WeaponCanSwitchTo(CBaseCombatWeapon *pWeapon)
|
||||
{
|
||||
cell_t result = Call(META_IFACEPTR(CBaseEntity), SDKHook_WeaponCanSwitchTo, pWeapon);
|
||||
|
||||
+342
-354
@@ -1,361 +1,349 @@
|
||||
#ifndef _INCLUDE_SOURCEMOD_EXTENSION_PROPER_H_
|
||||
#define _INCLUDE_SOURCEMOD_EXTENSION_PROPER_H_
|
||||
|
||||
#include "smsdk_ext.h"
|
||||
#include <ISDKHooks.h>
|
||||
#include <IBinTools.h>
|
||||
#include <convar.h>
|
||||
#include <sh_list.h>
|
||||
#include <amtl/am-vector.h>
|
||||
#include <vtable_hook_helper.h>
|
||||
|
||||
#include <iplayerinfo.h>
|
||||
#include <shareddefs.h>
|
||||
|
||||
#if SOURCE_ENGINE >= SE_ORANGEBOX
|
||||
#include <itoolentity.h>
|
||||
#endif
|
||||
|
||||
#include "takedamageinfohack.h"
|
||||
|
||||
#ifndef METAMOD_PLAPI_VERSION
|
||||
#define GetCGlobals pGlobals
|
||||
#define GetEngineFactory engineFactory
|
||||
#define GetServerFactory serverFactory
|
||||
#endif
|
||||
|
||||
#if SOURCE_ENGINE >= SE_CSS && SOURCE_ENGINE != SE_LEFT4DEAD
|
||||
#define GETMAXHEALTH_IS_VIRTUAL
|
||||
#endif
|
||||
#if SOURCE_ENGINE != SE_HL2DM && SOURCE_ENGINE != SE_DODS && SOURCE_ENGINE != SE_CSS && SOURCE_ENGINE != SE_TF2 && SOURCE_ENGINE != SE_LEFT4DEAD2 && SOURCE_ENGINE != SE_CSGO && SOURCE_ENGINE != SE_NUCLEARDAWN
|
||||
#define GAMEDESC_CAN_CHANGE
|
||||
#endif
|
||||
|
||||
#if SOURCE_ENGINE == SE_DOTA
|
||||
class CEntityKeyValues;
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
* Globals
|
||||
*/
|
||||
|
||||
struct HookTypeData
|
||||
{
|
||||
const char *name;
|
||||
const char *dtReq;
|
||||
bool supported;
|
||||
};
|
||||
|
||||
enum SDKHookType
|
||||
{
|
||||
SDKHook_EndTouch,
|
||||
SDKHook_FireBulletsPost,
|
||||
SDKHook_OnTakeDamage,
|
||||
SDKHook_OnTakeDamagePost,
|
||||
SDKHook_PreThink,
|
||||
SDKHook_PostThink,
|
||||
SDKHook_SetTransmit,
|
||||
SDKHook_Spawn,
|
||||
SDKHook_StartTouch,
|
||||
SDKHook_Think,
|
||||
SDKHook_Touch,
|
||||
SDKHook_TraceAttack,
|
||||
SDKHook_TraceAttackPost,
|
||||
SDKHook_WeaponCanSwitchTo,
|
||||
SDKHook_WeaponCanUse,
|
||||
SDKHook_WeaponDrop,
|
||||
SDKHook_WeaponEquip,
|
||||
SDKHook_WeaponSwitch,
|
||||
SDKHook_ShouldCollide,
|
||||
SDKHook_PreThinkPost,
|
||||
SDKHook_PostThinkPost,
|
||||
SDKHook_ThinkPost,
|
||||
SDKHook_EndTouchPost,
|
||||
SDKHook_GroundEntChangedPost,
|
||||
SDKHook_SpawnPost,
|
||||
SDKHook_StartTouchPost,
|
||||
SDKHook_TouchPost,
|
||||
SDKHook_VPhysicsUpdate,
|
||||
SDKHook_VPhysicsUpdatePost,
|
||||
SDKHook_WeaponCanSwitchToPost,
|
||||
SDKHook_WeaponCanUsePost,
|
||||
SDKHook_WeaponDropPost,
|
||||
SDKHook_WeaponEquipPost,
|
||||
SDKHook_WeaponSwitchPost,
|
||||
SDKHook_Use,
|
||||
SDKHook_UsePost,
|
||||
SDKHook_Reload,
|
||||
SDKHook_ReloadPost,
|
||||
SDKHook_GetMaxHealth,
|
||||
SDKHook_Blocked,
|
||||
SDKHook_BlockedPost,
|
||||
SDKHook_OnTakeDamage_Alive,
|
||||
SDKHook_OnTakeDamage_AlivePost,
|
||||
SDKHook_MAXHOOKS
|
||||
};
|
||||
|
||||
enum HookReturn
|
||||
{
|
||||
HookRet_Successful,
|
||||
HookRet_InvalidEntity,
|
||||
HookRet_InvalidHookType,
|
||||
HookRet_NotSupported,
|
||||
HookRet_BadEntForHookType,
|
||||
};
|
||||
|
||||
#if SOURCE_ENGINE >= SE_CSS
|
||||
typedef void *(*ReticulateSplines)();
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Classes
|
||||
*/
|
||||
|
||||
class IPhysicsObject;
|
||||
class CDmgAccumulator;
|
||||
typedef CBaseEntity CBaseCombatWeapon;
|
||||
|
||||
struct HookList
|
||||
{
|
||||
public:
|
||||
int entity;
|
||||
IPluginFunction *callback;
|
||||
};
|
||||
|
||||
class CVTableList
|
||||
{
|
||||
public:
|
||||
CVTableList() : vtablehook(NULL)
|
||||
{
|
||||
};
|
||||
|
||||
~CVTableList()
|
||||
{
|
||||
delete vtablehook;
|
||||
};
|
||||
public:
|
||||
CVTableHook *vtablehook;
|
||||
ke::Vector<HookList> hooks;
|
||||
};
|
||||
|
||||
#ifndef _INCLUDE_SOURCEMOD_EXTENSION_PROPER_H_
|
||||
#define _INCLUDE_SOURCEMOD_EXTENSION_PROPER_H_
|
||||
|
||||
#include "smsdk_ext.h"
|
||||
#include <ISDKHooks.h>
|
||||
#include <IBinTools.h>
|
||||
#include <convar.h>
|
||||
#include <sh_list.h>
|
||||
#include <amtl/am-vector.h>
|
||||
#include <vtable_hook_helper.h>
|
||||
|
||||
#include <iplayerinfo.h>
|
||||
#include <shareddefs.h>
|
||||
|
||||
#if SOURCE_ENGINE >= SE_ORANGEBOX
|
||||
#include <itoolentity.h>
|
||||
#endif
|
||||
|
||||
#include "takedamageinfohack.h"
|
||||
|
||||
#ifndef METAMOD_PLAPI_VERSION
|
||||
#define GetCGlobals pGlobals
|
||||
#define GetEngineFactory engineFactory
|
||||
#define GetServerFactory serverFactory
|
||||
#endif
|
||||
|
||||
#if SOURCE_ENGINE >= SE_CSS && SOURCE_ENGINE != SE_LEFT4DEAD
|
||||
#define GETMAXHEALTH_IS_VIRTUAL
|
||||
#endif
|
||||
#if SOURCE_ENGINE != SE_HL2DM && SOURCE_ENGINE != SE_DODS && SOURCE_ENGINE != SE_CSS && SOURCE_ENGINE != SE_TF2 && SOURCE_ENGINE != SE_LEFT4DEAD2 && SOURCE_ENGINE != SE_CSGO && SOURCE_ENGINE != SE_NUCLEARDAWN
|
||||
#define GAMEDESC_CAN_CHANGE
|
||||
#endif
|
||||
|
||||
#if SOURCE_ENGINE == SE_DOTA
|
||||
class CEntityKeyValues;
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
* Globals
|
||||
*/
|
||||
|
||||
struct HookTypeData
|
||||
{
|
||||
const char *name;
|
||||
const char *dtReq;
|
||||
bool supported;
|
||||
};
|
||||
|
||||
enum SDKHookType
|
||||
{
|
||||
SDKHook_EndTouch,
|
||||
SDKHook_FireBulletsPost,
|
||||
SDKHook_OnTakeDamage,
|
||||
SDKHook_OnTakeDamagePost,
|
||||
SDKHook_PreThink,
|
||||
SDKHook_PostThink,
|
||||
SDKHook_SetTransmit,
|
||||
SDKHook_Spawn,
|
||||
SDKHook_StartTouch,
|
||||
SDKHook_Think,
|
||||
SDKHook_Touch,
|
||||
SDKHook_TraceAttack,
|
||||
SDKHook_TraceAttackPost,
|
||||
SDKHook_WeaponCanSwitchTo,
|
||||
SDKHook_WeaponCanUse,
|
||||
SDKHook_WeaponDrop,
|
||||
SDKHook_WeaponEquip,
|
||||
SDKHook_WeaponSwitch,
|
||||
SDKHook_ShouldCollide,
|
||||
SDKHook_PreThinkPost,
|
||||
SDKHook_PostThinkPost,
|
||||
SDKHook_ThinkPost,
|
||||
SDKHook_EndTouchPost,
|
||||
SDKHook_GroundEntChangedPost,
|
||||
SDKHook_SpawnPost,
|
||||
SDKHook_StartTouchPost,
|
||||
SDKHook_TouchPost,
|
||||
SDKHook_VPhysicsUpdate,
|
||||
SDKHook_VPhysicsUpdatePost,
|
||||
SDKHook_WeaponCanSwitchToPost,
|
||||
SDKHook_WeaponCanUsePost,
|
||||
SDKHook_WeaponDropPost,
|
||||
SDKHook_WeaponEquipPost,
|
||||
SDKHook_WeaponSwitchPost,
|
||||
SDKHook_Use,
|
||||
SDKHook_UsePost,
|
||||
SDKHook_Reload,
|
||||
SDKHook_ReloadPost,
|
||||
SDKHook_GetMaxHealth,
|
||||
SDKHook_MAXHOOKS
|
||||
};
|
||||
|
||||
enum HookReturn
|
||||
{
|
||||
HookRet_Successful,
|
||||
HookRet_InvalidEntity,
|
||||
HookRet_InvalidHookType,
|
||||
HookRet_NotSupported,
|
||||
HookRet_BadEntForHookType,
|
||||
};
|
||||
|
||||
#if SOURCE_ENGINE >= SE_CSS
|
||||
typedef void *(*ReticulateSplines)();
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Classes
|
||||
*/
|
||||
|
||||
class IPhysicsObject;
|
||||
class CDmgAccumulator;
|
||||
typedef CBaseEntity CBaseCombatWeapon;
|
||||
|
||||
struct HookList
|
||||
{
|
||||
public:
|
||||
int entity;
|
||||
IPluginFunction *callback;
|
||||
};
|
||||
|
||||
class CVTableList
|
||||
{
|
||||
public:
|
||||
CVTableList() : vtablehook(NULL)
|
||||
{
|
||||
};
|
||||
|
||||
~CVTableList()
|
||||
{
|
||||
delete vtablehook;
|
||||
};
|
||||
public:
|
||||
CVTableHook *vtablehook;
|
||||
ke::Vector<HookList> hooks;
|
||||
};
|
||||
|
||||
class IEntityListener
|
||||
{
|
||||
public:
|
||||
virtual void OnEntityCreated( CBaseEntity *pEntity ) {};
|
||||
virtual void OnEntitySpawned( CBaseEntity *pEntity ) {};
|
||||
virtual void OnEntityDeleted( CBaseEntity *pEntity ) {};
|
||||
};
|
||||
|
||||
class SDKHooks :
|
||||
public SDKExtension,
|
||||
public IConCommandBaseAccessor,
|
||||
public IPluginsListener,
|
||||
public IFeatureProvider,
|
||||
public IEntityListener,
|
||||
public IClientListener,
|
||||
public ISDKHooks
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @brief This is called after the initial loading sequence has been processed.
|
||||
*
|
||||
* @param error Error message buffer.
|
||||
* @param maxlength Size of error message buffer.
|
||||
* @param late Whether or not the module was loaded after map load.
|
||||
* @return True to succeed loading, false to fail.
|
||||
*/
|
||||
virtual bool SDK_OnLoad(char *error, size_t maxlength, bool late);
|
||||
|
||||
/**
|
||||
* @brief This is called right before the extension is unloaded.
|
||||
*/
|
||||
virtual void SDK_OnUnload();
|
||||
|
||||
/**
|
||||
* @brief This is called once all known extensions have been loaded.
|
||||
* Note: It is is a good idea to add natives here, if any are provided.
|
||||
*/
|
||||
virtual void SDK_OnAllLoaded();
|
||||
|
||||
/**
|
||||
* @brief Called when the pause state is changed.
|
||||
*/
|
||||
//virtual void SDK_OnPauseChange(bool paused);
|
||||
|
||||
/**
|
||||
* @brief this is called when Core wants to know if your extension is working.
|
||||
*
|
||||
* @param error Error message buffer.
|
||||
* @param maxlength Size of error message buffer.
|
||||
* @return True if working, false otherwise.
|
||||
*/
|
||||
//virtual bool QueryRunning(char *error, size_t maxlength);
|
||||
|
||||
/** Returns version string */
|
||||
virtual const char *GetExtensionVerString();
|
||||
|
||||
/** Returns date string */
|
||||
virtual const char *GetExtensionDateString();
|
||||
|
||||
public:
|
||||
#if defined SMEXT_CONF_METAMOD
|
||||
/**
|
||||
* @brief Called when Metamod is attached, before the extension version is called.
|
||||
*
|
||||
* @param error Error buffer.
|
||||
* @param maxlength Maximum size of error buffer.
|
||||
* @param late Whether or not Metamod considers this a late load.
|
||||
* @return True to succeed, false to fail.
|
||||
*/
|
||||
virtual bool SDK_OnMetamodLoad(ISmmAPI *ismm, char *error, size_t maxlength, bool late);
|
||||
|
||||
/**
|
||||
* @brief Called when Metamod is detaching, after the extension version is called.
|
||||
* NOTE: By default this is blocked unless sent from SourceMod.
|
||||
*
|
||||
* @param error Error buffer.
|
||||
* @param maxlength Maximum size of error buffer.
|
||||
* @return True to succeed, false to fail.
|
||||
*/
|
||||
//virtual bool SDK_OnMetamodUnload(char *error, size_t maxlength);
|
||||
|
||||
/**
|
||||
* @brief Called when Metamod's pause state is changing.
|
||||
* NOTE: By default this is blocked unless sent from SourceMod.
|
||||
*
|
||||
* @param paused Pause state being set.
|
||||
* @param error Error buffer.
|
||||
* @param maxlength Maximum size of error buffer.
|
||||
* @return True to succeed, false to fail.
|
||||
*/
|
||||
//virtual bool SDK_OnMetamodPauseChange(bool paused, char *error, size_t maxlength);
|
||||
#endif
|
||||
|
||||
public: // IPluginsListener
|
||||
virtual void OnPluginLoaded(IPlugin *plugin);
|
||||
virtual void OnPluginUnloaded(IPlugin *plugin);
|
||||
|
||||
public: // IConCommandBaseAccessor
|
||||
virtual bool RegisterConCommandBase(ConCommandBase *pVar);
|
||||
|
||||
public: // IFeatureProvider
|
||||
virtual FeatureStatus GetFeatureStatus(FeatureType type, const char *name);
|
||||
|
||||
public: // IEntityListener
|
||||
virtual void OnEntityCreated(CBaseEntity *pEntity);
|
||||
virtual void OnEntityDeleted(CBaseEntity *pEntity);
|
||||
|
||||
public: // IClientListener
|
||||
virtual void OnClientPutInServer(int client);
|
||||
virtual void OnClientDisconnecting(int client);
|
||||
|
||||
public: // ISDKHooks
|
||||
virtual void AddEntityListener(ISMEntityListener *listener);
|
||||
virtual void RemoveEntityListener(ISMEntityListener *listener);
|
||||
|
||||
private:
|
||||
SourceHook::List<ISMEntityListener *> m_EntListeners;
|
||||
|
||||
public:
|
||||
/**
|
||||
* Functions
|
||||
*/
|
||||
};
|
||||
|
||||
class SDKHooks :
|
||||
public SDKExtension,
|
||||
public IConCommandBaseAccessor,
|
||||
public IPluginsListener,
|
||||
public IFeatureProvider,
|
||||
public IEntityListener,
|
||||
public IClientListener,
|
||||
public ISDKHooks
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @brief This is called after the initial loading sequence has been processed.
|
||||
*
|
||||
* @param error Error message buffer.
|
||||
* @param maxlength Size of error message buffer.
|
||||
* @param late Whether or not the module was loaded after map load.
|
||||
* @return True to succeed loading, false to fail.
|
||||
*/
|
||||
virtual bool SDK_OnLoad(char *error, size_t maxlength, bool late);
|
||||
|
||||
/**
|
||||
* @brief This is called right before the extension is unloaded.
|
||||
*/
|
||||
virtual void SDK_OnUnload();
|
||||
|
||||
/**
|
||||
* @brief This is called once all known extensions have been loaded.
|
||||
* Note: It is is a good idea to add natives here, if any are provided.
|
||||
*/
|
||||
virtual void SDK_OnAllLoaded();
|
||||
|
||||
/**
|
||||
* @brief Called when the pause state is changed.
|
||||
*/
|
||||
//virtual void SDK_OnPauseChange(bool paused);
|
||||
|
||||
/**
|
||||
* @brief this is called when Core wants to know if your extension is working.
|
||||
*
|
||||
* @param error Error message buffer.
|
||||
* @param maxlength Size of error message buffer.
|
||||
* @return True if working, false otherwise.
|
||||
*/
|
||||
//virtual bool QueryRunning(char *error, size_t maxlength);
|
||||
|
||||
/** Returns version string */
|
||||
virtual const char *GetExtensionVerString();
|
||||
|
||||
/** Returns date string */
|
||||
virtual const char *GetExtensionDateString();
|
||||
|
||||
public:
|
||||
#if defined SMEXT_CONF_METAMOD
|
||||
/**
|
||||
* @brief Called when Metamod is attached, before the extension version is called.
|
||||
*
|
||||
* @param error Error buffer.
|
||||
* @param maxlength Maximum size of error buffer.
|
||||
* @param late Whether or not Metamod considers this a late load.
|
||||
* @return True to succeed, false to fail.
|
||||
*/
|
||||
virtual bool SDK_OnMetamodLoad(ISmmAPI *ismm, char *error, size_t maxlength, bool late);
|
||||
|
||||
/**
|
||||
* @brief Called when Metamod is detaching, after the extension version is called.
|
||||
* NOTE: By default this is blocked unless sent from SourceMod.
|
||||
*
|
||||
* @param error Error buffer.
|
||||
* @param maxlength Maximum size of error buffer.
|
||||
* @return True to succeed, false to fail.
|
||||
*/
|
||||
//virtual bool SDK_OnMetamodUnload(char *error, size_t maxlength);
|
||||
|
||||
/**
|
||||
* @brief Called when Metamod's pause state is changing.
|
||||
* NOTE: By default this is blocked unless sent from SourceMod.
|
||||
*
|
||||
* @param paused Pause state being set.
|
||||
* @param error Error buffer.
|
||||
* @param maxlength Maximum size of error buffer.
|
||||
* @return True to succeed, false to fail.
|
||||
*/
|
||||
//virtual bool SDK_OnMetamodPauseChange(bool paused, char *error, size_t maxlength);
|
||||
#endif
|
||||
|
||||
public: // IPluginsListener
|
||||
virtual void OnPluginLoaded(IPlugin *plugin);
|
||||
virtual void OnPluginUnloaded(IPlugin *plugin);
|
||||
|
||||
public: // IConCommandBaseAccessor
|
||||
virtual bool RegisterConCommandBase(ConCommandBase *pVar);
|
||||
|
||||
public: // IFeatureProvider
|
||||
virtual FeatureStatus GetFeatureStatus(FeatureType type, const char *name);
|
||||
|
||||
public: // IEntityListener
|
||||
virtual void OnEntityCreated(CBaseEntity *pEntity);
|
||||
virtual void OnEntityDeleted(CBaseEntity *pEntity);
|
||||
|
||||
public: // IClientListener
|
||||
virtual void OnClientPutInServer(int client);
|
||||
virtual void OnClientDisconnecting(int client);
|
||||
|
||||
public: // ISDKHooks
|
||||
virtual void AddEntityListener(ISMEntityListener *listener);
|
||||
virtual void RemoveEntityListener(ISMEntityListener *listener);
|
||||
|
||||
private:
|
||||
SourceHook::List<ISMEntityListener *> m_EntListeners;
|
||||
|
||||
public:
|
||||
/**
|
||||
* Functions
|
||||
*/
|
||||
cell_t Call(int entity, SDKHookType type, int other=INVALID_EHANDLE_INDEX);
|
||||
cell_t Call(CBaseEntity *pEnt, SDKHookType type, int other=INVALID_EHANDLE_INDEX);
|
||||
cell_t Call(CBaseEntity *pEnt, SDKHookType type, CBaseEntity *pOther);
|
||||
void SetupHooks();
|
||||
|
||||
HookReturn Hook(int entity, SDKHookType type, IPluginFunction *pCallback);
|
||||
void Unhook(int entity, SDKHookType type, IPluginFunction *pCallback);
|
||||
|
||||
/**
|
||||
* IServerGameDLL & IVEngineServer Hook Handlers
|
||||
*/
|
||||
#ifdef GAMEDESC_CAN_CHANGE
|
||||
const char *Hook_GetGameDescription();
|
||||
#endif
|
||||
const char *Hook_GetMapEntitiesString();
|
||||
bool Hook_LevelInit(char const *pMapName, char const *pMapEntities, char const *pOldLevel, char const *pLandmarkName, bool loadGame, bool background);
|
||||
|
||||
/**
|
||||
* CBaseEntity Hook Handlers
|
||||
*/
|
||||
void Hook_EndTouch(CBaseEntity *pOther);
|
||||
void Hook_EndTouchPost(CBaseEntity *pOther);
|
||||
void Hook_FireBulletsPost(const FireBulletsInfo_t &info);
|
||||
#ifdef GETMAXHEALTH_IS_VIRTUAL
|
||||
int Hook_GetMaxHealth();
|
||||
#endif
|
||||
void Hook_GroundEntChangedPost(void *pVar);
|
||||
int Hook_OnTakeDamage(CTakeDamageInfoHack &info);
|
||||
int Hook_OnTakeDamagePost(CTakeDamageInfoHack &info);
|
||||
int Hook_OnTakeDamage_Alive(CTakeDamageInfoHack &info);
|
||||
int Hook_OnTakeDamage_AlivePost(CTakeDamageInfoHack &info);
|
||||
void Hook_PreThink();
|
||||
void Hook_PreThinkPost();
|
||||
void Hook_PostThink();
|
||||
void Hook_PostThinkPost();
|
||||
bool Hook_Reload();
|
||||
bool Hook_ReloadPost();
|
||||
void Hook_SetTransmit(CCheckTransmitInfo *pInfo, bool bAlways);
|
||||
bool Hook_ShouldCollide(int collisonGroup, int contentsMask);
|
||||
#if SOURCE_ENGINE == SE_DOTA
|
||||
void Hook_Spawn(CEntityKeyValues *kv);
|
||||
void Hook_SpawnPost(CEntityKeyValues *kv);
|
||||
#else
|
||||
void Hook_Spawn();
|
||||
void Hook_SpawnPost();
|
||||
#endif
|
||||
void Hook_StartTouch(CBaseEntity *pOther);
|
||||
void Hook_StartTouchPost(CBaseEntity *pOther);
|
||||
void Hook_Think();
|
||||
void Hook_ThinkPost();
|
||||
void Hook_Touch(CBaseEntity *pOther);
|
||||
void Hook_TouchPost(CBaseEntity *pOther);
|
||||
#if SOURCE_ENGINE == SE_HL2DM || SOURCE_ENGINE == SE_DODS || SOURCE_ENGINE == SE_CSS || SOURCE_ENGINE == SE_TF2 || SOURCE_ENGINE == SE_SDK2013
|
||||
void Hook_TraceAttack(CTakeDamageInfoHack &info, const Vector &vecDir, trace_t *ptr, CDmgAccumulator *pAccumulator);
|
||||
void Hook_TraceAttackPost(CTakeDamageInfoHack &info, const Vector &vecDir, trace_t *ptr, CDmgAccumulator *pAccumulator);
|
||||
#else
|
||||
void Hook_TraceAttack(CTakeDamageInfoHack &info, const Vector &vecDir, trace_t *ptr);
|
||||
void Hook_TraceAttackPost(CTakeDamageInfoHack &info, const Vector &vecDir, trace_t *ptr);
|
||||
#endif
|
||||
void Hook_UpdateOnRemove();
|
||||
void Hook_Use(CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value);
|
||||
void Hook_UsePost(CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value);
|
||||
void Hook_VPhysicsUpdate(IPhysicsObject *pPhysics);
|
||||
void Hook_VPhysicsUpdatePost(IPhysicsObject *pPhysics);
|
||||
void Hook_Blocked(CBaseEntity *pOther);
|
||||
void Hook_BlockedPost(CBaseEntity *pOther);
|
||||
bool Hook_WeaponCanSwitchTo(CBaseCombatWeapon *pWeapon);
|
||||
bool Hook_WeaponCanSwitchToPost(CBaseCombatWeapon *pWeapon);
|
||||
bool Hook_WeaponCanUse(CBaseCombatWeapon *pWeapon);
|
||||
bool Hook_WeaponCanUsePost(CBaseCombatWeapon *pWeapon);
|
||||
void Hook_WeaponDrop(CBaseCombatWeapon *pWeapon, const Vector *pvecTarget, const Vector *pVelocity);
|
||||
void Hook_WeaponDropPost(CBaseCombatWeapon *pWeapon, const Vector *pvecTarget, const Vector *pVelocity);
|
||||
void Hook_WeaponEquip(CBaseCombatWeapon *pWeapon);
|
||||
void Hook_WeaponEquipPost(CBaseCombatWeapon *pWeapon);
|
||||
bool Hook_WeaponSwitch(CBaseCombatWeapon *pWeapon, int viewmodelindex);
|
||||
bool Hook_WeaponSwitchPost(CBaseCombatWeapon *pWeapon, int viewmodelindex);
|
||||
|
||||
private:
|
||||
void HandleEntityCreated(CBaseEntity *pEntity, int ref);
|
||||
void HandleEntityDeleted(CBaseEntity *pEntity, int ref);
|
||||
void Unhook(CBaseEntity *pEntity);
|
||||
void Unhook(IPluginContext *pContext);
|
||||
|
||||
private:
|
||||
int HandleOnTakeDamageHook(CTakeDamageInfoHack &info, SDKHookType hookType);
|
||||
int HandleOnTakeDamageHookPost(CTakeDamageInfoHack &info, SDKHookType hookType);
|
||||
};
|
||||
|
||||
extern CGlobalVars *gpGlobals;
|
||||
extern ke::Vector<CVTableList *> g_HookList[SDKHook_MAXHOOKS];
|
||||
|
||||
extern ICvar *icvar;
|
||||
|
||||
#if SOURCE_ENGINE >= SE_ORANGEBOX
|
||||
extern IServerTools *servertools;
|
||||
#endif
|
||||
|
||||
#endif // _INCLUDE_SOURCEMOD_EXTENSION_PROPER_H_
|
||||
cell_t Call(CBaseEntity *pEnt, SDKHookType type, int other=INVALID_EHANDLE_INDEX);
|
||||
cell_t Call(CBaseEntity *pEnt, SDKHookType type, CBaseEntity *pOther);
|
||||
void SetupHooks();
|
||||
|
||||
HookReturn Hook(int entity, SDKHookType type, IPluginFunction *pCallback);
|
||||
void Unhook(int entity, SDKHookType type, IPluginFunction *pCallback);
|
||||
|
||||
/**
|
||||
* IServerGameDLL & IVEngineServer Hook Handlers
|
||||
*/
|
||||
#ifdef GAMEDESC_CAN_CHANGE
|
||||
const char *Hook_GetGameDescription();
|
||||
#endif
|
||||
const char *Hook_GetMapEntitiesString();
|
||||
bool Hook_LevelInit(char const *pMapName, char const *pMapEntities, char const *pOldLevel, char const *pLandmarkName, bool loadGame, bool background);
|
||||
|
||||
/**
|
||||
* CBaseEntity Hook Handlers
|
||||
*/
|
||||
void Hook_EndTouch(CBaseEntity *pOther);
|
||||
void Hook_EndTouchPost(CBaseEntity *pOther);
|
||||
void Hook_FireBulletsPost(const FireBulletsInfo_t &info);
|
||||
#ifdef GETMAXHEALTH_IS_VIRTUAL
|
||||
int Hook_GetMaxHealth();
|
||||
#endif
|
||||
void Hook_GroundEntChangedPost(void *pVar);
|
||||
int Hook_OnTakeDamage(CTakeDamageInfoHack &info);
|
||||
int Hook_OnTakeDamagePost(CTakeDamageInfoHack &info);
|
||||
void Hook_PreThink();
|
||||
void Hook_PreThinkPost();
|
||||
void Hook_PostThink();
|
||||
void Hook_PostThinkPost();
|
||||
bool Hook_Reload();
|
||||
bool Hook_ReloadPost();
|
||||
void Hook_SetTransmit(CCheckTransmitInfo *pInfo, bool bAlways);
|
||||
bool Hook_ShouldCollide(int collisonGroup, int contentsMask);
|
||||
#if SOURCE_ENGINE == SE_DOTA
|
||||
void Hook_Spawn(CEntityKeyValues *kv);
|
||||
void Hook_SpawnPost(CEntityKeyValues *kv);
|
||||
#else
|
||||
void Hook_Spawn();
|
||||
void Hook_SpawnPost();
|
||||
#endif
|
||||
void Hook_StartTouch(CBaseEntity *pOther);
|
||||
void Hook_StartTouchPost(CBaseEntity *pOther);
|
||||
void Hook_Think();
|
||||
void Hook_ThinkPost();
|
||||
void Hook_Touch(CBaseEntity *pOther);
|
||||
void Hook_TouchPost(CBaseEntity *pOther);
|
||||
#if SOURCE_ENGINE == SE_HL2DM || SOURCE_ENGINE == SE_DODS || SOURCE_ENGINE == SE_CSS || SOURCE_ENGINE == SE_TF2 || SOURCE_ENGINE == SE_SDK2013
|
||||
void Hook_TraceAttack(CTakeDamageInfoHack &info, const Vector &vecDir, trace_t *ptr, CDmgAccumulator *pAccumulator);
|
||||
void Hook_TraceAttackPost(CTakeDamageInfoHack &info, const Vector &vecDir, trace_t *ptr, CDmgAccumulator *pAccumulator);
|
||||
#else
|
||||
void Hook_TraceAttack(CTakeDamageInfoHack &info, const Vector &vecDir, trace_t *ptr);
|
||||
void Hook_TraceAttackPost(CTakeDamageInfoHack &info, const Vector &vecDir, trace_t *ptr);
|
||||
#endif
|
||||
void Hook_UpdateOnRemove();
|
||||
void Hook_Use(CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value);
|
||||
void Hook_UsePost(CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value);
|
||||
void Hook_VPhysicsUpdate(IPhysicsObject *pPhysics);
|
||||
void Hook_VPhysicsUpdatePost(IPhysicsObject *pPhysics);
|
||||
bool Hook_WeaponCanSwitchTo(CBaseCombatWeapon *pWeapon);
|
||||
bool Hook_WeaponCanSwitchToPost(CBaseCombatWeapon *pWeapon);
|
||||
bool Hook_WeaponCanUse(CBaseCombatWeapon *pWeapon);
|
||||
bool Hook_WeaponCanUsePost(CBaseCombatWeapon *pWeapon);
|
||||
void Hook_WeaponDrop(CBaseCombatWeapon *pWeapon, const Vector *pvecTarget, const Vector *pVelocity);
|
||||
void Hook_WeaponDropPost(CBaseCombatWeapon *pWeapon, const Vector *pvecTarget, const Vector *pVelocity);
|
||||
void Hook_WeaponEquip(CBaseCombatWeapon *pWeapon);
|
||||
void Hook_WeaponEquipPost(CBaseCombatWeapon *pWeapon);
|
||||
bool Hook_WeaponSwitch(CBaseCombatWeapon *pWeapon, int viewmodelindex);
|
||||
bool Hook_WeaponSwitchPost(CBaseCombatWeapon *pWeapon, int viewmodelindex);
|
||||
|
||||
private:
|
||||
void HandleEntityCreated(CBaseEntity *pEntity, int ref);
|
||||
void HandleEntityDeleted(CBaseEntity *pEntity, int ref);
|
||||
void Unhook(CBaseEntity *pEntity);
|
||||
void Unhook(IPluginContext *pContext);
|
||||
};
|
||||
|
||||
extern CGlobalVars *gpGlobals;
|
||||
extern ke::Vector<CVTableList *> g_HookList[SDKHook_MAXHOOKS];
|
||||
|
||||
extern ICvar *icvar;
|
||||
|
||||
#if SOURCE_ENGINE >= SE_ORANGEBOX
|
||||
extern IServerTools *servertools;
|
||||
#endif
|
||||
|
||||
#endif // _INCLUDE_SOURCEMOD_EXTENSION_PROPER_H_
|
||||
|
||||
@@ -66,7 +66,6 @@ IPlayerInfoManager *playerinfomngr = NULL;
|
||||
ICvar *icvar = NULL;
|
||||
IServer *iserver = NULL;
|
||||
CGlobalVars *gpGlobals;
|
||||
ISoundEmitterSystemBase *soundemitterbase = NULL;
|
||||
|
||||
#if SOURCE_ENGINE >= SE_ORANGEBOX
|
||||
IServerTools *servertools = NULL;
|
||||
@@ -259,7 +258,6 @@ bool SDKTools::SDK_OnMetamodLoad(ISmmAPI *ismm, char *error, size_t maxlen, bool
|
||||
#if SOURCE_ENGINE >= SE_ORANGEBOX
|
||||
GET_V_IFACE_ANY(GetServerFactory, servertools, IServerTools, VSERVERTOOLS_INTERFACE_VERSION);
|
||||
#endif
|
||||
GET_V_IFACE_ANY(GetEngineFactory, soundemitterbase, ISoundEmitterSystemBase, SOUNDEMITTERSYSTEM_INTERFACE_VERSION);
|
||||
|
||||
gpGlobals = ismm->GetCGlobals();
|
||||
enginePatch = SH_GET_CALLCLASS(engine);
|
||||
@@ -340,10 +338,6 @@ bool SDKTools::RegisterConCommandBase(ConCommandBase *pVar)
|
||||
|
||||
bool SDKTools::LevelInit(char const *pMapName, char const *pMapEntities, char const *pOldLevel, char const *pLandmarkName, bool loadGame, bool background)
|
||||
{
|
||||
m_bAnyLevelInited = true;
|
||||
|
||||
UpdateValveGlobals();
|
||||
|
||||
const char *name;
|
||||
char key[32];
|
||||
int count, n = 1;
|
||||
@@ -476,7 +470,10 @@ public:
|
||||
|
||||
virtual void *GetGameRules()
|
||||
{
|
||||
return GameRules();
|
||||
if (!g_pGameRules)
|
||||
return NULL;
|
||||
|
||||
return *g_pGameRules;
|
||||
}
|
||||
} g_SDKTools_API;
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user