Compare commits
51
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3e63e611c2 | ||
|
|
c3598d8e71 | ||
|
|
f57097651b | ||
|
|
a5450aad18 | ||
|
|
0a4a06d9e1 | ||
|
|
dd51da519d | ||
|
|
c79f52e2c9 | ||
|
|
c4279da3b2 | ||
|
|
3923177037 | ||
|
|
80a0e24b66 | ||
|
|
75d770ba0f | ||
|
|
d9e6daa006 | ||
|
|
f08b60bc98 | ||
|
|
4d98fc2a3d | ||
|
|
0b4ec459d3 | ||
|
|
65269551f9 | ||
|
|
47b0022331 | ||
|
|
7df2b28fe0 | ||
|
|
7df1069613 | ||
|
|
7585acaeef | ||
|
|
dfcf953131 | ||
|
|
cb31a65807 | ||
|
|
6123c5e013 | ||
|
|
cb73b935ec | ||
|
|
76e8e7e50c | ||
|
|
40d049e1f6 | ||
|
|
48012ccf08 | ||
|
|
80ceb149b0 | ||
|
|
1ef60a13d0 | ||
|
|
e8e40d126e | ||
|
|
c7033827f5 | ||
|
|
ff27214615 | ||
|
|
7b45e963d5 | ||
|
|
96965ef7cd | ||
|
|
8f7ce184fb | ||
|
|
4bed0a2893 | ||
|
|
6ab2e23d9d | ||
|
|
dd27de8d85 | ||
|
|
8c79a6df33 | ||
|
|
e8111f3c0a | ||
|
|
a038181193 | ||
|
|
52fe916311 | ||
|
|
d01d7b1879 | ||
|
|
d8406a3efc | ||
|
|
d74204aded | ||
|
|
77be859667 | ||
|
|
71193c67b2 | ||
|
|
cc1493aa66 | ||
|
|
43946e6b6f | ||
|
|
5776909b13 | ||
|
|
048c227fcc |
@@ -381,6 +381,9 @@ 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)]
|
||||
|
||||
|
||||
@@ -1,5 +1,40 @@
|
||||
SourceMod Changelog
|
||||
|
||||
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,13 +132,5 @@
|
||||
* 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"
|
||||
}
|
||||
|
||||
|
||||
+3
-5
@@ -52,17 +52,14 @@ 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.3.0', 'src'),
|
||||
os.path.join(sdk.path, 'common', 'protobuf-2.5.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.4.1', 'src'),
|
||||
os.path.join(sdk.path, 'common', 'protobuf-2.5.0', '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')
|
||||
@@ -109,6 +106,7 @@ 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'),
|
||||
|
||||
+12
-2
@@ -648,8 +648,11 @@ QueryCvarCookie_t ConVarManager::QueryClientConVar(edict_t *pPlayer, const char
|
||||
return InvalidQueryCvarCookie;
|
||||
}
|
||||
|
||||
ConVarQuery query = {cookie, pCallback, (cell_t)hndl, IndexOfEdict(pPlayer)};
|
||||
m_ConVarQueries.push_back(query);
|
||||
if (pCallback != NULL)
|
||||
{
|
||||
ConVarQuery query = { cookie, pCallback, (cell_t) hndl, IndexOfEdict(pPlayer) };
|
||||
m_ConVarQueries.push_back(query);
|
||||
}
|
||||
#endif
|
||||
|
||||
return cookie;
|
||||
@@ -753,6 +756,13 @@ 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;
|
||||
|
||||
@@ -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
|
||||
#if SOURCE_ENGINE >= SE_LEFT4DEAD && SOURCE_ENGINE != SE_DOTA
|
||||
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
|
||||
#if SOURCE_ENGINE >= SE_LEFT4DEAD && SOURCE_ENGINE != SE_DOTA
|
||||
int GetEventDebugID();
|
||||
#endif
|
||||
public:
|
||||
|
||||
@@ -47,6 +47,12 @@
|
||||
#include "logic_bridge.h"
|
||||
#include <sourcemod_version.h>
|
||||
|
||||
#if SOURCE_ENGINE >= SE_ORANGEBOX
|
||||
#include <steam/steamclientpublic.h>
|
||||
#endif
|
||||
|
||||
class CSteamID;
|
||||
|
||||
PlayerManager g_Players;
|
||||
bool g_OnMapStarted = false;
|
||||
IForward *PreAdminCheck = NULL;
|
||||
@@ -399,15 +405,28 @@ void PlayerManager::RunAuthChecks()
|
||||
{
|
||||
CPlayer *pPlayer;
|
||||
const char *authstr;
|
||||
const CSteamID *steamid = NULL;
|
||||
unsigned int removed = 0;
|
||||
for (unsigned int i=1; i<=m_AuthQueue[0]; i++)
|
||||
{
|
||||
pPlayer = &m_Players[m_AuthQueue[i]];
|
||||
#if SOURCE_ENGINE == SE_DOTA
|
||||
steamid = engine->GetClientSteamID(pPlayer->m_iIndex);
|
||||
authstr = engine->GetPlayerNetworkIDString(pPlayer->m_iIndex - 1);
|
||||
#elif SOURCE_ENGINE >= SE_ORANGEBOX
|
||||
steamid = engine->GetClientSteamID(pPlayer->m_pEdict);
|
||||
authstr = engine->GetPlayerNetworkIDString(pPlayer->m_pEdict);
|
||||
#else
|
||||
authstr = engine->GetPlayerNetworkIDString(pPlayer->m_pEdict);
|
||||
#endif
|
||||
|
||||
#if SOURCE_ENGINE >= SE_ORANGEBOX
|
||||
if (authstr && authstr[0] == '[' && steamid)
|
||||
{
|
||||
authstr = steamid->Render();
|
||||
}
|
||||
#endif
|
||||
|
||||
pPlayer->SetAuthString(authstr);
|
||||
|
||||
if (!pPlayer->IsAuthStringValidated())
|
||||
@@ -502,6 +521,9 @@ 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")))
|
||||
{
|
||||
@@ -510,6 +532,7 @@ bool PlayerManager::OnClientConnect(edict_t *pEntity, const char *pszName, const
|
||||
} else {
|
||||
pPlayer->m_LangId = translator->GetServerLanguage();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
List<IClientListener *>::iterator iter;
|
||||
@@ -727,6 +750,13 @@ void PlayerManager::OnClientPutInServer(edict_t *pEntity, const char *playername
|
||||
}
|
||||
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)
|
||||
{
|
||||
@@ -1862,6 +1892,24 @@ 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 ***
|
||||
@@ -1886,6 +1934,9 @@ CPlayer::CPlayer()
|
||||
m_bIsReplay = false;
|
||||
m_Serial.value = -1;
|
||||
m_SteamAccountID = 0;
|
||||
#if SOURCE_ENGINE == SE_CSGO
|
||||
m_LanguageCookie = InvalidQueryCvarCookie;
|
||||
#endif
|
||||
}
|
||||
|
||||
void CPlayer::Initialize(const char *name, const char *ip, edict_t *pEntity)
|
||||
@@ -1966,6 +2017,9 @@ void CPlayer::Disconnect()
|
||||
m_bIsReplay = false;
|
||||
m_Serial.value = -1;
|
||||
m_SteamAccountID = 0;
|
||||
#if SOURCE_ENGINE == SE_CSGO
|
||||
m_LanguageCookie = InvalidQueryCvarCookie;
|
||||
#endif
|
||||
}
|
||||
|
||||
void CPlayer::SetName(const char *name)
|
||||
@@ -2401,3 +2455,28 @@ void CPlayer::PrintToConsole(const char *pMsg)
|
||||
engine->ClientPrintf(m_pEdict, pMsg);
|
||||
#endif
|
||||
}
|
||||
|
||||
#if SOURCE_ENGINE >= SE_LEFT4DEAD
|
||||
const EUniverse kCurrentSteamUniverse = k_EUniversePublic;
|
||||
#elif SOURCE_ENGINE >= SE_ORANGEBOX
|
||||
const EUniverse kCurrentSteamUniverse = k_EUniverseInvalid;
|
||||
#endif
|
||||
|
||||
#if SOURCE_ENGINE >= SE_ORANGEBOX
|
||||
const char *CSteamID::Render() const
|
||||
{
|
||||
static char szSteamID[64];
|
||||
|
||||
switch (GetEAccountType())
|
||||
{
|
||||
case k_EAccountTypeInvalid:
|
||||
case k_EAccountTypeIndividual:
|
||||
snprintf(szSteamID, sizeof(szSteamID), "STEAM_%u:%u:%u", kCurrentSteamUniverse, GetAccountID() % 2, GetAccountID() >> 1);
|
||||
break;
|
||||
default:
|
||||
szSteamID[0] = '\0';
|
||||
}
|
||||
|
||||
return szSteamID;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -131,6 +131,9 @@ private:
|
||||
bool m_bIsReplay;
|
||||
serial_t m_Serial;
|
||||
unsigned int m_SteamAccountID;
|
||||
#if SOURCE_ENGINE == SE_CSGO
|
||||
QueryCvarCookie_t m_LanguageCookie;
|
||||
#endif
|
||||
};
|
||||
|
||||
class PlayerManager :
|
||||
@@ -211,6 +214,9 @@ 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();
|
||||
|
||||
@@ -19,6 +19,12 @@ 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',
|
||||
|
||||
@@ -615,6 +615,17 @@ 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)
|
||||
|
||||
+28
-1
@@ -797,6 +797,32 @@ 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,6 +1127,7 @@ REGISTER_NATIVES(keyvaluenatives)
|
||||
{"KvGetDataType", smn_KvGetDataType},
|
||||
{"KeyValuesToFile", smn_KeyValuesToFile},
|
||||
{"FileToKeyValues", smn_FileToKeyValues},
|
||||
{"StringToKeyValues", smn_StringToKeyValues},
|
||||
{"KvSetEscapeSequences", smn_KvSetEscapeSequences},
|
||||
{"KvDeleteThis", smn_KvDeleteThis},
|
||||
{"KvDeleteKey", smn_KvDeleteKey},
|
||||
@@ -1113,4 +1140,4 @@ REGISTER_NATIVES(keyvaluenatives)
|
||||
{"KvGetVector", smn_KvGetVector},
|
||||
{"KvSetVector", smn_KvSetVector},
|
||||
{NULL, NULL}
|
||||
};
|
||||
};
|
||||
@@ -37,6 +37,15 @@
|
||||
#include <inetchannel.h>
|
||||
#include <iclient.h>
|
||||
|
||||
#ifndef PRIu64
|
||||
#ifdef _WIN32
|
||||
#define PRIu64 "I64u"
|
||||
#else
|
||||
#define PRIu64 "llu"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
static cell_t sm_GetMaxHumanPlayers(IPluginContext *pCtx, const cell_t *params)
|
||||
{
|
||||
int maxHumans = -1;
|
||||
@@ -380,6 +389,124 @@ static cell_t RunAdminCacheChecks(IPluginContext *pContext, const cell_t *params
|
||||
return (id != pPlayer->GetAdminId()) ? 1 : 0;
|
||||
}
|
||||
|
||||
// Must match clients.inc
|
||||
enum AuthIdType
|
||||
{
|
||||
AuthType_Engine = 0,
|
||||
AuthType_Steam2,
|
||||
AuthType_Steam3,
|
||||
AuthType_SteamId64,
|
||||
};
|
||||
|
||||
static cell_t GetClientAuthId(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]);
|
||||
}
|
||||
else if (!pPlayer->IsConnected())
|
||||
{
|
||||
return pContext->ThrowNativeError("Client %d is not connected", params[1]);
|
||||
}
|
||||
|
||||
bool validate = !!params[5];
|
||||
|
||||
switch (params[2])
|
||||
{
|
||||
case AuthType_Engine:
|
||||
{
|
||||
const char *authstr;
|
||||
if (validate)
|
||||
{
|
||||
// Keep this as a validation check
|
||||
authstr = pPlayer->GetAuthString(params[5]);
|
||||
if (!authstr || authstr[0] == '\0')
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
#if SOURCE_ENGINE == SE_DOTA
|
||||
authstr = engine->GetPlayerNetworkIDString(pPlayer->GetIndex());
|
||||
#else
|
||||
authstr = engine->GetPlayerNetworkIDString(pPlayer->GetEdict());
|
||||
#endif
|
||||
pContext->StringToLocal(params[3], params[4], authstr);
|
||||
}
|
||||
break;
|
||||
case AuthType_Steam2:
|
||||
case AuthType_Steam3:
|
||||
{
|
||||
if (pPlayer->IsFakeClient())
|
||||
{
|
||||
pContext->StringToLocal(params[3], params[4], "BOT");
|
||||
return 1;
|
||||
}
|
||||
|
||||
static char authstr[64];
|
||||
unsigned int acctId = pPlayer->GetSteamAccountID(validate);
|
||||
if (acctId == 0)
|
||||
{
|
||||
if (g_HL2.IsLANServer())
|
||||
{
|
||||
pContext->StringToLocal(params[3], params[4], "STEAM_ID_LAN");
|
||||
return 1;
|
||||
}
|
||||
else if (!params[5])
|
||||
{
|
||||
pContext->StringToLocal(params[3], params[4], "STEAM_ID_PENDING");
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (params[2] == AuthType_Steam2)
|
||||
{
|
||||
#if SOURCE_ENGINE <= SE_LEFT4DEAD
|
||||
unsigned int universe = 0;
|
||||
#else
|
||||
unsigned int universe = 1;
|
||||
#endif
|
||||
_snprintf(authstr, sizeof(authstr), "STEAM_%u:%u:%u", universe, acctId & 1, acctId >> 1);
|
||||
pContext->StringToLocal(params[3], params[4], authstr);
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
_snprintf(authstr, sizeof(authstr), "[U:1:%u]", acctId);
|
||||
pContext->StringToLocal(params[3], params[4], authstr);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case AuthType_SteamId64:
|
||||
{
|
||||
if (pPlayer->IsFakeClient() || g_HL2.IsLANServer())
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
unsigned int acctId = pPlayer->GetSteamAccountID(validate);
|
||||
if (acctId == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint64_t steamId = acctId;
|
||||
steamId |= ((uint64_t)1<<32); // Instance (1/Desktop)
|
||||
steamId |= ((uint64_t)1<<52); // Type (1/Individual)
|
||||
steamId |= ((uint64_t)1<<56); // Universe (1/Public)
|
||||
|
||||
static char authstr[64];
|
||||
snprintf(authstr, sizeof(authstr), "%" PRIu64, steamId);
|
||||
pContext->StringToLocal(params[3], params[4], authstr);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
REGISTER_NATIVES(playernatives)
|
||||
{
|
||||
{"GetMaxHumanPlayers", sm_GetMaxHumanPlayers},
|
||||
@@ -393,6 +520,7 @@ REGISTER_NATIVES(playernatives)
|
||||
{"GetClientAvgData", GetAvgData},
|
||||
{"GetClientAvgPackets", GetAvgPackets},
|
||||
{"RunAdminCacheChecks", RunAdminCacheChecks},
|
||||
{"GetClientAuthId", GetClientAuthId},
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
||||
|
||||
@@ -8,6 +8,10 @@ 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,6 +5,10 @@ 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',
|
||||
|
||||
@@ -372,12 +372,10 @@ 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
|
||||
}
|
||||
|
||||
@@ -8,6 +8,10 @@ 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,6 +2,10 @@
|
||||
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,6 +7,10 @@ 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 += [
|
||||
|
||||
@@ -5,6 +5,10 @@ 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 file handle %x (error %d)", hndl, err);
|
||||
return pCtx->ThrowNativeError("Invalid regex 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 file handle %x (error %d)", hndl, err);
|
||||
return pCtx->ThrowNativeError("Invalid regex handle %x (error %d)", hndl, err);
|
||||
}
|
||||
|
||||
if (!x)
|
||||
|
||||
@@ -438,6 +438,21 @@ 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));
|
||||
@@ -461,17 +476,14 @@ 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);
|
||||
for (entry = 0; entry < pawnlist.length(); ++entry)
|
||||
{
|
||||
if (entity != pawnlist[entry].entity)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
IPluginFunction *callback = pawnlist[entry].callback;
|
||||
ke::Vector<IPluginFunction *> callbackList;
|
||||
PopulateCallbackList(vtablehooklist[entry]->hooks, callbackList, entity);
|
||||
for (entry = 0; entry < callbackList.length(); ++entry)
|
||||
{
|
||||
IPluginFunction *callback = callbackList[entry];
|
||||
callback->PushCell(entity);
|
||||
callback->PushCell(other);
|
||||
|
||||
@@ -914,15 +926,11 @@ void SDKHooks::Hook_FireBulletsPost(const FireBulletsInfo_t &info)
|
||||
|
||||
const char *weapon = pInfo->GetWeaponName();
|
||||
|
||||
ke::Vector<HookList> &pawnlist = vtablehooklist[entry]->hooks;
|
||||
for (entry = 0; entry < pawnlist.length(); ++entry)
|
||||
ke::Vector<IPluginFunction *> callbackList;
|
||||
PopulateCallbackList(vtablehooklist[entry]->hooks, callbackList, entity);
|
||||
for (entry = 0; entry < callbackList.length(); ++entry)
|
||||
{
|
||||
if (entity != pawnlist[entry].entity)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
IPluginFunction *callback = pawnlist[entry].callback;
|
||||
IPluginFunction *callback = callbackList[entry];
|
||||
callback->PushCell(entity);
|
||||
callback->PushCell(info.m_iShots);
|
||||
callback->PushString(weapon?weapon:"");
|
||||
@@ -956,15 +964,11 @@ int SDKHooks::Hook_GetMaxHealth()
|
||||
|
||||
cell_t res = Pl_Continue;
|
||||
|
||||
ke::Vector<HookList> &pawnlist = vtablehooklist[entry]->hooks;
|
||||
for (entry = 0; entry < pawnlist.length(); ++entry)
|
||||
ke::Vector<IPluginFunction *> callbackList;
|
||||
PopulateCallbackList(vtablehooklist[entry]->hooks, callbackList, entity);
|
||||
for (entry = 0; entry < callbackList.length(); ++entry)
|
||||
{
|
||||
if (entity != pawnlist[entry].entity)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
IPluginFunction *callback = pawnlist[entry].callback;
|
||||
IPluginFunction *callback = callbackList[entry];
|
||||
callback->PushCell(entity);
|
||||
callback->PushCellByRef(&new_max);
|
||||
callback->Execute(&res);
|
||||
@@ -1013,15 +1017,11 @@ int SDKHooks::Hook_OnTakeDamage(CTakeDamageInfoHack &info)
|
||||
|
||||
cell_t res, ret = Pl_Continue;
|
||||
|
||||
ke::Vector<HookList> &pawnlist = vtablehooklist[entry]->hooks;
|
||||
for (entry = 0; entry < pawnlist.length(); ++entry)
|
||||
ke::Vector<IPluginFunction *> callbackList;
|
||||
PopulateCallbackList(vtablehooklist[entry]->hooks, callbackList, entity);
|
||||
for (entry = 0; entry < callbackList.length(); ++entry)
|
||||
{
|
||||
if (entity != pawnlist[entry].entity)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
IPluginFunction *callback = pawnlist[entry].callback;
|
||||
IPluginFunction *callback = callbackList[entry];
|
||||
callback->PushCell(entity);
|
||||
callback->PushCellByRef(&attacker);
|
||||
callback->PushCellByRef(&inflictor);
|
||||
@@ -1095,15 +1095,11 @@ int SDKHooks::Hook_OnTakeDamagePost(CTakeDamageInfoHack &info)
|
||||
|
||||
int entity = gamehelpers->EntityToBCompatRef(pEntity);
|
||||
|
||||
ke::Vector<HookList> &pawnlist = vtablehooklist[entry]->hooks;
|
||||
for (entry = 0; entry < pawnlist.length(); ++entry)
|
||||
ke::Vector<IPluginFunction *> callbackList;
|
||||
PopulateCallbackList(vtablehooklist[entry]->hooks, callbackList, entity);
|
||||
for (entry = 0; entry < callbackList.length(); ++entry)
|
||||
{
|
||||
if (entity != pawnlist[entry].entity)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
IPluginFunction *callback = pawnlist[entry].callback;
|
||||
IPluginFunction *callback = callbackList[entry];
|
||||
callback->PushCell(entity);
|
||||
callback->PushCell(info.GetAttacker());
|
||||
callback->PushCell(info.GetInflictor());
|
||||
@@ -1168,15 +1164,11 @@ bool SDKHooks::Hook_Reload()
|
||||
int entity = gamehelpers->EntityToBCompatRef(pEntity);
|
||||
cell_t res = Pl_Continue;
|
||||
|
||||
ke::Vector<HookList> &pawnlist = vtablehooklist[entry]->hooks;
|
||||
for (entry = 0; entry < pawnlist.length(); ++entry)
|
||||
ke::Vector<IPluginFunction *> callbackList;
|
||||
PopulateCallbackList(vtablehooklist[entry]->hooks, callbackList, entity);
|
||||
for (entry = 0; entry < callbackList.length(); ++entry)
|
||||
{
|
||||
if (entity != pawnlist[entry].entity)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
IPluginFunction *callback = pawnlist[entry].callback;
|
||||
IPluginFunction *callback = callbackList[entry];
|
||||
callback->PushCell(entity);
|
||||
callback->Execute(&res);
|
||||
}
|
||||
@@ -1195,7 +1187,7 @@ bool SDKHooks::Hook_ReloadPost()
|
||||
CBaseEntity *pEntity = META_IFACEPTR(CBaseEntity);
|
||||
|
||||
CVTableHook vhook(pEntity);
|
||||
ke::Vector<CVTableList *> &vtablehooklist = g_HookList[SDKHook_Reload];
|
||||
ke::Vector<CVTableList *> &vtablehooklist = g_HookList[SDKHook_ReloadPost];
|
||||
for (size_t entry = 0; entry < vtablehooklist.length(); ++entry)
|
||||
{
|
||||
if (vhook != vtablehooklist[entry]->vtablehook)
|
||||
@@ -1206,15 +1198,11 @@ bool SDKHooks::Hook_ReloadPost()
|
||||
int entity = gamehelpers->EntityToBCompatRef(pEntity);
|
||||
cell_t origreturn = META_RESULT_ORIG_RET(bool) ? 1 : 0;
|
||||
|
||||
ke::Vector<HookList> &pawnlist = vtablehooklist[entry]->hooks;
|
||||
for (entry = 0; entry < pawnlist.length(); ++entry)
|
||||
ke::Vector<IPluginFunction *> callbackList;
|
||||
PopulateCallbackList(vtablehooklist[entry]->hooks, callbackList, entity);
|
||||
for (entry = 0; entry < callbackList.length(); ++entry)
|
||||
{
|
||||
if (entity != pawnlist[entry].entity)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
IPluginFunction *callback = pawnlist[entry].callback;
|
||||
IPluginFunction *callback = callbackList[entry];
|
||||
callback->PushCell(entity);
|
||||
callback->PushCell(origreturn);
|
||||
callback->Execute(NULL);
|
||||
@@ -1253,15 +1241,11 @@ 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<HookList> &pawnlist = vtablehooklist[entry]->hooks;
|
||||
for (entry = 0; entry < pawnlist.length(); ++entry)
|
||||
ke::Vector<IPluginFunction *> callbackList;
|
||||
PopulateCallbackList(vtablehooklist[entry]->hooks, callbackList, entity);
|
||||
for (entry = 0; entry < callbackList.length(); ++entry)
|
||||
{
|
||||
if (entity != pawnlist[entry].entity)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
IPluginFunction *callback = pawnlist[entry].callback;
|
||||
IPluginFunction *callback = callbackList[entry];
|
||||
callback->PushCell(entity);
|
||||
callback->PushCell(collisionGroup);
|
||||
callback->PushCell(contentsMask);
|
||||
@@ -1301,15 +1285,11 @@ void SDKHooks::Hook_Spawn()
|
||||
int entity = gamehelpers->EntityToBCompatRef(pEntity);
|
||||
cell_t res = Pl_Continue;
|
||||
|
||||
ke::Vector<HookList> &pawnlist = vtablehooklist[entry]->hooks;
|
||||
for (entry = 0; entry < pawnlist.length(); ++entry)
|
||||
ke::Vector<IPluginFunction *> callbackList;
|
||||
PopulateCallbackList(vtablehooklist[entry]->hooks, callbackList, entity);
|
||||
for (entry = 0; entry < callbackList.length(); ++entry)
|
||||
{
|
||||
if (entity != pawnlist[entry].entity)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
IPluginFunction *callback = pawnlist[entry].callback;
|
||||
IPluginFunction *callback = callbackList[entry];
|
||||
callback->PushCell(entity);
|
||||
callback->Execute(&res);
|
||||
}
|
||||
@@ -1399,15 +1379,11 @@ void SDKHooks::Hook_TraceAttack(CTakeDamageInfoHack &info, const Vector &vecDir,
|
||||
int ammotype = info.GetAmmoType();
|
||||
cell_t res, ret = Pl_Continue;
|
||||
|
||||
ke::Vector<HookList> &pawnlist = vtablehooklist[entry]->hooks;
|
||||
for (entry = 0; entry < pawnlist.length(); ++entry)
|
||||
ke::Vector<IPluginFunction *> callbackList;
|
||||
PopulateCallbackList(vtablehooklist[entry]->hooks, callbackList, entity);
|
||||
for (entry = 0; entry < callbackList.length(); ++entry)
|
||||
{
|
||||
if (entity != pawnlist[entry].entity)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
IPluginFunction *callback = pawnlist[entry].callback;
|
||||
IPluginFunction *callback = callbackList[entry];
|
||||
callback->PushCell(entity);
|
||||
callback->PushCellByRef(&attacker);
|
||||
callback->PushCellByRef(&inflictor);
|
||||
@@ -1477,15 +1453,11 @@ void SDKHooks::Hook_TraceAttackPost(CTakeDamageInfoHack &info, const Vector &vec
|
||||
|
||||
int entity = gamehelpers->EntityToBCompatRef(pEntity);
|
||||
|
||||
ke::Vector<HookList> &pawnlist = vtablehooklist[entry]->hooks;
|
||||
for (entry = 0; entry < pawnlist.length(); ++entry)
|
||||
ke::Vector<IPluginFunction *> callbackList;
|
||||
PopulateCallbackList(vtablehooklist[entry]->hooks, callbackList, entity);
|
||||
for (entry = 0; entry < callbackList.length(); ++entry)
|
||||
{
|
||||
if (entity != pawnlist[entry].entity)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
IPluginFunction *callback = pawnlist[entry].callback;
|
||||
IPluginFunction *callback = callbackList[entry];
|
||||
callback->PushCell(entity);
|
||||
callback->PushCell(info.GetAttacker());
|
||||
callback->PushCell(info.GetInflictor());
|
||||
@@ -1521,15 +1493,11 @@ void SDKHooks::Hook_Use(CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE
|
||||
int caller = gamehelpers->EntityToBCompatRef(pCaller);
|
||||
cell_t ret = Pl_Continue;
|
||||
|
||||
ke::Vector<HookList> &pawnlist = vtablehooklist[entry]->hooks;
|
||||
for (entry = 0; entry < pawnlist.length(); ++entry)
|
||||
ke::Vector<IPluginFunction *> callbackList;
|
||||
PopulateCallbackList(vtablehooklist[entry]->hooks, callbackList, entity);
|
||||
for (entry = 0; entry < callbackList.length(); ++entry)
|
||||
{
|
||||
if (entity != pawnlist[entry].entity)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
IPluginFunction *callback = pawnlist[entry].callback;
|
||||
IPluginFunction *callback = callbackList[entry];
|
||||
callback->PushCell(entity);
|
||||
callback->PushCell(activator);
|
||||
callback->PushCell(caller);
|
||||
@@ -1564,15 +1532,11 @@ void SDKHooks::Hook_UsePost(CBaseEntity *pActivator, CBaseEntity *pCaller, USE_T
|
||||
int activator = gamehelpers->EntityToBCompatRef(pActivator);
|
||||
int caller = gamehelpers->EntityToBCompatRef(pCaller);
|
||||
|
||||
ke::Vector<HookList> &pawnlist = vtablehooklist[entry]->hooks;
|
||||
for (entry = 0; entry < pawnlist.length(); ++entry)
|
||||
ke::Vector<IPluginFunction *> callbackList;
|
||||
PopulateCallbackList(vtablehooklist[entry]->hooks, callbackList, entity);
|
||||
for (entry = 0; entry < callbackList.length(); ++entry)
|
||||
{
|
||||
if (entity != pawnlist[entry].entity)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
IPluginFunction *callback = pawnlist[entry].callback;
|
||||
IPluginFunction *callback = callbackList[entry];
|
||||
callback->PushCell(entity);
|
||||
callback->PushCell(activator);
|
||||
callback->PushCell(caller);
|
||||
|
||||
@@ -66,6 +66,7 @@ IPlayerInfoManager *playerinfomngr = NULL;
|
||||
ICvar *icvar = NULL;
|
||||
IServer *iserver = NULL;
|
||||
CGlobalVars *gpGlobals;
|
||||
ISoundEmitterSystemBase *soundemitterbase = NULL;
|
||||
|
||||
#if SOURCE_ENGINE >= SE_ORANGEBOX
|
||||
IServerTools *servertools = NULL;
|
||||
@@ -258,6 +259,7 @@ 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);
|
||||
|
||||
@@ -50,6 +50,7 @@
|
||||
#include <convar.h>
|
||||
#include <iserver.h>
|
||||
#include <cdll_int.h>
|
||||
#include "SoundEmitterSystem/isoundemittersystembase.h"
|
||||
|
||||
#if SOURCE_ENGINE >= SE_ORANGEBOX
|
||||
#include <itoolentity.h>
|
||||
@@ -124,6 +125,7 @@ extern CGlobalVars *gpGlobals;
|
||||
#if SOURCE_ENGINE >= SE_ORANGEBOX
|
||||
extern IServerTools *servertools;
|
||||
#endif
|
||||
extern ISoundEmitterSystemBase *soundemitterbase;
|
||||
/* Interfaces from SourceMod */
|
||||
extern IBinTools *g_pBinTools;
|
||||
extern IGameConfig *g_pGameConf;
|
||||
|
||||
@@ -512,6 +512,74 @@ RETURN_META_NEWPARAMS(
|
||||
#endif
|
||||
}
|
||||
|
||||
bool GetSoundParams(CSoundParameters *soundParams, const char *soundname, cell_t entindex)
|
||||
{
|
||||
if ( !soundname[0] )
|
||||
return false;
|
||||
|
||||
#if SOURCE_ENGINE >= SE_PORTAL2
|
||||
HSOUNDSCRIPTHASH index = (HSOUNDSCRIPTHASH)soundemitterbase->GetSoundIndex(soundname);
|
||||
#else
|
||||
HSOUNDSCRIPTHANDLE index = (HSOUNDSCRIPTHANDLE)soundemitterbase->GetSoundIndex(soundname);
|
||||
#endif
|
||||
if (!soundemitterbase->IsValidIndex(index))
|
||||
return false;
|
||||
|
||||
gender_t gender = GENDER_NONE;
|
||||
|
||||
// I don't know if gender applies to any mutliplayer games, but just in case...
|
||||
// Of course, if it's SOUND_FROM_PLAYER, we have no idea which gender it is
|
||||
int ent = SoundReferenceToIndex(entindex);
|
||||
if (ent > 0)
|
||||
{
|
||||
edict_t *edict = gamehelpers->EdictOfIndex(ent);
|
||||
if (edict != NULL && !edict->IsFree())
|
||||
{
|
||||
IServerEntity *serverEnt = edict->GetIServerEntity();
|
||||
if (serverEnt != NULL)
|
||||
{
|
||||
const char *actormodel = STRING(serverEnt->GetModelName());
|
||||
gender = soundemitterbase->GetActorGender(actormodel);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return soundemitterbase->GetParametersForSoundEx(soundname, index, *soundParams, gender);
|
||||
}
|
||||
|
||||
bool InternalPrecacheScriptSound(const char *soundname)
|
||||
{
|
||||
int soundIndex = soundemitterbase->GetSoundIndex(soundname);
|
||||
if (!soundemitterbase->IsValidIndex(soundIndex))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
CSoundParametersInternal *internal = soundemitterbase->InternalGetParametersForSound(soundIndex);
|
||||
|
||||
if (!internal)
|
||||
return false;
|
||||
|
||||
int waveCount = internal->NumSoundNames();
|
||||
|
||||
if (!waveCount)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
for (int wave = 0; wave < waveCount; wave++)
|
||||
{
|
||||
const char* waveName = soundemitterbase->GetWaveName(internal->GetSoundNames()[wave].symbol);
|
||||
// return true even if we precache no new wavs
|
||||
if (!engsound->IsSoundPrecached(waveName))
|
||||
{
|
||||
engsound->PrecacheSound(waveName);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/************************
|
||||
* *
|
||||
* Sound Related Natives *
|
||||
@@ -1135,6 +1203,51 @@ static cell_t smn_GetDistGainFromSoundLevel(IPluginContext *pContext, const cell
|
||||
return sp_ftoc(engsound->GetDistGainFromSoundLevel((soundlevel_t)decibel, distance));
|
||||
}
|
||||
|
||||
// native bool:GetGameSoundParams(const String:gameSound[], &channel, &soundLevel, &Float:volume, &pitch, String:sample[], maxlength, entity=SOUND_FROM_WORLD)
|
||||
static cell_t smn_GetGameSoundParams(IPluginContext *pContext, const cell_t *params)
|
||||
{
|
||||
char *soundname;
|
||||
pContext->LocalToString(params[1], &soundname);
|
||||
|
||||
CSoundParameters soundParams;
|
||||
|
||||
if (!GetSoundParams(&soundParams, soundname, params[8]))
|
||||
return false;
|
||||
|
||||
cell_t *channel;
|
||||
cell_t *fakeVolume;
|
||||
cell_t *pitch;
|
||||
cell_t *soundLevel;
|
||||
|
||||
pContext->LocalToPhysAddr(params[2], &channel);
|
||||
pContext->LocalToPhysAddr(params[3], &soundLevel);
|
||||
pContext->LocalToPhysAddr(params[4], &fakeVolume);
|
||||
pContext->LocalToPhysAddr(params[5], &pitch);
|
||||
|
||||
*channel = soundParams.channel;
|
||||
*pitch = soundParams.pitch;
|
||||
*soundLevel = (cell_t)soundParams.soundlevel;
|
||||
*fakeVolume = sp_ftoc(soundParams.volume);
|
||||
|
||||
pContext->StringToLocal(params[6], params[7], soundParams.soundname);
|
||||
|
||||
// Precache the sound we're returning
|
||||
if (!engsound->IsSoundPrecached(soundParams.soundname))
|
||||
{
|
||||
InternalPrecacheScriptSound(soundname);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// native bool:PrecacheScriptSound(const String:soundname[])
|
||||
static cell_t smn_PrecacheScriptSound(IPluginContext *pContext, const cell_t *params)
|
||||
{
|
||||
char *soundname;
|
||||
pContext->LocalToString(params[1], &soundname);
|
||||
return InternalPrecacheScriptSound(soundname);
|
||||
}
|
||||
|
||||
sp_nativeinfo_t g_SoundNatives[] =
|
||||
{
|
||||
{"EmitAmbientSound", EmitAmbientSound},
|
||||
@@ -1149,5 +1262,7 @@ sp_nativeinfo_t g_SoundNatives[] =
|
||||
{"RemoveAmbientSoundHook", smn_RemoveAmbientSoundHook},
|
||||
{"RemoveNormalSoundHook", smn_RemoveNormalSoundHook},
|
||||
{"GetDistGainFromSoundLevel", smn_GetDistGainFromSoundLevel},
|
||||
{"GetGameSoundParams", smn_GetGameSoundParams},
|
||||
{"PrecacheScriptSound", smn_PrecacheScriptSound},
|
||||
{NULL, NULL},
|
||||
};
|
||||
|
||||
@@ -5,6 +5,10 @@ binary = SM.ExtLibrary(builder, 'dbi.sqlite.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.compiler.defines += [
|
||||
'SQLITE_OMIT_LOAD_EXTENSION',
|
||||
|
||||
@@ -599,6 +599,55 @@ cell_t TF2_IsHolidayActive(IPluginContext *pContext, const cell_t *params)
|
||||
return (retValue) ? 1 : 0;
|
||||
}
|
||||
|
||||
cell_t TF2_RemoveWearable(IPluginContext *pContext, const cell_t *params)
|
||||
{
|
||||
static ICallWrapper *pWrapper = NULL;
|
||||
|
||||
//CBasePlayer::RemoveWearable(CEconWearable *)
|
||||
|
||||
if (!pWrapper)
|
||||
{
|
||||
int offset;
|
||||
|
||||
if (!g_pGameConf->GetOffset("RemoveWearable", &offset))
|
||||
{
|
||||
return pContext->ThrowNativeError("Failed to locate function");
|
||||
}
|
||||
|
||||
PassInfo pass[1];
|
||||
pass[0].flags = PASSFLAG_BYVAL;
|
||||
pass[0].size = sizeof(CBaseEntity *);
|
||||
pass[0].type = PassType_Basic;
|
||||
|
||||
pWrapper = g_pBinTools->CreateVCall(offset, 0, 0, NULL, pass, 1);
|
||||
|
||||
g_RegNatives.Register(pWrapper);
|
||||
}
|
||||
|
||||
CBaseEntity *pEntity;
|
||||
if (!(pEntity = UTIL_GetCBaseEntity(params[1], true)))
|
||||
{
|
||||
return pContext->ThrowNativeError("Client index %d is not valid", params[1]);
|
||||
}
|
||||
|
||||
CBaseEntity *pWearable;
|
||||
if (!(pWearable = UTIL_GetCBaseEntity(params[2], false)))
|
||||
{
|
||||
return pContext->ThrowNativeError("Wearable index %d is not valid", params[2]);
|
||||
}
|
||||
|
||||
unsigned char vstk[sizeof(void *) + sizeof(CBaseEntity *)];
|
||||
unsigned char *vptr = vstk;
|
||||
|
||||
*(void **)vptr = (void *)pEntity;
|
||||
vptr += sizeof(void *);
|
||||
*(CBaseEntity **)vptr = pWearable;
|
||||
|
||||
pWrapper->Execute(vstk, NULL);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
sp_nativeinfo_t g_TFNatives[] =
|
||||
{
|
||||
{"TF2_IgnitePlayer", TF2_Burn},
|
||||
@@ -616,5 +665,6 @@ sp_nativeinfo_t g_TFNatives[] =
|
||||
{"TF2_MakeBleed", TF2_MakeBleed},
|
||||
{"TF2_IsPlayerInDuel", TF2_IsPlayerInDuel},
|
||||
{"TF2_IsHolidayActive", TF2_IsHolidayActive},
|
||||
{"TF2_RemoveWearable", TF2_RemoveWearable},
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
||||
@@ -5,6 +5,10 @@ binary = SM.ExtLibrary(builder, 'topmenus.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',
|
||||
|
||||
@@ -5,6 +5,10 @@ binary = SM.ExtLibrary(builder, 'updater.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',
|
||||
|
||||
@@ -24,9 +24,11 @@
|
||||
"plugin_f99d77668e7aa0adb6a960322ab05568" "" /* UCP Server (Endi) - Version 7.8 */
|
||||
"plugin_7b3ce69f15e61cc896228cb8424be589" "" /* UCP Server (Endi) - Version 7.8.2 */
|
||||
"plugin_24602c74f183cfcd157b3d50dee96c52" "" /* UCP Server (Endi) - Version 7.8.3 */
|
||||
"plugin_43bd225c5fdcd3af35729ca9d481b20d" "" /* UCP Server (Endi) - Version 8.3 */
|
||||
"plugin_78140f1a0f26cd3297767d0598eac4b1" "" /* [Any] PReplay (DarthNinja) - Version 1.0.0 */
|
||||
"plugin_55923ba6bfe41569a3e4fbd7ca4606e5" "" /* VIP Plugin (World-Source.Ru) - Version 2.0 */
|
||||
"plugin_4bf983e1d5b61ba0b1ab9a7e53bfda27" "" /* WarMod CS:GO (Twelve-60) */
|
||||
"plugin_4bf983e1d5b61ba0b1ab9a7e53bfda27" "" /* WarMod CS:GO (Twelve-60) */
|
||||
"plugin_08574c4295afdaa5f613b8ceef96ecc3" "" /* AlliedBans (TommY) - Version 3.140902A */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,9 +12,9 @@
|
||||
}
|
||||
"FireBullets"
|
||||
{
|
||||
"windows" "112"
|
||||
"linux" "113"
|
||||
"mac" "113"
|
||||
"windows" "113"
|
||||
"linux" "114"
|
||||
"mac" "114"
|
||||
}
|
||||
"OnTakeDamage"
|
||||
{
|
||||
@@ -24,15 +24,15 @@
|
||||
}
|
||||
"PreThink"
|
||||
{
|
||||
"windows" "331"
|
||||
"linux" "332"
|
||||
"mac" "332"
|
||||
"windows" "333"
|
||||
"linux" "334"
|
||||
"mac" "334"
|
||||
}
|
||||
"PostThink"
|
||||
{
|
||||
"windows" "332"
|
||||
"linux" "333"
|
||||
"mac" "333"
|
||||
"windows" "334"
|
||||
"linux" "335"
|
||||
"mac" "335"
|
||||
}
|
||||
"SetTransmit"
|
||||
{
|
||||
@@ -78,39 +78,39 @@
|
||||
}
|
||||
"VPhysicsUpdate"
|
||||
{
|
||||
"windows" "157"
|
||||
"linux" "158"
|
||||
"mac" "158"
|
||||
"windows" "158"
|
||||
"linux" "159"
|
||||
"mac" "159"
|
||||
}
|
||||
"Weapon_CanSwitchTo"
|
||||
{
|
||||
"windows" "265"
|
||||
"linux" "266"
|
||||
"mac" "266"
|
||||
"windows" "267"
|
||||
"linux" "268"
|
||||
"mac" "268"
|
||||
}
|
||||
"Weapon_CanUse"
|
||||
{
|
||||
"windows" "259"
|
||||
"linux" "260"
|
||||
"mac" "260"
|
||||
"windows" "261"
|
||||
"linux" "262"
|
||||
"mac" "262"
|
||||
}
|
||||
"Weapon_Drop"
|
||||
{
|
||||
"windows" "264"
|
||||
"linux" "265"
|
||||
"mac" "265"
|
||||
}
|
||||
"Weapon_Equip"
|
||||
{
|
||||
"windows" "262"
|
||||
"linux" "263"
|
||||
"mac" "263"
|
||||
}
|
||||
"Weapon_Equip"
|
||||
{
|
||||
"windows" "260"
|
||||
"linux" "261"
|
||||
"mac" "261"
|
||||
}
|
||||
"Weapon_Switch"
|
||||
{
|
||||
"windows" "263"
|
||||
"linux" "264"
|
||||
"mac" "264"
|
||||
"windows" "265"
|
||||
"linux" "266"
|
||||
"mac" "266"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,9 +30,9 @@
|
||||
}
|
||||
"PreThink"
|
||||
{
|
||||
"windows" "344"
|
||||
"linux" "345"
|
||||
"mac" "345"
|
||||
"windows" "345"
|
||||
"linux" "346"
|
||||
"mac" "346"
|
||||
}
|
||||
"PostThink"
|
||||
{
|
||||
|
||||
@@ -48,21 +48,6 @@
|
||||
}
|
||||
}
|
||||
|
||||
/* No longer necessary. Remove later. */
|
||||
"#default"
|
||||
{
|
||||
"Signatures"
|
||||
{
|
||||
"EntityFactory"
|
||||
{
|
||||
"library" "server"
|
||||
"windows" "\xB8\x01\x00\x00\x00\x84\x2A\x2A\x2A\x2A\x2A\x75\x1D\x09\x2A\x2A\x2A\x2A\x2A\xB9\x2A\x2A\x2A\x2A\xE8\x2A\x2A\x2A\x2A\x68\x2A\x2A\x2A\x2A\xE8\x2A\x2A\x2A\x2A\x83\xC4\x04\xB8\x2A\x2A\x2A\x2A\xC3"
|
||||
"linux" "@_Z23EntityFactoryDictionaryv"
|
||||
"mac" "@_Z23EntityFactoryDictionaryv"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* SetUserInfo data */
|
||||
"#default"
|
||||
{
|
||||
|
||||
@@ -131,57 +131,57 @@
|
||||
{
|
||||
"GiveNamedItem"
|
||||
{
|
||||
"windows" "400"
|
||||
"linux" "401"
|
||||
"mac" "401"
|
||||
"windows" "402"
|
||||
"linux" "403"
|
||||
"mac" "403"
|
||||
}
|
||||
"RemovePlayerItem"
|
||||
{
|
||||
"windows" "271"
|
||||
"linux" "272"
|
||||
"mac" "272"
|
||||
}
|
||||
"Weapon_GetSlot"
|
||||
{
|
||||
"windows" "269"
|
||||
"linux" "270"
|
||||
"mac" "270"
|
||||
}
|
||||
"Weapon_GetSlot"
|
||||
{
|
||||
"windows" "267"
|
||||
"linux" "268"
|
||||
"mac" "268"
|
||||
}
|
||||
"Ignite"
|
||||
{
|
||||
"windows" "208"
|
||||
"linux" "209"
|
||||
"mac" "209"
|
||||
"windows" "210"
|
||||
"linux" "211"
|
||||
"mac" "211"
|
||||
}
|
||||
"Extinguish"
|
||||
{
|
||||
"windows" "212"
|
||||
"linux" "213"
|
||||
"mac" "213"
|
||||
"windows" "214"
|
||||
"linux" "215"
|
||||
"mac" "215"
|
||||
}
|
||||
"Teleport"
|
||||
{
|
||||
"windows" "108"
|
||||
"linux" "109"
|
||||
"mac" "109"
|
||||
"windows" "109"
|
||||
"linux" "110"
|
||||
"mac" "110"
|
||||
}
|
||||
"CommitSuicide"
|
||||
{
|
||||
"windows" "441"
|
||||
"linux" "441"
|
||||
"mac" "441"
|
||||
"windows" "444"
|
||||
"linux" "444"
|
||||
"mac" "444"
|
||||
}
|
||||
"GetVelocity"
|
||||
{
|
||||
"windows" "140"
|
||||
"linux" "141"
|
||||
"mac" "141"
|
||||
"windows" "141"
|
||||
"linux" "142"
|
||||
"mac" "142"
|
||||
}
|
||||
"EyeAngles"
|
||||
{
|
||||
"windows" "131"
|
||||
"linux" "132"
|
||||
"mac" "132"
|
||||
"windows" "132"
|
||||
"linux" "133"
|
||||
"mac" "133"
|
||||
}
|
||||
"AcceptInput"
|
||||
{
|
||||
@@ -197,9 +197,9 @@
|
||||
}
|
||||
"WeaponEquip"
|
||||
{
|
||||
"windows" "260"
|
||||
"linux" "261"
|
||||
"mac" "261"
|
||||
"windows" "262"
|
||||
"linux" "263"
|
||||
"mac" "263"
|
||||
}
|
||||
"Activate"
|
||||
{
|
||||
@@ -209,15 +209,15 @@
|
||||
}
|
||||
"PlayerRunCmd"
|
||||
{
|
||||
"windows" "418"
|
||||
"linux" "419"
|
||||
"mac" "419"
|
||||
"windows" "420"
|
||||
"linux" "421"
|
||||
"mac" "421"
|
||||
}
|
||||
"GiveAmmo"
|
||||
{
|
||||
"windows" "251"
|
||||
"linux" "252"
|
||||
"mac" "252"
|
||||
"windows" "253"
|
||||
"linux" "254"
|
||||
"mac" "254"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -131,9 +131,9 @@
|
||||
{
|
||||
"GiveNamedItem"
|
||||
{
|
||||
"windows" "412"
|
||||
"linux" "413"
|
||||
"mac" "413"
|
||||
"windows" "413"
|
||||
"linux" "414"
|
||||
"mac" "414"
|
||||
}
|
||||
"RemovePlayerItem"
|
||||
{
|
||||
@@ -167,9 +167,9 @@
|
||||
}
|
||||
"CommitSuicide"
|
||||
{
|
||||
"windows" "451"
|
||||
"linux" "451"
|
||||
"mac" "451"
|
||||
"windows" "452"
|
||||
"linux" "452"
|
||||
"mac" "452"
|
||||
}
|
||||
"GetVelocity"
|
||||
{
|
||||
@@ -209,9 +209,9 @@
|
||||
}
|
||||
"PlayerRunCmd"
|
||||
{
|
||||
"windows" "430"
|
||||
"linux" "431"
|
||||
"mac" "431"
|
||||
"windows" "431"
|
||||
"linux" "432"
|
||||
"mac" "432"
|
||||
}
|
||||
"GiveAmmo"
|
||||
{
|
||||
|
||||
@@ -33,27 +33,27 @@
|
||||
"CTTeamScoreOffset"
|
||||
{
|
||||
"windows" "98"
|
||||
"linux" "124"
|
||||
"linux" "109"
|
||||
"mac" "150"
|
||||
}
|
||||
//Offset into CheckRestartRound
|
||||
"TTeamScoreOffset"
|
||||
{
|
||||
"windows" "122"
|
||||
"linux" "159"
|
||||
"linux" "142"
|
||||
"mac" "185"
|
||||
}
|
||||
"ClanTagOffset"
|
||||
{
|
||||
"windows" "12"
|
||||
"linux" "41"
|
||||
"linux" "29"
|
||||
"mac" "22"
|
||||
}
|
||||
//Offset into HandleCommand_Buy_Internal
|
||||
"CCSPlayerInventoryOffset"
|
||||
{
|
||||
"windows" "285"
|
||||
"linux" "87"
|
||||
"linux" "32"
|
||||
"mac" "109"
|
||||
}
|
||||
"GetItemInLoadout"
|
||||
@@ -96,7 +96,7 @@
|
||||
"TerminateRound"
|
||||
{
|
||||
"library" "server"
|
||||
"windows" "\x55\x8B\xEC\x83\x2A\x2A\x83\x2A\x2A\x53\x56\x8B\xF1\xF3\x0F\x2A\x2A\x2A\x2A\x57\x33\xFF\x89\x2A\x2A\x2A\xC7\x2A\x2A\x2A\x00\x00\x00\x00"
|
||||
"windows" "\x55\x8B\xEC\x83\x2A\x2A\x83\x2A\x2A\x53\x56\x57\x8B\xF9\xF3\x0F\x2A\x2A\x2A\x2A\x33\xDB\xC7\x2A\x2A\x2A\x00\x00\x00\x00\x89"
|
||||
"linux" "@_ZN12CCSGameRules14TerminateRoundEfi"
|
||||
"mac" "@_ZN12CCSGameRules14TerminateRoundEfi"
|
||||
}
|
||||
|
||||
@@ -137,6 +137,13 @@
|
||||
"linux" "139"
|
||||
"mac" "139"
|
||||
}
|
||||
|
||||
"RemoveWearable"
|
||||
{
|
||||
"windows" "426"
|
||||
"linux" "427"
|
||||
"mac" "427"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,6 +13,10 @@ binary.compiler.cxxincludes += [
|
||||
os.path.join(SM.mms_root, 'core'),
|
||||
os.path.join(SM.mms_root, '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.compiler.linkflags += extra_ldflags
|
||||
binary.sources = [
|
||||
'loader.cpp'
|
||||
|
||||
+17
-34
@@ -58,22 +58,12 @@ new String:g_BanReasonsPath[PLATFORM_MAX_PATH];
|
||||
|
||||
#include "basebans/ban.sp"
|
||||
|
||||
public APLRes:AskPluginLoad2(Handle:myself, bool:late, String:error[], err_max)
|
||||
{
|
||||
BuildPath(Path_SM, g_BanReasonsPath, sizeof(g_BanReasonsPath), "configs/banreasons.txt");
|
||||
if(LoadBanReasons())
|
||||
{
|
||||
return APLRes_Success;
|
||||
}
|
||||
else
|
||||
{
|
||||
Format(error, err_max, "Couldn't load file %s: See log for details.", g_BanReasonsPath);
|
||||
return APLRes_Failure;
|
||||
}
|
||||
}
|
||||
|
||||
public OnPluginStart()
|
||||
{
|
||||
BuildPath(Path_SM, g_BanReasonsPath, sizeof(g_BanReasonsPath), "configs/banreasons.txt");
|
||||
|
||||
LoadBanReasons();
|
||||
|
||||
LoadTranslations("common.phrases");
|
||||
LoadTranslations("basebans.phrases");
|
||||
LoadTranslations("core.phrases");
|
||||
@@ -106,14 +96,7 @@ public OnPluginEnd()
|
||||
public OnMapStart()
|
||||
{
|
||||
//(Re-)Load BanReasons
|
||||
if(g_hKvBanReasons != INVALID_HANDLE)
|
||||
{
|
||||
CloseHandle(g_hKvBanReasons);
|
||||
}
|
||||
if(!LoadBanReasons())
|
||||
{
|
||||
SetFailState("Error trying to load or parse %s: See logfile for details", g_BanReasonsPath);
|
||||
}
|
||||
LoadBanReasons();
|
||||
}
|
||||
|
||||
public OnClientDisconnect(client)
|
||||
@@ -121,32 +104,32 @@ public OnClientDisconnect(client)
|
||||
g_IsWaitingForChatReason[client] = false;
|
||||
}
|
||||
|
||||
public bool:LoadBanReasons()
|
||||
LoadBanReasons()
|
||||
{
|
||||
if (g_hKvBanReasons != INVALID_HANDLE)
|
||||
{
|
||||
CloseHandle(g_hKvBanReasons);
|
||||
}
|
||||
|
||||
g_hKvBanReasons = CreateKeyValues("banreasons");
|
||||
|
||||
if(FileToKeyValues(g_hKvBanReasons, g_BanReasonsPath))
|
||||
{
|
||||
decl String:sectionName[255];
|
||||
if(!KvGetSectionName(g_hKvBanReasons, sectionName, sizeof(sectionName)))
|
||||
{
|
||||
LogMessage("Error in %s: File corrupt or in the wrong format", g_BanReasonsPath);
|
||||
return false;
|
||||
return SetFailState("Error in %s: File corrupt or in the wrong format", g_BanReasonsPath);
|
||||
}
|
||||
|
||||
if(strcmp(sectionName, "banreasons") != 0)
|
||||
{
|
||||
LogMessage("Error in %s: Couldn't find 'banreasons'", g_BanReasonsPath);
|
||||
return false;
|
||||
return SetFailState("Error in %s: Couldn't find 'banreasons'", g_BanReasonsPath);
|
||||
}
|
||||
|
||||
//Reset kvHandle
|
||||
KvRewind(g_hKvBanReasons);
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
LogMessage("Error in %s: File not found, corrupt or in the wrong format", g_BanReasonsPath);
|
||||
return false;
|
||||
} else {
|
||||
return SetFailState("Error in %s: File not found, corrupt or in the wrong format", g_BanReasonsPath);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -36,7 +36,7 @@ new g_GravityTarget[MAXPLAYERS+1];
|
||||
PerformGravity(client, target, Float:amount)
|
||||
{
|
||||
SetEntityGravity(target, amount);
|
||||
LogAction(client, target, "\"%L\" set gravity on \"%L\" to %d.", client, target, amount);
|
||||
LogAction(client, target, "\"%L\" set gravity on \"%L\" to %f.", client, target, amount);
|
||||
}
|
||||
|
||||
public AdminMenu_Gravity(Handle:topmenu,
|
||||
|
||||
@@ -45,6 +45,25 @@ enum NetFlow
|
||||
NetFlow_Both, /**< Both values added together */
|
||||
};
|
||||
|
||||
/**
|
||||
* Auth string types.
|
||||
*
|
||||
* Note that for the Steam2 and Steam3 types, the following ids are
|
||||
* also valid values:
|
||||
* "STEAM_ID_PENDING" - Authentication is pending.
|
||||
* "STEAM_ID_LAN" - Authentication is disabled because of being on a LAN server.
|
||||
* "BOT" - The client is a bot.
|
||||
*/
|
||||
enum AuthIdType
|
||||
{
|
||||
AuthId_Engine = 0, /**< The game-specific auth string as returned from the engine */
|
||||
|
||||
// The following are only available on games that support Steam authentication.
|
||||
AuthId_Steam2, /**< Steam2 rendered format, ex "STEAM_1:1:4153990" */
|
||||
AuthId_Steam3, /**< Steam3 rendered format, ex "[U:1:8307981]" */
|
||||
AuthId_SteamID64, /**< A SteamID64 (uint64) as a String, ex "76561197968573709" */
|
||||
};
|
||||
|
||||
/**
|
||||
* MAXPLAYERS is not the same as MaxClients.
|
||||
* MAXPLAYERS is a hardcoded value as an upper limit. MaxClients changes based on the server.
|
||||
@@ -261,14 +280,29 @@ native bool:GetClientIP(client, String:ip[], maxlen, bool:remport=true);
|
||||
* @param client Player index.
|
||||
* @param auth Buffer to store the client's auth string.
|
||||
* @param maxlen Maximum length of string buffer (includes NULL terminator).
|
||||
* @param validate Check backend validation status.
|
||||
* DO NOT PASS FALSE UNLESS YOU UNDERSTAND THE CONSEQUENCES,
|
||||
* @param validate Check backend validation status.
|
||||
* DO NOT PASS FALSE UNLESS YOU UNDERSTAND THE CONSEQUENCES,
|
||||
* You WILL KNOW if you need to use this, MOST WILL NOT.
|
||||
* @return True on success, false otherwise.
|
||||
* @error If the client is not connected or the index is invalid.
|
||||
*/
|
||||
native bool:GetClientAuthString(client, String:auth[], maxlen, bool:validate=true);
|
||||
|
||||
/**
|
||||
* Retrieves a client's authentication string (SteamID).
|
||||
*
|
||||
* @param client Player index.
|
||||
* @param authType Auth id type and format to use.
|
||||
* @param auth Buffer to store the client's auth id.
|
||||
* @param maxlen Maximum length of string buffer (includes NULL terminator).
|
||||
* @param validate Check backend validation status.
|
||||
* DO NOT PASS FALSE UNLESS YOU UNDERSTAND THE CONSEQUENCES,
|
||||
* You WILL KNOW if you need to use this, MOST WILL NOT.
|
||||
* @return True on success, false otherwise.
|
||||
* @error If the client is not connected or the index is invalid.
|
||||
*/
|
||||
native bool:GetClientAuthId(client, AuthIdType:authType, String:auth[], maxlen, bool:validate=true);
|
||||
|
||||
/**
|
||||
* Returns the client's Steam account ID.
|
||||
*
|
||||
|
||||
@@ -360,6 +360,18 @@ native bool:KeyValuesToFile(Handle:kv, const String:file[]);
|
||||
*/
|
||||
native bool:FileToKeyValues(Handle:kv, const String:file[]);
|
||||
|
||||
/**
|
||||
* Converts a given string to a KeyValues tree. The string is read into
|
||||
* the current postion of the tree.
|
||||
*
|
||||
* @param kv KeyValues Handle.
|
||||
* @param buffer String buffer to load into the KeyValues.
|
||||
* @param resourceName The resource name of the KeyValues, used for error tracking purposes.
|
||||
* @return True on success, false otherwise.
|
||||
* @error Invalid Handle.
|
||||
*/
|
||||
native bool:StringToKeyValues(Handle:kv, const String:buffer[], const String:resourceName[]="StringToKeyValues");
|
||||
|
||||
/**
|
||||
* Sets whether or not the KeyValues parser will read escape sequences.
|
||||
* For example, \n would be read as a literal newline. This defaults
|
||||
|
||||
@@ -448,3 +448,229 @@ stock ATTN_TO_SNDLEVEL(Float:attn)
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the parameters for a game sound.
|
||||
*
|
||||
* Game sounds are found in a game's scripts/game_sound.txt or other files
|
||||
* referenced from it
|
||||
*
|
||||
* Note that if a game sound has a rndwave section, one of them will be returned
|
||||
* at random.
|
||||
*
|
||||
* @param gameSound Name of game sound.
|
||||
* @param channel Channel to emit with.
|
||||
* @param level Sound level.
|
||||
* @param volume Sound volume.
|
||||
* @param pitch Sound pitch.
|
||||
* @param sample Sound file name relative to the "sounds" folder.
|
||||
* @param maxlength Maximum length of sample string buffer.
|
||||
* @param entity Entity the sound is being emitted from.
|
||||
* @return True if the sound was successfully retrieved, false if it
|
||||
* was not found
|
||||
*/
|
||||
native bool:GetGameSoundParams(const String:gameSound[],
|
||||
&channel,
|
||||
&soundLevel,
|
||||
&Float:volume,
|
||||
&pitch,
|
||||
String:sample[],
|
||||
maxlength,
|
||||
entity=SOUND_FROM_PLAYER);
|
||||
|
||||
/**
|
||||
* Emits a game sound to a list of clients.
|
||||
*
|
||||
* Game sounds are found in a game's scripts/game_sound.txt or other files
|
||||
* referenced from it
|
||||
*
|
||||
* Note that if a game sound has a rndwave section, one of them will be returned
|
||||
* at random.
|
||||
*
|
||||
* @param clients Array of client indexes.
|
||||
* @param numClients Number of clients in the array.
|
||||
* @param gameSound Name of game sound.
|
||||
* @param entity Entity to emit from.
|
||||
* @param flags Sound flags.
|
||||
* @param speakerentity Unknown.
|
||||
* @param origin Sound origin.
|
||||
* @param dir Sound direction.
|
||||
* @param updatePos Unknown (updates positions?)
|
||||
* @param soundtime Alternate time to play sound for.
|
||||
* @return True if the sound was played successfully, false if it failed
|
||||
* @error Invalid client index.
|
||||
*/
|
||||
stock bool:EmitGameSound(const clients[],
|
||||
numClients,
|
||||
const String:gameSound[],
|
||||
entity = SOUND_FROM_PLAYER,
|
||||
flags = SND_NOFLAGS,
|
||||
speakerentity = -1,
|
||||
const Float:origin[3] = NULL_VECTOR,
|
||||
const Float:dir[3] = NULL_VECTOR,
|
||||
bool:updatePos = true,
|
||||
Float:soundtime = 0.0)
|
||||
{
|
||||
new channel;
|
||||
new level;
|
||||
new Float:volume;
|
||||
new pitch;
|
||||
new String:sample[PLATFORM_MAX_PATH];
|
||||
|
||||
if (GetGameSoundParams(gameSound, channel, level, volume, pitch, sample, sizeof(sample), entity))
|
||||
{
|
||||
EmitSound(clients, numClients, sample, entity, channel, level, flags, volume, pitch, speakerentity, origin, dir, updatePos, soundtime);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Emits an ambient game sound.
|
||||
*
|
||||
* Game sounds are found in a game's scripts/game_sound.txt or other files
|
||||
* referenced from it
|
||||
*
|
||||
* Note that if a game sound has a rndwave section, one of them will be returned
|
||||
* at random.
|
||||
*
|
||||
* @param gameSound Name of game sound.
|
||||
* @param pos Origin of sound.
|
||||
* @param entity Entity index to associate sound with.
|
||||
* @param flags Sound flags.
|
||||
* @param delay Play delay.
|
||||
* @noreturn
|
||||
*/
|
||||
stock bool:EmitAmbientGameSound(const String:gameSound[],
|
||||
const Float:pos[3],
|
||||
entity = SOUND_FROM_WORLD,
|
||||
flags = SND_NOFLAGS,
|
||||
Float:delay = 0.0)
|
||||
{
|
||||
new channel; // This is never actually used for Ambients, but it's a mandatory field to GetGameSoundParams
|
||||
new level;
|
||||
new Float:volume;
|
||||
new pitch;
|
||||
new String:sample[PLATFORM_MAX_PATH];
|
||||
|
||||
if (GetGameSoundParams(gameSound, channel, level, volume, pitch, sample, sizeof(sample), entity))
|
||||
{
|
||||
EmitAmbientSound(sample, pos, entity, level, flags, volume, pitch, delay);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrapper to emit a game sound to one client.
|
||||
*
|
||||
* Game sounds are found in a game's scripts/game_sound.txt or other files
|
||||
* referenced from it
|
||||
*
|
||||
* Note that if a game sound has a rndwave section, one of them will be returned
|
||||
* at random.
|
||||
*
|
||||
* @param client Client index.
|
||||
* @param gameSound Name of game sound.
|
||||
* @param entity Entity to emit from.
|
||||
* @param flags Sound flags.
|
||||
* @param speakerentity Unknown.
|
||||
* @param origin Sound origin.
|
||||
* @param dir Sound direction.
|
||||
* @param updatePos Unknown (updates positions?)
|
||||
* @param soundtime Alternate time to play sound for.
|
||||
* @noreturn
|
||||
* @error Invalid client index.
|
||||
*/
|
||||
stock bool:EmitGameSoundToClient(client,
|
||||
const String:gameSound[],
|
||||
entity = SOUND_FROM_PLAYER,
|
||||
flags = SND_NOFLAGS,
|
||||
speakerentity = -1,
|
||||
const Float:origin[3] = NULL_VECTOR,
|
||||
const Float:dir[3] = NULL_VECTOR,
|
||||
bool:updatePos = true,
|
||||
Float:soundtime = 0.0)
|
||||
{
|
||||
new clients[1];
|
||||
clients[0] = client;
|
||||
/* Save some work for SDKTools and remove SOUND_FROM_PLAYER references */
|
||||
entity = (entity == SOUND_FROM_PLAYER) ? client : entity;
|
||||
return EmitGameSound(clients, 1, gameSound, entity, flags,
|
||||
speakerentity, origin, dir, updatePos, soundtime);
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrapper to emit game sound to all clients.
|
||||
*
|
||||
* Game sounds are found in a game's scripts/game_sound.txt or other files
|
||||
* referenced from it
|
||||
*
|
||||
* Note that if a game sound has a rndwave section, one of them will be returned
|
||||
* at random.
|
||||
*
|
||||
* @param gameSound Name of game sound.
|
||||
* @param entity Entity to emit from.
|
||||
* @param flags Sound flags.
|
||||
* @param speakerentity Unknown.
|
||||
* @param origin Sound origin.
|
||||
* @param dir Sound direction.
|
||||
* @param updatePos Unknown (updates positions?)
|
||||
* @param soundtime Alternate time to play sound for.
|
||||
* @noreturn
|
||||
* @error Invalid client index.
|
||||
*/
|
||||
stock bool:EmitGameSoundToAll(const String:gameSound[],
|
||||
entity = SOUND_FROM_PLAYER,
|
||||
flags = SND_NOFLAGS,
|
||||
speakerentity = -1,
|
||||
const Float:origin[3] = NULL_VECTOR,
|
||||
const Float:dir[3] = NULL_VECTOR,
|
||||
bool:updatePos = true,
|
||||
Float:soundtime = 0.0)
|
||||
{
|
||||
new clients[MaxClients];
|
||||
new total = 0;
|
||||
|
||||
for (new i=1; i<=MaxClients; i++)
|
||||
{
|
||||
if (IsClientInGame(i))
|
||||
{
|
||||
clients[total++] = i;
|
||||
}
|
||||
}
|
||||
|
||||
if (!total)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return EmitGameSound(clients, total, gameSound, entity, flags,
|
||||
speakerentity, origin, dir, updatePos, soundtime);
|
||||
}
|
||||
|
||||
/**
|
||||
* Precache a game sound.
|
||||
*
|
||||
* Most games will precache all game sounds on map start, but this is not guaranteed...
|
||||
* Team Fortress 2 is known to not pre-cache MvM game mode sounds on non-MvM maps.
|
||||
*
|
||||
* Due to the above, this native should be called before any calls to GetGameSoundParams,
|
||||
* EmitGameSound*, or EmitAmbientGameSound.
|
||||
*
|
||||
* It should be safe to pass already precached game sounds to this function.
|
||||
*
|
||||
* Note: It precaches all files for a game sound.
|
||||
*
|
||||
* @param soundname Game sound to precache
|
||||
*
|
||||
* @return True if the game sound was found, false if sound did not exist
|
||||
* or had no files
|
||||
*/
|
||||
native bool:PrecacheScriptSound(const String:soundname[]);
|
||||
|
||||
@@ -153,6 +153,10 @@ enum TFCond
|
||||
TFCond_HalloweenTiny,
|
||||
TFCond_HalloweenInHell,
|
||||
TFCond_HalloweenGhostMode,
|
||||
|
||||
TFCond_DodgeChance = 79,
|
||||
TFCond_Parachute,
|
||||
TFCond_BlastJumping,
|
||||
};
|
||||
|
||||
const Float:TFCondDuration_Infinite = -1.0;
|
||||
@@ -359,6 +363,17 @@ native bool:TF2_IsHolidayActive(TFHoliday:holiday);
|
||||
*/
|
||||
native bool:TF2_IsPlayerInDuel(client);
|
||||
|
||||
/**
|
||||
* Removes an econ wearable (hat, misc, etc) from a player.
|
||||
* This also deletes the wearable entity.
|
||||
*
|
||||
* @param client Client index.
|
||||
* @param wearable Index of the wearable entity.
|
||||
* @noreturn
|
||||
* @error Invalid client index, client not in game, invalid wearable entity, or no mod support.
|
||||
*/
|
||||
native TF2_RemoveWearable(client, wearable);
|
||||
|
||||
/**
|
||||
* Called after a condition is added to a player
|
||||
*
|
||||
@@ -436,5 +451,6 @@ public __ext_tf2_SetNTVOptional()
|
||||
MarkNativeAsOptional("TF2_GetClass");
|
||||
MarkNativeAsOptional("TF2_IsPlayerInDuel");
|
||||
MarkNativeAsOptional("TF2_IsHolidayActive");
|
||||
MarkNativeAsOptional("TF2_RemoveWearable");
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -249,6 +249,7 @@ enum {
|
||||
TF_WEAPON_SPELLBOOK,
|
||||
TF_WEAPON_SPELLBOOK_PROJECTILE,
|
||||
TF_WEAPON_SNIPERRIFLE_CLASSIC,
|
||||
TF_WEAPON_PARACHUTE,
|
||||
};
|
||||
|
||||
// TF2 Weapon Loadout Slots
|
||||
@@ -435,6 +436,20 @@ stock TF2_RemoveWeaponSlot(client, slot)
|
||||
new weaponIndex;
|
||||
while ((weaponIndex = GetPlayerWeaponSlot(client, slot)) != -1)
|
||||
{
|
||||
// bug #6206
|
||||
// papering over a valve bug where a weapon's extra wearables aren't properly removed from the weapon's owner
|
||||
new extraWearable = GetEntPropEnt(weaponIndex, Prop_Send, "m_hExtraWearable");
|
||||
if (extraWearable != -1)
|
||||
{
|
||||
TF2_RemoveWearable(client, extraWearable);
|
||||
}
|
||||
|
||||
extraWearable = GetEntPropEnt(weaponIndex, Prop_Send, "m_hExtraWearableViewModel");
|
||||
if (extraWearable != -1)
|
||||
{
|
||||
TF2_RemoveWearable(client, extraWearable);
|
||||
}
|
||||
|
||||
RemovePlayerItem(client, weaponIndex);
|
||||
AcceptEntityInput(weaponIndex, "Kill");
|
||||
}
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
1.6.0
|
||||
1.6.2
|
||||
|
||||
@@ -10,6 +10,7 @@ i
|
||||
D
|
||||
S
|
||||
!
|
||||
she calls it a mayonegg
|
||||
joys of buildbot, part 5: a watermelon's diatribes need not be cause for spilling the queen's tea
|
||||
crab
|
||||
joys of buildbot, part 6: a merry metal matchturtle mocks mostly and mainly in Madrid.
|
||||
|
||||
@@ -14,6 +14,11 @@ binary.compiler.includes += [
|
||||
os.path.join(builder.sourcePath, 'knight', 'shared'),
|
||||
]
|
||||
|
||||
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':
|
||||
binary.compiler.postlink += ['-lpthread', '-lrt']
|
||||
|
||||
|
||||
Reference in New Issue
Block a user