Compare commits
76 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
078e754a82 | ||
|
a776c14cf8 | ||
|
bd296a27f8 | ||
|
2e9619ff67 | ||
|
67a0d18ce7 | ||
|
c5428a8726 | ||
|
8db2132856 | ||
|
2e28df3dc6 | ||
|
b362abf4b2 | ||
|
da1cd9eb11 | ||
|
82628cfc5a | ||
|
690b3c5a28 | ||
|
865fa37ed9 | ||
|
6fae1811d9 | ||
|
7b476e4532 | ||
|
ba7fedca6e | ||
|
b2b29cb33f | ||
|
c5efe48aa3 | ||
|
c2d4643204 | ||
|
328fbf3f19 | ||
|
b5119201ff | ||
|
fe2a488f30 | ||
|
2bfc349952 | ||
|
eb6a39ecde | ||
|
266532f18c | ||
|
95027e0ae8 | ||
|
b5a0332181 | ||
|
ff935b4707 | ||
|
793c603826 | ||
|
03b270cf18 | ||
|
3c1c6f6c79 | ||
|
81766d31f7 | ||
|
cb886d4524 | ||
|
31836d2667 | ||
|
5dcd01801c | ||
|
5215abe5c5 | ||
|
d34d232682 | ||
|
a084b3295e | ||
|
48f7e6bcd5 | ||
|
74195870e2 | ||
|
e27e75b197 | ||
|
0cdc3616f2 | ||
|
92e9ca7153 | ||
|
ff727d537a | ||
|
8803219dd5 | ||
|
ada56b06bb | ||
|
14eaa097cb | ||
|
98be188cbe | ||
|
3a61446626 | ||
|
dd456dcb19 | ||
|
c6303d1ec3 | ||
|
ece57df986 | ||
|
3803fbfe20 | ||
|
50b5bb1970 | ||
|
047e0280ca | ||
|
afc493394d | ||
|
54a32e979f | ||
|
07f8043bce | ||
|
0a7a01e617 | ||
|
a68b21369c | ||
|
9a53fc4425 | ||
|
ab68d046c8 | ||
|
cdb9851da6 | ||
|
93e9a29353 | ||
|
fba6997c67 | ||
|
880f8869a6 | ||
|
e71497eaa6 | ||
|
256b33f75a | ||
|
c316d8fccd | ||
|
bc09b06166 | ||
|
208299f703 | ||
|
523befc238 | ||
|
2098a36d4b | ||
|
083ab81035 | ||
|
847261b6c9 | ||
|
309e6ae959 |
2
.gitmodules
vendored
2
.gitmodules
vendored
@ -3,4 +3,4 @@
|
||||
url = https://github.com/alliedmodders/amtl
|
||||
[submodule "sourcepawn"]
|
||||
path = sourcepawn
|
||||
url = https://github.com/alliedmodders/sourcepawn
|
||||
url = https://github.com/BotoX/sourcepawn.git
|
||||
|
@ -200,7 +200,7 @@ class SMConfig(object):
|
||||
'-pipe',
|
||||
'-fno-strict-aliasing',
|
||||
'-Wall',
|
||||
'-Werror',
|
||||
# '-Werror',
|
||||
'-Wno-unused',
|
||||
'-Wno-switch',
|
||||
'-Wno-array-bounds',
|
||||
|
@ -60,6 +60,9 @@ for sdk_name in SM.sdks:
|
||||
os.path.join(sdk.path, 'public', 'game', 'shared', 'csgo', 'protobuf')
|
||||
]
|
||||
|
||||
if compiler.like('msvc'):
|
||||
compiler.defines += ['_XKEYCHECK_H']
|
||||
|
||||
if builder.target.platform == 'linux':
|
||||
compiler.postlink += ['-lpthread', '-lrt']
|
||||
|
||||
@ -74,10 +77,8 @@ for sdk_name in SM.sdks:
|
||||
vs_year = ''
|
||||
if msvc_ver == 1800:
|
||||
vs_year = '2013'
|
||||
elif msvc_ver == 1900:
|
||||
elif 1900 <= msvc_ver < 2000:
|
||||
vs_year = '2015'
|
||||
elif msvc_ver == 1910:
|
||||
vs_year = '2017'
|
||||
else:
|
||||
raise Exception('Cannot find libprotobuf for MSVC version "' + str(compiler.version) + '"')
|
||||
|
||||
|
@ -43,6 +43,7 @@
|
||||
#include <compat_wrappers.h>
|
||||
#include "concmd_cleaner.h"
|
||||
#include "PlayerManager.h"
|
||||
#include <sm_stringhashmap.h>
|
||||
|
||||
using namespace SourceHook;
|
||||
|
||||
@ -67,6 +68,10 @@ struct ConVarInfo
|
||||
{
|
||||
return strcmp(name, info->pVar->GetName()) == 0;
|
||||
}
|
||||
static inline uint32_t hash(const detail::CharsAndLength &key)
|
||||
{
|
||||
return key.hash();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -412,8 +412,11 @@ bool SM_ExecuteConfig(IPlugin *pl, AutoConfig *cfg, bool can_create)
|
||||
for (iter = convars->begin(); iter != convars->end(); iter++)
|
||||
{
|
||||
const ConVar *cvar = (*iter);
|
||||
|
||||
if ((cvar->GetFlags() & FCVAR_DONTRECORD) == FCVAR_DONTRECORD)
|
||||
#if SOURCE_ENGINE >= SE_ORANGEBOX
|
||||
if (cvar->IsFlagSet(FCVAR_DONTRECORD))
|
||||
#else
|
||||
if (cvar->IsBitSet(FCVAR_DONTRECORD))
|
||||
#endif
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
@ -77,6 +77,10 @@ struct EventHook
|
||||
{
|
||||
return strcmp(name, hook->name.chars()) == 0;
|
||||
}
|
||||
static inline uint32_t hash(const detail::CharsAndLength &key)
|
||||
{
|
||||
return key.hash();
|
||||
}
|
||||
};
|
||||
|
||||
enum EventHookMode
|
||||
|
@ -50,26 +50,8 @@
|
||||
|
||||
typedef ICommandLine *(*FakeGetCommandLine)();
|
||||
|
||||
#if defined _WIN32
|
||||
#define TIER0_NAME "tier0.dll"
|
||||
#define VSTDLIB_NAME "vstdlib.dll"
|
||||
#elif defined __APPLE__
|
||||
#define TIER0_NAME "libtier0.dylib"
|
||||
#define VSTDLIB_NAME "libvstdlib.dylib"
|
||||
#elif defined __linux__
|
||||
#if SOURCE_ENGINE == SE_HL2DM || SOURCE_ENGINE == SE_DODS || SOURCE_ENGINE == SE_CSS || SOURCE_ENGINE == SE_TF2 \
|
||||
|| SOURCE_ENGINE == SE_SDK2013 || SOURCE_ENGINE == SE_LEFT4DEAD2 || SOURCE_ENGINE == SE_NUCLEARDAWN \
|
||||
|| SOURCE_ENGINE == SE_BMS || SOURCE_ENGINE == SE_INSURGENCY || SOURCE_ENGINE == SE_DOI
|
||||
#define TIER0_NAME "libtier0_srv.so"
|
||||
#define VSTDLIB_NAME "libvstdlib_srv.so"
|
||||
#elif SOURCE_ENGINE >= SE_LEFT4DEAD
|
||||
#define TIER0_NAME "libtier0.so"
|
||||
#define VSTDLIB_NAME "libvstdlib.so"
|
||||
#else
|
||||
#define TIER0_NAME "tier0_i486.so"
|
||||
#define VSTDLIB_NAME "vstdlib_i486.so"
|
||||
#endif
|
||||
#endif
|
||||
#define TIER0_NAME SOURCE_BIN_PREFIX "tier0" SOURCE_BIN_SUFFIX SOURCE_BIN_EXT
|
||||
#define VSTDLIB_NAME SOURCE_BIN_PREFIX "vstdlib" SOURCE_BIN_SUFFIX SOURCE_BIN_EXT
|
||||
|
||||
CHalfLife2 g_HL2;
|
||||
ConVar *sv_lan = NULL;
|
||||
|
@ -60,6 +60,30 @@ using namespace SourceMod;
|
||||
#define HUD_PRINTTALK 3
|
||||
#define HUD_PRINTCENTER 4
|
||||
|
||||
#if defined _WIN32
|
||||
#define SOURCE_BIN_PREFIX ""
|
||||
#define SOURCE_BIN_SUFFIX ""
|
||||
#define SOURCE_BIN_EXT ".dll"
|
||||
#elif defined __APPLE__
|
||||
#define SOURCE_BIN_PREFIX ""
|
||||
#define SOURCE_BIN_SUFFIX ""
|
||||
#define SOURCE_BIN_EXT ".dylib"
|
||||
#elif defined __linux__
|
||||
#if SOURCE_ENGINE == SE_HL2DM || SOURCE_ENGINE == SE_DODS || SOURCE_ENGINE == SE_CSS || SOURCE_ENGINE == SE_TF2 \
|
||||
|| SOURCE_ENGINE == SE_SDK2013 || SOURCE_ENGINE == SE_LEFT4DEAD2 || SOURCE_ENGINE == SE_NUCLEARDAWN \
|
||||
|| SOURCE_ENGINE == SE_BMS || SOURCE_ENGINE == SE_INSURGENCY || SOURCE_ENGINE == SE_DOI
|
||||
#define SOURCE_BIN_PREFIX "lib"
|
||||
#define SOURCE_BIN_SUFFIX "_srv"
|
||||
#elif SOURCE_ENGINE >= SE_LEFT4DEAD
|
||||
#define SOURCE_BIN_PREFIX "lib"
|
||||
#define SOURCE_BIN_SUFFIX ""
|
||||
#else
|
||||
#define SOURCE_BIN_PREFIX ""
|
||||
#define SOURCE_BIN_SUFFIX "_i486"
|
||||
#endif
|
||||
#define SOURCE_BIN_EXT ".so"
|
||||
#endif
|
||||
|
||||
struct DataTableInfo
|
||||
{
|
||||
struct SendPropPolicy
|
||||
@ -68,13 +92,21 @@ struct DataTableInfo
|
||||
{
|
||||
return strcmp(name, info.prop->GetName()) == 0;
|
||||
}
|
||||
static inline uint32_t hash(const detail::CharsAndLength &key)
|
||||
{
|
||||
return key.hash();
|
||||
}
|
||||
};
|
||||
|
||||
static inline bool matches(const char *name, const DataTableInfo *info)
|
||||
{
|
||||
return strcmp(name, info->sc->GetName()) == 0;
|
||||
}
|
||||
|
||||
static inline uint32_t hash(const detail::CharsAndLength &key)
|
||||
{
|
||||
return key.hash();
|
||||
}
|
||||
|
||||
DataTableInfo(ServerClass *sc)
|
||||
: sc(sc)
|
||||
{
|
||||
@ -90,6 +122,10 @@ struct DataMapCachePolicy
|
||||
{
|
||||
return strcmp(name, info.prop->fieldName) == 0;
|
||||
}
|
||||
static inline uint32_t hash(const detail::CharsAndLength &key)
|
||||
{
|
||||
return key.hash();
|
||||
}
|
||||
};
|
||||
|
||||
typedef NameHashSet<sm_datatable_info_t, DataMapCachePolicy> DataMapCache;
|
||||
|
@ -308,7 +308,7 @@ IMenuPanel *MenuManager::RenderMenu(int client, menu_states_t &md, ItemOrder ord
|
||||
{
|
||||
ItemDrawInfo &dr = drawItems[foundItems].draw;
|
||||
/* Is the item valid? */
|
||||
if (menu->GetItemInfo(i, &dr) != NULL)
|
||||
if (menu->GetItemInfo(i, &dr, client) != NULL)
|
||||
{
|
||||
/* Ask the user to change the style, if necessary */
|
||||
mh->OnMenuDrawItem(menu, client, i, dr.style);
|
||||
@ -398,7 +398,7 @@ IMenuPanel *MenuManager::RenderMenu(int client, menu_states_t &md, ItemOrder ord
|
||||
}
|
||||
while (++lastItem < totalItems)
|
||||
{
|
||||
if (menu->GetItemInfo(lastItem, &dr) != NULL)
|
||||
if (menu->GetItemInfo(lastItem, &dr, client) != NULL)
|
||||
{
|
||||
mh->OnMenuDrawItem(menu, client, lastItem, dr.style);
|
||||
if (IsSlotItem(panel, dr.style))
|
||||
@ -420,7 +420,7 @@ IMenuPanel *MenuManager::RenderMenu(int client, menu_states_t &md, ItemOrder ord
|
||||
lastItem--;
|
||||
while (lastItem != 0)
|
||||
{
|
||||
if (menu->GetItemInfo(lastItem, &dr) != NULL)
|
||||
if (menu->GetItemInfo(lastItem, &dr, client) != NULL)
|
||||
{
|
||||
mh->OnMenuDrawItem(menu, client, lastItem, dr.style);
|
||||
if (IsSlotItem(panel, dr.style))
|
||||
|
@ -633,7 +633,7 @@ bool CBaseMenu::AppendItem(const char *info, const ItemDrawInfo &draw)
|
||||
return false;
|
||||
}
|
||||
|
||||
CItem item;
|
||||
CItem item(m_items.length());
|
||||
|
||||
item.info = info;
|
||||
if (draw.display)
|
||||
@ -655,7 +655,7 @@ bool CBaseMenu::InsertItem(unsigned int position, const char *info, const ItemDr
|
||||
if (position >= m_items.length())
|
||||
return false;
|
||||
|
||||
CItem item;
|
||||
CItem item(position);
|
||||
item.info = info;
|
||||
if (draw.display)
|
||||
item.display = new ke::AString(draw.display);
|
||||
@ -679,11 +679,16 @@ void CBaseMenu::RemoveAllItems()
|
||||
m_items.clear();
|
||||
}
|
||||
|
||||
const char *CBaseMenu::GetItemInfo(unsigned int position, ItemDrawInfo *draw/* =NULL */)
|
||||
const char *CBaseMenu::GetItemInfo(unsigned int position, ItemDrawInfo *draw/* =NULL */, int client/* =0 */)
|
||||
{
|
||||
if (position >= m_items.length())
|
||||
return NULL;
|
||||
|
||||
if (client > 0 && position < m_RandomMaps[client].length())
|
||||
{
|
||||
position = m_RandomMaps[client][position];
|
||||
}
|
||||
|
||||
if (draw)
|
||||
{
|
||||
draw->display = m_items[position].display->chars();
|
||||
@ -693,6 +698,62 @@ const char *CBaseMenu::GetItemInfo(unsigned int position, ItemDrawInfo *draw/* =
|
||||
return m_items[position].info.chars();
|
||||
}
|
||||
|
||||
void CBaseMenu::ShufflePerClient(int start, int stop)
|
||||
{
|
||||
// limit map len to 255 items since it's using uint8
|
||||
int length = MIN(GetItemCount(), 255);
|
||||
if (stop >= 0)
|
||||
length = MIN(length, stop);
|
||||
|
||||
for (int i = 1; i < SM_MAXPLAYERS + 1; i++)
|
||||
{
|
||||
// populate per-client map ...
|
||||
m_RandomMaps[i].resize(length);
|
||||
for (int j = 0; j < length; j++)
|
||||
m_RandomMaps[i][j] = j;
|
||||
|
||||
// ... and random shuffle it
|
||||
for (int j = length - 1; j > start; j--)
|
||||
{
|
||||
int x = rand() % (j - start + 1) + start;
|
||||
uint8_t tmp = m_RandomMaps[i][x];
|
||||
m_RandomMaps[i][x] = m_RandomMaps[i][j];
|
||||
m_RandomMaps[i][j] = tmp;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CBaseMenu::SetClientMapping(int client, int *array, int length)
|
||||
{
|
||||
length = MIN(length, 255);
|
||||
m_RandomMaps[client].resize(length);
|
||||
for (int i = 0; i < length; i++)
|
||||
{
|
||||
m_RandomMaps[client][i] = array[i];
|
||||
}
|
||||
}
|
||||
|
||||
bool CBaseMenu::IsPerClientShuffled()
|
||||
{
|
||||
for (int i = 1; i < SM_MAXPLAYERS + 1; i++)
|
||||
{
|
||||
if(m_RandomMaps[i].length() > 0)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
unsigned int CBaseMenu::GetRealItemIndex(int client, unsigned int position)
|
||||
{
|
||||
if (client > 0 && position < m_RandomMaps[client].length())
|
||||
{
|
||||
position = m_RandomMaps[client][position];
|
||||
return m_items[position].index;
|
||||
}
|
||||
|
||||
return position;
|
||||
}
|
||||
|
||||
unsigned int CBaseMenu::GetItemCount()
|
||||
{
|
||||
return m_items.length();
|
||||
|
@ -43,8 +43,9 @@ using namespace SourceMod;
|
||||
class CItem
|
||||
{
|
||||
public:
|
||||
CItem()
|
||||
CItem(unsigned int index)
|
||||
{
|
||||
this->index = index;
|
||||
style = 0;
|
||||
access = 0;
|
||||
}
|
||||
@ -52,11 +53,13 @@ public:
|
||||
: info(ke::Move(other.info)),
|
||||
display(ke::Move(other.display))
|
||||
{
|
||||
index = other.index;
|
||||
style = other.style;
|
||||
access = other.access;
|
||||
}
|
||||
CItem & operator =(CItem &&other)
|
||||
{
|
||||
index = other.index;
|
||||
info = ke::Move(other.info);
|
||||
display = ke::Move(other.display);
|
||||
style = other.style;
|
||||
@ -65,6 +68,7 @@ public:
|
||||
}
|
||||
|
||||
public:
|
||||
unsigned int index;
|
||||
ke::AString info;
|
||||
ke::AutoPtr<ke::AString> display;
|
||||
unsigned int style;
|
||||
@ -137,7 +141,7 @@ public:
|
||||
virtual bool InsertItem(unsigned int position, const char *info, const ItemDrawInfo &draw);
|
||||
virtual bool RemoveItem(unsigned int position);
|
||||
virtual void RemoveAllItems();
|
||||
virtual const char *GetItemInfo(unsigned int position, ItemDrawInfo *draw=NULL);
|
||||
virtual const char *GetItemInfo(unsigned int position, ItemDrawInfo *draw=NULL, int client=0);
|
||||
virtual unsigned int GetItemCount();
|
||||
virtual bool SetPagination(unsigned int itemsPerPage);
|
||||
virtual unsigned int GetPagination();
|
||||
@ -151,6 +155,10 @@ public:
|
||||
virtual unsigned int GetMenuOptionFlags();
|
||||
virtual void SetMenuOptionFlags(unsigned int flags);
|
||||
virtual IMenuHandler *GetHandler();
|
||||
virtual void ShufflePerClient(int start, int stop);
|
||||
virtual void SetClientMapping(int client, int *array, int length);
|
||||
virtual bool IsPerClientShuffled();
|
||||
virtual unsigned int GetRealItemIndex(int client, unsigned int position);
|
||||
unsigned int GetBaseMemUsage();
|
||||
private:
|
||||
void InternalDelete();
|
||||
@ -167,6 +175,7 @@ protected:
|
||||
Handle_t m_hHandle;
|
||||
IMenuHandler *m_pHandler;
|
||||
unsigned int m_nFlags;
|
||||
ke::Vector<uint8_t> m_RandomMaps[SM_MAXPLAYERS+1];
|
||||
};
|
||||
|
||||
#endif //_INCLUDE_MENUSTYLE_BASE_H
|
||||
|
@ -514,15 +514,16 @@ void VoteMenuHandler::OnMenuSelect(IBaseMenu *menu, int client, unsigned int ite
|
||||
/* Check by our item count, NOT the vote array size */
|
||||
if (item < m_Items)
|
||||
{
|
||||
m_ClientVotes[client] = item;
|
||||
m_Votes[item]++;
|
||||
unsigned int index = menu->GetRealItemIndex(client, item);
|
||||
m_ClientVotes[client] = index;
|
||||
m_Votes[index]++;
|
||||
m_NumVotes++;
|
||||
|
||||
if (sm_vote_chat.GetBool() || sm_vote_console.GetBool() || sm_vote_client_console.GetBool())
|
||||
{
|
||||
static char buffer[1024];
|
||||
ItemDrawInfo dr;
|
||||
menu->GetItemInfo(item, &dr);
|
||||
menu->GetItemInfo(item, &dr, client);
|
||||
|
||||
if (sm_vote_console.GetBool())
|
||||
{
|
||||
|
@ -30,6 +30,7 @@
|
||||
*/
|
||||
|
||||
#include "PlayerManager.h"
|
||||
#include "sourcemod.h"
|
||||
#include "IAdminSystem.h"
|
||||
#include "ConCmdManager.h"
|
||||
#include "MenuStyle_Valve.h"
|
||||
@ -92,6 +93,12 @@ SH_DECL_EXTERN1_void(ConCommand, Dispatch, SH_NOATTRIB, false, const CCommand &)
|
||||
#else
|
||||
SH_DECL_EXTERN0_void(ConCommand, Dispatch, SH_NOATTRIB, false);
|
||||
#endif
|
||||
SH_DECL_HOOK2_void(IVEngineServer, ClientPrintf, SH_NOATTRIB, 0, edict_t *, const char *);
|
||||
|
||||
static void PrintfBuffer_FrameAction(void *data)
|
||||
{
|
||||
g_Players.OnPrintfFrameAction(reinterpret_cast<unsigned int>(data));
|
||||
}
|
||||
|
||||
ConCommand *maxplayersCmd = NULL;
|
||||
|
||||
@ -172,6 +179,7 @@ void PlayerManager::OnSourceModAllInitialized()
|
||||
#elif SOURCE_ENGINE > SE_EYE // 2013/orangebox, but not original orangebox.
|
||||
SH_ADD_HOOK(IServerGameDLL, SetServerHibernation, gamedll, SH_MEMBER(this, &PlayerManager::OnServerHibernationUpdate), true);
|
||||
#endif
|
||||
SH_ADD_HOOK(IVEngineServer, ClientPrintf, engine, SH_MEMBER(this, &PlayerManager::OnClientPrintf), false);
|
||||
|
||||
sharesys->AddInterface(NULL, this);
|
||||
|
||||
@ -225,6 +233,7 @@ void PlayerManager::OnSourceModShutdown()
|
||||
#elif SOURCE_ENGINE > SE_EYE // 2013/orangebox, but not original orangebox.
|
||||
SH_REMOVE_HOOK(IServerGameDLL, SetServerHibernation, gamedll, SH_MEMBER(this, &PlayerManager::OnServerHibernationUpdate), true);
|
||||
#endif
|
||||
SH_REMOVE_HOOK(IVEngineServer, ClientPrintf, engine, SH_MEMBER(this, &PlayerManager::OnClientPrintf), false);
|
||||
|
||||
/* Release forwards */
|
||||
forwardsys->ReleaseForward(m_clconnect);
|
||||
@ -846,6 +855,88 @@ void PlayerManager::OnClientDisconnect_Post(edict_t *pEntity)
|
||||
}
|
||||
}
|
||||
|
||||
void PlayerManager::OnClientPrintf(edict_t *pEdict, const char *szMsg)
|
||||
{
|
||||
int client = IndexOfEdict(pEdict);
|
||||
|
||||
CPlayer &player = m_Players[client];
|
||||
if (!player.IsConnected())
|
||||
RETURN_META(MRES_IGNORED);
|
||||
|
||||
INetChannel *pNetChan = static_cast<INetChannel *>(engine->GetPlayerNetInfo(client));
|
||||
if (pNetChan == NULL)
|
||||
RETURN_META(MRES_IGNORED);
|
||||
|
||||
size_t nMsgLen = strlen(szMsg);
|
||||
#if SOURCE_ENGINE == SE_EPISODEONE
|
||||
static const int nNumBitsWritten = 0;
|
||||
#else
|
||||
int nNumBitsWritten = pNetChan->GetNumBitsWritten(false); // SVC_Print uses unreliable netchan
|
||||
#endif
|
||||
|
||||
// if the msg is bigger than allowed then just let it fail
|
||||
if (nMsgLen + 1 >= SVC_Print_BufferSize) // +1 for NETMSG_TYPE_BITS
|
||||
RETURN_META(MRES_IGNORED);
|
||||
|
||||
// enqueue msgs if we'd overflow the SVC_Print buffer (+7 as ceil)
|
||||
if (!player.m_PrintfBuffer.empty() || (nNumBitsWritten + NETMSG_TYPE_BITS + 7) / 8 + nMsgLen >= SVC_Print_BufferSize)
|
||||
{
|
||||
// Don't send any more messages for this player until the buffer is empty.
|
||||
// Queue up a gameframe hook to empty the buffer (if we haven't already)
|
||||
if (player.m_PrintfBuffer.empty())
|
||||
g_SourceMod.AddFrameAction(PrintfBuffer_FrameAction, (void *)(uintptr_t)player.GetSerial());
|
||||
|
||||
player.m_PrintfBuffer.append(szMsg);
|
||||
|
||||
RETURN_META(MRES_SUPERCEDE);
|
||||
}
|
||||
|
||||
RETURN_META(MRES_IGNORED);
|
||||
}
|
||||
|
||||
void PlayerManager::OnPrintfFrameAction(unsigned int serial)
|
||||
{
|
||||
int client = GetClientFromSerial(serial);
|
||||
CPlayer &player = m_Players[client];
|
||||
if (!player.IsConnected())
|
||||
{
|
||||
player.ClearNetchannelQueue();
|
||||
return;
|
||||
}
|
||||
|
||||
INetChannel *pNetChan = static_cast<INetChannel *>(engine->GetPlayerNetInfo(client));
|
||||
if (pNetChan == NULL)
|
||||
{
|
||||
player.ClearNetchannelQueue();
|
||||
return;
|
||||
}
|
||||
|
||||
while (!player.m_PrintfBuffer.empty())
|
||||
{
|
||||
#if SOURCE_ENGINE == SE_EPISODEONE
|
||||
static const int nNumBitsWritten = 0;
|
||||
#else
|
||||
int nNumBitsWritten = pNetChan->GetNumBitsWritten(false); // SVC_Print uses unreliable netchan
|
||||
#endif
|
||||
|
||||
ke::AString &string = player.m_PrintfBuffer.front();
|
||||
|
||||
// stop if we'd overflow the SVC_Print buffer (+7 as ceil)
|
||||
if ((nNumBitsWritten + NETMSG_TYPE_BITS + 7) / 8 + string.length() >= SVC_Print_BufferSize)
|
||||
break;
|
||||
|
||||
SH_CALL(engine, &IVEngineServer::ClientPrintf)(player.m_pEdict, string.chars());
|
||||
|
||||
player.m_PrintfBuffer.popFront();
|
||||
}
|
||||
|
||||
if (!player.m_PrintfBuffer.empty())
|
||||
{
|
||||
// continue processing it on the next gameframe as buffer is not empty
|
||||
g_SourceMod.AddFrameAction(PrintfBuffer_FrameAction, (void *)(uintptr_t)player.GetSerial());
|
||||
}
|
||||
}
|
||||
|
||||
void ClientConsolePrint(edict_t *e, const char *fmt, ...)
|
||||
{
|
||||
char buffer[512];
|
||||
@ -2145,6 +2236,13 @@ void CPlayer::Disconnect()
|
||||
#if SOURCE_ENGINE == SE_CSGO
|
||||
m_LanguageCookie = InvalidQueryCvarCookie;
|
||||
#endif
|
||||
ClearNetchannelQueue();
|
||||
}
|
||||
|
||||
void CPlayer::ClearNetchannelQueue(void)
|
||||
{
|
||||
while (!m_PrintfBuffer.empty())
|
||||
m_PrintfBuffer.popFront();
|
||||
}
|
||||
|
||||
void CPlayer::SetName(const char *name)
|
||||
|
@ -43,6 +43,7 @@
|
||||
#include <sh_list.h>
|
||||
#include <sh_vector.h>
|
||||
#include <am-string.h>
|
||||
#include <am-deque.h>
|
||||
#include "ConVarManager.h"
|
||||
|
||||
#include <steam/steamclientpublic.h>
|
||||
@ -123,6 +124,7 @@ private:
|
||||
bool IsAuthStringValidated();
|
||||
bool SetEngineString();
|
||||
bool SetCSteamID();
|
||||
void ClearNetchannelQueue(void);
|
||||
private:
|
||||
bool m_IsConnected = false;
|
||||
bool m_IsInGame = false;
|
||||
@ -152,6 +154,7 @@ private:
|
||||
#if SOURCE_ENGINE == SE_CSGO
|
||||
QueryCvarCookie_t m_LanguageCookie = InvalidQueryCvarCookie;
|
||||
#endif
|
||||
ke::Deque<ke::AString> m_PrintfBuffer;
|
||||
};
|
||||
|
||||
class PlayerManager :
|
||||
@ -190,6 +193,8 @@ public:
|
||||
void OnClientSettingsChanged(edict_t *pEntity);
|
||||
//void OnClientSettingsChanged_Pre(edict_t *pEntity);
|
||||
void OnServerHibernationUpdate(bool bHibernating);
|
||||
void OnClientPrintf(edict_t *pEdict, const char *szMsg);
|
||||
void OnPrintfFrameAction(unsigned int serial);
|
||||
public: //IPlayerManager
|
||||
void AddClientListener(IClientListener *listener);
|
||||
void RemoveClientListener(IClientListener *listener);
|
||||
@ -267,6 +272,9 @@ private:
|
||||
int m_SourceTVUserId;
|
||||
int m_ReplayUserId;
|
||||
bool m_bInCCKVHook;
|
||||
private:
|
||||
static const int NETMSG_TYPE_BITS = 5; // SVC_Print overhead for netmsg type
|
||||
static const int SVC_Print_BufferSize = 2048 - 1; // -1 for terminating \0
|
||||
};
|
||||
|
||||
#if SOURCE_ENGINE >= SE_ORANGEBOX
|
||||
|
@ -36,7 +36,11 @@
|
||||
|
||||
#if SOURCE_ENGINE >= SE_ORANGEBOX
|
||||
SH_DECL_HOOK1_void(ICvar, UnregisterConCommand, SH_NOATTRIB, 0, ConCommandBase *);
|
||||
#if SOURCE_ENGINE == SE_CSGO
|
||||
SH_DECL_HOOK2_void(ICvar, RegisterConCommand, SH_NOATTRIB, 0, ConCommandBase *, bool);
|
||||
#else
|
||||
SH_DECL_HOOK1_void(ICvar, RegisterConCommand, SH_NOATTRIB, 0, ConCommandBase *);
|
||||
#endif
|
||||
#else
|
||||
SH_DECL_HOOK1_void(ICvar, RegisterConCommandBase, SH_NOATTRIB, 0, ConCommandBase *);
|
||||
#endif
|
||||
@ -78,7 +82,11 @@ public:
|
||||
#endif
|
||||
}
|
||||
|
||||
#if SOURCE_ENGINE == SE_CSGO
|
||||
void LinkConCommandBase(ConCommandBase *pBase, bool unknown)
|
||||
#else
|
||||
void LinkConCommandBase(ConCommandBase *pBase)
|
||||
#endif
|
||||
{
|
||||
IConCommandLinkListener *listener = IConCommandLinkListener::head;
|
||||
while (listener)
|
||||
|
551
core/convar_sm.h
551
core/convar_sm.h
@ -1,551 +0,0 @@
|
||||
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $Workfile: $
|
||||
// $Date: 2006-08-13 06:34:30 -0500 (Sun, 13 Aug 2006) $
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef CONVAR_H
|
||||
#define CONVAR_H
|
||||
#if _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "tier0/dbg.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#define FORCEINLINE_CVAR FORCEINLINE
|
||||
#elif _LINUX
|
||||
#define FORCEINLINE_CVAR __inline__ FORCEINLINE
|
||||
#else
|
||||
#error "implement me"
|
||||
#endif
|
||||
|
||||
// The default, no flags at all
|
||||
#define FCVAR_NONE 0
|
||||
|
||||
// Command to ConVars and ConCommands
|
||||
// ConVar Systems
|
||||
#define FCVAR_UNREGISTERED (1<<0) // If this is set, don't add to linked list, etc.
|
||||
#define FCVAR_LAUNCHER (1<<1) // defined by launcher
|
||||
#define FCVAR_GAMEDLL (1<<2) // defined by the game DLL
|
||||
#define FCVAR_CLIENTDLL (1<<3) // defined by the client DLL
|
||||
#define FCVAR_MATERIAL_SYSTEM (1<<4) // Defined by the material system.
|
||||
#define FCVAR_DATACACHE (1<<19) // Defined by the datacache system.
|
||||
#define FCVAR_STUDIORENDER (1<<15) // Defined by the studiorender system.
|
||||
#define FCVAR_FILESYSTEM (1<<21) // Defined by the file system.
|
||||
#define FCVAR_PLUGIN (1<<18) // Defined by a 3rd party plugin.
|
||||
#define FCVAR_TOOLSYSTEM (1<<20) // Defined by an IToolSystem library
|
||||
#define FCVAR_SOUNDSYSTEM (1<<23) // Defined by the soundsystem library
|
||||
#define FCVAR_INPUTSYSTEM (1<<25) // Defined by the inputsystem dll
|
||||
#define FCVAR_NETWORKSYSTEM (1<<26) // Defined by the network system
|
||||
// NOTE!! if you add a cvar system, add it here too!!!!
|
||||
// the engine lacks a cvar flag, but needs it for xbox
|
||||
// an engine cvar is thus a cvar not marked with any other system
|
||||
#define FCVAR_NON_ENGINE ((FCVAR_LAUNCHER|FCVAR_GAMEDLL|FCVAR_CLIENTDLL|FCVAR_MATERIAL_SYSTEM|FCVAR_DATACACHE|FCVAR_STUDIORENDER|FCVAR_FILESYSTEM|FCVAR_PLUGIN|FCVAR_TOOLSYSTEM|FCVAR_SOUNDSYSTEM|FCVAR_INPUTSYSTEM|FCVAR_NETWORKSYSTEM))
|
||||
|
||||
// ConVar only
|
||||
#define FCVAR_PROTECTED (1<<5) // It's a server cvar, but we don't send the data since it's a password, etc. Sends 1 if it's not bland/zero, 0 otherwise as value
|
||||
#define FCVAR_SPONLY (1<<6) // This cvar cannot be changed by clients connected to a multiplayer server.
|
||||
#define FCVAR_ARCHIVE (1<<7) // set to cause it to be saved to vars.rc
|
||||
#define FCVAR_NOTIFY (1<<8) // notifies players when changed
|
||||
#define FCVAR_USERINFO (1<<9) // changes the client's info string
|
||||
#define FCVAR_CHEAT (1<<14) // Only useable in singleplayer / debug / multiplayer & sv_cheats
|
||||
|
||||
#define FCVAR_PRINTABLEONLY (1<<10) // This cvar's string cannot contain unprintable characters ( e.g., used for player name etc ).
|
||||
#define FCVAR_UNLOGGED (1<<11) // If this is a FCVAR_SERVER, don't log changes to the log file / console if we are creating a log
|
||||
#define FCVAR_NEVER_AS_STRING (1<<12) // never try to print that cvar
|
||||
|
||||
// It's a ConVar that's shared between the client and the server.
|
||||
// At signon, the values of all such ConVars are sent from the server to the client (skipped for local
|
||||
// client, of course )
|
||||
// If a change is requested it must come from the console (i.e., no remote client changes)
|
||||
// If a value is changed while a server is active, it's replicated to all connected clients
|
||||
#define FCVAR_REPLICATED (1<<13) // server setting enforced on clients, TODO rename to FCAR_SERVER at some time
|
||||
#define FCVAR_DEMO (1<<16) // record this cvar when starting a demo file
|
||||
#define FCVAR_DONTRECORD (1<<17) // don't record these command in demofiles
|
||||
|
||||
#define FCVAR_NOT_CONNECTED (1<<22) // cvar cannot be changed by a client that is connected to a server
|
||||
|
||||
#define FCVAR_ARCHIVE_XBOX (1<<24) // cvar written to config.cfg on the Xbox
|
||||
|
||||
|
||||
// #define FCVAR_AVAILABLE (1<<27)
|
||||
// #define FCVAR_AVAILABLE (1<<28)
|
||||
// #define FCVAR_AVAILABLE (1<<29)
|
||||
// #define FCVAR_AVAILABLE (1<<30)
|
||||
// #define FCVAR_AVAILABLE (1<<31)
|
||||
|
||||
|
||||
class ConVar;
|
||||
class ConCommand;
|
||||
class ConCommandBase;
|
||||
|
||||
// Any executable that wants to use ConVars need to implement one of
|
||||
// these to hook up access to console variables.
|
||||
class IConCommandBaseAccessor
|
||||
{
|
||||
public:
|
||||
// Flags is a combination of FCVAR flags in cvar.h.
|
||||
// hOut is filled in with a handle to the variable.
|
||||
virtual bool RegisterConCommandBase( ConCommandBase *pVar )=0;
|
||||
};
|
||||
|
||||
|
||||
// You don't have to instantiate one of these, just call its
|
||||
// OneTimeInit function when your executable is initializing.
|
||||
class ConCommandBaseMgr
|
||||
{
|
||||
public:
|
||||
// Call this ONCE when the executable starts up.
|
||||
static void OneTimeInit( IConCommandBaseAccessor *pAccessor );
|
||||
#ifdef _XBOX
|
||||
static bool Fixup( ConCommandBase* pConCommandBase );
|
||||
#ifndef _RETAIL
|
||||
static void PublishCommands( bool bForce );
|
||||
#endif
|
||||
#endif
|
||||
};
|
||||
|
||||
// Called when a ConVar changes value
|
||||
typedef void ( *FnChangeCallback )( ConVar *var, char const *pOldString );
|
||||
|
||||
// Called when a ConCommand needs to execute
|
||||
typedef void ( *FnCommandCallback )( void );
|
||||
|
||||
#define COMMAND_COMPLETION_MAXITEMS 64
|
||||
#define COMMAND_COMPLETION_ITEM_LENGTH 64
|
||||
|
||||
// Returns 0 to COMMAND_COMPLETION_MAXITEMS worth of completion strings
|
||||
typedef int ( *FnCommandCompletionCallback )( char const *partial, char commands[ COMMAND_COMPLETION_MAXITEMS ][ COMMAND_COMPLETION_ITEM_LENGTH ] );
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: The base console invoked command/cvar interface
|
||||
//-----------------------------------------------------------------------------
|
||||
class ConCommandBase
|
||||
{
|
||||
friend class ConCommandBaseMgr;
|
||||
friend class CCvar;
|
||||
friend class ConVar;
|
||||
friend class ConCommand;
|
||||
|
||||
public:
|
||||
ConCommandBase( void );
|
||||
ConCommandBase( char const *pName, char const *pHelpString = 0,
|
||||
int flags = 0 );
|
||||
|
||||
virtual ~ConCommandBase( void );
|
||||
|
||||
virtual bool IsCommand( void ) const;
|
||||
|
||||
// Check flag
|
||||
virtual bool IsBitSet( int flag ) const;
|
||||
// Set flag
|
||||
virtual void AddFlags( int flags );
|
||||
|
||||
// Return name of cvar
|
||||
virtual char const *GetName( void ) const;
|
||||
|
||||
// Return help text for cvar
|
||||
virtual char const *GetHelpText( void ) const;
|
||||
|
||||
// Deal with next pointer
|
||||
const ConCommandBase *GetNext( void ) const;
|
||||
void SetNext( ConCommandBase *next );
|
||||
|
||||
virtual bool IsRegistered( void ) const;
|
||||
|
||||
// Global methods
|
||||
static ConCommandBase const *GetCommands( void );
|
||||
static void AddToList( ConCommandBase *var );
|
||||
static void RemoveFlaggedCommands( int flag );
|
||||
static void RevertFlaggedCvars( int flag );
|
||||
static ConCommandBase const *FindCommand( char const *name );
|
||||
|
||||
protected:
|
||||
virtual void Create( char const *pName, char const *pHelpString = 0,
|
||||
int flags = 0 );
|
||||
|
||||
// Used internally by OneTimeInit to initialize.
|
||||
virtual void Init();
|
||||
|
||||
// Internal copy routine ( uses new operator from correct module )
|
||||
char *CopyString( char const *from );
|
||||
|
||||
// Next ConVar in chain
|
||||
ConCommandBase *m_pNext;
|
||||
|
||||
private:
|
||||
// Has the cvar been added to the global list?
|
||||
bool m_bRegistered;
|
||||
|
||||
// Static data
|
||||
char const *m_pszName;
|
||||
char const *m_pszHelpString;
|
||||
|
||||
// ConVar flags
|
||||
int m_nFlags;
|
||||
|
||||
protected:
|
||||
|
||||
// ConVars add themselves to this list for the executable. Then ConVarMgr::Init() runs through
|
||||
// all the console variables and registers them.
|
||||
static ConCommandBase *s_pConCommandBases;
|
||||
|
||||
// ConVars in this executable use this 'global' to access values.
|
||||
static IConCommandBaseAccessor *s_pAccessor;
|
||||
|
||||
public: // Hackalicous
|
||||
inline int GetFlags() const
|
||||
{
|
||||
return m_nFlags;
|
||||
}
|
||||
inline void SetFlags(int flags)
|
||||
{
|
||||
m_nFlags = flags;
|
||||
}
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: The console invoked command
|
||||
//-----------------------------------------------------------------------------
|
||||
class ConCommand : public ConCommandBase
|
||||
{
|
||||
friend class ConCommandBaseMgr;
|
||||
friend class CCvar;
|
||||
#ifdef _STATIC_LINKED
|
||||
friend class G_ConCommand;
|
||||
friend class C_ConCommand;
|
||||
friend class M_ConCommand;
|
||||
friend class S_ConCommand;
|
||||
friend class D_ConCommand;
|
||||
#endif
|
||||
|
||||
public:
|
||||
typedef ConCommandBase BaseClass;
|
||||
|
||||
ConCommand( void );
|
||||
ConCommand( char const *pName, FnCommandCallback callback,
|
||||
char const *pHelpString = 0, int flags = 0, FnCommandCompletionCallback completionFunc = 0 );
|
||||
|
||||
virtual ~ConCommand( void );
|
||||
|
||||
virtual bool IsCommand( void ) const;
|
||||
|
||||
virtual int AutoCompleteSuggest( char const *partial, char commands[ COMMAND_COMPLETION_MAXITEMS ][ COMMAND_COMPLETION_ITEM_LENGTH ] );
|
||||
|
||||
virtual bool CanAutoComplete( void );
|
||||
|
||||
// Invoke the function
|
||||
virtual void Dispatch( void );
|
||||
private:
|
||||
virtual void Create( char const *pName, FnCommandCallback callback,
|
||||
char const *pHelpString = 0, int flags = 0, FnCommandCompletionCallback completionFunc = 0 );
|
||||
|
||||
// Call this function when executing the command
|
||||
FnCommandCallback m_fnCommandCallback;
|
||||
|
||||
FnCommandCompletionCallback m_fnCompletionCallback;
|
||||
bool m_bHasCompletionCallback;
|
||||
public: // Hackalicous
|
||||
inline FnCommandCallback GetCallback() const
|
||||
{
|
||||
return m_fnCommandCallback;
|
||||
}
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: A console variable
|
||||
//-----------------------------------------------------------------------------
|
||||
class ConVar : public ConCommandBase
|
||||
{
|
||||
friend class ConCommandBaseMgr;
|
||||
friend class CCvar;
|
||||
friend class CDefaultCvar;
|
||||
#ifdef _STATIC_LINKED
|
||||
friend class G_ConVar;
|
||||
friend class C_ConVar;
|
||||
friend class M_ConVar;
|
||||
friend class S_ConVar;
|
||||
friend class D_ConVar;
|
||||
#endif
|
||||
|
||||
public:
|
||||
typedef ConCommandBase BaseClass;
|
||||
|
||||
ConVar( char const *pName, char const *pDefaultValue, int flags = 0);
|
||||
|
||||
ConVar( char const *pName, char const *pDefaultValue, int flags,
|
||||
char const *pHelpString );
|
||||
ConVar( char const *pName, char const *pDefaultValue, int flags,
|
||||
char const *pHelpString, bool bMin, float fMin, bool bMax, float fMax );
|
||||
ConVar( char const *pName, char const *pDefaultValue, int flags,
|
||||
char const *pHelpString, FnChangeCallback callback );
|
||||
ConVar( char const *pName, char const *pDefaultValue, int flags,
|
||||
char const *pHelpString, bool bMin, float fMin, bool bMax, float fMax,
|
||||
FnChangeCallback callback );
|
||||
|
||||
virtual ~ConVar( void );
|
||||
|
||||
virtual bool IsBitSet( int flag ) const;
|
||||
virtual char const* GetHelpText( void ) const;
|
||||
virtual bool IsRegistered( void ) const;
|
||||
virtual char const *GetName( void ) const;
|
||||
virtual void AddFlags( int flags );
|
||||
virtual bool IsCommand( void ) const;
|
||||
|
||||
// Install a change callback (there shouldn't already be one....)
|
||||
void InstallChangeCallback( FnChangeCallback callback );
|
||||
|
||||
// Retrieve value
|
||||
FORCEINLINE_CVAR float GetFloat( void ) const;
|
||||
FORCEINLINE_CVAR int GetInt( void ) const;
|
||||
FORCEINLINE_CVAR bool GetBool() const { return !!GetInt(); }
|
||||
FORCEINLINE_CVAR char const *GetString( void ) const;
|
||||
|
||||
// Any function that allocates/frees memory needs to be virtual or else you'll have crashes
|
||||
// from alloc/free across dll/exe boundaries.
|
||||
|
||||
// These just call into the IConCommandBaseAccessor to check flags and set the var (which ends up calling InternalSetValue).
|
||||
virtual void SetValue( char const *value );
|
||||
virtual void SetValue( float value );
|
||||
virtual void SetValue( int value );
|
||||
|
||||
// Reset to default value
|
||||
void Revert( void );
|
||||
|
||||
// True if it has a min/max setting
|
||||
bool GetMin( float& minVal ) const;
|
||||
bool GetMax( float& maxVal ) const;
|
||||
char const *GetDefault( void ) const;
|
||||
|
||||
static void RevertAll( void );
|
||||
private:
|
||||
// Called by CCvar when the value of a var is changing.
|
||||
virtual void InternalSetValue(char const *value);
|
||||
// For CVARs marked FCVAR_NEVER_AS_STRING
|
||||
virtual void InternalSetFloatValue( float fNewValue );
|
||||
virtual void InternalSetIntValue( int nValue );
|
||||
|
||||
virtual bool ClampValue( float& value );
|
||||
virtual void ChangeStringValue( char const *tempVal );
|
||||
|
||||
virtual void Create( char const *pName, char const *pDefaultValue, int flags = 0,
|
||||
char const *pHelpString = 0, bool bMin = false, float fMin = 0.0,
|
||||
bool bMax = false, float fMax = false, FnChangeCallback callback = 0 );
|
||||
|
||||
// Used internally by OneTimeInit to initialize.
|
||||
virtual void Init();
|
||||
|
||||
private:
|
||||
|
||||
// This either points to "this" or it points to the original declaration of a ConVar.
|
||||
// This allows ConVars to exist in separate modules, and they all use the first one to be declared.
|
||||
// m_pParent->m_pParent must equal m_pParent (ie: m_pParent must be the root, or original, ConVar).
|
||||
ConVar *m_pParent;
|
||||
|
||||
// Static data
|
||||
char const *m_pszDefaultValue;
|
||||
|
||||
// Value
|
||||
// Dynamically allocated
|
||||
char *m_pszString;
|
||||
int m_StringLength;
|
||||
|
||||
// Values
|
||||
float m_fValue;
|
||||
int m_nValue;
|
||||
|
||||
// Min/Max values
|
||||
bool m_bHasMin;
|
||||
float m_fMinVal;
|
||||
bool m_bHasMax;
|
||||
float m_fMaxVal;
|
||||
|
||||
// Call this function when ConVar changes
|
||||
FnChangeCallback m_fnChangeCallback;
|
||||
public: // Hackalicous
|
||||
inline FnChangeCallback GetCallback() const
|
||||
{
|
||||
return m_fnChangeCallback;
|
||||
}
|
||||
inline void SetMin(bool set, float min=0.0)
|
||||
{
|
||||
m_bHasMin = set;
|
||||
m_fMinVal = min;
|
||||
}
|
||||
inline void SetMax(bool set, float max=0.0)
|
||||
{
|
||||
m_bHasMax = set;
|
||||
m_fMaxVal = max;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Return ConVar value as a float
|
||||
// Output : float
|
||||
//-----------------------------------------------------------------------------
|
||||
FORCEINLINE_CVAR float ConVar::GetFloat( void ) const
|
||||
{
|
||||
return m_pParent->m_fValue;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Return ConVar value as an int
|
||||
// Output : int
|
||||
//-----------------------------------------------------------------------------
|
||||
FORCEINLINE_CVAR int ConVar::GetInt( void ) const
|
||||
{
|
||||
return m_pParent->m_nValue;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Return ConVar value as a string, return "" for bogus string pointer, etc.
|
||||
// Output : char const *
|
||||
//-----------------------------------------------------------------------------
|
||||
FORCEINLINE_CVAR char const *ConVar::GetString( void ) const
|
||||
{
|
||||
if ( m_nFlags & FCVAR_NEVER_AS_STRING )
|
||||
{
|
||||
return "FCVAR_NEVER_AS_STRING";
|
||||
}
|
||||
|
||||
return ( m_pParent->m_pszString ) ? m_pParent->m_pszString : "";
|
||||
}
|
||||
|
||||
|
||||
#ifdef _STATIC_LINKED
|
||||
// identifies subsystem via piggybacking constructors with flags
|
||||
class G_ConCommand : public ConCommand
|
||||
{
|
||||
public:
|
||||
G_ConCommand(char const *pName, FnCommandCallback callback, char const *pHelpString = 0, int flags = 0, FnCommandCompletionCallback completionFunc = 0 ) : ConCommand(pName, callback, pHelpString, flags|FCVAR_GAMEDLL, completionFunc) {}
|
||||
};
|
||||
|
||||
class C_ConCommand : public ConCommand
|
||||
{
|
||||
public:
|
||||
C_ConCommand(char const *pName, FnCommandCallback callback, char const *pHelpString = 0, int flags = 0, FnCommandCompletionCallback completionFunc = 0 ) : ConCommand(pName, callback, pHelpString, flags|FCVAR_CLIENTDLL, completionFunc) {}
|
||||
};
|
||||
|
||||
class M_ConCommand : public ConCommand
|
||||
{
|
||||
public:
|
||||
M_ConCommand(char const *pName, FnCommandCallback callback, char const *pHelpString = 0, int flags = 0, FnCommandCompletionCallback completionFunc = 0 ) : ConCommand(pName, callback, pHelpString, flags|FCVAR_MATERIAL_SYSTEM, completionFunc) {}
|
||||
};
|
||||
|
||||
class S_ConCommand : public ConCommand
|
||||
{
|
||||
public:
|
||||
S_ConCommand(char const *pName, FnCommandCallback callback, char const *pHelpString = 0, int flags = 0, FnCommandCompletionCallback completionFunc = 0 ) : ConCommand(pName, callback, pHelpString, flags|FCVAR_STUDIORENDER, completionFunc) {}
|
||||
};
|
||||
|
||||
class D_ConCommand : public ConCommand
|
||||
{
|
||||
public:
|
||||
D_ConCommand(char const *pName, FnCommandCallback callback, char const *pHelpString = 0, int flags = 0, FnCommandCompletionCallback completionFunc = 0 ) : ConCommand(pName, callback, pHelpString, flags|FCVAR_DATACACHE, completionFunc) {}
|
||||
};
|
||||
|
||||
typedef void ( *G_FnChangeCallback )( G_ConVar *var, char const *pOldString );
|
||||
typedef void ( *C_FnChangeCallback )( C_ConVar *var, char const *pOldString );
|
||||
typedef void ( *M_FnChangeCallback )( M_ConVar *var, char const *pOldString );
|
||||
typedef void ( *S_FnChangeCallback )( S_ConVar *var, char const *pOldString );
|
||||
typedef void ( *D_FnChangeCallback )( D_ConVar *var, char const *pOldString );
|
||||
|
||||
class G_ConVar : public ConVar
|
||||
{
|
||||
public:
|
||||
G_ConVar( char const *pName, char const *pDefaultValue, int flags = 0) : ConVar(pName, pDefaultValue, flags|FCVAR_GAMEDLL) {}
|
||||
G_ConVar( char const *pName, char const *pDefaultValue, int flags, char const *pHelpString ) : ConVar(pName, pDefaultValue, flags|FCVAR_GAMEDLL, pHelpString ) {}
|
||||
G_ConVar( char const *pName, char const *pDefaultValue, int flags, char const *pHelpString, bool bMin, float fMin, bool bMax, float fMax ) : ConVar(pName, pDefaultValue, flags|FCVAR_GAMEDLL, pHelpString, bMin, fMin, bMax, fMax) {}
|
||||
G_ConVar( char const *pName, char const *pDefaultValue, int flags, char const *pHelpString, G_FnChangeCallback callback ) : ConVar(pName, pDefaultValue, flags|FCVAR_GAMEDLL, pHelpString, (FnChangeCallback)callback ) {}
|
||||
G_ConVar( char const *pName, char const *pDefaultValue, int flags, char const *pHelpString, bool bMin, float fMin, bool bMax, float fMax, G_FnChangeCallback callback ) : ConVar(pName, pDefaultValue, flags|FCVAR_GAMEDLL, pHelpString, bMin, fMin, bMax, fMax, (FnChangeCallback)callback ) {}
|
||||
};
|
||||
|
||||
class C_ConVar : public ConVar
|
||||
{
|
||||
public:
|
||||
C_ConVar( char const *pName, char const *pDefaultValue, int flags = 0) : ConVar(pName, pDefaultValue, flags|FCVAR_CLIENTDLL) {}
|
||||
C_ConVar( char const *pName, char const *pDefaultValue, int flags, char const *pHelpString ) : ConVar(pName, pDefaultValue, flags|FCVAR_CLIENTDLL, pHelpString ) {}
|
||||
C_ConVar( char const *pName, char const *pDefaultValue, int flags, char const *pHelpString, bool bMin, float fMin, bool bMax, float fMax ) : ConVar(pName, pDefaultValue, flags|FCVAR_CLIENTDLL, pHelpString, bMin, fMin, bMax, fMax) {}
|
||||
C_ConVar( char const *pName, char const *pDefaultValue, int flags, char const *pHelpString, C_FnChangeCallback callback ) : ConVar(pName, pDefaultValue, flags|FCVAR_CLIENTDLL, pHelpString, (FnChangeCallback)callback ) {}
|
||||
C_ConVar( char const *pName, char const *pDefaultValue, int flags, char const *pHelpString, bool bMin, float fMin, bool bMax, float fMax, C_FnChangeCallback callback ) : ConVar(pName, pDefaultValue, flags|FCVAR_CLIENTDLL, pHelpString, bMin, fMin, bMax, fMax, (FnChangeCallback)callback ) {}
|
||||
};
|
||||
|
||||
class M_ConVar : public ConVar
|
||||
{
|
||||
public:
|
||||
M_ConVar( char const *pName, char const *pDefaultValue, int flags = 0) : ConVar(pName, pDefaultValue, flags|FCVAR_MATERIAL_SYSTEM) {}
|
||||
M_ConVar( char const *pName, char const *pDefaultValue, int flags, char const *pHelpString ) : ConVar(pName, pDefaultValue, flags|FCVAR_MATERIAL_SYSTEM, pHelpString ) {}
|
||||
M_ConVar( char const *pName, char const *pDefaultValue, int flags, char const *pHelpString, bool bMin, float fMin, bool bMax, float fMax ) : ConVar(pName, pDefaultValue, flags|FCVAR_MATERIAL_SYSTEM, pHelpString, bMin, fMin, bMax, fMax) {}
|
||||
M_ConVar( char const *pName, char const *pDefaultValue, int flags, char const *pHelpString, M_FnChangeCallback callback ) : ConVar(pName, pDefaultValue, flags|FCVAR_MATERIAL_SYSTEM, pHelpString, (FnChangeCallback)callback ) {}
|
||||
M_ConVar( char const *pName, char const *pDefaultValue, int flags, char const *pHelpString, bool bMin, float fMin, bool bMax, float fMax, M_FnChangeCallback callback ) : ConVar(pName, pDefaultValue, flags|FCVAR_MATERIAL_SYSTEM, pHelpString, bMin, fMin, bMax, fMax, (FnChangeCallback)callback ) {}
|
||||
};
|
||||
|
||||
class S_ConVar : public ConVar
|
||||
{
|
||||
public:
|
||||
S_ConVar( char const *pName, char const *pDefaultValue, int flags = 0) : ConVar(pName, pDefaultValue, flags|FCVAR_STUDIORENDER) {}
|
||||
S_ConVar( char const *pName, char const *pDefaultValue, int flags, char const *pHelpString ) : ConVar(pName, pDefaultValue, flags|FCVAR_STUDIORENDER, pHelpString ) {}
|
||||
S_ConVar( char const *pName, char const *pDefaultValue, int flags, char const *pHelpString, bool bMin, float fMin, bool bMax, float fMax ) : ConVar(pName, pDefaultValue, flags|FCVAR_STUDIORENDER, pHelpString, bMin, fMin, bMax, fMax) {}
|
||||
S_ConVar( char const *pName, char const *pDefaultValue, int flags, char const *pHelpString, M_FnChangeCallback callback ) : ConVar(pName, pDefaultValue, flags|FCVAR_STUDIORENDER, pHelpString, (FnChangeCallback)callback ) {}
|
||||
S_ConVar( char const *pName, char const *pDefaultValue, int flags, char const *pHelpString, bool bMin, float fMin, bool bMax, float fMax, S_FnChangeCallback callback ) : ConVar(pName, pDefaultValue, flags|FCVAR_STUDIORENDER, pHelpString, bMin, fMin, bMax, fMax, (FnChangeCallback)callback ) {}
|
||||
};
|
||||
|
||||
class D_ConVar : public ConVar
|
||||
{
|
||||
public:
|
||||
D_ConVar( char const *pName, char const *pDefaultValue, int flags = 0) : ConVar(pName, pDefaultValue, flags|FCVAR_DATACACHE) {}
|
||||
D_ConVar( char const *pName, char const *pDefaultValue, int flags, char const *pHelpString ) : ConVar(pName, pDefaultValue, flags|FCVAR_DATACACHE, pHelpString ) {}
|
||||
D_ConVar( char const *pName, char const *pDefaultValue, int flags, char const *pHelpString, bool bMin, float fMin, bool bMax, float fMax ) : ConVar(pName, pDefaultValue, flags|FCVAR_DATACACHE, pHelpString, bMin, fMin, bMax, fMax) {}
|
||||
D_ConVar( char const *pName, char const *pDefaultValue, int flags, char const *pHelpString, M_FnChangeCallback callback ) : ConVar(pName, pDefaultValue, flags|FCVAR_DATACACHE, pHelpString, (FnChangeCallback)callback ) {}
|
||||
D_ConVar( char const *pName, char const *pDefaultValue, int flags, char const *pHelpString, bool bMin, float fMin, bool bMax, float fMax, D_FnChangeCallback callback ) : ConVar(pName, pDefaultValue, flags|FCVAR_DATACACHE, pHelpString, bMin, fMin, bMax, fMax, (FnChangeCallback)callback ) {}
|
||||
};
|
||||
|
||||
// redirect these declarations to their specific subsystem
|
||||
#ifdef GAME_DLL
|
||||
#define ConCommand G_ConCommand
|
||||
#define ConVar G_ConVar
|
||||
#endif
|
||||
#ifdef CLIENT_DLL
|
||||
#define ConCommand C_ConCommand
|
||||
#define ConVar C_ConVar
|
||||
#endif
|
||||
#ifdef MATERIALSYSTEM_DLL
|
||||
#define ConCommand M_ConCommand
|
||||
#define ConVar M_ConVar
|
||||
#endif
|
||||
#ifdef STUDIORENDER_DLL
|
||||
#define ConCommand S_ConCommand
|
||||
#define ConVar S_ConVar
|
||||
#endif
|
||||
#ifdef DATACACHE_DLL
|
||||
#define ConCommand D_ConCommand
|
||||
#define ConVar D_ConVar
|
||||
#endif
|
||||
#endif // _STATIC_LINKED
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Utility to quicky generate a simple console command
|
||||
//-----------------------------------------------------------------------------
|
||||
#define CON_COMMAND( name, description ) \
|
||||
static void name(); \
|
||||
static ConCommand name##_command( #name, name, description ); \
|
||||
static void name()
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Utility to quicky generate a simple console command
|
||||
//-----------------------------------------------------------------------------
|
||||
#define CON_COMMAND_F( name, description, flags ) \
|
||||
static void name(); \
|
||||
static ConCommand name##_command( #name, name, description, flags ); \
|
||||
static void name()
|
||||
|
||||
|
||||
#endif // CONVAR_H
|
@ -1,718 +0,0 @@
|
||||
//===== Copyright © 1996-2005, Valve Corporation, All rights reserved. ======//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $Workfile: $
|
||||
// $Date: $
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// $NoKeywords: $
|
||||
//===========================================================================//
|
||||
|
||||
#ifndef CONVAR_H
|
||||
#define CONVAR_H
|
||||
|
||||
#if _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "tier0/dbg.h"
|
||||
#include "tier1/iconvar.h"
|
||||
#include "tier1/utlvector.h"
|
||||
#include "tier1/utlstring.h"
|
||||
#include "icvar.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#define FORCEINLINE_CVAR FORCEINLINE
|
||||
#elif defined _LINUX || defined __APPLE__
|
||||
#define FORCEINLINE_CVAR inline
|
||||
#else
|
||||
#error "implement me"
|
||||
#endif
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Forward declarations
|
||||
//-----------------------------------------------------------------------------
|
||||
class ConVar;
|
||||
class CCommand;
|
||||
class ConCommand;
|
||||
class ConCommandBase;
|
||||
struct characterset_t;
|
||||
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Any executable that wants to use ConVars need to implement one of
|
||||
// these to hook up access to console variables.
|
||||
//-----------------------------------------------------------------------------
|
||||
class IConCommandBaseAccessor
|
||||
{
|
||||
public:
|
||||
// Flags is a combination of FCVAR flags in cvar.h.
|
||||
// hOut is filled in with a handle to the variable.
|
||||
virtual bool RegisterConCommandBase( ConCommandBase *pVar ) = 0;
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Helper method for console development
|
||||
//-----------------------------------------------------------------------------
|
||||
#if defined( _X360 ) && !defined( _RETAIL )
|
||||
void ConVar_PublishToVXConsole();
|
||||
#endif
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Called when a ConCommand needs to execute
|
||||
//-----------------------------------------------------------------------------
|
||||
typedef void ( *FnCommandCallbackV1_t )( void );
|
||||
typedef void ( *FnCommandCallback_t )( const CCommand &command );
|
||||
|
||||
#define COMMAND_COMPLETION_MAXITEMS 64
|
||||
#define COMMAND_COMPLETION_ITEM_LENGTH 64
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Returns 0 to COMMAND_COMPLETION_MAXITEMS worth of completion strings
|
||||
//-----------------------------------------------------------------------------
|
||||
typedef int ( *FnCommandCompletionCallback )( const char *partial, char commands[ COMMAND_COMPLETION_MAXITEMS ][ COMMAND_COMPLETION_ITEM_LENGTH ] );
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Interface version
|
||||
//-----------------------------------------------------------------------------
|
||||
class ICommandCallback
|
||||
{
|
||||
public:
|
||||
virtual void CommandCallback( const CCommand &command ) = 0;
|
||||
};
|
||||
|
||||
class ICommandCompletionCallback
|
||||
{
|
||||
public:
|
||||
virtual int CommandCompletionCallback( const char *pPartial, CUtlVector< CUtlString > &commands ) = 0;
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: The base console invoked command/cvar interface
|
||||
//-----------------------------------------------------------------------------
|
||||
class ConCommandBase
|
||||
{
|
||||
friend class CCvar;
|
||||
friend class ConVar;
|
||||
friend class ConCommand;
|
||||
friend void ConVar_Register( int nCVarFlag, IConCommandBaseAccessor *pAccessor );
|
||||
friend void ConVar_PublishToVXConsole();
|
||||
|
||||
// FIXME: Remove when ConVar changes are done
|
||||
friend class CDefaultCvar;
|
||||
|
||||
public:
|
||||
ConCommandBase( void );
|
||||
ConCommandBase( const char *pName, const char *pHelpString = 0,
|
||||
int flags = 0 );
|
||||
|
||||
virtual ~ConCommandBase( void );
|
||||
|
||||
virtual bool IsCommand( void ) const;
|
||||
|
||||
// Check flag
|
||||
virtual bool IsFlagSet( int flag ) const;
|
||||
// Set flag
|
||||
virtual void AddFlags( int flags );
|
||||
// Remove flag
|
||||
virtual void RemoveFlags( int flags );
|
||||
// Get flags
|
||||
virtual int GetFlags( void ) const;
|
||||
|
||||
// Return name of cvar
|
||||
virtual const char *GetName( void ) const;
|
||||
|
||||
// Return help text for cvar
|
||||
virtual const char *GetHelpText( void ) const;
|
||||
|
||||
// Deal with next pointer
|
||||
const ConCommandBase *GetNext( void ) const;
|
||||
ConCommandBase *GetNext( void );
|
||||
|
||||
inline void SetNext(ConCommandBase *pBase)
|
||||
{
|
||||
m_pNext = pBase;
|
||||
}
|
||||
|
||||
virtual bool IsRegistered( void ) const;
|
||||
|
||||
// Returns the DLL identifier
|
||||
virtual CVarDLLIdentifier_t GetDLLIdentifier() const;
|
||||
|
||||
protected:
|
||||
virtual void Create( const char *pName, const char *pHelpString = 0,
|
||||
int flags = 0 );
|
||||
|
||||
// Used internally by OneTimeInit to initialize/shutdown
|
||||
virtual void Init();
|
||||
void Shutdown();
|
||||
|
||||
// Internal copy routine ( uses new operator from correct module )
|
||||
char *CopyString( const char *from );
|
||||
|
||||
private:
|
||||
// Next ConVar in chain
|
||||
// Prior to register, it points to the next convar in the DLL.
|
||||
// Once registered, though, m_pNext is reset to point to the next
|
||||
// convar in the global list
|
||||
ConCommandBase *m_pNext;
|
||||
|
||||
// Has the cvar been added to the global list?
|
||||
bool m_bRegistered;
|
||||
|
||||
// Static data
|
||||
const char *m_pszName;
|
||||
const char *m_pszHelpString;
|
||||
|
||||
// ConVar flags
|
||||
int m_nFlags;
|
||||
|
||||
protected:
|
||||
// ConVars add themselves to this list for the executable.
|
||||
// Then ConVar_Register runs through all the console variables
|
||||
// and registers them into a global list stored in vstdlib.dll
|
||||
static ConCommandBase *s_pConCommandBases;
|
||||
|
||||
// ConVars in this executable use this 'global' to access values.
|
||||
static IConCommandBaseAccessor *s_pAccessor;
|
||||
public:
|
||||
inline void SetFlags(int flags)
|
||||
{
|
||||
m_nFlags = flags;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Command tokenizer
|
||||
//-----------------------------------------------------------------------------
|
||||
class CCommand
|
||||
{
|
||||
public:
|
||||
CCommand();
|
||||
CCommand( int nArgC, const char **ppArgV );
|
||||
bool Tokenize( const char *pCommand, characterset_t *pBreakSet = NULL );
|
||||
void Reset();
|
||||
|
||||
int ArgC() const;
|
||||
const char **ArgV() const;
|
||||
const char *ArgS() const; // All args that occur after the 0th arg, in string form
|
||||
const char *GetCommandString() const; // The entire command in string form, including the 0th arg
|
||||
const char *operator[]( int nIndex ) const; // Gets at arguments
|
||||
const char *Arg( int nIndex ) const; // Gets at arguments
|
||||
|
||||
// Helper functions to parse arguments to commands.
|
||||
const char* FindArg( const char *pName ) const;
|
||||
int FindArgInt( const char *pName, int nDefaultVal ) const;
|
||||
|
||||
static int MaxCommandLength();
|
||||
static characterset_t* DefaultBreakSet();
|
||||
|
||||
private:
|
||||
enum
|
||||
{
|
||||
COMMAND_MAX_ARGC = 64,
|
||||
COMMAND_MAX_LENGTH = 512,
|
||||
};
|
||||
|
||||
int m_nArgc;
|
||||
int m_nArgv0Size;
|
||||
char m_pArgSBuffer[ COMMAND_MAX_LENGTH ];
|
||||
char m_pArgvBuffer[ COMMAND_MAX_LENGTH ];
|
||||
const char* m_ppArgv[ COMMAND_MAX_ARGC ];
|
||||
};
|
||||
|
||||
inline int CCommand::MaxCommandLength()
|
||||
{
|
||||
return COMMAND_MAX_LENGTH - 1;
|
||||
}
|
||||
|
||||
inline int CCommand::ArgC() const
|
||||
{
|
||||
return m_nArgc;
|
||||
}
|
||||
|
||||
inline const char **CCommand::ArgV() const
|
||||
{
|
||||
return m_nArgc ? (const char**)m_ppArgv : NULL;
|
||||
}
|
||||
|
||||
inline const char *CCommand::ArgS() const
|
||||
{
|
||||
return m_nArgv0Size ? &m_pArgSBuffer[m_nArgv0Size] : "";
|
||||
}
|
||||
|
||||
inline const char *CCommand::GetCommandString() const
|
||||
{
|
||||
return m_nArgc ? m_pArgSBuffer : "";
|
||||
}
|
||||
|
||||
inline const char *CCommand::Arg( int nIndex ) const
|
||||
{
|
||||
// FIXME: Many command handlers appear to not be particularly careful
|
||||
// about checking for valid argc range. For now, we're going to
|
||||
// do the extra check and return an empty string if it's out of range
|
||||
if ( nIndex < 0 || nIndex >= m_nArgc )
|
||||
return "";
|
||||
return m_ppArgv[nIndex];
|
||||
}
|
||||
|
||||
inline const char *CCommand::operator[]( int nIndex ) const
|
||||
{
|
||||
return Arg( nIndex );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: The console invoked command
|
||||
//-----------------------------------------------------------------------------
|
||||
class ConCommand : public ConCommandBase
|
||||
{
|
||||
friend class CCvar;
|
||||
|
||||
public:
|
||||
typedef ConCommandBase BaseClass;
|
||||
|
||||
ConCommand( const char *pName, FnCommandCallbackV1_t callback,
|
||||
const char *pHelpString = 0, int flags = 0, FnCommandCompletionCallback completionFunc = 0 );
|
||||
ConCommand( const char *pName, FnCommandCallback_t callback,
|
||||
const char *pHelpString = 0, int flags = 0, FnCommandCompletionCallback completionFunc = 0 );
|
||||
ConCommand( const char *pName, ICommandCallback *pCallback,
|
||||
const char *pHelpString = 0, int flags = 0, ICommandCompletionCallback *pCommandCompletionCallback = 0 );
|
||||
|
||||
virtual ~ConCommand( void );
|
||||
|
||||
virtual bool IsCommand( void ) const;
|
||||
|
||||
virtual int AutoCompleteSuggest( const char *partial, CUtlVector< CUtlString > &commands );
|
||||
|
||||
virtual bool CanAutoComplete( void );
|
||||
|
||||
// Invoke the function
|
||||
virtual void Dispatch( const CCommand &command );
|
||||
|
||||
private:
|
||||
// NOTE: To maintain backward compat, we have to be very careful:
|
||||
// All public virtual methods must appear in the same order always
|
||||
// since engine code will be calling into this code, which *does not match*
|
||||
// in the mod code; it's using slightly different, but compatible versions
|
||||
// of this class. Also: Be very careful about adding new fields to this class.
|
||||
// Those fields will not exist in the version of this class that is instanced
|
||||
// in mod code.
|
||||
|
||||
// Call this function when executing the command
|
||||
union
|
||||
{
|
||||
FnCommandCallbackV1_t m_fnCommandCallbackV1;
|
||||
FnCommandCallback_t m_fnCommandCallback;
|
||||
ICommandCallback *m_pCommandCallback;
|
||||
};
|
||||
|
||||
union
|
||||
{
|
||||
FnCommandCompletionCallback m_fnCompletionCallback;
|
||||
ICommandCompletionCallback *m_pCommandCompletionCallback;
|
||||
};
|
||||
|
||||
bool m_bHasCompletionCallback : 1;
|
||||
bool m_bUsingNewCommandCallback : 1;
|
||||
bool m_bUsingCommandCallbackInterface : 1;
|
||||
public:
|
||||
inline FnCommandCallback_t GetCallback() const
|
||||
{
|
||||
return m_fnCommandCallback;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: A console variable
|
||||
//-----------------------------------------------------------------------------
|
||||
class ConVar : public ConCommandBase, public IConVar
|
||||
{
|
||||
friend class CCvar;
|
||||
friend class ConVarRef;
|
||||
|
||||
public:
|
||||
typedef ConCommandBase BaseClass;
|
||||
|
||||
ConVar( const char *pName, const char *pDefaultValue, int flags = 0);
|
||||
|
||||
ConVar( const char *pName, const char *pDefaultValue, int flags,
|
||||
const char *pHelpString );
|
||||
ConVar( const char *pName, const char *pDefaultValue, int flags,
|
||||
const char *pHelpString, bool bMin, float fMin, bool bMax, float fMax );
|
||||
ConVar( const char *pName, const char *pDefaultValue, int flags,
|
||||
const char *pHelpString, FnChangeCallback_t callback );
|
||||
ConVar( const char *pName, const char *pDefaultValue, int flags,
|
||||
const char *pHelpString, bool bMin, float fMin, bool bMax, float fMax,
|
||||
FnChangeCallback_t callback );
|
||||
|
||||
virtual ~ConVar( void );
|
||||
|
||||
virtual bool IsCommand( void ) const;
|
||||
virtual bool IsFlagSet( int flag ) const;
|
||||
virtual void AddFlags( int flags );
|
||||
virtual int GetFlags( void ) const;
|
||||
virtual const char *GetName( void ) const;
|
||||
virtual const char* GetHelpText( void ) const;
|
||||
virtual bool IsRegistered( void ) const;
|
||||
|
||||
// Install a change callback (there shouldn't already be one....)
|
||||
void InstallChangeCallback( FnChangeCallback_t callback );
|
||||
|
||||
// Retrieve value
|
||||
FORCEINLINE_CVAR float GetFloat( void ) const;
|
||||
FORCEINLINE_CVAR int GetInt( void ) const;
|
||||
FORCEINLINE_CVAR bool GetBool() const { return !!GetInt(); }
|
||||
FORCEINLINE_CVAR char const *GetString( void ) const;
|
||||
|
||||
// Used internally by OneTimeInit to initialize.
|
||||
virtual void Init();
|
||||
|
||||
virtual const char *GetBaseName( void ) const;
|
||||
virtual int GetSplitScreenPlayerSlot ( void ) const;
|
||||
|
||||
// Any function that allocates/frees memory needs to be virtual or else you'll have crashes
|
||||
// from alloc/free across dll/exe boundaries.
|
||||
|
||||
// These just call into the IConCommandBaseAccessor to check flags and set the var (which ends up calling InternalSetValue).
|
||||
virtual void SetValue( const char *value );
|
||||
virtual void SetValue( float value );
|
||||
virtual void SetValue( int value );
|
||||
#if SOURCE_ENGINE >= SE_NUCLEARDAWN
|
||||
virtual void SetValue( Color value );
|
||||
#endif
|
||||
|
||||
// Reset to default value
|
||||
void Revert( void );
|
||||
|
||||
// True if it has a min/max setting
|
||||
bool GetMin( float& minVal ) const;
|
||||
bool GetMax( float& maxVal ) const;
|
||||
const char *GetDefault( void ) const;
|
||||
|
||||
private:
|
||||
// Called by CCvar when the value of a var is changing.
|
||||
virtual void InternalSetValue(const char *value);
|
||||
// For CVARs marked FCVAR_NEVER_AS_STRING
|
||||
virtual void InternalSetFloatValue( float fNewValue );
|
||||
virtual void InternalSetIntValue( int nValue );
|
||||
#if SOURCE_ENGINE >= SE_LEFT4DEAD2
|
||||
virtual void InternalSetColorValue( Color value );
|
||||
#endif
|
||||
|
||||
virtual bool ClampValue( float& value );
|
||||
virtual void ChangeStringValue( const char *tempVal, float flOldValue );
|
||||
|
||||
virtual void Create( const char *pName, const char *pDefaultValue, int flags = 0,
|
||||
const char *pHelpString = 0, bool bMin = false, float fMin = 0.0,
|
||||
bool bMax = false, float fMax = false, FnChangeCallback_t callback = 0 );
|
||||
|
||||
private:
|
||||
|
||||
// This either points to "this" or it points to the original declaration of a ConVar.
|
||||
// This allows ConVars to exist in separate modules, and they all use the first one to be declared.
|
||||
// m_pParent->m_pParent must equal m_pParent (ie: m_pParent must be the root, or original, ConVar).
|
||||
ConVar *m_pParent;
|
||||
|
||||
// Static data
|
||||
const char *m_pszDefaultValue;
|
||||
|
||||
// Value
|
||||
// Dynamically allocated
|
||||
char *m_pszString;
|
||||
int m_StringLength;
|
||||
|
||||
// Values
|
||||
float m_fValue;
|
||||
int m_nValue;
|
||||
|
||||
// Min/Max values
|
||||
bool m_bHasMin;
|
||||
float m_fMinVal;
|
||||
bool m_bHasMax;
|
||||
float m_fMaxVal;
|
||||
|
||||
// Call this function when ConVar changes
|
||||
FnChangeCallback_t m_fnChangeCallback;
|
||||
public:
|
||||
inline FnChangeCallback_t GetCallback() const
|
||||
{
|
||||
return m_fnChangeCallback;
|
||||
}
|
||||
inline void SetMin(bool set, float min=0.0)
|
||||
{
|
||||
m_bHasMin = set;
|
||||
m_fMinVal = min;
|
||||
}
|
||||
inline void SetMax(bool set, float max=0.0)
|
||||
{
|
||||
m_bHasMax = set;
|
||||
m_fMaxVal = max;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Return ConVar value as a float
|
||||
// Output : float
|
||||
//-----------------------------------------------------------------------------
|
||||
FORCEINLINE_CVAR float ConVar::GetFloat( void ) const
|
||||
{
|
||||
return m_pParent->m_fValue;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Return ConVar value as an int
|
||||
// Output : int
|
||||
//-----------------------------------------------------------------------------
|
||||
FORCEINLINE_CVAR int ConVar::GetInt( void ) const
|
||||
{
|
||||
return m_pParent->m_nValue;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Return ConVar value as a string, return "" for bogus string pointer, etc.
|
||||
// Output : const char *
|
||||
//-----------------------------------------------------------------------------
|
||||
FORCEINLINE_CVAR const char *ConVar::GetString( void ) const
|
||||
{
|
||||
if ( m_nFlags & FCVAR_NEVER_AS_STRING )
|
||||
return "FCVAR_NEVER_AS_STRING";
|
||||
|
||||
return ( m_pParent->m_pszString ) ? m_pParent->m_pszString : "";
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Used to read/write convars that already exist (replaces the FindVar method)
|
||||
//-----------------------------------------------------------------------------
|
||||
class ConVarRef
|
||||
{
|
||||
public:
|
||||
ConVarRef( const char *pName );
|
||||
ConVarRef( const char *pName, bool bIgnoreMissing );
|
||||
ConVarRef( IConVar *pConVar );
|
||||
|
||||
void Init( const char *pName, bool bIgnoreMissing );
|
||||
bool IsValid() const;
|
||||
bool IsFlagSet( int nFlags ) const;
|
||||
IConVar *GetLinkedConVar();
|
||||
|
||||
// Get/Set value
|
||||
float GetFloat( void ) const;
|
||||
int GetInt( void ) const;
|
||||
bool GetBool() const { return !!GetInt(); }
|
||||
const char *GetString( void ) const;
|
||||
|
||||
void SetValue( const char *pValue );
|
||||
void SetValue( float flValue );
|
||||
void SetValue( int nValue );
|
||||
void SetValue( bool bValue );
|
||||
|
||||
const char *GetName() const;
|
||||
|
||||
const char *GetDefault() const;
|
||||
|
||||
private:
|
||||
// High-speed method to read convar data
|
||||
IConVar *m_pConVar;
|
||||
ConVar *m_pConVarState;
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Did we find an existing convar of that name?
|
||||
//-----------------------------------------------------------------------------
|
||||
FORCEINLINE_CVAR bool ConVarRef::IsFlagSet( int nFlags ) const
|
||||
{
|
||||
return ( m_pConVar->IsFlagSet( nFlags ) != 0 );
|
||||
}
|
||||
|
||||
FORCEINLINE_CVAR IConVar *ConVarRef::GetLinkedConVar()
|
||||
{
|
||||
return m_pConVar;
|
||||
}
|
||||
|
||||
FORCEINLINE_CVAR const char *ConVarRef::GetName() const
|
||||
{
|
||||
return m_pConVar->GetName();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Return ConVar value as a float
|
||||
//-----------------------------------------------------------------------------
|
||||
FORCEINLINE_CVAR float ConVarRef::GetFloat( void ) const
|
||||
{
|
||||
return m_pConVarState->m_fValue;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Return ConVar value as an int
|
||||
//-----------------------------------------------------------------------------
|
||||
FORCEINLINE_CVAR int ConVarRef::GetInt( void ) const
|
||||
{
|
||||
return m_pConVarState->m_nValue;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Return ConVar value as a string, return "" for bogus string pointer, etc.
|
||||
//-----------------------------------------------------------------------------
|
||||
FORCEINLINE_CVAR const char *ConVarRef::GetString( void ) const
|
||||
{
|
||||
Assert( !IsFlagSet( FCVAR_NEVER_AS_STRING ) );
|
||||
return m_pConVarState->m_pszString;
|
||||
}
|
||||
|
||||
|
||||
FORCEINLINE_CVAR void ConVarRef::SetValue( const char *pValue )
|
||||
{
|
||||
m_pConVar->SetValue( pValue );
|
||||
}
|
||||
|
||||
FORCEINLINE_CVAR void ConVarRef::SetValue( float flValue )
|
||||
{
|
||||
m_pConVar->SetValue( flValue );
|
||||
}
|
||||
|
||||
FORCEINLINE_CVAR void ConVarRef::SetValue( int nValue )
|
||||
{
|
||||
m_pConVar->SetValue( nValue );
|
||||
}
|
||||
|
||||
FORCEINLINE_CVAR void ConVarRef::SetValue( bool bValue )
|
||||
{
|
||||
m_pConVar->SetValue( bValue ? 1 : 0 );
|
||||
}
|
||||
|
||||
FORCEINLINE_CVAR const char *ConVarRef::GetDefault() const
|
||||
{
|
||||
return m_pConVarState->m_pszDefaultValue;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Called by the framework to register ConCommands with the ICVar
|
||||
//-----------------------------------------------------------------------------
|
||||
void ConVar_Register( int nCVarFlag = 0, IConCommandBaseAccessor *pAccessor = NULL );
|
||||
void ConVar_Unregister( );
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Utility methods
|
||||
//-----------------------------------------------------------------------------
|
||||
void ConVar_PrintFlags( const ConCommandBase *var );
|
||||
void ConVar_PrintDescription( const ConCommandBase *pVar );
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Utility class to quickly allow ConCommands to call member methods
|
||||
//-----------------------------------------------------------------------------
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning (disable : 4355 )
|
||||
#endif
|
||||
|
||||
template< class T >
|
||||
class CConCommandMemberAccessor : public ConCommand, public ICommandCallback, public ICommandCompletionCallback
|
||||
{
|
||||
typedef ConCommand BaseClass;
|
||||
typedef void ( T::*FnMemberCommandCallback_t )( const CCommand &command );
|
||||
typedef int ( T::*FnMemberCommandCompletionCallback_t )( const char *pPartial, CUtlVector< CUtlString > &commands );
|
||||
|
||||
public:
|
||||
CConCommandMemberAccessor( T* pOwner, const char *pName, FnMemberCommandCallback_t callback, const char *pHelpString = 0,
|
||||
int flags = 0, FnMemberCommandCompletionCallback_t completionFunc = 0 ) :
|
||||
BaseClass( pName, this, pHelpString, flags, ( completionFunc != 0 ) ? this : NULL )
|
||||
{
|
||||
m_pOwner = pOwner;
|
||||
m_Func = callback;
|
||||
m_CompletionFunc = completionFunc;
|
||||
}
|
||||
|
||||
~CConCommandMemberAccessor()
|
||||
{
|
||||
Shutdown();
|
||||
}
|
||||
|
||||
void SetOwner( T* pOwner )
|
||||
{
|
||||
m_pOwner = pOwner;
|
||||
}
|
||||
|
||||
virtual void CommandCallback( const CCommand &command )
|
||||
{
|
||||
Assert( m_pOwner && m_Func );
|
||||
(m_pOwner->*m_Func)( command );
|
||||
}
|
||||
|
||||
virtual int CommandCompletionCallback( const char *pPartial, CUtlVector< CUtlString > &commands )
|
||||
{
|
||||
Assert( m_pOwner && m_CompletionFunc );
|
||||
return (m_pOwner->*m_CompletionFunc)( pPartial, commands );
|
||||
}
|
||||
|
||||
private:
|
||||
T* m_pOwner;
|
||||
FnMemberCommandCallback_t m_Func;
|
||||
FnMemberCommandCompletionCallback_t m_CompletionFunc;
|
||||
};
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning ( default : 4355 )
|
||||
#endif
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Utility macros to quicky generate a simple console command
|
||||
//-----------------------------------------------------------------------------
|
||||
#define CON_COMMAND( name, description ) \
|
||||
static void name( const CCommand &args ); \
|
||||
static ConCommand name##_command( #name, name, description ); \
|
||||
static void name( const CCommand &args )
|
||||
|
||||
#define CON_COMMAND_F( name, description, flags ) \
|
||||
static void name( const CCommand &args ); \
|
||||
static ConCommand name##_command( #name, name, description, flags ); \
|
||||
static void name( const CCommand &args )
|
||||
|
||||
#define CON_COMMAND_F_COMPLETION( name, description, flags, completion ) \
|
||||
static void name( const CCommand &args ); \
|
||||
static ConCommand name##_command( #name, name, description, flags, completion ); \
|
||||
static void name( const CCommand &args )
|
||||
|
||||
#define CON_COMMAND_EXTERN( name, _funcname, description ) \
|
||||
void _funcname( const CCommand &args ); \
|
||||
static ConCommand name##_command( #name, _funcname, description ); \
|
||||
void _funcname( const CCommand &args )
|
||||
|
||||
#define CON_COMMAND_EXTERN_F( name, _funcname, description, flags ) \
|
||||
void _funcname( const CCommand &args ); \
|
||||
static ConCommand name##_command( #name, _funcname, description, flags ); \
|
||||
void _funcname( const CCommand &args )
|
||||
|
||||
#define CON_COMMAND_MEMBER_F( _thisclass, name, _funcname, description, flags ) \
|
||||
void _funcname( const CCommand &args ); \
|
||||
friend class CCommandMemberInitializer_##_funcname; \
|
||||
class CCommandMemberInitializer_##_funcname \
|
||||
{ \
|
||||
public: \
|
||||
CCommandMemberInitializer_##_funcname() : m_ConCommandAccessor( NULL, name, &_thisclass::_funcname, description, flags ) \
|
||||
{ \
|
||||
m_ConCommandAccessor.SetOwner( GET_OUTER( _thisclass, m_##_funcname##_register ) ); \
|
||||
} \
|
||||
private: \
|
||||
CConCommandMemberAccessor< _thisclass > m_ConCommandAccessor; \
|
||||
}; \
|
||||
\
|
||||
CCommandMemberInitializer_##_funcname m_##_funcname##_register; \
|
||||
|
||||
|
||||
#endif // CONVAR_H
|
@ -1,709 +0,0 @@
|
||||
//===== Copyright © 1996-2005, Valve Corporation, All rights reserved. ======//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $Workfile: $
|
||||
// $Date: $
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// $NoKeywords: $
|
||||
//===========================================================================//
|
||||
|
||||
#ifndef CONVAR_H
|
||||
#define CONVAR_H
|
||||
|
||||
#if _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "tier0/dbg.h"
|
||||
#include "tier1/iconvar.h"
|
||||
#include "tier1/utlvector.h"
|
||||
#include "tier1/utlstring.h"
|
||||
#include "icvar.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#define FORCEINLINE_CVAR FORCEINLINE
|
||||
#elif defined _LINUX || defined __APPLE__
|
||||
#define FORCEINLINE_CVAR inline
|
||||
#else
|
||||
#error "implement me"
|
||||
#endif
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Forward declarations
|
||||
//-----------------------------------------------------------------------------
|
||||
class ConVar;
|
||||
class CCommand;
|
||||
class ConCommand;
|
||||
class ConCommandBase;
|
||||
struct characterset_t;
|
||||
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Any executable that wants to use ConVars need to implement one of
|
||||
// these to hook up access to console variables.
|
||||
//-----------------------------------------------------------------------------
|
||||
class IConCommandBaseAccessor
|
||||
{
|
||||
public:
|
||||
// Flags is a combination of FCVAR flags in cvar.h.
|
||||
// hOut is filled in with a handle to the variable.
|
||||
virtual bool RegisterConCommandBase( ConCommandBase *pVar ) = 0;
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Helper method for console development
|
||||
//-----------------------------------------------------------------------------
|
||||
#if defined( _X360 ) && !defined( _RETAIL )
|
||||
void ConVar_PublishToVXConsole();
|
||||
#endif
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Called when a ConCommand needs to execute
|
||||
//-----------------------------------------------------------------------------
|
||||
typedef void ( *FnCommandCallbackV1_t )( void );
|
||||
typedef void ( *FnCommandCallback_t )( const CCommand &command );
|
||||
|
||||
#define COMMAND_COMPLETION_MAXITEMS 64
|
||||
#define COMMAND_COMPLETION_ITEM_LENGTH 64
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Returns 0 to COMMAND_COMPLETION_MAXITEMS worth of completion strings
|
||||
//-----------------------------------------------------------------------------
|
||||
typedef int ( *FnCommandCompletionCallback )( const char *partial, char commands[ COMMAND_COMPLETION_MAXITEMS ][ COMMAND_COMPLETION_ITEM_LENGTH ] );
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Interface version
|
||||
//-----------------------------------------------------------------------------
|
||||
class ICommandCallback
|
||||
{
|
||||
public:
|
||||
virtual void CommandCallback( const CCommand &command ) = 0;
|
||||
};
|
||||
|
||||
class ICommandCompletionCallback
|
||||
{
|
||||
public:
|
||||
virtual int CommandCompletionCallback( const char *pPartial, CUtlVector< CUtlString > &commands ) = 0;
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: The base console invoked command/cvar interface
|
||||
//-----------------------------------------------------------------------------
|
||||
class ConCommandBase
|
||||
{
|
||||
friend class CCvar;
|
||||
friend class ConVar;
|
||||
friend class ConCommand;
|
||||
friend void ConVar_Register( int nCVarFlag, IConCommandBaseAccessor *pAccessor );
|
||||
friend void ConVar_PublishToVXConsole();
|
||||
|
||||
// FIXME: Remove when ConVar changes are done
|
||||
friend class CDefaultCvar;
|
||||
|
||||
public:
|
||||
ConCommandBase( void );
|
||||
ConCommandBase( const char *pName, const char *pHelpString = 0,
|
||||
int flags = 0 );
|
||||
|
||||
virtual ~ConCommandBase( void );
|
||||
|
||||
virtual bool IsCommand( void ) const;
|
||||
|
||||
// Check flag
|
||||
virtual bool IsFlagSet( int flag ) const;
|
||||
// Set flag
|
||||
virtual void AddFlags( int flags );
|
||||
|
||||
// Return name of cvar
|
||||
virtual const char *GetName( void ) const;
|
||||
|
||||
// Return help text for cvar
|
||||
virtual const char *GetHelpText( void ) const;
|
||||
|
||||
// Deal with next pointer
|
||||
const ConCommandBase *GetNext( void ) const;
|
||||
ConCommandBase *GetNext( void );
|
||||
|
||||
void SetNext(ConCommandBase *pBase)
|
||||
{
|
||||
m_pNext = pBase;
|
||||
}
|
||||
|
||||
virtual bool IsRegistered( void ) const;
|
||||
|
||||
// Returns the DLL identifier
|
||||
virtual CVarDLLIdentifier_t GetDLLIdentifier() const;
|
||||
|
||||
protected:
|
||||
virtual void Create( const char *pName, const char *pHelpString = 0,
|
||||
int flags = 0 );
|
||||
|
||||
// Used internally by OneTimeInit to initialize/shutdown
|
||||
virtual void Init();
|
||||
void Shutdown();
|
||||
|
||||
// Internal copy routine ( uses new operator from correct module )
|
||||
char *CopyString( const char *from );
|
||||
|
||||
private:
|
||||
// Next ConVar in chain
|
||||
// Prior to register, it points to the next convar in the DLL.
|
||||
// Once registered, though, m_pNext is reset to point to the next
|
||||
// convar in the global list
|
||||
ConCommandBase *m_pNext;
|
||||
|
||||
// Has the cvar been added to the global list?
|
||||
bool m_bRegistered;
|
||||
|
||||
// Static data
|
||||
const char *m_pszName;
|
||||
const char *m_pszHelpString;
|
||||
|
||||
// ConVar flags
|
||||
int m_nFlags;
|
||||
|
||||
protected:
|
||||
// ConVars add themselves to this list for the executable.
|
||||
// Then ConVar_Register runs through all the console variables
|
||||
// and registers them into a global list stored in vstdlib.dll
|
||||
static ConCommandBase *s_pConCommandBases;
|
||||
|
||||
// ConVars in this executable use this 'global' to access values.
|
||||
static IConCommandBaseAccessor *s_pAccessor;
|
||||
public: // Hackalicous
|
||||
inline int GetFlags() const
|
||||
{
|
||||
return m_nFlags;
|
||||
}
|
||||
inline void SetFlags(int flags)
|
||||
{
|
||||
m_nFlags = flags;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Command tokenizer
|
||||
//-----------------------------------------------------------------------------
|
||||
class CCommand
|
||||
{
|
||||
public:
|
||||
CCommand();
|
||||
CCommand( int nArgC, const char **ppArgV );
|
||||
bool Tokenize( const char *pCommand, characterset_t *pBreakSet = NULL );
|
||||
void Reset();
|
||||
|
||||
int ArgC() const;
|
||||
const char **ArgV() const;
|
||||
const char *ArgS() const; // All args that occur after the 0th arg, in string form
|
||||
const char *GetCommandString() const; // The entire command in string form, including the 0th arg
|
||||
const char *operator[]( int nIndex ) const; // Gets at arguments
|
||||
const char *Arg( int nIndex ) const; // Gets at arguments
|
||||
|
||||
// Helper functions to parse arguments to commands.
|
||||
const char* FindArg( const char *pName ) const;
|
||||
int FindArgInt( const char *pName, int nDefaultVal ) const;
|
||||
|
||||
static int MaxCommandLength();
|
||||
static characterset_t* DefaultBreakSet();
|
||||
|
||||
private:
|
||||
enum
|
||||
{
|
||||
COMMAND_MAX_ARGC = 64,
|
||||
COMMAND_MAX_LENGTH = 512,
|
||||
};
|
||||
|
||||
int m_nArgc;
|
||||
int m_nArgv0Size;
|
||||
char m_pArgSBuffer[ COMMAND_MAX_LENGTH ];
|
||||
char m_pArgvBuffer[ COMMAND_MAX_LENGTH ];
|
||||
const char* m_ppArgv[ COMMAND_MAX_ARGC ];
|
||||
};
|
||||
|
||||
inline int CCommand::MaxCommandLength()
|
||||
{
|
||||
return COMMAND_MAX_LENGTH - 1;
|
||||
}
|
||||
|
||||
inline int CCommand::ArgC() const
|
||||
{
|
||||
return m_nArgc;
|
||||
}
|
||||
|
||||
inline const char **CCommand::ArgV() const
|
||||
{
|
||||
return m_nArgc ? (const char**)m_ppArgv : NULL;
|
||||
}
|
||||
|
||||
inline const char *CCommand::ArgS() const
|
||||
{
|
||||
return m_nArgv0Size ? &m_pArgSBuffer[m_nArgv0Size] : "";
|
||||
}
|
||||
|
||||
inline const char *CCommand::GetCommandString() const
|
||||
{
|
||||
return m_nArgc ? m_pArgSBuffer : "";
|
||||
}
|
||||
|
||||
inline const char *CCommand::Arg( int nIndex ) const
|
||||
{
|
||||
// FIXME: Many command handlers appear to not be particularly careful
|
||||
// about checking for valid argc range. For now, we're going to
|
||||
// do the extra check and return an empty string if it's out of range
|
||||
if ( nIndex < 0 || nIndex >= m_nArgc )
|
||||
return "";
|
||||
return m_ppArgv[nIndex];
|
||||
}
|
||||
|
||||
inline const char *CCommand::operator[]( int nIndex ) const
|
||||
{
|
||||
return Arg( nIndex );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: The console invoked command
|
||||
//-----------------------------------------------------------------------------
|
||||
class ConCommand : public ConCommandBase
|
||||
{
|
||||
friend class CCvar;
|
||||
|
||||
public:
|
||||
typedef ConCommandBase BaseClass;
|
||||
|
||||
ConCommand( const char *pName, FnCommandCallbackV1_t callback,
|
||||
const char *pHelpString = 0, int flags = 0, FnCommandCompletionCallback completionFunc = 0 );
|
||||
ConCommand( const char *pName, FnCommandCallback_t callback,
|
||||
const char *pHelpString = 0, int flags = 0, FnCommandCompletionCallback completionFunc = 0 );
|
||||
ConCommand( const char *pName, ICommandCallback *pCallback,
|
||||
const char *pHelpString = 0, int flags = 0, ICommandCompletionCallback *pCommandCompletionCallback = 0 );
|
||||
|
||||
virtual ~ConCommand( void );
|
||||
|
||||
virtual bool IsCommand( void ) const;
|
||||
|
||||
virtual int AutoCompleteSuggest( const char *partial, CUtlVector< CUtlString > &commands );
|
||||
|
||||
virtual bool CanAutoComplete( void );
|
||||
|
||||
// Invoke the function
|
||||
virtual void Dispatch( const CCommand &command );
|
||||
|
||||
private:
|
||||
// NOTE: To maintain backward compat, we have to be very careful:
|
||||
// All public virtual methods must appear in the same order always
|
||||
// since engine code will be calling into this code, which *does not match*
|
||||
// in the mod code; it's using slightly different, but compatible versions
|
||||
// of this class. Also: Be very careful about adding new fields to this class.
|
||||
// Those fields will not exist in the version of this class that is instanced
|
||||
// in mod code.
|
||||
|
||||
// Call this function when executing the command
|
||||
union
|
||||
{
|
||||
FnCommandCallbackV1_t m_fnCommandCallbackV1;
|
||||
FnCommandCallback_t m_fnCommandCallback;
|
||||
ICommandCallback *m_pCommandCallback;
|
||||
};
|
||||
|
||||
union
|
||||
{
|
||||
FnCommandCompletionCallback m_fnCompletionCallback;
|
||||
ICommandCompletionCallback *m_pCommandCompletionCallback;
|
||||
};
|
||||
|
||||
bool m_bHasCompletionCallback : 1;
|
||||
bool m_bUsingNewCommandCallback : 1;
|
||||
bool m_bUsingCommandCallbackInterface : 1;
|
||||
public: // Hackalicous
|
||||
inline FnCommandCallback_t GetCallback() const
|
||||
{
|
||||
return m_fnCommandCallback;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: A console variable
|
||||
//-----------------------------------------------------------------------------
|
||||
class ConVar : public ConCommandBase, public IConVar
|
||||
{
|
||||
friend class CCvar;
|
||||
friend class ConVarRef;
|
||||
|
||||
public:
|
||||
typedef ConCommandBase BaseClass;
|
||||
|
||||
ConVar( const char *pName, const char *pDefaultValue, int flags = 0);
|
||||
|
||||
ConVar( const char *pName, const char *pDefaultValue, int flags,
|
||||
const char *pHelpString );
|
||||
ConVar( const char *pName, const char *pDefaultValue, int flags,
|
||||
const char *pHelpString, bool bMin, float fMin, bool bMax, float fMax );
|
||||
ConVar( const char *pName, const char *pDefaultValue, int flags,
|
||||
const char *pHelpString, FnChangeCallback_t callback );
|
||||
ConVar( const char *pName, const char *pDefaultValue, int flags,
|
||||
const char *pHelpString, bool bMin, float fMin, bool bMax, float fMax,
|
||||
FnChangeCallback_t callback );
|
||||
|
||||
virtual ~ConVar( void );
|
||||
|
||||
virtual bool IsFlagSet( int flag ) const;
|
||||
virtual const char* GetHelpText( void ) const;
|
||||
virtual bool IsRegistered( void ) const;
|
||||
virtual const char *GetName( void ) const;
|
||||
virtual void AddFlags( int flags );
|
||||
virtual bool IsCommand( void ) const;
|
||||
|
||||
// Install a change callback (there shouldn't already be one....)
|
||||
void InstallChangeCallback( FnChangeCallback_t callback );
|
||||
|
||||
// Retrieve value
|
||||
FORCEINLINE_CVAR float GetFloat( void ) const;
|
||||
FORCEINLINE_CVAR int GetInt( void ) const;
|
||||
FORCEINLINE_CVAR bool GetBool() const { return !!GetInt(); }
|
||||
FORCEINLINE_CVAR char const *GetString( void ) const;
|
||||
|
||||
// Any function that allocates/frees memory needs to be virtual or else you'll have crashes
|
||||
// from alloc/free across dll/exe boundaries.
|
||||
|
||||
// These just call into the IConCommandBaseAccessor to check flags and set the var (which ends up calling InternalSetValue).
|
||||
virtual void SetValue( const char *value );
|
||||
virtual void SetValue( float value );
|
||||
virtual void SetValue( int value );
|
||||
|
||||
// Reset to default value
|
||||
void Revert( void );
|
||||
|
||||
// True if it has a min/max setting
|
||||
bool GetMin( float& minVal ) const;
|
||||
bool GetMax( float& maxVal ) const;
|
||||
const char *GetDefault( void ) const;
|
||||
|
||||
private:
|
||||
// Called by CCvar when the value of a var is changing.
|
||||
virtual void InternalSetValue(const char *value);
|
||||
// For CVARs marked FCVAR_NEVER_AS_STRING
|
||||
virtual void InternalSetFloatValue( float fNewValue );
|
||||
virtual void InternalSetIntValue( int nValue );
|
||||
|
||||
virtual bool ClampValue( float& value );
|
||||
virtual void ChangeStringValue( const char *tempVal, float flOldValue );
|
||||
|
||||
virtual void Create( const char *pName, const char *pDefaultValue, int flags = 0,
|
||||
const char *pHelpString = 0, bool bMin = false, float fMin = 0.0,
|
||||
bool bMax = false, float fMax = false, FnChangeCallback_t callback = 0 );
|
||||
|
||||
// Used internally by OneTimeInit to initialize.
|
||||
virtual void Init();
|
||||
|
||||
private:
|
||||
|
||||
// This either points to "this" or it points to the original declaration of a ConVar.
|
||||
// This allows ConVars to exist in separate modules, and they all use the first one to be declared.
|
||||
// m_pParent->m_pParent must equal m_pParent (ie: m_pParent must be the root, or original, ConVar).
|
||||
ConVar *m_pParent;
|
||||
|
||||
// Static data
|
||||
const char *m_pszDefaultValue;
|
||||
|
||||
// Value
|
||||
// Dynamically allocated
|
||||
char *m_pszString;
|
||||
int m_StringLength;
|
||||
|
||||
// Values
|
||||
float m_fValue;
|
||||
int m_nValue;
|
||||
|
||||
// Min/Max values
|
||||
bool m_bHasMin;
|
||||
float m_fMinVal;
|
||||
bool m_bHasMax;
|
||||
float m_fMaxVal;
|
||||
|
||||
// Call this function when ConVar changes
|
||||
FnChangeCallback_t m_fnChangeCallback;
|
||||
public: // Hackalicous
|
||||
inline FnChangeCallback_t GetCallback() const
|
||||
{
|
||||
return m_fnChangeCallback;
|
||||
}
|
||||
inline void SetMin(bool set, float min=0.0)
|
||||
{
|
||||
m_bHasMin = set;
|
||||
m_fMinVal = min;
|
||||
}
|
||||
inline void SetMax(bool set, float max=0.0)
|
||||
{
|
||||
m_bHasMax = set;
|
||||
m_fMaxVal = max;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Return ConVar value as a float
|
||||
// Output : float
|
||||
//-----------------------------------------------------------------------------
|
||||
FORCEINLINE_CVAR float ConVar::GetFloat( void ) const
|
||||
{
|
||||
return m_pParent->m_fValue;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Return ConVar value as an int
|
||||
// Output : int
|
||||
//-----------------------------------------------------------------------------
|
||||
FORCEINLINE_CVAR int ConVar::GetInt( void ) const
|
||||
{
|
||||
return m_pParent->m_nValue;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Return ConVar value as a string, return "" for bogus string pointer, etc.
|
||||
// Output : const char *
|
||||
//-----------------------------------------------------------------------------
|
||||
FORCEINLINE_CVAR const char *ConVar::GetString( void ) const
|
||||
{
|
||||
if ( m_nFlags & FCVAR_NEVER_AS_STRING )
|
||||
return "FCVAR_NEVER_AS_STRING";
|
||||
|
||||
return ( m_pParent->m_pszString ) ? m_pParent->m_pszString : "";
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Used to read/write convars that already exist (replaces the FindVar method)
|
||||
//-----------------------------------------------------------------------------
|
||||
class ConVarRef
|
||||
{
|
||||
public:
|
||||
ConVarRef( const char *pName );
|
||||
ConVarRef( const char *pName, bool bIgnoreMissing );
|
||||
ConVarRef( IConVar *pConVar );
|
||||
|
||||
void Init( const char *pName, bool bIgnoreMissing );
|
||||
bool IsValid() const;
|
||||
bool IsFlagSet( int nFlags ) const;
|
||||
IConVar *GetLinkedConVar();
|
||||
|
||||
// Get/Set value
|
||||
float GetFloat( void ) const;
|
||||
int GetInt( void ) const;
|
||||
bool GetBool() const { return !!GetInt(); }
|
||||
const char *GetString( void ) const;
|
||||
|
||||
void SetValue( const char *pValue );
|
||||
void SetValue( float flValue );
|
||||
void SetValue( int nValue );
|
||||
void SetValue( bool bValue );
|
||||
|
||||
const char *GetName() const;
|
||||
|
||||
const char *GetDefault() const;
|
||||
|
||||
private:
|
||||
// High-speed method to read convar data
|
||||
IConVar *m_pConVar;
|
||||
ConVar *m_pConVarState;
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Did we find an existing convar of that name?
|
||||
//-----------------------------------------------------------------------------
|
||||
FORCEINLINE_CVAR bool ConVarRef::IsFlagSet( int nFlags ) const
|
||||
{
|
||||
return ( m_pConVar->IsFlagSet( nFlags ) != 0 );
|
||||
}
|
||||
|
||||
FORCEINLINE_CVAR IConVar *ConVarRef::GetLinkedConVar()
|
||||
{
|
||||
return m_pConVar;
|
||||
}
|
||||
|
||||
FORCEINLINE_CVAR const char *ConVarRef::GetName() const
|
||||
{
|
||||
return m_pConVar->GetName();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Return ConVar value as a float
|
||||
//-----------------------------------------------------------------------------
|
||||
FORCEINLINE_CVAR float ConVarRef::GetFloat( void ) const
|
||||
{
|
||||
return m_pConVarState->m_fValue;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Return ConVar value as an int
|
||||
//-----------------------------------------------------------------------------
|
||||
FORCEINLINE_CVAR int ConVarRef::GetInt( void ) const
|
||||
{
|
||||
return m_pConVarState->m_nValue;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Return ConVar value as a string, return "" for bogus string pointer, etc.
|
||||
//-----------------------------------------------------------------------------
|
||||
FORCEINLINE_CVAR const char *ConVarRef::GetString( void ) const
|
||||
{
|
||||
Assert( !IsFlagSet( FCVAR_NEVER_AS_STRING ) );
|
||||
return m_pConVarState->m_pszString;
|
||||
}
|
||||
|
||||
|
||||
FORCEINLINE_CVAR void ConVarRef::SetValue( const char *pValue )
|
||||
{
|
||||
m_pConVar->SetValue( pValue );
|
||||
}
|
||||
|
||||
FORCEINLINE_CVAR void ConVarRef::SetValue( float flValue )
|
||||
{
|
||||
m_pConVar->SetValue( flValue );
|
||||
}
|
||||
|
||||
FORCEINLINE_CVAR void ConVarRef::SetValue( int nValue )
|
||||
{
|
||||
m_pConVar->SetValue( nValue );
|
||||
}
|
||||
|
||||
FORCEINLINE_CVAR void ConVarRef::SetValue( bool bValue )
|
||||
{
|
||||
m_pConVar->SetValue( bValue ? 1 : 0 );
|
||||
}
|
||||
|
||||
FORCEINLINE_CVAR const char *ConVarRef::GetDefault() const
|
||||
{
|
||||
return m_pConVarState->m_pszDefaultValue;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Called by the framework to register ConCommands with the ICVar
|
||||
//-----------------------------------------------------------------------------
|
||||
void ConVar_Register( int nCVarFlag = 0, IConCommandBaseAccessor *pAccessor = NULL );
|
||||
void ConVar_Unregister( );
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Utility methods
|
||||
//-----------------------------------------------------------------------------
|
||||
void ConVar_PrintFlags( const ConCommandBase *var );
|
||||
void ConVar_PrintDescription( const ConCommandBase *pVar );
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Utility class to quickly allow ConCommands to call member methods
|
||||
//-----------------------------------------------------------------------------
|
||||
#if defined _MSC_VER
|
||||
#pragma warning (disable : 4355 )
|
||||
#endif
|
||||
|
||||
template< class T >
|
||||
class CConCommandMemberAccessor : public ConCommand, public ICommandCallback, public ICommandCompletionCallback
|
||||
{
|
||||
typedef ConCommand BaseClass;
|
||||
typedef void ( T::*FnMemberCommandCallback_t )( const CCommand &command );
|
||||
typedef int ( T::*FnMemberCommandCompletionCallback_t )( const char *pPartial, CUtlVector< CUtlString > &commands );
|
||||
|
||||
public:
|
||||
CConCommandMemberAccessor( T* pOwner, const char *pName, FnMemberCommandCallback_t callback, const char *pHelpString = 0,
|
||||
int flags = 0, FnMemberCommandCompletionCallback_t completionFunc = 0 ) :
|
||||
BaseClass( pName, this, pHelpString, flags, ( completionFunc != 0 ) ? this : NULL )
|
||||
{
|
||||
m_pOwner = pOwner;
|
||||
m_Func = callback;
|
||||
m_CompletionFunc = completionFunc;
|
||||
}
|
||||
|
||||
~CConCommandMemberAccessor()
|
||||
{
|
||||
Shutdown();
|
||||
}
|
||||
|
||||
void SetOwner( T* pOwner )
|
||||
{
|
||||
m_pOwner = pOwner;
|
||||
}
|
||||
|
||||
virtual void CommandCallback( const CCommand &command )
|
||||
{
|
||||
Assert( m_pOwner && m_Func );
|
||||
(m_pOwner->*m_Func)( command );
|
||||
}
|
||||
|
||||
virtual int CommandCompletionCallback( const char *pPartial, CUtlVector< CUtlString > &commands )
|
||||
{
|
||||
Assert( m_pOwner && m_CompletionFunc );
|
||||
return (m_pOwner->*m_CompletionFunc)( pPartial, commands );
|
||||
}
|
||||
|
||||
private:
|
||||
T* m_pOwner;
|
||||
FnMemberCommandCallback_t m_Func;
|
||||
FnMemberCommandCompletionCallback_t m_CompletionFunc;
|
||||
};
|
||||
|
||||
#if defined _MSC_VER
|
||||
#pragma warning ( default : 4355 )
|
||||
#endif
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Utility macros to quicky generate a simple console command
|
||||
//-----------------------------------------------------------------------------
|
||||
#define CON_COMMAND( name, description ) \
|
||||
static void name( const CCommand &args ); \
|
||||
static ConCommand name##_command( #name, name, description ); \
|
||||
static void name( const CCommand &args )
|
||||
|
||||
#define CON_COMMAND_F( name, description, flags ) \
|
||||
static void name( const CCommand &args ); \
|
||||
static ConCommand name##_command( #name, name, description, flags ); \
|
||||
static void name( const CCommand &args )
|
||||
|
||||
#define CON_COMMAND_F_COMPLETION( name, description, flags, completion ) \
|
||||
static void name( const CCommand &args ); \
|
||||
static ConCommand name##_command( #name, name, description, flags, completion ); \
|
||||
static void name( const CCommand &args )
|
||||
|
||||
#define CON_COMMAND_EXTERN( name, _funcname, description ) \
|
||||
void _funcname( const CCommand &args ); \
|
||||
static ConCommand name##_command( #name, _funcname, description ); \
|
||||
void _funcname( const CCommand &args )
|
||||
|
||||
#define CON_COMMAND_EXTERN_F( name, _funcname, description, flags ) \
|
||||
void _funcname( const CCommand &args ); \
|
||||
static ConCommand name##_command( #name, _funcname, description, flags ); \
|
||||
void _funcname( const CCommand &args )
|
||||
|
||||
#define CON_COMMAND_MEMBER_F( _thisclass, name, _funcname, description, flags ) \
|
||||
void _funcname( const CCommand &args ); \
|
||||
friend class CCommandMemberInitializer_##_funcname; \
|
||||
class CCommandMemberInitializer_##_funcname \
|
||||
{ \
|
||||
public: \
|
||||
CCommandMemberInitializer_##_funcname() : m_ConCommandAccessor( NULL, name, &_thisclass::_funcname, description, flags ) \
|
||||
{ \
|
||||
m_ConCommandAccessor.SetOwner( GET_OUTER( _thisclass, m_##_funcname##_register ) ); \
|
||||
} \
|
||||
private: \
|
||||
CConCommandMemberAccessor< _thisclass > m_ConCommandAccessor; \
|
||||
}; \
|
||||
\
|
||||
CCommandMemberInitializer_##_funcname m_##_funcname##_register; \
|
||||
|
||||
|
||||
#endif // CONVAR_H
|
File diff suppressed because it is too large
Load Diff
@ -83,10 +83,12 @@ binary.sources += [
|
||||
'frame_tasks.cpp',
|
||||
'smn_halflife.cpp',
|
||||
'FrameIterator.cpp',
|
||||
'NativeInvoker.cpp',
|
||||
]
|
||||
if builder.target.platform == 'windows':
|
||||
binary.sources += ['thread/WinThreads.cpp']
|
||||
else:
|
||||
binary.sources += ['thread/PosixThreads.cpp']
|
||||
|
||||
|
||||
SM.binaries += [builder.Add(binary)]
|
||||
|
@ -82,6 +82,10 @@ struct AuthMethod
|
||||
{
|
||||
return strcmp(name, method->name.c_str()) == 0;
|
||||
}
|
||||
static inline uint32_t hash(const detail::CharsAndLength &key)
|
||||
{
|
||||
return key.hash();
|
||||
}
|
||||
};
|
||||
|
||||
struct UserAuth
|
||||
|
@ -948,20 +948,7 @@ void CExtensionManager::OnRootConsoleCommand(const char *cmdname, const ICommand
|
||||
CExtension *pExt;
|
||||
unsigned int num = 1;
|
||||
|
||||
List<CExtension *> required; // List of loaded and required extensions
|
||||
List<CExtension *> optional; // List of non loaded optional extensions
|
||||
|
||||
for (iter = m_Libs.begin(); iter != m_Libs.end(); iter++)
|
||||
{
|
||||
pExt = (*iter);
|
||||
|
||||
if (pExt->IsLoaded() || pExt->IsRequired())
|
||||
required.push_back(pExt);
|
||||
else if (!pExt->IsLoaded() && !pExt->IsRequired())
|
||||
optional.push_back(pExt);
|
||||
}
|
||||
|
||||
switch (required.size())
|
||||
switch (m_Libs.size())
|
||||
{
|
||||
case 1:
|
||||
{
|
||||
@ -975,11 +962,11 @@ void CExtensionManager::OnRootConsoleCommand(const char *cmdname, const ICommand
|
||||
}
|
||||
default:
|
||||
{
|
||||
rootmenu->ConsolePrint("[SM] Displaying %d extensions:", required.size());
|
||||
rootmenu->ConsolePrint("[SM] Displaying %d extensions:", m_Libs.size());
|
||||
break;
|
||||
}
|
||||
}
|
||||
for (iter = required.begin(); iter != required.end(); iter++,num++)
|
||||
for (iter = m_Libs.begin(); iter != m_Libs.end(); iter++,num++)
|
||||
{
|
||||
pExt = (*iter);
|
||||
if (pExt->IsLoaded())
|
||||
@ -998,32 +985,13 @@ void CExtensionManager::OnRootConsoleCommand(const char *cmdname, const ICommand
|
||||
rootmenu->ConsolePrint("[%02d] %s (%s): %s", num, name, version, descr);
|
||||
}
|
||||
}
|
||||
else
|
||||
else if(pExt->IsRequired() || libsys->PathExists(pExt->GetPath()))
|
||||
{
|
||||
rootmenu->ConsolePrint("[%02d] <FAILED> file \"%s\": %s", num, pExt->GetFilename(), pExt->m_Error.c_str());
|
||||
}
|
||||
}
|
||||
if (optional.size())
|
||||
{
|
||||
num = 1;
|
||||
switch (optional.size())
|
||||
else
|
||||
{
|
||||
case 1:
|
||||
{
|
||||
rootmenu->ConsolePrint("\n[SM] Displaying 1 optional extension not found:");
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
rootmenu->ConsolePrint("\n[SM] Displaying %d optional extensions not found:", optional.size());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (iter = optional.begin(); iter != optional.end(); iter++,num++)
|
||||
{
|
||||
pExt = (*iter);
|
||||
rootmenu->ConsolePrint("[%02d] \"%s\"", num, pExt->GetFilename());
|
||||
rootmenu->ConsolePrint("[%02d] <OPTIONAL> file \"%s\": %s", num, pExt->GetFilename(), pExt->m_Error.c_str());
|
||||
}
|
||||
}
|
||||
return;
|
||||
|
@ -46,18 +46,13 @@ SafeFrameIterator::SafeFrameIterator(IFrameIterator *it)
|
||||
|
||||
bool SafeFrameIterator::Done() const
|
||||
{
|
||||
return current == frames.length();
|
||||
return current >= frames.length();
|
||||
}
|
||||
|
||||
bool SafeFrameIterator::Next()
|
||||
{
|
||||
if (!this->Done())
|
||||
{
|
||||
current++;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
current++;
|
||||
return !this->Done();
|
||||
}
|
||||
|
||||
void SafeFrameIterator::Reset()
|
||||
|
@ -72,6 +72,10 @@ public: //NameHashSet
|
||||
{
|
||||
return strcmp(key, value->m_File) == 0;
|
||||
}
|
||||
static inline uint32_t hash(const detail::CharsAndLength &key)
|
||||
{
|
||||
return key.hash();
|
||||
}
|
||||
private:
|
||||
char m_File[PLATFORM_MAX_PATH];
|
||||
char m_CurFile[PLATFORM_MAX_PATH];
|
||||
|
@ -110,6 +110,10 @@ struct QHandleType
|
||||
{
|
||||
return type->name && type->name->compare(key) == 0;
|
||||
}
|
||||
static inline uint32_t hash(const detail::CharsAndLength &key)
|
||||
{
|
||||
return key.hash();
|
||||
}
|
||||
};
|
||||
|
||||
typedef ke::Lambda<void(const char *)> HandleReporter;
|
||||
|
@ -36,6 +36,7 @@
|
||||
#include <am-string.h>
|
||||
#include <am-utility.h>
|
||||
#include <am-refcounting.h>
|
||||
#include <sm_stringhashmap.h>
|
||||
#include "common_logic.h"
|
||||
|
||||
class CNativeOwner;
|
||||
@ -93,6 +94,10 @@ struct Native : public ke::Refcounted<Native>
|
||||
{
|
||||
return strcmp(name, entry->name()) == 0;
|
||||
}
|
||||
static inline uint32_t hash(const detail::CharsAndLength &key)
|
||||
{
|
||||
return key.hash();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
321
core/logic/NativeInvoker.cpp
Normal file
321
core/logic/NativeInvoker.cpp
Normal file
@ -0,0 +1,321 @@
|
||||
// vim: set sts=2 ts=8 sw=2 tw=99 et:
|
||||
//
|
||||
// Copyright (C) 2006-2015 AlliedModders LLC
|
||||
//
|
||||
// This file is part of SourcePawn. SourcePawn is free software: you can
|
||||
// redistribute it and/or modify it under the terms of the GNU General Public
|
||||
// License as published by the Free Software Foundation, either version 3 of
|
||||
// the License, or (at your option) any later version.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License along with
|
||||
// SourcePawn. If not, see http://www.gnu.org/licenses/.
|
||||
//
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "NativeInvoker.h"
|
||||
|
||||
/********************
|
||||
* FUNCTION CALLING *
|
||||
********************/
|
||||
|
||||
NativeInvoker::NativeInvoker(IPluginContext *pContext, const ke::RefPtr<Native> &native)
|
||||
: context_(pContext),
|
||||
m_curparam(0),
|
||||
m_errorstate(SP_ERROR_NONE),
|
||||
native_(native)
|
||||
{
|
||||
}
|
||||
|
||||
NativeInvoker::~NativeInvoker()
|
||||
{
|
||||
Cancel();
|
||||
}
|
||||
|
||||
bool
|
||||
NativeInvoker::IsRunnable()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
IPluginContext *
|
||||
NativeInvoker::GetParentContext()
|
||||
{
|
||||
return context_;
|
||||
}
|
||||
|
||||
int NativeInvoker::PushCell(cell_t cell)
|
||||
{
|
||||
if (m_curparam >= SP_MAX_EXEC_PARAMS)
|
||||
return SetError(SP_ERROR_PARAMS_MAX);
|
||||
|
||||
m_info[m_curparam].marked = false;
|
||||
m_params[m_curparam] = cell;
|
||||
m_curparam++;
|
||||
|
||||
return SP_ERROR_NONE;
|
||||
}
|
||||
|
||||
int
|
||||
NativeInvoker::PushCellByRef(cell_t *cell, int flags)
|
||||
{
|
||||
return PushArray(cell, 1, flags);
|
||||
}
|
||||
|
||||
int
|
||||
NativeInvoker::PushFloat(float number)
|
||||
{
|
||||
cell_t val = sp::FloatCellUnion(number).cell;
|
||||
|
||||
return PushCell(val);
|
||||
}
|
||||
|
||||
int
|
||||
NativeInvoker::PushFloatByRef(float *number, int flags)
|
||||
{
|
||||
return PushCellByRef((cell_t *)number, flags);
|
||||
}
|
||||
|
||||
int
|
||||
NativeInvoker::PushArray(cell_t *inarray, unsigned int cells, int copyback)
|
||||
{
|
||||
if (m_curparam >= SP_MAX_EXEC_PARAMS)
|
||||
{
|
||||
return SetError(SP_ERROR_PARAMS_MAX);
|
||||
}
|
||||
|
||||
ParamInfo *info = &m_info[m_curparam];
|
||||
|
||||
info->flags = inarray ? copyback : 0;
|
||||
info->marked = true;
|
||||
info->size = cells;
|
||||
info->str.is_sz = false;
|
||||
info->orig_addr = inarray;
|
||||
|
||||
m_curparam++;
|
||||
|
||||
return SP_ERROR_NONE;
|
||||
}
|
||||
|
||||
int
|
||||
NativeInvoker::PushString(const char *string)
|
||||
{
|
||||
return _PushString(string, SM_PARAM_STRING_COPY, 0, strlen(string)+1);
|
||||
}
|
||||
|
||||
int
|
||||
NativeInvoker::PushStringEx(char *buffer, size_t length, int sz_flags, int cp_flags)
|
||||
{
|
||||
return _PushString(buffer, sz_flags, cp_flags, length);
|
||||
}
|
||||
|
||||
int
|
||||
NativeInvoker::_PushString(const char *string, int sz_flags, int cp_flags, size_t len)
|
||||
{
|
||||
if (m_curparam >= SP_MAX_EXEC_PARAMS)
|
||||
return SetError(SP_ERROR_PARAMS_MAX);
|
||||
|
||||
ParamInfo *info = &m_info[m_curparam];
|
||||
|
||||
info->marked = true;
|
||||
info->orig_addr = (cell_t *)string;
|
||||
info->flags = cp_flags;
|
||||
info->size = len;
|
||||
info->str.sz_flags = sz_flags;
|
||||
info->str.is_sz = true;
|
||||
|
||||
m_curparam++;
|
||||
|
||||
return SP_ERROR_NONE;
|
||||
}
|
||||
|
||||
void
|
||||
NativeInvoker::Cancel()
|
||||
{
|
||||
if (!m_curparam)
|
||||
return;
|
||||
|
||||
m_errorstate = SP_ERROR_NONE;
|
||||
m_curparam = 0;
|
||||
}
|
||||
|
||||
int
|
||||
NativeInvoker::Execute(cell_t *result, cell_t buffer, cell_t size)
|
||||
{
|
||||
context_->ClearLastNativeError();
|
||||
|
||||
// For backward compatibility, we have to clear the exception state.
|
||||
// Otherwise code like this:
|
||||
//
|
||||
// static cell_t native(cx, params) {
|
||||
// for (auto callback : callbacks) {
|
||||
// callback->Execute();
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// Could unintentionally leak a pending exception back to the caller,
|
||||
// which wouldn't have happened before the Great Exception Refactoring.
|
||||
|
||||
SourcePawn::ExceptionHandler eh(context_);
|
||||
eh.Debug(!size);
|
||||
|
||||
if (!Invoke(result)) {
|
||||
if(size)
|
||||
context_->StringToLocalUTF8(buffer, size, eh.Message(), NULL);
|
||||
int Err = context_->GetLastNativeError();
|
||||
context_->ClearLastNativeError();
|
||||
return Err;
|
||||
}
|
||||
|
||||
return SP_ERROR_NONE;
|
||||
}
|
||||
|
||||
bool
|
||||
NativeInvoker::Invoke(cell_t *result)
|
||||
{
|
||||
if (!IsRunnable()) {
|
||||
Cancel();
|
||||
context_->ReportErrorNumber(SP_ERROR_NOT_RUNNABLE);
|
||||
return false;
|
||||
}
|
||||
if (int err = m_errorstate) {
|
||||
Cancel();
|
||||
context_->ReportErrorNumber(err);
|
||||
return false;
|
||||
}
|
||||
|
||||
//This is for re-entrancy!
|
||||
cell_t _temp_params[SP_MAX_EXEC_PARAMS + 1];
|
||||
cell_t *temp_params = &_temp_params[1];
|
||||
ParamInfo temp_info[SP_MAX_EXEC_PARAMS];
|
||||
unsigned int numparams = m_curparam;
|
||||
unsigned int i;
|
||||
|
||||
if (numparams)
|
||||
{
|
||||
//Save the info locally, then reset it for re-entrant calls.
|
||||
memcpy(temp_info, m_info, numparams * sizeof(ParamInfo));
|
||||
}
|
||||
m_curparam = 0;
|
||||
|
||||
/* Initialize 0th parameter */
|
||||
_temp_params[0] = numparams;
|
||||
|
||||
/* Browse the parameters and build arrays */
|
||||
bool ok = true;
|
||||
for (i=0; i<numparams; i++) {
|
||||
/* Is this marked as an array? */
|
||||
if (temp_info[i].marked) {
|
||||
if (!temp_info[i].str.is_sz) {
|
||||
/* Allocate a normal/generic array */
|
||||
int err = context_->HeapAlloc(
|
||||
temp_info[i].size,
|
||||
&(temp_info[i].local_addr),
|
||||
&(temp_info[i].phys_addr));
|
||||
if (err != SP_ERROR_NONE) {
|
||||
context_->ReportErrorNumber(err);
|
||||
ok = false;
|
||||
break;
|
||||
}
|
||||
if (temp_info[i].orig_addr)
|
||||
{
|
||||
memcpy(temp_info[i].phys_addr, temp_info[i].orig_addr, sizeof(cell_t) * temp_info[i].size);
|
||||
}
|
||||
} else {
|
||||
/* Calculate cells required for the string */
|
||||
size_t cells = (temp_info[i].size + sizeof(cell_t) - 1) / sizeof(cell_t);
|
||||
|
||||
/* Allocate the buffer */
|
||||
int err = context_->HeapAlloc(
|
||||
cells,
|
||||
&(temp_info[i].local_addr),
|
||||
&(temp_info[i].phys_addr));
|
||||
if (err != SP_ERROR_NONE) {
|
||||
context_->ReportErrorNumber(err);
|
||||
ok = false;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Copy original string if necessary */
|
||||
if ((temp_info[i].str.sz_flags & SM_PARAM_STRING_COPY) && (temp_info[i].orig_addr != NULL))
|
||||
{
|
||||
/* Cut off UTF-8 properly */
|
||||
if (temp_info[i].str.sz_flags & SM_PARAM_STRING_UTF8) {
|
||||
context_->StringToLocalUTF8(
|
||||
temp_info[i].local_addr,
|
||||
temp_info[i].size,
|
||||
(const char *)temp_info[i].orig_addr,
|
||||
NULL);
|
||||
}
|
||||
/* Copy a binary blob */
|
||||
else if (temp_info[i].str.sz_flags & SM_PARAM_STRING_BINARY)
|
||||
{
|
||||
memmove(temp_info[i].phys_addr, temp_info[i].orig_addr, temp_info[i].size);
|
||||
}
|
||||
/* Copy ASCII characters */
|
||||
else
|
||||
{
|
||||
context_->StringToLocal(
|
||||
temp_info[i].local_addr,
|
||||
temp_info[i].size,
|
||||
(const char *)temp_info[i].orig_addr);
|
||||
}
|
||||
}
|
||||
} /* End array/string calculation */
|
||||
/* Update the pushed parameter with the byref local address */
|
||||
temp_params[i] = temp_info[i].local_addr;
|
||||
} else {
|
||||
/* Just copy the value normally */
|
||||
temp_params[i] = m_params[i];
|
||||
}
|
||||
}
|
||||
|
||||
/* Make the call if we can */
|
||||
if (ok)
|
||||
{
|
||||
*result = native_->func()(context_, _temp_params);
|
||||
}
|
||||
|
||||
/* i should be equal to the last valid parameter + 1 */
|
||||
bool docopies = ok;
|
||||
while (i--) {
|
||||
if (!temp_info[i].marked)
|
||||
continue;
|
||||
|
||||
if (docopies && (temp_info[i].flags & SM_PARAM_COPYBACK)) {
|
||||
if (temp_info[i].orig_addr) {
|
||||
if (temp_info[i].str.is_sz) {
|
||||
memcpy(temp_info[i].orig_addr, temp_info[i].phys_addr, temp_info[i].size);
|
||||
|
||||
} else {
|
||||
if (temp_info[i].size == 1) {
|
||||
*temp_info[i].orig_addr = *(temp_info[i].phys_addr);
|
||||
} else {
|
||||
memcpy(temp_info[i].orig_addr,
|
||||
temp_info[i].phys_addr,
|
||||
temp_info[i].size * sizeof(cell_t));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (int err = context_->HeapPop(temp_info[i].local_addr))
|
||||
context_->ReportErrorNumber(err);
|
||||
}
|
||||
|
||||
return context_->GetLastNativeError() == SP_ERROR_NONE;
|
||||
}
|
||||
|
||||
int
|
||||
NativeInvoker::SetError(int err)
|
||||
{
|
||||
m_errorstate = err;
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
int NativeInvoker::CallFunction(const cell_t *params, unsigned int num_params, cell_t *result) { return 0; }
|
||||
funcid_t NativeInvoker::GetFunctionID() { return 0; }
|
||||
int NativeInvoker::Execute2(IPluginContext *ctx, cell_t *result) { return 0; }
|
||||
int NativeInvoker::CallFunction2(IPluginContext *ctx, const cell_t *params, unsigned int num_params, cell_t *result) { return 0; }
|
||||
IPluginRuntime *NativeInvoker::GetParentRuntime() { return NULL; }
|
79
core/logic/NativeInvoker.h
Normal file
79
core/logic/NativeInvoker.h
Normal file
@ -0,0 +1,79 @@
|
||||
// vim: set sts=2 ts=8 sw=2 tw=99 et:
|
||||
//
|
||||
// Copyright (C) 2006-2015 AlliedModders LLC
|
||||
//
|
||||
// This file is part of SourcePawn. SourcePawn is free software: you can
|
||||
// redistribute it and/or modify it under the terms of the GNU General Public
|
||||
// License as published by the Free Software Foundation, either version 3 of
|
||||
// the License, or (at your option) any later version.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License along with
|
||||
// SourcePawn. If not, see http://www.gnu.org/licenses/.
|
||||
//
|
||||
#ifndef _INCLUDE_SOURCEMOD_NATIVE_INVOKER_H_
|
||||
#define _INCLUDE_SOURCEMOD_NATIVE_INVOKER_H_
|
||||
|
||||
#include <sp_vm_api.h>
|
||||
#include <amtl/am-autoptr.h>
|
||||
#include <amtl/am-refcounting.h>
|
||||
#include "Native.h"
|
||||
|
||||
struct ParamInfo
|
||||
{
|
||||
int flags; /* Copy-back flags */
|
||||
bool marked; /* Whether this is marked as being used */
|
||||
cell_t local_addr; /* Local address to free */
|
||||
cell_t *phys_addr; /* Physical address of our copy */
|
||||
cell_t *orig_addr; /* Original address to copy back to */
|
||||
ucell_t size; /* Size of array in bytes */
|
||||
struct {
|
||||
bool is_sz; /* is a string */
|
||||
int sz_flags; /* has sz flags */
|
||||
} str;
|
||||
};
|
||||
|
||||
class NativeInvoker : public IPluginFunction
|
||||
{
|
||||
public:
|
||||
NativeInvoker(IPluginContext *pContext, const ke::RefPtr<Native> &native);
|
||||
virtual ~NativeInvoker();
|
||||
|
||||
public:
|
||||
int PushCell(cell_t cell);
|
||||
int PushCellByRef(cell_t *cell, int flags);
|
||||
int PushFloat(float number);
|
||||
int PushFloatByRef(float *number, int flags);
|
||||
int PushArray(cell_t *inarray, unsigned int cells, int copyback);
|
||||
int PushString(const char *string);
|
||||
int PushStringEx(char *buffer, size_t length, int sz_flags, int cp_flags);
|
||||
int Execute(cell_t *result, cell_t buffer=0, cell_t size=0);
|
||||
void Cancel();
|
||||
int CallFunction(const cell_t *params, unsigned int num_params, cell_t *result);
|
||||
IPluginContext *GetParentContext();
|
||||
bool Invoke(cell_t *result);
|
||||
bool IsRunnable();
|
||||
funcid_t GetFunctionID();
|
||||
int Execute2(IPluginContext *ctx, cell_t *result);
|
||||
int CallFunction2(IPluginContext *ctx,
|
||||
const cell_t *params,
|
||||
unsigned int num_params,
|
||||
cell_t *result);
|
||||
IPluginRuntime *GetParentRuntime();
|
||||
const char *DebugName() {
|
||||
return native_->name();
|
||||
}
|
||||
|
||||
private:
|
||||
int _PushString(const char *string, int sz_flags, int cp_flags, size_t len);
|
||||
int SetError(int err);
|
||||
|
||||
private:
|
||||
IPluginContext *context_;
|
||||
cell_t m_params[SP_MAX_EXEC_PARAMS];
|
||||
ParamInfo m_info[SP_MAX_EXEC_PARAMS];
|
||||
unsigned int m_curparam;
|
||||
int m_errorstate;
|
||||
ke::RefPtr<Native> native_;
|
||||
};
|
||||
|
||||
#endif //_INCLUDE_SOURCEMOD_NATIVE_INVOKER_H_
|
@ -31,7 +31,6 @@
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <ctype.h>
|
||||
#include "PluginSys.h"
|
||||
#include "ShareSys.h"
|
||||
#include <ILibrarySys.h>
|
||||
@ -47,7 +46,6 @@
|
||||
#include "frame_tasks.h"
|
||||
#include <amtl/am-string.h>
|
||||
#include <amtl/am-linkedlist.h>
|
||||
#include <amtl/am-uniqueptr.h>
|
||||
#include <bridge/include/IVEngineServerBridge.h>
|
||||
#include <bridge/include/CoreProvider.h>
|
||||
|
||||
@ -934,38 +932,16 @@ void CPluginManager::LoadPluginsFromDir(const char *basedir, const char *localpa
|
||||
libsys->CloseDirectory(dir);
|
||||
}
|
||||
|
||||
#if defined PLATFORM_WINDOWS || defined PLATFORM_APPLE
|
||||
char *strdup_tolower(const char *input)
|
||||
{
|
||||
char *str = strdup(input);
|
||||
|
||||
for (char *c = str; *c; c++)
|
||||
{
|
||||
*c = tolower((unsigned char)*c);
|
||||
}
|
||||
|
||||
return str;
|
||||
}
|
||||
#endif
|
||||
|
||||
LoadRes CPluginManager::LoadPlugin(CPlugin **aResult, const char *path, bool debug, PluginType type)
|
||||
{
|
||||
if (m_LoadingLocked)
|
||||
return LoadRes_NeverLoad;
|
||||
|
||||
/* For windows & mac, we convert the path to lower-case in order to avoid duplicate plugin loading */
|
||||
#if defined PLATFORM_WINDOWS || defined PLATFORM_APPLE
|
||||
ke::UniquePtr<char> finalPath = ke::UniquePtr<char>(strdup_tolower(path));
|
||||
#else
|
||||
ke::UniquePtr<char> finalPath = ke::UniquePtr<char>(strdup(path));
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
* Does this plugin already exist?
|
||||
*/
|
||||
CPlugin *pPlugin;
|
||||
if (m_LoadLookup.retrieve(finalPath.get(), &pPlugin))
|
||||
if (m_LoadLookup.retrieve(path, &pPlugin))
|
||||
{
|
||||
/* Check to see if we should try reloading it */
|
||||
if (pPlugin->GetStatus() == Plugin_BadLoad
|
||||
@ -978,12 +954,11 @@ LoadRes CPluginManager::LoadPlugin(CPlugin **aResult, const char *path, bool deb
|
||||
{
|
||||
if (aResult)
|
||||
*aResult = pPlugin;
|
||||
|
||||
return LoadRes_AlreadyLoaded;
|
||||
}
|
||||
}
|
||||
|
||||
CPlugin *plugin = CompileAndPrep(finalPath.get());
|
||||
CPlugin *plugin = CompileAndPrep(path);
|
||||
|
||||
// Assign our outparam so we can return early. It must be set.
|
||||
*aResult = plugin;
|
||||
@ -2416,4 +2391,4 @@ static OldPluginAPI sOldPluginAPI;
|
||||
IPluginManager *CPluginManager::GetOldAPI()
|
||||
{
|
||||
return &sOldPluginAPI;
|
||||
}
|
||||
}
|
@ -55,6 +55,9 @@
|
||||
#include <bridge/include/IScriptManager.h>
|
||||
#include <am-function.h>
|
||||
#include <ReentrantList.h>
|
||||
#ifdef PLATFORM_APPLE
|
||||
#include <cctype>
|
||||
#endif
|
||||
|
||||
class CPlayer;
|
||||
|
||||
@ -143,11 +146,6 @@ public:
|
||||
*/
|
||||
static CPlugin *Create(const char *file);
|
||||
|
||||
static inline bool matches(const char *file, const CPlugin *plugin)
|
||||
{
|
||||
return strcmp(plugin->m_filename, file) == 0;
|
||||
}
|
||||
|
||||
public:
|
||||
// Evicts the plugin from memory and sets an error state.
|
||||
void EvictWithError(PluginStatus status, const char *error_fmt, ...);
|
||||
@ -483,7 +481,54 @@ private:
|
||||
typedef decltype(m_listeners)::iterator ListenerIter;
|
||||
typedef decltype(m_plugins)::iterator PluginIter;
|
||||
|
||||
NameHashSet<CPlugin *> m_LoadLookup;
|
||||
struct CPluginPolicy
|
||||
{
|
||||
static inline uint32_t hash(const detail::CharsAndLength &key)
|
||||
{
|
||||
/* For windows & mac, we convert the path to lower-case in order to avoid duplicate plugin loading */
|
||||
#if defined PLATFORM_WINDOWS || defined PLATFORM_APPLE
|
||||
const char *original = key.chars();
|
||||
char *copy = strdup(original);
|
||||
|
||||
for (size_t i = 0; copy[i]; ++i)
|
||||
{
|
||||
copy[i] = tolower(copy[i]);
|
||||
}
|
||||
|
||||
uint32_t hash = detail::CharsAndLength(copy).hash();
|
||||
free(copy);
|
||||
return hash;
|
||||
#else
|
||||
return key.hash();
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline bool matches(const char *file, const CPlugin *plugin)
|
||||
{
|
||||
const char *pluginFile = const_cast<CPlugin*>(plugin)->GetFilename();
|
||||
#if defined PLATFORM_WINDOWS || defined PLATFORM_APPLE
|
||||
size_t fileLen = strlen(file);
|
||||
if (fileLen != strlen(pluginFile))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < fileLen; ++i)
|
||||
{
|
||||
if (tolower(file[i]) != tolower(pluginFile[i]))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
#else
|
||||
return strcmp(pluginFile, file) == 0;
|
||||
#endif
|
||||
}
|
||||
};
|
||||
NameHashSet<CPlugin *, CPluginPolicy> m_LoadLookup;
|
||||
|
||||
bool m_AllPluginsLoaded;
|
||||
IdentityToken_t *m_MyIdent;
|
||||
|
||||
|
@ -46,6 +46,10 @@ struct ConsoleEntry
|
||||
{
|
||||
return strcmp(name, entry->command.c_str()) == 0;
|
||||
}
|
||||
static inline uint32_t hash(const detail::CharsAndLength &key)
|
||||
{
|
||||
return key.hash();
|
||||
}
|
||||
};
|
||||
|
||||
class RootConsoleMenu :
|
||||
|
@ -267,8 +267,7 @@ static cell_t ReplyToCommand(IPluginContext *pContext, const cell_t *params)
|
||||
size_t len;
|
||||
{
|
||||
DetectExceptions eh(pContext);
|
||||
g_pSM->FormatString(buffer, sizeof(buffer), pContext, params, 2);
|
||||
len = g_pSM->FormatString(buffer, sizeof(buffer) - 2, pContext, params, 2);
|
||||
len = g_pSM->FormatString(buffer, sizeof(buffer) - 1, pContext, params, 2);
|
||||
if (eh.HasException())
|
||||
return 0;
|
||||
}
|
||||
|
@ -35,6 +35,8 @@
|
||||
#include <IForwardSys.h>
|
||||
#include <ISourceMod.h>
|
||||
#include <amtl/am-autoptr.h>
|
||||
#include "ShareSys.h"
|
||||
#include "NativeInvoker.h"
|
||||
|
||||
HandleType_t g_GlobalFwdType = 0;
|
||||
HandleType_t g_PrivateFwdType = 0;
|
||||
@ -43,6 +45,7 @@ static bool s_CallStarted = false;
|
||||
static ICallable *s_pCallable = NULL;
|
||||
static IPluginFunction *s_pFunction = NULL;
|
||||
static IForward *s_pForward = NULL;
|
||||
static NativeInvoker *s_pInvoker = NULL;
|
||||
|
||||
class ForwardNativeHelpers :
|
||||
public SMGlobalClass,
|
||||
@ -102,6 +105,9 @@ inline void ResetCall()
|
||||
s_pFunction = NULL;
|
||||
s_pForward = NULL;
|
||||
s_pCallable = NULL;
|
||||
if(s_pInvoker)
|
||||
delete s_pInvoker;
|
||||
s_pInvoker = NULL;
|
||||
}
|
||||
|
||||
static cell_t sm_GetFunctionByName(IPluginContext *pContext, const cell_t *params)
|
||||
@ -366,6 +372,27 @@ static cell_t sm_CallStartForward(IPluginContext *pContext, const cell_t *params
|
||||
return 1;
|
||||
}
|
||||
|
||||
static cell_t sm_CallStartNative(IPluginContext *pContext, const cell_t *params)
|
||||
{
|
||||
ResetCall();
|
||||
|
||||
char *name;
|
||||
pContext->LocalToString(params[1], &name);
|
||||
|
||||
ke::RefPtr<Native> pNative = g_ShareSys.FindNative(name);
|
||||
|
||||
if (!pNative)
|
||||
return 0;//pContext->ThrowNativeError("Invalid native \"%s\"", name);
|
||||
|
||||
s_pInvoker = new NativeInvoker(pContext, pNative);
|
||||
|
||||
s_pCallable = static_cast<ICallable *>(s_pInvoker);
|
||||
|
||||
s_CallStarted = true;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static cell_t sm_CallPushCell(IPluginContext *pContext, const cell_t *params)
|
||||
{
|
||||
int err;
|
||||
@ -656,6 +683,39 @@ static cell_t sm_CallFinish(IPluginContext *pContext, const cell_t *params)
|
||||
IForward *pForward = s_pForward;
|
||||
ResetCall();
|
||||
err = pForward->Execute(result, NULL);
|
||||
} else if (s_pInvoker) {
|
||||
err = s_pInvoker->Execute(result);
|
||||
ResetCall();
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static cell_t sm_CallFinishEx(IPluginContext *pContext, const cell_t *params)
|
||||
{
|
||||
int err = SP_ERROR_NOT_RUNNABLE;
|
||||
cell_t *result;
|
||||
|
||||
if (!s_CallStarted)
|
||||
{
|
||||
return pContext->ThrowNativeError("Cannot finish call when there is no call in progress");
|
||||
}
|
||||
|
||||
pContext->LocalToPhysAddr(params[1], &result);
|
||||
|
||||
// Note: Execute() swallows exceptions, so this is okay.
|
||||
if (s_pFunction)
|
||||
{
|
||||
IPluginFunction *pFunction = s_pFunction;
|
||||
ResetCall();
|
||||
err = pFunction->Execute(result, params[2], params[3]);
|
||||
} else if (s_pForward) {
|
||||
IForward *pForward = s_pForward;
|
||||
ResetCall();
|
||||
err = pForward->Execute(result, NULL);
|
||||
} else if (s_pInvoker) {
|
||||
err = s_pInvoker->Execute(result, params[2], params[3]);
|
||||
ResetCall();
|
||||
}
|
||||
|
||||
return err;
|
||||
@ -742,6 +802,7 @@ REGISTER_NATIVES(functionNatives)
|
||||
{"RemoveAllFromForward", sm_RemoveAllFromForward},
|
||||
{"Call_StartFunction", sm_CallStartFunction},
|
||||
{"Call_StartForward", sm_CallStartForward},
|
||||
{"Call_StartNative", sm_CallStartNative},
|
||||
{"Call_PushCell", sm_CallPushCell},
|
||||
{"Call_PushCellRef", sm_CallPushCellRef},
|
||||
{"Call_PushFloat", sm_CallPushFloat},
|
||||
@ -753,6 +814,7 @@ REGISTER_NATIVES(functionNatives)
|
||||
{"Call_PushNullVector", sm_CallPushNullVector},
|
||||
{"Call_PushNullString", sm_CallPushNullString},
|
||||
{"Call_Finish", sm_CallFinish},
|
||||
{"Call_FinishEx", sm_CallFinishEx},
|
||||
{"Call_Cancel", sm_CallCancel},
|
||||
{"RequestFrame", sm_AddFrameAction},
|
||||
{NULL, NULL},
|
||||
|
@ -58,6 +58,10 @@ struct maplist_info_t
|
||||
{
|
||||
return strcmp(value->name, key) == 0;
|
||||
}
|
||||
static inline uint32_t hash(const detail::CharsAndLength &key)
|
||||
{
|
||||
return key.hash();
|
||||
}
|
||||
};
|
||||
|
||||
#define MAPLIST_FLAG_MAPSFOLDER (1<<0) /**< On failure, use all maps in the maps folder. */
|
||||
|
@ -816,8 +816,14 @@ static cell_t GetMenuItem(IPluginContext *pContext, const cell_t *params)
|
||||
|
||||
ItemDrawInfo dr;
|
||||
const char *info;
|
||||
cell_t client = (params[0] >= 8) ? params[8] : 0;
|
||||
if(!client && menu->IsPerClientShuffled())
|
||||
{
|
||||
return pContext->ThrowNativeError("This menu has been per-client random shuffled. "
|
||||
"You have to call GetMenuItem with a client index!");
|
||||
}
|
||||
|
||||
if ((info=menu->GetItemInfo(params[2], &dr)) == NULL)
|
||||
if ((info=menu->GetItemInfo(params[2], &dr, client)) == NULL)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
@ -832,6 +838,57 @@ static cell_t GetMenuItem(IPluginContext *pContext, const cell_t *params)
|
||||
return 1;
|
||||
}
|
||||
|
||||
static cell_t MenuShufflePerClient(IPluginContext *pContext, const cell_t *params)
|
||||
{
|
||||
Handle_t hndl = (Handle_t)params[1];
|
||||
HandleError err;
|
||||
IBaseMenu *menu;
|
||||
|
||||
if ((err = ReadMenuHandle(params[1], &menu)) != HandleError_None)
|
||||
{
|
||||
return pContext->ThrowNativeError("Menu handle %x is invalid (error %d)", hndl, err);
|
||||
}
|
||||
|
||||
int start = params[2];
|
||||
int stop = params[3];
|
||||
|
||||
if (stop > 0 && !(stop >= start))
|
||||
{
|
||||
return pContext->ThrowNativeError("Stop must be -1 or >= start!");
|
||||
}
|
||||
|
||||
menu->ShufflePerClient(start, stop);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static cell_t MenuSetClientMapping(IPluginContext *pContext, const cell_t *params)
|
||||
{
|
||||
Handle_t hndl = (Handle_t)params[1];
|
||||
HandleError err;
|
||||
IBaseMenu *menu;
|
||||
|
||||
if ((err = ReadMenuHandle(params[1], &menu)) != HandleError_None)
|
||||
{
|
||||
return pContext->ThrowNativeError("Menu handle %x is invalid (error %d)", hndl, err);
|
||||
}
|
||||
|
||||
int client = params[2];
|
||||
if (client < 1 || client > SM_MAXPLAYERS)
|
||||
{
|
||||
return pContext->ThrowNativeError("Invalid client index!");
|
||||
}
|
||||
|
||||
cell_t *array;
|
||||
pContext->LocalToPhysAddr(params[3], &array);
|
||||
|
||||
int length = params[4];
|
||||
|
||||
menu->SetClientMapping(client, array, length);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static cell_t SetMenuPagination(IPluginContext *pContext, const cell_t *params)
|
||||
{
|
||||
Handle_t hndl = (Handle_t)params[1];
|
||||
@ -1645,6 +1702,8 @@ REGISTER_NATIVES(menuNatives)
|
||||
{"SetPanelKeys", SetPanelKeys},
|
||||
{"SetVoteResultCallback", SetVoteResultCallback},
|
||||
{"VoteMenu", VoteMenu},
|
||||
{"MenuShufflePerClient", MenuShufflePerClient},
|
||||
{"MenuSetClientMapping", MenuSetClientMapping},
|
||||
{"SetMenuNoVoteButton", SetMenuNoVoteButton},
|
||||
|
||||
// Transitional syntax support.
|
||||
@ -1673,6 +1732,8 @@ REGISTER_NATIVES(menuNatives)
|
||||
{"Menu.ToPanel", CreatePanelFromMenu},
|
||||
{"Menu.Cancel", CancelMenu},
|
||||
{"Menu.DisplayVote", VoteMenu},
|
||||
{"Menu.ShufflePerClient", MenuShufflePerClient},
|
||||
{"Menu.SetClientMapping", MenuSetClientMapping},
|
||||
{"Menu.Pagination.get", GetMenuPagination},
|
||||
{"Menu.Pagination.set", SetMenuPagination},
|
||||
{"Menu.OptionFlags.get", GetMenuOptionFlags},
|
||||
|
@ -141,6 +141,7 @@ public: //ICommandTargetProcessor
|
||||
|
||||
smtf->fun->PushString(info->pattern);
|
||||
smtf->fun->PushCell(ahc.getClone());
|
||||
smtf->fun->PushCell(info->admin);
|
||||
cell_t result = 0;
|
||||
if (smtf->fun->Execute(&result) != SP_ERROR_NONE || !result)
|
||||
return false;
|
||||
@ -1460,24 +1461,23 @@ static cell_t IsClientInKickQueue(IPluginContext *pContext, const cell_t *params
|
||||
return pPlayer->IsInKickQueue() ? 1 : 0;
|
||||
}
|
||||
|
||||
cmd_target_info_t g_ProcessTargetString_info;
|
||||
static cell_t ProcessTargetString(IPluginContext *pContext, const cell_t *params)
|
||||
{
|
||||
cmd_target_info_t info;
|
||||
|
||||
pContext->LocalToString(params[1], (char **) &info.pattern);
|
||||
info.admin = params[2];
|
||||
pContext->LocalToPhysAddr(params[3], &info.targets);
|
||||
info.max_targets = params[4];
|
||||
info.flags = params[5];
|
||||
pContext->LocalToString(params[6], &info.target_name);
|
||||
info.target_name_maxlength = params[7];
|
||||
pContext->LocalToString(params[1], (char **) &g_ProcessTargetString_info.pattern);
|
||||
g_ProcessTargetString_info.admin = params[2];
|
||||
pContext->LocalToPhysAddr(params[3], &g_ProcessTargetString_info.targets);
|
||||
g_ProcessTargetString_info.max_targets = params[4];
|
||||
g_ProcessTargetString_info.flags = params[5];
|
||||
pContext->LocalToString(params[6], &g_ProcessTargetString_info.target_name);
|
||||
g_ProcessTargetString_info.target_name_maxlength = params[7];
|
||||
|
||||
cell_t *tn_is_ml;
|
||||
pContext->LocalToPhysAddr(params[8], &tn_is_ml);
|
||||
|
||||
playerhelpers->ProcessCommandTarget(&info);
|
||||
playerhelpers->ProcessCommandTarget(&g_ProcessTargetString_info);
|
||||
|
||||
if (info.target_name_style == COMMAND_TARGETNAME_ML)
|
||||
if (g_ProcessTargetString_info.target_name_style == COMMAND_TARGETNAME_ML)
|
||||
{
|
||||
*tn_is_ml = 1;
|
||||
}
|
||||
@ -1486,16 +1486,30 @@ static cell_t ProcessTargetString(IPluginContext *pContext, const cell_t *params
|
||||
*tn_is_ml = 0;
|
||||
}
|
||||
|
||||
if (info.num_targets == 0)
|
||||
if (g_ProcessTargetString_info.num_targets == 0)
|
||||
{
|
||||
return info.reason;
|
||||
return g_ProcessTargetString_info.reason;
|
||||
}
|
||||
else
|
||||
{
|
||||
return info.num_targets;
|
||||
return g_ProcessTargetString_info.num_targets;
|
||||
}
|
||||
}
|
||||
|
||||
static cell_t GetLastProcessTargetString(IPluginContext *pContext, const cell_t *params)
|
||||
{
|
||||
cell_t *admin, *flags;
|
||||
|
||||
pContext->StringToLocalUTF8(params[1], params[2], g_ProcessTargetString_info.pattern, NULL);
|
||||
pContext->LocalToPhysAddr(params[3], &admin);
|
||||
pContext->LocalToPhysAddr(params[4], &flags);
|
||||
|
||||
*admin = g_ProcessTargetString_info.admin;
|
||||
*flags = g_ProcessTargetString_info.flags;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static cell_t FormatActivitySource(IPluginContext *pContext, const cell_t *params)
|
||||
{
|
||||
int value;
|
||||
@ -1647,6 +1661,7 @@ REGISTER_NATIVES(playernatives)
|
||||
{ "NotifyPostAdminCheck", NotifyPostAdminCheck },
|
||||
{ "IsClientInKickQueue", IsClientInKickQueue },
|
||||
{ "ProcessTargetString", ProcessTargetString },
|
||||
{ "GetLastProcessTargetString", GetLastProcessTargetString },
|
||||
{ "FormatActivitySource", FormatActivitySource },
|
||||
{ "GetClientSerial", sm_GetClientSerial },
|
||||
{ "GetClientFromSerial", sm_GetClientFromSerial },
|
||||
|
@ -45,35 +45,14 @@
|
||||
#include "ConCmdManager.h"
|
||||
#include "IDBDriver.h"
|
||||
#include "provider.h"
|
||||
#if SOURCE_ENGINE >= SE_ALIENSWARM
|
||||
# include "convar_sm_swarm.h"
|
||||
#elif SOURCE_ENGINE >= SE_LEFT4DEAD
|
||||
# include "convar_sm_l4d.h"
|
||||
#elif SOURCE_ENGINE >= SE_ORANGEBOX
|
||||
# include "convar_sm_ob.h"
|
||||
#else
|
||||
# include "convar_sm.h"
|
||||
#endif
|
||||
#include "sm_convar.h"
|
||||
#include <amtl/os/am-shared-library.h>
|
||||
#include <amtl/os/am-path.h>
|
||||
#include <bridge/include/IVEngineServerBridge.h>
|
||||
#include <bridge/include/IPlayerInfoBridge.h>
|
||||
#include <bridge/include/IFileSystemBridge.h>
|
||||
|
||||
#if defined _WIN32
|
||||
# define MATCHMAKINGDS_SUFFIX ""
|
||||
# define MATCHMAKINGDS_EXT "dll"
|
||||
#elif defined __APPLE__
|
||||
# define MATCHMAKINGDS_SUFFIX ""
|
||||
# define MATCHMAKINGDS_EXT "dylib"
|
||||
#elif defined __linux__
|
||||
#if SOURCE_ENGINE < SE_LEFT4DEAD2
|
||||
# define MATCHMAKINGDS_SUFFIX "_i486"
|
||||
#else
|
||||
# define MATCHMAKINGDS_SUFFIX ""
|
||||
#endif
|
||||
# define MATCHMAKINGDS_EXT "so"
|
||||
#endif
|
||||
#define MATCHMAKINGDS_NAME "matchmaking_ds" SOURCE_BIN_SUFFIX SOURCE_BIN_EXT
|
||||
|
||||
sm_logic_t logicore;
|
||||
|
||||
@ -653,10 +632,8 @@ void CoreProviderImpl::InitializeBridge()
|
||||
char path[PLATFORM_MAX_PATH];
|
||||
|
||||
ke::path::Format(path, sizeof(path),
|
||||
"%s/bin/matchmaking_ds%s.%s",
|
||||
g_SMAPI->GetBaseDir(),
|
||||
MATCHMAKINGDS_SUFFIX,
|
||||
MATCHMAKINGDS_EXT);
|
||||
"%s/bin/" MATCHMAKINGDS_NAME,
|
||||
g_SMAPI->GetBaseDir());
|
||||
|
||||
if (ke::RefPtr<ke::SharedLib> mmlib = ke::SharedLib::Open(path, NULL, 0)) {
|
||||
this->matchmakingDSFactory =
|
||||
|
38
core/sm_convar.h
Normal file
38
core/sm_convar.h
Normal file
@ -0,0 +1,38 @@
|
||||
/**
|
||||
* vim: set ts=4 :
|
||||
* =============================================================================
|
||||
* SourceMod
|
||||
* Copyright (C) 2004-2018 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$
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#define protected public
|
||||
#define private public
|
||||
#include <tier1/convar.h>
|
||||
#undef protected
|
||||
#undef private
|
@ -141,14 +141,14 @@ public:
|
||||
if (m_CmdFlags.retrieve(name, &pCmd))
|
||||
{
|
||||
TrackConCommandBase(pCmd, this);
|
||||
*flags = pCmd->GetFlags();
|
||||
*flags = pCmd->m_nFlags;
|
||||
return true;
|
||||
}
|
||||
else if ((pCmd=FindCommandBase(name)))
|
||||
{
|
||||
m_CmdFlags.insert(name, pCmd);
|
||||
TrackConCommandBase(pCmd, this);
|
||||
*flags = pCmd->GetFlags();
|
||||
*flags = pCmd->m_nFlags;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
@ -161,14 +161,14 @@ public:
|
||||
ConCommandBase *pCmd;
|
||||
if (m_CmdFlags.retrieve(name, &pCmd))
|
||||
{
|
||||
pCmd->SetFlags(flags);
|
||||
pCmd->m_nFlags = flags;
|
||||
TrackConCommandBase(pCmd, this);
|
||||
return true;
|
||||
}
|
||||
else if ((pCmd=FindCommandBase(name)))
|
||||
{
|
||||
m_CmdFlags.insert(name, pCmd);
|
||||
pCmd->SetFlags(flags);
|
||||
pCmd->m_nFlags = flags;
|
||||
TrackConCommandBase(pCmd, this);
|
||||
return true;
|
||||
}
|
||||
@ -184,6 +184,10 @@ private:
|
||||
{
|
||||
return strcmp(name, base->GetName()) == 0;
|
||||
}
|
||||
static inline uint32_t hash(const detail::CharsAndLength &key)
|
||||
{
|
||||
return key.hash();
|
||||
}
|
||||
};
|
||||
NameHashSet<ConCommandBase *, ConCommandPolicy> m_CmdFlags;
|
||||
} s_CommandFlagsHelper;
|
||||
@ -540,7 +544,7 @@ static cell_t sm_GetConVarFlags(IPluginContext *pContext, const cell_t *params)
|
||||
return pContext->ThrowNativeError("Invalid convar handle %x (error %d)", hndl, err);
|
||||
}
|
||||
|
||||
return pConVar->GetFlags();
|
||||
return pConVar->m_nFlags;
|
||||
}
|
||||
|
||||
static cell_t sm_SetConVarFlags(IPluginContext *pContext, const cell_t *params)
|
||||
@ -555,7 +559,7 @@ static cell_t sm_SetConVarFlags(IPluginContext *pContext, const cell_t *params)
|
||||
return pContext->ThrowNativeError("Invalid convar handle %x (error %d)", hndl, err);
|
||||
}
|
||||
|
||||
pConVar->SetFlags(params[2]);
|
||||
pConVar->m_nFlags = params[2];
|
||||
|
||||
return 1;
|
||||
}
|
||||
@ -609,10 +613,12 @@ static cell_t sm_SetConVarBounds(IPluginContext *pContext, const cell_t *params)
|
||||
switch (params[2])
|
||||
{
|
||||
case ConVarBound_Upper:
|
||||
pConVar->SetMax(params[3] ? true : false, sp_ctof(params[4]));
|
||||
pConVar->m_fMaxVal = sp_ctof(params[4]);
|
||||
pConVar->m_bHasMax = params[3] ? true : false;
|
||||
break;
|
||||
case ConVarBound_Lower:
|
||||
pConVar->SetMin(params[3] ? true : false, sp_ctof(params[4]));
|
||||
pConVar->m_fMinVal = sp_ctof(params[4]);
|
||||
pConVar->m_bHasMin = params[3] ? true : false;
|
||||
break;
|
||||
default:
|
||||
return pContext->ThrowNativeError("Invalid ConVarBounds value %d");
|
||||
@ -782,6 +788,16 @@ static cell_t sm_RegAdminCmd(IPluginContext *pContext, const cell_t *params)
|
||||
return 1;
|
||||
}
|
||||
|
||||
static cell_t sm_IsCommandCallback(IPluginContext *pContext, const cell_t *params)
|
||||
{
|
||||
const ICommandArgs *pCmd = g_HL2.PeekCommandStack();
|
||||
|
||||
if (!pCmd)
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static cell_t sm_GetCmdArgs(IPluginContext *pContext, const cell_t *params)
|
||||
{
|
||||
const ICommandArgs *pCmd = g_HL2.PeekCommandStack();
|
||||
@ -1086,7 +1102,7 @@ static cell_t FindFirstConCommand(IPluginContext *pContext, const cell_t *params
|
||||
|
||||
pContext->StringToLocalUTF8(params[1], params[2], pConCmd->GetName(), NULL);
|
||||
*pIsCmd = pConCmd->IsCommand() ? 1 : 0;
|
||||
*pFlags = pConCmd->GetFlags();
|
||||
*pFlags = pConCmd->m_nFlags;
|
||||
|
||||
if (params[6])
|
||||
{
|
||||
@ -1135,7 +1151,7 @@ static cell_t FindNextConCommand(IPluginContext *pContext, const cell_t *params)
|
||||
|
||||
pContext->StringToLocalUTF8(params[2], params[3], pConCmd->GetName(), NULL);
|
||||
*pIsCmd = pConCmd->IsCommand() ? 1 : 0;
|
||||
*pFlags = pConCmd->GetFlags();
|
||||
*pFlags = pConCmd->m_nFlags;
|
||||
|
||||
if (params[7])
|
||||
{
|
||||
@ -1325,6 +1341,7 @@ REGISTER_NATIVES(consoleNatives)
|
||||
{"GetConVarDefault", GetConVarDefault},
|
||||
{"RegServerCmd", sm_RegServerCmd},
|
||||
{"RegConsoleCmd", sm_RegConsoleCmd},
|
||||
{"IsCommandCallback", sm_IsCommandCallback},
|
||||
{"GetCmdArgString", sm_GetCmdArgString},
|
||||
{"GetCmdArgs", sm_GetCmdArgs},
|
||||
{"GetCmdArg", sm_GetCmdArg},
|
||||
|
@ -94,6 +94,7 @@ enum PropFieldType
|
||||
PropField_Variant, /**< Valid for variants/any. (User must know type) */
|
||||
};
|
||||
|
||||
// From game/server/variant_t.h, same on all supported games.
|
||||
class variant_t
|
||||
{
|
||||
public:
|
||||
@ -111,6 +112,15 @@ public:
|
||||
fieldtype_t fieldType;
|
||||
};
|
||||
|
||||
// From game/server/baseentity.h, same on all supported games.
|
||||
struct inputdata_t
|
||||
{
|
||||
CBaseEntity *pActivator; // The entity that initially caused this chain of output events.
|
||||
CBaseEntity *pCaller; // The entity that fired this particular output.
|
||||
variant_t value; // The data parameter for this output.
|
||||
int nOutputID; // The unique ID of the output that was fired.
|
||||
};
|
||||
|
||||
inline bool CanSetPropName(const char *pszPropName)
|
||||
{
|
||||
#if SOURCE_ENGINE == SE_CSGO
|
||||
@ -280,6 +290,47 @@ static cell_t RemoveEdict(IPluginContext *pContext, const cell_t *params)
|
||||
return 1;
|
||||
}
|
||||
|
||||
static cell_t RemoveEntity(IPluginContext *pContext, const cell_t *params)
|
||||
{
|
||||
auto *pEntity = GetEntity(params[1]);
|
||||
if (!pEntity)
|
||||
{
|
||||
return pContext->ThrowNativeError("Entity %d (%d) is not a valid entity", g_HL2.ReferenceToIndex(params[1]), params[1]);
|
||||
}
|
||||
|
||||
// Some games have UTIL_Remove exposed on IServerTools, but for consistence, we'll
|
||||
// use this method for all. Results in DeathNotice( this ) being called on parent,
|
||||
// and parent being cleared (both if any parent) before UTIL_Remove is called.
|
||||
static inputfunc_t fnKillEntity = nullptr;
|
||||
if (!fnKillEntity)
|
||||
{
|
||||
// Get world, as other ents aren't guaranteed to inherit full datadesc (but kill func is same for all)
|
||||
CBaseEntity *pGetterEnt = g_HL2.ReferenceToEntity(0);
|
||||
if (pGetterEnt == nullptr)
|
||||
{
|
||||
// If we don't have a world entity yet, we'll have to rely on the given entity. Does this even make sense???
|
||||
pGetterEnt = pEntity;
|
||||
}
|
||||
|
||||
datamap_t *pMap = g_HL2.GetDataMap(pGetterEnt);
|
||||
|
||||
sm_datatable_info_t info;
|
||||
if (!g_HL2.FindDataMapInfo(pMap, "InputKill", &info))
|
||||
{
|
||||
return pContext->ThrowNativeError("Failed to find Kill input!");
|
||||
}
|
||||
|
||||
fnKillEntity = info.prop->inputFunc;
|
||||
}
|
||||
|
||||
// Input data is ignored for this. No need to initialize
|
||||
static inputdata_t data;
|
||||
|
||||
(pEntity->*fnKillEntity)(data);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static cell_t IsValidEdict(IPluginContext *pContext, const cell_t *params)
|
||||
{
|
||||
edict_t *pEdict = GetEdict(params[1]);
|
||||
@ -2640,6 +2691,7 @@ REGISTER_NATIVES(entityNatives)
|
||||
{"IsEntNetworkable", IsEntNetworkable},
|
||||
{"IsValidEdict", IsValidEdict},
|
||||
{"IsValidEntity", IsValidEntity},
|
||||
{"RemoveEntity", RemoveEntity},
|
||||
{"RemoveEdict", RemoveEdict},
|
||||
{"SetEdictFlags", SetEdictFlags},
|
||||
{"SetEntData", SetEntData},
|
||||
|
@ -356,6 +356,27 @@ static cell_t GetAvgPackets(IPluginContext *pContext, const cell_t *params)
|
||||
return sp_ftoc(value);
|
||||
}
|
||||
|
||||
static cell_t sm_GetClientIClient(IPluginContext *pContext, const cell_t *params)
|
||||
{
|
||||
int client = params[1];
|
||||
|
||||
CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
|
||||
if (!pPlayer)
|
||||
{
|
||||
return pContext->ThrowNativeError("Client index %d is invalid", client);
|
||||
}
|
||||
else if (!pPlayer->IsConnected())
|
||||
{
|
||||
return pContext->ThrowNativeError("Client %d is not connected", client);
|
||||
}
|
||||
else if (pPlayer->IsFakeClient())
|
||||
{
|
||||
return pContext->ThrowNativeError("Client %d is a bot", client);
|
||||
}
|
||||
|
||||
return (cell_t)pPlayer->GetIClient();
|
||||
}
|
||||
|
||||
static cell_t RunAdminCacheChecks(IPluginContext *pContext, const cell_t *params)
|
||||
{
|
||||
int client = params[1];
|
||||
@ -392,6 +413,7 @@ REGISTER_NATIVES(playernatives)
|
||||
{"GetClientAvgChoke", GetAvgChoke},
|
||||
{"GetClientAvgData", GetAvgData},
|
||||
{"GetClientAvgPackets", GetAvgPackets},
|
||||
{"GetClientIClient", sm_GetClientIClient },
|
||||
{"RunAdminCacheChecks", RunAdminCacheChecks},
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
@ -32,15 +32,7 @@
|
||||
#ifndef _INCLUDE_SOURCEMOD_MM_API_H_
|
||||
#define _INCLUDE_SOURCEMOD_MM_API_H_
|
||||
|
||||
#if SOURCE_ENGINE >= SE_ALIENSWARM
|
||||
#include "convar_sm_swarm.h"
|
||||
#elif SOURCE_ENGINE >= SE_LEFT4DEAD
|
||||
#include "convar_sm_l4d.h"
|
||||
#elif SOURCE_ENGINE >= SE_ORANGEBOX
|
||||
#include "convar_sm_ob.h"
|
||||
#else
|
||||
#include "convar_sm.h"
|
||||
#endif
|
||||
#include "sm_convar.h"
|
||||
#include <ISmmPlugin.h>
|
||||
#include <eiface.h>
|
||||
#include <igameevents.h>
|
||||
|
@ -96,6 +96,10 @@ struct Cookie
|
||||
{
|
||||
return strcmp(name, cookie->name) == 0;
|
||||
}
|
||||
static inline uint32_t hash(const detail::CharsAndLength &key)
|
||||
{
|
||||
return key.hash();
|
||||
}
|
||||
};
|
||||
|
||||
class CookieManager : public IClientListener, public IPluginsListener
|
||||
|
@ -51,6 +51,7 @@ IGameConfig *g_pGameConf = NULL;
|
||||
IGameEventManager2 *gameevents = NULL;
|
||||
bool hooked_everything = false;
|
||||
int g_msgHintText = -1;
|
||||
CGlobalVars *gpGlobals;
|
||||
|
||||
SMEXT_LINK(&g_CStrike);
|
||||
|
||||
@ -107,6 +108,7 @@ bool CStrike::SDK_OnMetamodLoad(ISmmAPI *ismm, char *error, size_t maxlen, bool
|
||||
{
|
||||
GET_V_IFACE_CURRENT(GetEngineFactory, gameevents, IGameEventManager2, INTERFACEVERSION_GAMEEVENTSMANAGER2);
|
||||
GET_V_IFACE_CURRENT(GetEngineFactory, engine, IVEngineServer, INTERFACEVERSION_VENGINESERVER);
|
||||
gpGlobals = ismm->GetCGlobals();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -166,6 +166,7 @@ private:
|
||||
extern IBinTools *g_pBinTools;
|
||||
extern IGameConfig *g_pGameConf;
|
||||
extern ISDKTools *g_pSDKTools;
|
||||
extern CGlobalVars *gpGlobals;
|
||||
extern int g_msgHintText;
|
||||
extern bool g_pIgnoreTerminateDetour;
|
||||
extern bool g_pIgnoreCSWeaponDropDetour;
|
||||
|
@ -126,7 +126,7 @@ DETOUR_DECL_MEMBER0(DetourWeaponPrice, int)
|
||||
}
|
||||
#endif
|
||||
|
||||
#if SOURCE_ENGINE != SE_CSGO || !defined(WIN32)
|
||||
#if SOURCE_ENGINE != SE_CSGO
|
||||
DETOUR_DECL_MEMBER2(DetourTerminateRound, void, float, delay, int, reason)
|
||||
{
|
||||
if (g_pIgnoreTerminateDetour)
|
||||
@ -135,20 +135,31 @@ DETOUR_DECL_MEMBER2(DetourTerminateRound, void, float, delay, int, reason)
|
||||
DETOUR_MEMBER_CALL(DetourTerminateRound)(delay, reason);
|
||||
return;
|
||||
}
|
||||
#elif !defined(WIN32)
|
||||
DETOUR_DECL_MEMBER4(DetourTerminateRound, void, float, delay, int, reason, int, unknown, int, unknown2)
|
||||
{
|
||||
if (g_pIgnoreTerminateDetour)
|
||||
{
|
||||
g_pIgnoreTerminateDetour = false;
|
||||
DETOUR_MEMBER_CALL(DetourTerminateRound)(delay, reason, unknown, unknown2);
|
||||
return;
|
||||
}
|
||||
#else
|
||||
//Windows CSGO
|
||||
//char __userpurge TerminateRound(int a1@<ecx>, float a2@<xmm1>, int *a3)
|
||||
// a1 - this
|
||||
// a2 - delay
|
||||
// a3 - reason
|
||||
DETOUR_DECL_MEMBER1(DetourTerminateRound, void, int, reason)
|
||||
// a4 - unknown
|
||||
// a5 - unknown
|
||||
DETOUR_DECL_MEMBER3(DetourTerminateRound, void, int, reason, int, unknown, int, unknown2)
|
||||
{
|
||||
float delay;
|
||||
|
||||
if (g_pIgnoreTerminateDetour)
|
||||
{
|
||||
g_pIgnoreTerminateDetour = false;
|
||||
return DETOUR_MEMBER_CALL(DetourTerminateRound)(reason);
|
||||
return DETOUR_MEMBER_CALL(DetourTerminateRound)(reason, unknown, unknown2);
|
||||
}
|
||||
|
||||
//Save the delay
|
||||
@ -178,11 +189,16 @@ DETOUR_DECL_MEMBER1(DetourTerminateRound, void, int, reason)
|
||||
reason++;
|
||||
#endif
|
||||
|
||||
#if SOURCE_ENGINE != SE_CSGO || !defined(WIN32)
|
||||
#if SOURCE_ENGINE != SE_CSGO
|
||||
if (result == Pl_Changed)
|
||||
return DETOUR_MEMBER_CALL(DetourTerminateRound)(delay, reason);
|
||||
|
||||
return DETOUR_MEMBER_CALL(DetourTerminateRound)(orgdelay, orgreason);
|
||||
#elif !defined(WIN32)
|
||||
if (result == Pl_Changed)
|
||||
return DETOUR_MEMBER_CALL(DetourTerminateRound)(delay, reason, unknown, unknown2);
|
||||
|
||||
return DETOUR_MEMBER_CALL(DetourTerminateRound)(orgdelay, orgreason, unknown, unknown2);
|
||||
#else
|
||||
if (result == Pl_Changed)
|
||||
{
|
||||
@ -190,22 +206,22 @@ DETOUR_DECL_MEMBER1(DetourTerminateRound, void, int, reason)
|
||||
{
|
||||
movss xmm1, delay
|
||||
}
|
||||
return DETOUR_MEMBER_CALL(DetourTerminateRound)(reason);
|
||||
return DETOUR_MEMBER_CALL(DetourTerminateRound)(reason, unknown, unknown2);
|
||||
}
|
||||
__asm
|
||||
{
|
||||
movss xmm1, orgdelay
|
||||
}
|
||||
return DETOUR_MEMBER_CALL(DetourTerminateRound)(orgreason);
|
||||
return DETOUR_MEMBER_CALL(DetourTerminateRound)(orgreason, unknown, unknown2);
|
||||
#endif
|
||||
}
|
||||
|
||||
DETOUR_DECL_MEMBER3(DetourCSWeaponDrop, void, CBaseEntity *, weapon, bool, bDropShield, bool, bThrowForward)
|
||||
DETOUR_DECL_MEMBER2(DetourCSWeaponDrop, void, CBaseEntity *, weapon, bool, bThrowForward)
|
||||
{
|
||||
if (g_pIgnoreCSWeaponDropDetour)
|
||||
{
|
||||
g_pIgnoreCSWeaponDropDetour = false;
|
||||
DETOUR_MEMBER_CALL(DetourCSWeaponDrop)(weapon, bDropShield, bThrowForward);
|
||||
DETOUR_MEMBER_CALL(DetourCSWeaponDrop)(weapon, bThrowForward);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -220,7 +236,7 @@ DETOUR_DECL_MEMBER3(DetourCSWeaponDrop, void, CBaseEntity *, weapon, bool, bDrop
|
||||
|
||||
if (result == Pl_Continue)
|
||||
{
|
||||
DETOUR_MEMBER_CALL(DetourCSWeaponDrop)(weapon, bDropShield, bThrowForward);
|
||||
DETOUR_MEMBER_CALL(DetourCSWeaponDrop)(weapon, bThrowForward);
|
||||
}
|
||||
|
||||
return;
|
||||
|
@ -230,17 +230,14 @@ static cell_t CS_DropWeapon(IPluginContext *pContext, const cell_t *params)
|
||||
if (!pWrapper)
|
||||
{
|
||||
REGISTER_NATIVE_ADDR(WEAPONDROP_GAMEDATA_NAME,
|
||||
PassInfo pass[3]; \
|
||||
PassInfo pass[2]; \
|
||||
pass[0].flags = PASSFLAG_BYVAL; \
|
||||
pass[0].type = PassType_Basic; \
|
||||
pass[0].size = sizeof(CBaseEntity *); \
|
||||
pass[1].flags = PASSFLAG_BYVAL; \
|
||||
pass[1].type = PassType_Basic; \
|
||||
pass[1].size = sizeof(bool); \
|
||||
pass[2].flags = PASSFLAG_BYVAL; \
|
||||
pass[2].type = PassType_Basic; \
|
||||
pass[2].size = sizeof(bool); \
|
||||
pWrapper = g_pBinTools->CreateCall(addr, CallConv_ThisCall, NULL, pass, 3))
|
||||
pWrapper = g_pBinTools->CreateCall(addr, CallConv_ThisCall, NULL, pass, 2))
|
||||
}
|
||||
|
||||
CBaseEntity *pEntity;
|
||||
@ -273,16 +270,13 @@ static cell_t CS_DropWeapon(IPluginContext *pContext, const cell_t *params)
|
||||
if (params[4] == 1 && g_pCSWeaponDropDetoured)
|
||||
g_pIgnoreCSWeaponDropDetour = true;
|
||||
|
||||
unsigned char vstk[sizeof(CBaseEntity *) * 2 + sizeof(bool) * 2];
|
||||
unsigned char vstk[sizeof(CBaseEntity *) * 2 + sizeof(bool)];
|
||||
unsigned char *vptr = vstk;
|
||||
|
||||
// <psychonic> first one is always false. second is true to toss, false to just drop
|
||||
*(CBaseEntity **)vptr = pEntity;
|
||||
vptr += sizeof(CBaseEntity *);
|
||||
*(CBaseEntity **)vptr = pWeapon;
|
||||
vptr += sizeof(CBaseEntity *);
|
||||
*(bool *)vptr = false;
|
||||
vptr += sizeof(bool);
|
||||
*(bool *)vptr = (params[3]) ? true : false;
|
||||
|
||||
pWrapper->Execute(vstk, NULL);
|
||||
@ -314,7 +308,7 @@ static cell_t CS_TerminateRound(IPluginContext *pContext, const cell_t *params)
|
||||
reason++;
|
||||
#endif
|
||||
|
||||
#if SOURCE_ENGINE != SE_CSGO || !defined(WIN32)
|
||||
#if SOURCE_ENGINE != SE_CSGO
|
||||
static ICallWrapper *pWrapper = NULL;
|
||||
|
||||
if (!pWrapper)
|
||||
@ -342,6 +336,45 @@ static cell_t CS_TerminateRound(IPluginContext *pContext, const cell_t *params)
|
||||
vptr += sizeof(float);
|
||||
*(int*)vptr = reason;
|
||||
|
||||
pWrapper->Execute(vstk, NULL);
|
||||
#elif !defined(WIN32)
|
||||
static ICallWrapper *pWrapper = NULL;
|
||||
|
||||
if (!pWrapper)
|
||||
{
|
||||
REGISTER_NATIVE_ADDR("TerminateRound",
|
||||
PassInfo pass[4]; \
|
||||
pass[0].flags = PASSFLAG_BYVAL; \
|
||||
pass[0].type = PassType_Basic; \
|
||||
pass[0].size = sizeof(float); \
|
||||
pass[1].flags = PASSFLAG_BYVAL; \
|
||||
pass[1].type = PassType_Basic; \
|
||||
pass[1].size = sizeof(int); \
|
||||
pass[2].flags = PASSFLAG_BYVAL; \
|
||||
pass[2].type = PassType_Basic; \
|
||||
pass[2].size = sizeof(int); \
|
||||
pass[3].flags = PASSFLAG_BYVAL; \
|
||||
pass[3].type = PassType_Basic; \
|
||||
pass[3].size = sizeof(int); \
|
||||
pWrapper = g_pBinTools->CreateCall(addr, CallConv_ThisCall, NULL, pass, 4))
|
||||
}
|
||||
|
||||
if (params[3] == 1 && g_pTerminateRoundDetoured)
|
||||
g_pIgnoreTerminateDetour = true;
|
||||
|
||||
unsigned char vstk[sizeof(void *) + sizeof(float) + (sizeof(int)*3)];
|
||||
unsigned char *vptr = vstk;
|
||||
|
||||
*(void **)vptr = gamerules;
|
||||
vptr += sizeof(void *);
|
||||
*(float *)vptr = sp_ctof(params[1]);
|
||||
vptr += sizeof(float);
|
||||
*(int*)vptr = reason;
|
||||
vptr += sizeof(int);
|
||||
*(int*)vptr = 0;
|
||||
vptr += sizeof(int);
|
||||
*(int*)vptr = 0;
|
||||
|
||||
pWrapper->Execute(vstk, NULL);
|
||||
#else
|
||||
static void *addr = NULL;
|
||||
@ -358,6 +391,8 @@ static cell_t CS_TerminateRound(IPluginContext *pContext, const cell_t *params)
|
||||
|
||||
__asm
|
||||
{
|
||||
push 0
|
||||
push 0
|
||||
push reason
|
||||
movss xmm1, delay
|
||||
mov ecx, gamerules
|
||||
@ -866,9 +901,9 @@ static cell_t CS_UpdateClientModel(IPluginContext *pContext, const cell_t *param
|
||||
static cell_t CS_ItemDefIndexToID(IPluginContext *pContext, const cell_t *params)
|
||||
{
|
||||
#if SOURCE_ENGINE == SE_CSGO
|
||||
ItemIndexMap::Result res = g_mapDefIdxToClass.find((uint16_t)params[1]);
|
||||
|
||||
if (!res.found())
|
||||
ItemIndexMap::Result res = g_mapDefIdxToClass.find((uint16_t)params[1]);
|
||||
|
||||
if (!res.found())
|
||||
return pContext->ThrowNativeError("Invalid item definition passed.");
|
||||
|
||||
return res->value.m_iWeaponID;
|
||||
@ -880,9 +915,9 @@ static cell_t CS_ItemDefIndexToID(IPluginContext *pContext, const cell_t *params
|
||||
static cell_t CS_WeaponIDToItemDefIndex(IPluginContext *pContext, const cell_t *params)
|
||||
{
|
||||
#if SOURCE_ENGINE == SE_CSGO
|
||||
WeaponIDMap::Result res = g_mapWeaponIDToDefIdx.find((SMCSWeapon)params[1]);
|
||||
|
||||
if (!res.found())
|
||||
WeaponIDMap::Result res = g_mapWeaponIDToDefIdx.find((SMCSWeapon)params[1]);
|
||||
|
||||
if (!res.found())
|
||||
return pContext->ThrowNativeError("Invalid weapon id passed.");
|
||||
|
||||
return res->value.m_iDefIdx;
|
||||
|
@ -58,7 +58,19 @@ void TimeLeftEvents::FireGameEvent(IGameEvent *event)
|
||||
if (get_new_timeleft_offset || !round_end_found)
|
||||
{
|
||||
get_new_timeleft_offset = false;
|
||||
timersys->NotifyOfGameStart();
|
||||
|
||||
float flGameStartTime = gpGlobals->curtime;
|
||||
uintptr_t gamerules = (uintptr_t)g_pSDKTools->GetGameRules();
|
||||
if (gamerules)
|
||||
{
|
||||
sm_sendprop_info_t info;
|
||||
if (gamehelpers->FindSendPropInfo("CCSGameRulesProxy", "m_flGameStartTime", &info))
|
||||
{
|
||||
flGameStartTime = *(float *)(gamerules + info.actual_offset);
|
||||
}
|
||||
}
|
||||
|
||||
timersys->NotifyOfGameStart(flGameStartTime - gpGlobals->curtime);
|
||||
timersys->MapTimeLeftChanged();
|
||||
}
|
||||
round_end_found = false;
|
||||
|
@ -336,7 +336,7 @@ SMCSWeapon GetWeaponIdFromDefIdx(uint16_t iDefIdx)
|
||||
SMCSWeapon_AUG, SMCSWeapon_AWP, SMCSWeapon_FAMAS, SMCSWeapon_G3SG1,
|
||||
SMCSWeapon_NONE, SMCSWeapon_GALILAR, SMCSWeapon_M249, SMCSWeapon_NONE,
|
||||
SMCSWeapon_M4A1, SMCSWeapon_MAC10, SMCSWeapon_NONE, SMCSWeapon_P90,
|
||||
SMCSWeapon_NONE, SMCSWeapon_NONE, SMCSWeapon_NONE, SMCSWeapon_NONE,
|
||||
SMCSWeapon_NONE, SMCSWeapon_NONE, SMCSWeapon_NONE, SMCSWeapon_MP5NAVY,
|
||||
SMCSWeapon_UMP45, SMCSWeapon_XM1014, SMCSWeapon_BIZON, SMCSWeapon_MAG7,
|
||||
SMCSWeapon_NEGEV, SMCSWeapon_SAWEDOFF, SMCSWeapon_TEC9, SMCSWeapon_TASER,
|
||||
SMCSWeapon_HKP2000, SMCSWeapon_MP7, SMCSWeapon_MP9, SMCSWeapon_NOVA,
|
||||
|
@ -33,22 +33,23 @@
|
||||
|
||||
#include "pcre.h"
|
||||
#include "CRegEx.h"
|
||||
#include <sh_string.h>
|
||||
#include "extension.h"
|
||||
|
||||
RegEx::RegEx()
|
||||
{
|
||||
mErrorOffset = 0;
|
||||
mErrorCode = 0;
|
||||
mError = NULL;
|
||||
re = NULL;
|
||||
mFree = true;
|
||||
subject = NULL;
|
||||
mSubStrings = 0;
|
||||
mMatchCount = 0;
|
||||
}
|
||||
|
||||
void RegEx::Clear ()
|
||||
{
|
||||
mErrorOffset = 0;
|
||||
mErrorCode = 0;
|
||||
mError = NULL;
|
||||
if (re)
|
||||
pcre_free(re);
|
||||
@ -57,7 +58,7 @@ void RegEx::Clear ()
|
||||
if (subject)
|
||||
delete [] subject;
|
||||
subject = NULL;
|
||||
mSubStrings = 0;
|
||||
mMatchCount = 0;
|
||||
}
|
||||
|
||||
RegEx::~RegEx()
|
||||
@ -81,7 +82,7 @@ int RegEx::Compile(const char *pattern, int iFlags)
|
||||
if (!mFree)
|
||||
Clear();
|
||||
|
||||
re = pcre_compile(pattern, iFlags, &mError, &mErrorOffset, NULL);
|
||||
re = pcre_compile2(pattern, iFlags, &mErrorCode, &mError, &mErrorOffset, NULL);
|
||||
|
||||
if (re == NULL)
|
||||
{
|
||||
@ -93,7 +94,7 @@ int RegEx::Compile(const char *pattern, int iFlags)
|
||||
return 1;
|
||||
}
|
||||
|
||||
int RegEx::Match(const char *str)
|
||||
int RegEx::Match(const char *str, unsigned int offset)
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
@ -106,7 +107,9 @@ int RegEx::Match(const char *str)
|
||||
subject = new char[strlen(str)+1];
|
||||
strcpy(subject, str);
|
||||
|
||||
rc = pcre_exec(re, NULL, subject, (int)strlen(subject), 0, 0, ovector, 30);
|
||||
unsigned int len = strlen(subject);
|
||||
|
||||
rc = pcre_exec(re, NULL, subject, len, offset, 0, mMatches[0].mVector, MAX_CAPTURES);
|
||||
|
||||
if (rc < 0)
|
||||
{
|
||||
@ -114,34 +117,80 @@ int RegEx::Match(const char *str)
|
||||
{
|
||||
return 0;
|
||||
} else {
|
||||
mErrorOffset = rc;
|
||||
mErrorCode = rc;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
mSubStrings = rc;
|
||||
mMatches[0].mSubStringCount = rc;
|
||||
mMatchCount = 1;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int RegEx::MatchAll(const char *str)
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
if (mFree || re == NULL)
|
||||
return -1;
|
||||
|
||||
this->ClearMatch();
|
||||
|
||||
//save str
|
||||
subject = new char[strlen(str) + 1];
|
||||
strcpy(subject, str);
|
||||
|
||||
unsigned int offset = 0;
|
||||
unsigned int len = strlen(subject);
|
||||
unsigned int matches = 0;
|
||||
|
||||
while (matches < MAX_MATCHES && offset < len && (rc = pcre_exec(re, 0, subject, len, offset, 0, mMatches[matches].mVector, MAX_CAPTURES)) >= 0)
|
||||
{
|
||||
offset = mMatches[matches].mVector[1];
|
||||
mMatches[matches].mSubStringCount = rc;
|
||||
|
||||
matches++;
|
||||
}
|
||||
|
||||
if (rc < PCRE_ERROR_NOMATCH || (rc == PCRE_ERROR_NOMATCH && matches == 0))
|
||||
{
|
||||
if (rc == PCRE_ERROR_NOMATCH)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
else {
|
||||
mErrorCode = rc;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
mMatchCount = matches;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void RegEx::ClearMatch()
|
||||
{
|
||||
// Clears match results
|
||||
mErrorOffset = 0;
|
||||
mErrorCode = 0;
|
||||
mError = NULL;
|
||||
if (subject)
|
||||
delete [] subject;
|
||||
subject = NULL;
|
||||
mSubStrings = 0;
|
||||
mMatchCount = 0;
|
||||
}
|
||||
|
||||
const char *RegEx::GetSubstring(int s, char buffer[], int max)
|
||||
bool RegEx::GetSubstring(int s, char buffer[], int max, int match)
|
||||
{
|
||||
int i = 0;
|
||||
if (s >= mSubStrings || s < 0)
|
||||
return NULL;
|
||||
|
||||
char *substr_a = subject + ovector[2*s];
|
||||
int substr_l = ovector[2*s+1] - ovector[2*s];
|
||||
if (s >= mMatches[match].mSubStringCount || s < 0)
|
||||
return false;
|
||||
|
||||
char *substr_a = subject + mMatches[match].mVector[2 * s];
|
||||
int substr_l = mMatches[match].mVector[2 * s + 1] - mMatches[match].mVector[2 * s];
|
||||
|
||||
for (i = 0; i<substr_l; i++)
|
||||
{
|
||||
@ -152,6 +201,6 @@ const char *RegEx::GetSubstring(int s, char buffer[], int max)
|
||||
|
||||
buffer[i] = '\0';
|
||||
|
||||
return buffer;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -28,10 +28,20 @@
|
||||
*
|
||||
* Version: $Id$
|
||||
*/
|
||||
#include <am-string.h>
|
||||
|
||||
#ifndef _INCLUDE_CREGEX_H
|
||||
#define _INCLUDE_CREGEX_H
|
||||
|
||||
#define MAX_MATCHES 20
|
||||
#define MAX_CAPTURES MAX_MATCHES*3
|
||||
|
||||
struct RegexMatch
|
||||
{
|
||||
int mSubStringCount;
|
||||
int mVector[MAX_CAPTURES];
|
||||
};
|
||||
|
||||
class RegEx
|
||||
{
|
||||
public:
|
||||
@ -41,17 +51,19 @@ public:
|
||||
void Clear();
|
||||
|
||||
int Compile(const char *pattern, int iFlags);
|
||||
int Match(const char *str);
|
||||
int Match(const char *str, unsigned int offset);
|
||||
int MatchAll(const char *str);
|
||||
void ClearMatch();
|
||||
const char *GetSubstring(int s, char buffer[], int max);
|
||||
bool GetSubstring(int s, char buffer[], int max, int match);
|
||||
public:
|
||||
int mErrorOffset;
|
||||
int mErrorCode;
|
||||
const char *mError;
|
||||
int mSubStrings;
|
||||
int mMatchCount;
|
||||
RegexMatch mMatches[MAX_MATCHES];
|
||||
private:
|
||||
pcre *re;
|
||||
bool mFree;
|
||||
int ovector[30];
|
||||
char *subject;
|
||||
};
|
||||
|
||||
|
@ -33,6 +33,7 @@
|
||||
#include "extension.h"
|
||||
#include <sh_string.h>
|
||||
#include "pcre.h"
|
||||
#include "posix_map.h"
|
||||
#include "CRegEx.h"
|
||||
using namespace SourceHook;
|
||||
|
||||
@ -82,10 +83,11 @@ static cell_t CompileRegex(IPluginContext *pCtx, const cell_t *params)
|
||||
|
||||
if (x->Compile(regex, params[2]) == 0)
|
||||
{
|
||||
cell_t *eOff;
|
||||
pCtx->LocalToPhysAddr(params[5], &eOff);
|
||||
cell_t *eError;
|
||||
pCtx->LocalToPhysAddr(params[5], &eError);
|
||||
const char *err = x->mError;
|
||||
*eOff = x->mErrorOffset;
|
||||
// Convert error code to posix error code but use pcre's error string since it is more detailed.
|
||||
*eError = pcre_posix_compile_error_map[x->mErrorCode];
|
||||
pCtx->StringToLocal(params[3], params[4], err ? err:"unknown");
|
||||
delete x;
|
||||
return 0;
|
||||
@ -112,6 +114,13 @@ static cell_t MatchRegex(IPluginContext *pCtx, const cell_t *params)
|
||||
sec.pOwner = NULL;
|
||||
sec.pIdentity = myself->GetIdentity();
|
||||
|
||||
unsigned int offset = 0;
|
||||
|
||||
if (params[0] >= 4)
|
||||
{
|
||||
offset = (unsigned int)params[4];
|
||||
}
|
||||
|
||||
RegEx *x;
|
||||
|
||||
if ((err=g_pHandleSys->ReadHandle(hndl, g_RegexHandle, &sec, (void **)&x)) != HandleError_None)
|
||||
@ -129,14 +138,17 @@ static cell_t MatchRegex(IPluginContext *pCtx, const cell_t *params)
|
||||
char *str;
|
||||
pCtx->LocalToString(params[2], &str);
|
||||
|
||||
int e = x->Match(str);
|
||||
if(offset >= strlen(str))
|
||||
return pCtx->ThrowNativeError("Invalid string index\n");
|
||||
|
||||
int e = x->Match(str, offset);
|
||||
|
||||
if (e == -1)
|
||||
{
|
||||
/* there was a match error. move on. */
|
||||
cell_t *res;
|
||||
pCtx->LocalToPhysAddr(params[3], &res);
|
||||
*res = x->mErrorOffset;
|
||||
*res = x->mErrorCode;
|
||||
/* only clear the match results, since the regex object
|
||||
may still be referenced later */
|
||||
x->ClearMatch();
|
||||
@ -153,7 +165,60 @@ static cell_t MatchRegex(IPluginContext *pCtx, const cell_t *params)
|
||||
}
|
||||
else
|
||||
{
|
||||
return x->mSubStrings;
|
||||
return x->mMatches[0].mSubStringCount;
|
||||
}
|
||||
}
|
||||
|
||||
static cell_t MatchRegexAll(IPluginContext *pCtx, const cell_t *params)
|
||||
{
|
||||
Handle_t hndl = static_cast<Handle_t>(params[1]);
|
||||
HandleError err;
|
||||
HandleSecurity sec;
|
||||
sec.pOwner = NULL;
|
||||
sec.pIdentity = myself->GetIdentity();
|
||||
|
||||
RegEx *x;
|
||||
|
||||
if ((err = g_pHandleSys->ReadHandle(hndl, g_RegexHandle, &sec, (void **)&x)) != HandleError_None)
|
||||
{
|
||||
return pCtx->ThrowNativeError("Invalid regex handle %x (error %d)", hndl, err);
|
||||
}
|
||||
|
||||
if (!x)
|
||||
{
|
||||
pCtx->ThrowNativeError("Regex data not found\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
char *str;
|
||||
pCtx->LocalToString(params[2], &str);
|
||||
|
||||
int e = x->MatchAll(str);
|
||||
|
||||
if (e == -1)
|
||||
{
|
||||
/* there was a match error. move on. */
|
||||
cell_t *res;
|
||||
pCtx->LocalToPhysAddr(params[3], &res);
|
||||
*res = x->mErrorCode;
|
||||
/* only clear the match results, since the regex object
|
||||
may still be referenced later */
|
||||
x->ClearMatch();
|
||||
|
||||
return -1;
|
||||
}
|
||||
else if (e == 0)
|
||||
{
|
||||
/* only clear the match results, since the regex object
|
||||
may still be referenced later */
|
||||
x->ClearMatch();
|
||||
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
return x->mMatchCount;
|
||||
}
|
||||
}
|
||||
|
||||
@ -165,6 +230,8 @@ static cell_t GetRegexSubString(IPluginContext *pCtx, const cell_t *params)
|
||||
sec.pOwner=NULL;
|
||||
sec.pIdentity=myself->GetIdentity();
|
||||
|
||||
int match = 0;
|
||||
|
||||
RegEx *x;
|
||||
|
||||
if ((err=g_pHandleSys->ReadHandle(hndl, g_RegexHandle, &sec, (void **)&x)) != HandleError_None)
|
||||
@ -178,17 +245,93 @@ static cell_t GetRegexSubString(IPluginContext *pCtx, const cell_t *params)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static char buffer[4096];
|
||||
const char *ret=x->GetSubstring(params[2], buffer, sizeof(buffer));
|
||||
|
||||
if(!ret)
|
||||
if (params[0] >= 5)
|
||||
{
|
||||
return 0;
|
||||
match = params[5];
|
||||
}
|
||||
|
||||
pCtx->StringToLocalUTF8(params[3], params[4], ret, NULL);
|
||||
if(match >= x->mMatchCount || match < 0)
|
||||
return pCtx->ThrowNativeError("Invalid match index passed.\n");
|
||||
|
||||
return 1;
|
||||
char *buffer;
|
||||
pCtx->LocalToString(params[3], &buffer);
|
||||
|
||||
return x->GetSubstring(params[2], buffer, params[4], match);
|
||||
}
|
||||
|
||||
static cell_t GetRegexMatchCount(IPluginContext *pCtx, const cell_t *params)
|
||||
{
|
||||
Handle_t hndl = static_cast<Handle_t>(params[1]);
|
||||
HandleError err;
|
||||
HandleSecurity sec;
|
||||
sec.pOwner = NULL;
|
||||
sec.pIdentity = myself->GetIdentity();
|
||||
|
||||
RegEx *x;
|
||||
|
||||
if ((err = g_pHandleSys->ReadHandle(hndl, g_RegexHandle, &sec, (void **)&x)) != HandleError_None)
|
||||
{
|
||||
return pCtx->ThrowNativeError("Invalid regex handle %x (error %d)", hndl, err);
|
||||
}
|
||||
|
||||
if (!x)
|
||||
{
|
||||
return pCtx->ThrowNativeError("Regex data not found\n");
|
||||
}
|
||||
|
||||
return x->mMatchCount;
|
||||
}
|
||||
|
||||
static cell_t GetRegexCaptureCount(IPluginContext *pCtx, const cell_t *params)
|
||||
{
|
||||
Handle_t hndl = static_cast<Handle_t>(params[1]);
|
||||
HandleError err;
|
||||
HandleSecurity sec;
|
||||
sec.pOwner = NULL;
|
||||
sec.pIdentity = myself->GetIdentity();
|
||||
|
||||
RegEx *x;
|
||||
|
||||
if ((err = g_pHandleSys->ReadHandle(hndl, g_RegexHandle, &sec, (void **)&x)) != HandleError_None)
|
||||
{
|
||||
return pCtx->ThrowNativeError("Invalid regex handle %x (error %d)", hndl, err);
|
||||
}
|
||||
|
||||
if (!x)
|
||||
{
|
||||
return pCtx->ThrowNativeError("Regex data not found\n");
|
||||
}
|
||||
|
||||
if (params[2] >= x->mMatchCount || params[2] < 0)
|
||||
return pCtx->ThrowNativeError("Invalid match index passed.\n");
|
||||
|
||||
return x->mMatches[params[2]].mSubStringCount;
|
||||
}
|
||||
|
||||
static cell_t GetRegexOffset(IPluginContext *pCtx, const cell_t *params)
|
||||
{
|
||||
Handle_t hndl = static_cast<Handle_t>(params[1]);
|
||||
HandleError err;
|
||||
HandleSecurity sec;
|
||||
sec.pOwner = NULL;
|
||||
sec.pIdentity = myself->GetIdentity();
|
||||
|
||||
RegEx *x;
|
||||
|
||||
if ((err = g_pHandleSys->ReadHandle(hndl, g_RegexHandle, &sec, (void **)&x)) != HandleError_None)
|
||||
{
|
||||
return pCtx->ThrowNativeError("Invalid regex handle %x (error %d)", hndl, err);
|
||||
}
|
||||
|
||||
if (!x)
|
||||
{
|
||||
return pCtx->ThrowNativeError("Regex data not found\n");
|
||||
}
|
||||
|
||||
if (params[2] >= x->mMatchCount || params[2] < 0)
|
||||
return pCtx->ThrowNativeError("Invalid match index passed.\n");
|
||||
|
||||
return x->mMatches[params[2]].mVector[1];
|
||||
}
|
||||
|
||||
void RegexHandler::OnHandleDestroy(HandleType_t type, void *object)
|
||||
@ -209,5 +352,9 @@ const sp_nativeinfo_t regex_natives[] =
|
||||
{"Regex.GetSubString", GetRegexSubString},
|
||||
{"Regex.Match", MatchRegex},
|
||||
{"Regex.Regex", CompileRegex},
|
||||
{"Regex.MatchAll", MatchRegexAll},
|
||||
{"Regex.MatchCount", GetRegexMatchCount},
|
||||
{"Regex.CaptureCount", GetRegexCaptureCount},
|
||||
{"Regex.MatchOffset", GetRegexOffset},
|
||||
{NULL, NULL},
|
||||
};
|
||||
|
136
extensions/regex/posix_map.h
Normal file
136
extensions/regex/posix_map.h
Normal file
@ -0,0 +1,136 @@
|
||||
#pragma once
|
||||
|
||||
/*
|
||||
Maps pcre_compile2 error codes to posix error codes.
|
||||
From pcreposix.c and pcreposix.h
|
||||
*/
|
||||
|
||||
// posix error codes
|
||||
enum {
|
||||
REG_ASSERT = 1, /* internal error ? */
|
||||
REG_BADBR, /* invalid repeat counts in {} */
|
||||
REG_BADPAT, /* pattern error */
|
||||
REG_BADRPT, /* ? * + invalid */
|
||||
REG_EBRACE, /* unbalanced {} */
|
||||
REG_EBRACK, /* unbalanced [] */
|
||||
REG_ECOLLATE, /* collation error - not relevant */
|
||||
REG_ECTYPE, /* bad class */
|
||||
REG_EESCAPE, /* bad escape sequence */
|
||||
REG_EMPTY, /* empty expression */
|
||||
REG_EPAREN, /* unbalanced () */
|
||||
REG_ERANGE, /* bad range inside [] */
|
||||
REG_ESIZE, /* expression too big */
|
||||
REG_ESPACE, /* failed to get memory */
|
||||
REG_ESUBREG, /* bad back reference */
|
||||
REG_INVARG, /* bad argument */
|
||||
|
||||
// This isnt used below since it is not a compile error. So we remove it as to not conflict.
|
||||
//REG_NOMATCH /* match failed */
|
||||
};
|
||||
|
||||
// pcre compile error -> posix compile error
|
||||
const int pcre_posix_compile_error_map[] = {
|
||||
0, /* no error */
|
||||
REG_EESCAPE, /* \ at end of pattern */
|
||||
REG_EESCAPE, /* \c at end of pattern */
|
||||
REG_EESCAPE, /* unrecognized character follows \ */
|
||||
REG_BADBR, /* numbers out of order in {} quantifier */
|
||||
/* 5 */
|
||||
REG_BADBR, /* number too big in {} quantifier */
|
||||
REG_EBRACK, /* missing terminating ] for character class */
|
||||
REG_ECTYPE, /* invalid escape sequence in character class */
|
||||
REG_ERANGE, /* range out of order in character class */
|
||||
REG_BADRPT, /* nothing to repeat */
|
||||
/* 10 */
|
||||
REG_BADRPT, /* operand of unlimited repeat could match the empty string */
|
||||
REG_ASSERT, /* internal error: unexpected repeat */
|
||||
REG_BADPAT, /* unrecognized character after (? */
|
||||
REG_BADPAT, /* POSIX named classes are supported only within a class */
|
||||
REG_EPAREN, /* missing ) */
|
||||
/* 15 */
|
||||
REG_ESUBREG, /* reference to non-existent subpattern */
|
||||
REG_INVARG, /* erroffset passed as NULL */
|
||||
REG_INVARG, /* unknown option bit(s) set */
|
||||
REG_EPAREN, /* missing ) after comment */
|
||||
REG_ESIZE, /* parentheses nested too deeply */
|
||||
/* 20 */
|
||||
REG_ESIZE, /* regular expression too large */
|
||||
REG_ESPACE, /* failed to get memory */
|
||||
REG_EPAREN, /* unmatched parentheses */
|
||||
REG_ASSERT, /* internal error: code overflow */
|
||||
REG_BADPAT, /* unrecognized character after (?< */
|
||||
/* 25 */
|
||||
REG_BADPAT, /* lookbehind assertion is not fixed length */
|
||||
REG_BADPAT, /* malformed number or name after (?( */
|
||||
REG_BADPAT, /* conditional group contains more than two branches */
|
||||
REG_BADPAT, /* assertion expected after (?( */
|
||||
REG_BADPAT, /* (?R or (?[+-]digits must be followed by ) */
|
||||
/* 30 */
|
||||
REG_ECTYPE, /* unknown POSIX class name */
|
||||
REG_BADPAT, /* POSIX collating elements are not supported */
|
||||
REG_INVARG, /* this version of PCRE is not compiled with PCRE_UTF8 support */
|
||||
REG_BADPAT, /* spare error */
|
||||
REG_BADPAT, /* character value in \x{} or \o{} is too large */
|
||||
/* 35 */
|
||||
REG_BADPAT, /* invalid condition (?(0) */
|
||||
REG_BADPAT, /* \C not allowed in lookbehind assertion */
|
||||
REG_EESCAPE, /* PCRE does not support \L, \l, \N, \U, or \u */
|
||||
REG_BADPAT, /* number after (?C is > 255 */
|
||||
REG_BADPAT, /* closing ) for (?C expected */
|
||||
/* 40 */
|
||||
REG_BADPAT, /* recursive call could loop indefinitely */
|
||||
REG_BADPAT, /* unrecognized character after (?P */
|
||||
REG_BADPAT, /* syntax error in subpattern name (missing terminator) */
|
||||
REG_BADPAT, /* two named subpatterns have the same name */
|
||||
REG_BADPAT, /* invalid UTF-8 string */
|
||||
/* 45 */
|
||||
REG_BADPAT, /* support for \P, \p, and \X has not been compiled */
|
||||
REG_BADPAT, /* malformed \P or \p sequence */
|
||||
REG_BADPAT, /* unknown property name after \P or \p */
|
||||
REG_BADPAT, /* subpattern name is too long (maximum 32 characters) */
|
||||
REG_BADPAT, /* too many named subpatterns (maximum 10,000) */
|
||||
/* 50 */
|
||||
REG_BADPAT, /* repeated subpattern is too long */
|
||||
REG_BADPAT, /* octal value is greater than \377 (not in UTF-8 mode) */
|
||||
REG_BADPAT, /* internal error: overran compiling workspace */
|
||||
REG_BADPAT, /* internal error: previously-checked referenced subpattern not found */
|
||||
REG_BADPAT, /* DEFINE group contains more than one branch */
|
||||
/* 55 */
|
||||
REG_BADPAT, /* repeating a DEFINE group is not allowed */
|
||||
REG_INVARG, /* inconsistent NEWLINE options */
|
||||
REG_BADPAT, /* \g is not followed followed by an (optionally braced) non-zero number */
|
||||
REG_BADPAT, /* a numbered reference must not be zero */
|
||||
REG_BADPAT, /* an argument is not allowed for (*ACCEPT), (*FAIL), or (*COMMIT) */
|
||||
/* 60 */
|
||||
REG_BADPAT, /* (*VERB) not recognized */
|
||||
REG_BADPAT, /* number is too big */
|
||||
REG_BADPAT, /* subpattern name expected */
|
||||
REG_BADPAT, /* digit expected after (?+ */
|
||||
REG_BADPAT, /* ] is an invalid data character in JavaScript compatibility mode */
|
||||
/* 65 */
|
||||
REG_BADPAT, /* different names for subpatterns of the same number are not allowed */
|
||||
REG_BADPAT, /* (*MARK) must have an argument */
|
||||
REG_INVARG, /* this version of PCRE is not compiled with PCRE_UCP support */
|
||||
REG_BADPAT, /* \c must be followed by an ASCII character */
|
||||
REG_BADPAT, /* \k is not followed by a braced, angle-bracketed, or quoted name */
|
||||
/* 70 */
|
||||
REG_BADPAT, /* internal error: unknown opcode in find_fixedlength() */
|
||||
REG_BADPAT, /* \N is not supported in a class */
|
||||
REG_BADPAT, /* too many forward references */
|
||||
REG_BADPAT, /* disallowed UTF-8/16/32 code point (>= 0xd800 && <= 0xdfff) */
|
||||
REG_BADPAT, /* invalid UTF-16 string (should not occur) */
|
||||
/* 75 */
|
||||
REG_BADPAT, /* overlong MARK name */
|
||||
REG_BADPAT, /* character value in \u.... sequence is too large */
|
||||
REG_BADPAT, /* invalid UTF-32 string (should not occur) */
|
||||
REG_BADPAT, /* setting UTF is disabled by the application */
|
||||
REG_BADPAT, /* non-hex character in \\x{} (closing brace missing?) */
|
||||
/* 80 */
|
||||
REG_BADPAT, /* non-octal character in \o{} (closing brace missing?) */
|
||||
REG_BADPAT, /* missing opening brace after \o */
|
||||
REG_BADPAT, /* parentheses too deeply nested */
|
||||
REG_BADPAT, /* invalid range in character class */
|
||||
REG_BADPAT, /* group name must start with a non-digit */
|
||||
/* 85 */
|
||||
REG_BADPAT /* parentheses too deeply nested (stack check) */
|
||||
};
|
@ -112,6 +112,7 @@ IServerTools *servertools = NULL;
|
||||
|
||||
// global hooks and forwards
|
||||
IForward *g_pOnEntityCreated = NULL;
|
||||
IForward *g_pOnEntitySpawned = NULL;
|
||||
IForward *g_pOnEntityDestroyed = NULL;
|
||||
|
||||
#ifdef GAMEDESC_CAN_CHANGE
|
||||
@ -252,6 +253,7 @@ bool SDKHooks::SDK_OnLoad(char *error, size_t maxlength, bool late)
|
||||
plsys->AddPluginsListener(&g_Interface);
|
||||
|
||||
g_pOnEntityCreated = forwards->CreateForward("OnEntityCreated", ET_Ignore, 2, NULL, Param_Cell, Param_String);
|
||||
g_pOnEntitySpawned = forwards->CreateForward("OnEntitySpawned", ET_Ignore, 2, NULL, Param_Cell, Param_String);
|
||||
g_pOnEntityDestroyed = forwards->CreateForward("OnEntityDestroyed", ET_Ignore, 1, NULL, Param_Cell);
|
||||
#ifdef GAMEDESC_CAN_CHANGE
|
||||
g_pOnGetGameNameDescription = forwards->CreateForward("OnGetGameDescription", ET_Hook, 2, NULL, Param_String);
|
||||
@ -343,6 +345,7 @@ void SDKHooks::SDK_OnUnload()
|
||||
#endif
|
||||
|
||||
forwards->ReleaseForward(g_pOnEntityCreated);
|
||||
forwards->ReleaseForward(g_pOnEntitySpawned);
|
||||
forwards->ReleaseForward(g_pOnEntityDestroyed);
|
||||
#ifdef GAMEDESC_CAN_CHANGE
|
||||
forwards->ReleaseForward(g_pOnGetGameNameDescription);
|
||||
@ -878,6 +881,27 @@ void SDKHooks::OnEntityCreated(CBaseEntity *pEntity)
|
||||
}
|
||||
}
|
||||
|
||||
void SDKHooks::OnEntitySpawned(CBaseEntity *pEntity)
|
||||
{
|
||||
// Call OnEntitySpawned forward
|
||||
int ref = gamehelpers->EntityToReference(pEntity);
|
||||
int index = gamehelpers->ReferenceToIndex(ref);
|
||||
|
||||
// This can be -1 for player ents before any players have connected
|
||||
if ((unsigned)index == INVALID_EHANDLE_INDEX || (index > 0 && index <= playerhelpers->GetMaxClients()))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!IsEntityIndexInRange(index))
|
||||
{
|
||||
g_pSM->LogError(myself, "SDKHooks::OnEntitySpawned - Got entity index out of range (%d)", index);
|
||||
return;
|
||||
}
|
||||
|
||||
HandleEntitySpawned(pEntity, index, ref);
|
||||
}
|
||||
|
||||
#ifdef GAMEDESC_CAN_CHANGE
|
||||
const char *SDKHooks::Hook_GetGameDescription()
|
||||
{
|
||||
@ -1790,6 +1814,32 @@ void SDKHooks::HandleEntityCreated(CBaseEntity *pEntity, int index, cell_t ref)
|
||||
m_EntityCache[index] = ref;
|
||||
}
|
||||
|
||||
void SDKHooks::HandleEntitySpawned(CBaseEntity *pEntity, int index, cell_t ref)
|
||||
{
|
||||
if (g_pOnEntitySpawned->GetFunctionCount() || m_EntListeners.size())
|
||||
{
|
||||
cell_t bcompatRef = gamehelpers->EntityToBCompatRef(pEntity);
|
||||
const char *pName = gamehelpers->GetEntityClassname(pEntity);
|
||||
if (!pName)
|
||||
pName = "";
|
||||
|
||||
// Send OnEntitySpawned to SM listeners
|
||||
for (SourceHook::List<ISMEntityListener *>::iterator iter = m_EntListeners.begin(); iter != m_EntListeners.end(); iter++)
|
||||
{
|
||||
ISMEntityListener *pListener = (*iter);
|
||||
pListener->OnEntitySpawned(pEntity, pName);
|
||||
}
|
||||
|
||||
// Call OnEntitySpawned forward
|
||||
if (g_pOnEntitySpawned->GetFunctionCount())
|
||||
{
|
||||
g_pOnEntitySpawned->PushCell(bcompatRef);
|
||||
g_pOnEntitySpawned->PushString(pName);
|
||||
g_pOnEntitySpawned->Execute(NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SDKHooks::HandleEntityDeleted(CBaseEntity *pEntity)
|
||||
{
|
||||
cell_t bcompatRef = gamehelpers->EntityToBCompatRef(pEntity);
|
||||
|
@ -238,6 +238,7 @@ public: // IFeatureProvider
|
||||
|
||||
public: // IEntityListener
|
||||
virtual void OnEntityCreated(CBaseEntity *pEntity);
|
||||
virtual void OnEntitySpawned(CBaseEntity *pEntity);
|
||||
virtual void OnEntityDeleted(CBaseEntity *pEntity);
|
||||
|
||||
public: // IClientListener
|
||||
@ -330,6 +331,7 @@ public:
|
||||
|
||||
private:
|
||||
void HandleEntityCreated(CBaseEntity *pEntity, int index, cell_t ref);
|
||||
void HandleEntitySpawned(CBaseEntity *pEntity, int index, cell_t ref);
|
||||
void HandleEntityDeleted(CBaseEntity *pEntity);
|
||||
void Unhook(CBaseEntity *pEntity);
|
||||
void Unhook(IPluginContext *pContext);
|
||||
|
@ -453,7 +453,7 @@ bool SDKTools::ProcessCommandTarget(cmd_target_info_t *info)
|
||||
IPlayerInfo *plinfo = player->GetPlayerInfo();
|
||||
if (plinfo == NULL)
|
||||
continue;
|
||||
if (plinfo->GetTeamIndex() == 1 &&
|
||||
if ((plinfo->GetTeamIndex() == 0 || plinfo->GetTeamIndex() == 1) &&
|
||||
playerhelpers->FilterCommandTarget(pAdmin, player, info->flags) ==
|
||||
COMMAND_TARGET_VALID)
|
||||
{
|
||||
|
@ -53,6 +53,10 @@ static CBaseEntity *FindEntityByNetClass(int start, const char *classname)
|
||||
if (network == NULL)
|
||||
continue;
|
||||
|
||||
IHandleEntity *pHandleEnt = network->GetEntityHandle();
|
||||
if (pHandleEnt == NULL)
|
||||
continue;
|
||||
|
||||
ServerClass *sClass = network->GetServerClass();
|
||||
const char *name = sClass->GetName();
|
||||
|
||||
|
@ -51,7 +51,6 @@ void EntityOutputManager::Shutdown()
|
||||
return;
|
||||
}
|
||||
|
||||
EntityOutputs->Destroy();
|
||||
ClassNames->Destroy();
|
||||
fireOutputDetour->Destroy();
|
||||
}
|
||||
@ -65,7 +64,6 @@ void EntityOutputManager::Init()
|
||||
return;
|
||||
}
|
||||
|
||||
EntityOutputs = adtfactory->CreateBasicTrie();
|
||||
ClassNames = adtfactory->CreateBasicTrie();
|
||||
}
|
||||
|
||||
@ -119,45 +117,30 @@ bool EntityOutputManager::FireEventDetour(void *pOutput, CBaseEntity *pActivator
|
||||
return true;
|
||||
}
|
||||
|
||||
char sOutput[20];
|
||||
Q_snprintf(sOutput, sizeof(sOutput), "%p", pOutput);
|
||||
|
||||
// attempt to directly lookup a hook using the pOutput pointer
|
||||
OutputNameStruct *pOutputName = NULL;
|
||||
|
||||
bool fastLookup = false;
|
||||
|
||||
// Fast lookup failed - check the slow way for hooks that haven't fired yet
|
||||
if ((fastLookup = EntityOutputs->Retrieve(sOutput, (void **)&pOutputName)) == false)
|
||||
const char *classname = gamehelpers->GetEntityClassname(pCaller);
|
||||
if (!classname)
|
||||
{
|
||||
const char *classname = gamehelpers->GetEntityClassname(pCaller);
|
||||
if (!classname)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
const char *outputname = FindOutputName(pOutput, pCaller);
|
||||
if (!outputname)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
const char *outputname = FindOutputName(pOutput, pCaller);
|
||||
if (!outputname)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
pOutputName = FindOutputPointer(classname, outputname, false);
|
||||
pOutputName = FindOutputPointer(classname, outputname, false);
|
||||
|
||||
if (!pOutputName)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if (!pOutputName)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!pOutputName->hooks.empty())
|
||||
{
|
||||
if (!fastLookup)
|
||||
{
|
||||
// hook exists on this classname and output - map it into our quick find trie
|
||||
EntityOutputs->Insert(sOutput, pOutputName);
|
||||
}
|
||||
|
||||
SourceHook::List<omg_hooks *>::iterator _iter;
|
||||
|
||||
omg_hooks *hook;
|
||||
|
@ -121,8 +121,6 @@ private:
|
||||
|
||||
const char *FindOutputName(void *pOutput, CBaseEntity *pCaller);
|
||||
|
||||
//Maps CEntityOutput * to a OutputNameStruct
|
||||
IBasicTrie *EntityOutputs;
|
||||
// Maps classname to a ClassNameStruct
|
||||
IBasicTrie *ClassNames;
|
||||
|
||||
|
@ -445,6 +445,11 @@ static cell_t SDKCall(IPluginContext *pContext, const cell_t *params)
|
||||
cell_t *addr;
|
||||
size_t written;
|
||||
pContext->LocalToPhysAddr(params[retparam+1], &addr);
|
||||
if (!(*(char **)vc->retbuf))
|
||||
{
|
||||
pContext->StringToLocalUTF8(params[retparam], *addr, "", &written);
|
||||
return -1;
|
||||
}
|
||||
pContext->StringToLocalUTF8(params[retparam], *addr, *(char **)vc->retbuf, &written);
|
||||
return (cell_t)written;
|
||||
} else if (vc->retinfo->vtype == Valve_Vector
|
||||
|
@ -161,13 +161,14 @@ static cell_t GiveNamedItem(IPluginContext *pContext, const cell_t *params)
|
||||
static ValveCall *pCall = NULL;
|
||||
if (!pCall)
|
||||
{
|
||||
ValvePassInfo pass[5];
|
||||
ValvePassInfo pass[6];
|
||||
InitPass(pass[0], Valve_String, PassType_Basic, PASSFLAG_BYVAL);
|
||||
InitPass(pass[1], Valve_POD, PassType_Basic, PASSFLAG_BYVAL);
|
||||
InitPass(pass[2], Valve_POD, PassType_Basic, PASSFLAG_BYVAL);
|
||||
InitPass(pass[3], Valve_Bool, PassType_Basic, PASSFLAG_BYVAL);
|
||||
InitPass(pass[4], Valve_CBaseEntity, PassType_Basic, PASSFLAG_BYVAL);
|
||||
if (!CreateBaseCall("GiveNamedItem", ValveCall_Player, &pass[4], pass, 4, &pCall))
|
||||
InitPass(pass[5], Valve_POD, PassType_Basic, PASSFLAG_BYVAL);
|
||||
if (!CreateBaseCall("GiveNamedItem", ValveCall_Player, &pass[5], pass, 5, &pCall))
|
||||
{
|
||||
return pContext->ThrowNativeError("\"GiveNamedItem\" not supported by this mod");
|
||||
} else if (!pCall) {
|
||||
@ -182,6 +183,7 @@ static cell_t GiveNamedItem(IPluginContext *pContext, const cell_t *params)
|
||||
DECODE_VALVE_PARAM(3, vparams, 1);
|
||||
*(CEconItemView **)(vptr + 12) = NULL;
|
||||
*(bool *)(vptr + 16) = false;
|
||||
*(void **)(vptr + 17) = NULL;
|
||||
FINISH_CALL_SIMPLE(&pEntity);
|
||||
|
||||
return gamehelpers->EntityToBCompatRef(pEntity);
|
||||
|
@ -34,7 +34,10 @@
|
||||
|
||||
SH_DECL_HOOK8_void(IVEngineServer, EmitAmbientSound, SH_NOATTRIB, 0, int, const Vector &, const char *, float, soundlevel_t, int, int, float);
|
||||
|
||||
#if SOURCE_ENGINE >= SE_PORTAL2
|
||||
#if SOURCE_ENGINE == SE_CSGO
|
||||
SH_DECL_HOOK18(IEngineSound, EmitSound, SH_NOATTRIB, 0, int, IRecipientFilter &, int, int, const char *, unsigned int, const char *, float, float, int, int, int, const Vector *, const Vector *, CUtlVector<Vector> *, bool, float, int, void *);
|
||||
SH_DECL_HOOK18(IEngineSound, EmitSound, SH_NOATTRIB, 1, int, IRecipientFilter &, int, int, const char *, unsigned int, const char *, float, soundlevel_t, int, int, int, const Vector *, const Vector *, CUtlVector<Vector> *, bool, float, int, void *);
|
||||
#elif SOURCE_ENGINE >= SE_PORTAL2
|
||||
SH_DECL_HOOK17(IEngineSound, EmitSound, SH_NOATTRIB, 0, int, IRecipientFilter &, int, int, const char *, unsigned int, const char *, float, float, int, int, int, const Vector *, const Vector *, CUtlVector<Vector> *, bool, float, int);
|
||||
SH_DECL_HOOK17(IEngineSound, EmitSound, SH_NOATTRIB, 1, int, IRecipientFilter &, int, int, const char *, unsigned int, const char *, float, soundlevel_t, int, int, int, const Vector *, const Vector *, CUtlVector<Vector> *, bool, float, int);
|
||||
#elif SOURCE_ENGINE == SE_CSS || SOURCE_ENGINE == SE_HL2DM || SOURCE_ENGINE == SE_DODS || SOURCE_ENGINE == SE_SDK2013 \
|
||||
@ -79,13 +82,13 @@ size_t SoundHooks::_FillInPlayers(int *pl_array, IRecipientFilter *pFilter)
|
||||
void SoundHooks::_IncRefCounter(int type)
|
||||
{
|
||||
if (type == NORMAL_SOUND_HOOK)
|
||||
{
|
||||
if (m_NormalCount++ == 0)
|
||||
{
|
||||
if (m_NormalCount++ == 0)
|
||||
{
|
||||
SH_ADD_HOOK(IEngineSound, EmitSound, engsound, SH_MEMBER(this, &SoundHooks::OnEmitSound), false);
|
||||
SH_ADD_HOOK(IEngineSound, EmitSound, engsound, SH_MEMBER(this, &SoundHooks::OnEmitSound2), false);
|
||||
}
|
||||
SH_ADD_HOOK(IEngineSound, EmitSound, engsound, SH_MEMBER(this, &SoundHooks::OnEmitSound), false);
|
||||
SH_ADD_HOOK(IEngineSound, EmitSound, engsound, SH_MEMBER(this, &SoundHooks::OnEmitSound2), false);
|
||||
}
|
||||
}
|
||||
else if (type == AMBIENT_SOUND_HOOK)
|
||||
{
|
||||
if (m_AmbientCount++ == 0)
|
||||
@ -98,13 +101,13 @@ void SoundHooks::_IncRefCounter(int type)
|
||||
void SoundHooks::_DecRefCounter(int type)
|
||||
{
|
||||
if (type == NORMAL_SOUND_HOOK)
|
||||
{
|
||||
if (--m_NormalCount == 0)
|
||||
{
|
||||
if (--m_NormalCount == 0)
|
||||
{
|
||||
SH_REMOVE_HOOK(IEngineSound, EmitSound, engsound, SH_MEMBER(this, &SoundHooks::OnEmitSound), false);
|
||||
SH_REMOVE_HOOK(IEngineSound, EmitSound, engsound, SH_MEMBER(this, &SoundHooks::OnEmitSound2), false);
|
||||
}
|
||||
SH_REMOVE_HOOK(IEngineSound, EmitSound, engsound, SH_MEMBER(this, &SoundHooks::OnEmitSound), false);
|
||||
SH_REMOVE_HOOK(IEngineSound, EmitSound, engsound, SH_MEMBER(this, &SoundHooks::OnEmitSound2), false);
|
||||
}
|
||||
}
|
||||
else if (type == AMBIENT_SOUND_HOOK)
|
||||
{
|
||||
if (--m_AmbientCount == 0)
|
||||
@ -313,7 +316,12 @@ uint32 GenerateSoundEntryHash(char const *pSoundEntry)
|
||||
}
|
||||
#endif
|
||||
|
||||
#if SOURCE_ENGINE >= SE_PORTAL2
|
||||
#if SOURCE_ENGINE == SE_CSGO
|
||||
int SoundHooks::OnEmitSound(IRecipientFilter &filter, int iEntIndex, int iChannel, const char *pSoundEntry, unsigned int nSoundEntryHash, const char *pSample,
|
||||
float flVolume, soundlevel_t iSoundlevel, int nSeed, int iFlags, int iPitch, const Vector *pOrigin,
|
||||
const Vector *pDirection, CUtlVector<Vector> *pUtlVecOrigins, bool bUpdatePositions,
|
||||
float soundtime, int speakerentity, void *pUnknown)
|
||||
#elif SOURCE_ENGINE >= SE_PORTAL2
|
||||
int SoundHooks::OnEmitSound(IRecipientFilter &filter, int iEntIndex, int iChannel, const char *pSoundEntry, unsigned int nSoundEntryHash, const char *pSample,
|
||||
float flVolume, soundlevel_t iSoundlevel, int nSeed, int iFlags, int iPitch, const Vector *pOrigin,
|
||||
const Vector *pDirection, CUtlVector<Vector> *pUtlVecOrigins, bool bUpdatePositions,
|
||||
@ -414,7 +422,16 @@ void SoundHooks::OnEmitSound(IRecipientFilter &filter, int iEntIndex, int iChann
|
||||
|
||||
CellRecipientFilter crf;
|
||||
crf.Initialize(players, size);
|
||||
#if SOURCE_ENGINE >= SE_PORTAL2
|
||||
#if SOURCE_ENGINE == SE_CSGO
|
||||
RETURN_META_VALUE_NEWPARAMS(
|
||||
MRES_IGNORED,
|
||||
-1,
|
||||
static_cast<int (IEngineSound::*)(IRecipientFilter &, int, int, const char*, unsigned int, const char*, float, soundlevel_t,
|
||||
int, int, int, const Vector *, const Vector *, CUtlVector<Vector> *, bool, float, int, void *)>(&IEngineSound::EmitSound),
|
||||
(crf, iEntIndex, iChannel, soundEntry, nSoundEntryHash, buffer, flVolume, iSoundlevel, nSeed, iFlags, iPitch, pOrigin,
|
||||
pDirection, pUtlVecOrigins, bUpdatePositions, soundtime, speakerentity, nullptr)
|
||||
);
|
||||
#elif SOURCE_ENGINE >= SE_PORTAL2
|
||||
RETURN_META_VALUE_NEWPARAMS(
|
||||
MRES_IGNORED,
|
||||
-1,
|
||||
@ -450,7 +467,12 @@ void SoundHooks::OnEmitSound(IRecipientFilter &filter, int iEntIndex, int iChann
|
||||
#endif
|
||||
}
|
||||
|
||||
#if SOURCE_ENGINE >= SE_PORTAL2
|
||||
#if SOURCE_ENGINE == SE_CSGO
|
||||
int SoundHooks::OnEmitSound2(IRecipientFilter &filter, int iEntIndex, int iChannel, const char *pSoundEntry, unsigned int nSoundEntryHash, const char *pSample,
|
||||
float flVolume, float flAttenuation, int nSeed, int iFlags, int iPitch, const Vector *pOrigin,
|
||||
const Vector *pDirection, CUtlVector<Vector> *pUtlVecOrigins, bool bUpdatePositions,
|
||||
float soundtime, int speakerentity, void *pUnknown)
|
||||
#elif SOURCE_ENGINE >= SE_PORTAL2
|
||||
int SoundHooks::OnEmitSound2(IRecipientFilter &filter, int iEntIndex, int iChannel, const char *pSoundEntry, unsigned int nSoundEntryHash, const char *pSample,
|
||||
float flVolume, float flAttenuation, int nSeed, int iFlags, int iPitch, const Vector *pOrigin,
|
||||
const Vector *pDirection, CUtlVector<Vector> *pUtlVecOrigins, bool bUpdatePositions,
|
||||
@ -552,7 +574,16 @@ void SoundHooks::OnEmitSound2(IRecipientFilter &filter, int iEntIndex, int iChan
|
||||
|
||||
CellRecipientFilter crf;
|
||||
crf.Initialize(players, size);
|
||||
#if SOURCE_ENGINE >= SE_PORTAL2
|
||||
#if SOURCE_ENGINE == SE_CSGO
|
||||
RETURN_META_VALUE_NEWPARAMS(
|
||||
MRES_IGNORED,
|
||||
-1,
|
||||
static_cast<int (IEngineSound::*)(IRecipientFilter &, int, int, const char *, unsigned int, const char *, float, float,
|
||||
int, int, int, const Vector *, const Vector *, CUtlVector<Vector> *, bool, float, int, void *)>(&IEngineSound::EmitSound),
|
||||
(crf, iEntIndex, iChannel, soundEntry, nSoundEntryHash, buffer, flVolume, SNDLVL_TO_ATTN(static_cast<soundlevel_t>(sndlevel)),
|
||||
nSeed, iFlags, iPitch, pOrigin, pDirection, pUtlVecOrigins, bUpdatePositions, soundtime, speakerentity, pUnknown)
|
||||
);
|
||||
#elif SOURCE_ENGINE >= SE_PORTAL2
|
||||
RETURN_META_VALUE_NEWPARAMS(
|
||||
MRES_IGNORED,
|
||||
-1,
|
||||
@ -689,7 +720,7 @@ static cell_t EmitAmbientSound(IPluginContext *pContext, const cell_t *params)
|
||||
char *name;
|
||||
float vol, delay;
|
||||
int pitch, flags, level;
|
||||
|
||||
|
||||
entity = SoundReferenceToIndex(params[3]);
|
||||
|
||||
cell_t *addr;
|
||||
@ -849,7 +880,55 @@ static cell_t EmitSound(IPluginContext *pContext, const cell_t *params)
|
||||
player[0] = cl_array[i];
|
||||
crf.Reset();
|
||||
crf.Initialize(player, 1);
|
||||
#if SOURCE_ENGINE >= SE_PORTAL2
|
||||
#if SOURCE_ENGINE == SE_CSGO
|
||||
if (g_InSoundHook)
|
||||
{
|
||||
SH_CALL(enginesoundPatch,
|
||||
static_cast<int (IEngineSound::*)(IRecipientFilter &, int, int, const char*, unsigned int, const char*, float,
|
||||
soundlevel_t, int, int, int, const Vector *, const Vector *, CUtlVector<Vector> *, bool, float, int, void *)>
|
||||
|
||||
(&IEngineSound::EmitSound))
|
||||
(crf,
|
||||
player[0],
|
||||
channel,
|
||||
sample,
|
||||
-1,
|
||||
sample,
|
||||
vol,
|
||||
(soundlevel_t)level,
|
||||
0,
|
||||
flags,
|
||||
pitch,
|
||||
pOrigin,
|
||||
pDir,
|
||||
pOrigVec,
|
||||
updatePos,
|
||||
soundtime,
|
||||
speakerentity,
|
||||
nullptr);
|
||||
}
|
||||
else
|
||||
{
|
||||
engsound->EmitSound(crf,
|
||||
player[0],
|
||||
channel,
|
||||
sample,
|
||||
-1,
|
||||
sample,
|
||||
vol,
|
||||
(soundlevel_t)level,
|
||||
0,
|
||||
flags,
|
||||
pitch,
|
||||
pOrigin,
|
||||
pDir,
|
||||
pOrigVec,
|
||||
updatePos,
|
||||
soundtime,
|
||||
speakerentity,
|
||||
nullptr);
|
||||
}
|
||||
#elif SOURCE_ENGINE >= SE_PORTAL2
|
||||
if (g_InSoundHook)
|
||||
{
|
||||
SH_CALL(enginesoundPatch,
|
||||
@ -979,7 +1058,54 @@ static cell_t EmitSound(IPluginContext *pContext, const cell_t *params)
|
||||
#endif
|
||||
}
|
||||
} else {
|
||||
#if SOURCE_ENGINE >= SE_PORTAL2
|
||||
#if SOURCE_ENGINE == SE_CSGO
|
||||
if (g_InSoundHook)
|
||||
{
|
||||
SH_CALL(enginesoundPatch,
|
||||
static_cast<int (IEngineSound::*)(IRecipientFilter &, int, int, const char*, unsigned int, const char*, float,
|
||||
soundlevel_t, int, int, int, const Vector *, const Vector *, CUtlVector<Vector> *, bool, float, int, void *)>
|
||||
(&IEngineSound::EmitSound))
|
||||
(crf,
|
||||
entity,
|
||||
channel,
|
||||
sample,
|
||||
-1,
|
||||
sample,
|
||||
vol,
|
||||
(soundlevel_t)level,
|
||||
0,
|
||||
flags,
|
||||
pitch,
|
||||
pOrigin,
|
||||
pDir,
|
||||
pOrigVec,
|
||||
updatePos,
|
||||
soundtime,
|
||||
speakerentity,
|
||||
nullptr);
|
||||
}
|
||||
else
|
||||
{
|
||||
engsound->EmitSound(crf,
|
||||
entity,
|
||||
channel,
|
||||
sample,
|
||||
-1,
|
||||
sample,
|
||||
vol,
|
||||
(soundlevel_t)level,
|
||||
0,
|
||||
flags,
|
||||
pitch,
|
||||
pOrigin,
|
||||
pDir,
|
||||
pOrigVec,
|
||||
updatePos,
|
||||
soundtime,
|
||||
speakerentity,
|
||||
nullptr);
|
||||
}
|
||||
#elif SOURCE_ENGINE >= SE_PORTAL2
|
||||
if (g_InSoundHook)
|
||||
{
|
||||
SH_CALL(enginesoundPatch,
|
||||
@ -1219,11 +1345,19 @@ static cell_t EmitSoundEntry(IPluginContext *pContext, const cell_t *params)
|
||||
|
||||
if (g_InSoundHook)
|
||||
{
|
||||
#if SOURCE_ENGINE == SE_CSGO
|
||||
SH_CALL(enginesoundPatch,
|
||||
static_cast<int (IEngineSound::*)(IRecipientFilter &, int, int, const char*, unsigned int, const char*, float,
|
||||
soundlevel_t, int, int, int, const Vector *, const Vector *, CUtlVector<Vector> *, bool, float, int, void *)>
|
||||
(&IEngineSound::EmitSound))(crf, player[0], channel, soundEntry, soundEntryHash, sample, vol, (soundlevel_t)level, seed,
|
||||
flags, pitch, pOrigin, pDir, pOrigVec, updatePos, soundtime, speakerentity, nullptr);
|
||||
#else
|
||||
SH_CALL(enginesoundPatch,
|
||||
static_cast<int (IEngineSound::*)(IRecipientFilter &, int, int, const char*, unsigned int, const char*, float,
|
||||
soundlevel_t, int, int, int, const Vector *, const Vector *, CUtlVector<Vector> *, bool, float, int)>
|
||||
(&IEngineSound::EmitSound))(crf, player[0], channel, soundEntry, soundEntryHash, sample, vol, (soundlevel_t)level, seed,
|
||||
flags, pitch, pOrigin, pDir, pOrigVec, updatePos, soundtime, speakerentity);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1235,11 +1369,19 @@ static cell_t EmitSoundEntry(IPluginContext *pContext, const cell_t *params)
|
||||
else {
|
||||
if (g_InSoundHook)
|
||||
{
|
||||
#if SOURCE_ENGINE == SE_CSGO
|
||||
SH_CALL(enginesoundPatch,
|
||||
static_cast<int (IEngineSound::*)(IRecipientFilter &, int, int, const char*, unsigned int, const char*, float,
|
||||
soundlevel_t, int, int, int, const Vector *, const Vector *, CUtlVector<Vector> *, bool, float, int, void *)>
|
||||
(&IEngineSound::EmitSound))(crf, entity, channel, soundEntry, soundEntryHash, sample, vol, (soundlevel_t)level,
|
||||
seed, flags, pitch, pOrigin, pDir, pOrigVec, updatePos, soundtime, speakerentity, nullptr);
|
||||
#else
|
||||
SH_CALL(enginesoundPatch,
|
||||
static_cast<int (IEngineSound::*)(IRecipientFilter &, int, int, const char*, unsigned int, const char*, float,
|
||||
soundlevel_t, int, int, int, const Vector *, const Vector *, CUtlVector<Vector> *, bool, float, int)>
|
||||
(&IEngineSound::EmitSound))(crf, entity, channel, soundEntry, soundEntryHash, sample, vol, (soundlevel_t)level,
|
||||
seed, flags, pitch, pOrigin, pDir, pOrigVec, updatePos, soundtime, speakerentity);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -53,7 +53,16 @@ public:
|
||||
|
||||
void OnEmitAmbientSound(int entindex, const Vector &pos, const char *samp, float vol, soundlevel_t soundlevel, int fFlags, int pitch, float delay);
|
||||
|
||||
#if SOURCE_ENGINE >= SE_PORTAL2
|
||||
#if SOURCE_ENGINE == SE_CSGO
|
||||
int OnEmitSound(IRecipientFilter& filter, int iEntIndex, int iChannel, const char *, unsigned int, const char *pSample, float flVolume,
|
||||
soundlevel_t iSoundlevel, int nSeed, int iFlags, int iPitch, const Vector *pOrigin,
|
||||
const Vector *pDirection, CUtlVector<Vector> *pUtlVecOrigins, bool bUpdatePositions,
|
||||
float soundtime, int speakerentity, void *pUnknown);
|
||||
int OnEmitSound2(IRecipientFilter &filter, int iEntIndex, int iChannel, const char *pSoundEntry, unsigned int nSoundEntryHash, const char *pSample,
|
||||
float flVolume, float flAttenuation, int nSeed, int iFlags, int iPitch, const Vector *pOrigin,
|
||||
const Vector *pDirection, CUtlVector<Vector> *pUtlVecOrigins, bool bUpdatePositions,
|
||||
float soundtime, int speakerentity, void *pUnknown);
|
||||
#elif SOURCE_ENGINE >= SE_PORTAL2
|
||||
int OnEmitSound(IRecipientFilter& filter, int iEntIndex, int iChannel, const char *, unsigned int, const char *pSample, float flVolume,
|
||||
soundlevel_t iSoundlevel, int nSeed, int iFlags, int iPitch, const Vector *pOrigin,
|
||||
const Vector *pDirection, CUtlVector<Vector> *pUtlVecOrigins, bool bUpdatePositions,
|
||||
|
@ -77,6 +77,10 @@ struct topmenu_object_t
|
||||
{
|
||||
return strcmp(name, topmenu->name) == 0;
|
||||
}
|
||||
static inline uint32_t hash(const detail::CharsAndLength &key)
|
||||
{
|
||||
return key.hash();
|
||||
}
|
||||
};
|
||||
|
||||
struct topmenu_category_t
|
||||
|
@ -19,6 +19,8 @@
|
||||
"plugin_ee0bb0aa0d24491feda4235a92779f71" "http://forums.alliedmods.net/showpost.php?p=2032419&postcount=1" /* Advertising plugin being uploaded to CS:GO servers */
|
||||
"plugin_28a4f07bb94e25e160e9655f8a614292" "https://forums.alliedmods.net/showthread.php?t=291340" /* [AnoX]A-Nox Core - Version 2.5 */
|
||||
"plugin_dad1e86497adcbeb383da6bd8229069d" "https://forums.alliedmods.net/showpost.php?p=2511172&postcount=3" /* ZenServer: Ultimate (Zen) - Version 4.50 */
|
||||
"plugin_c71bb73bc544728fdcd7fc9b0353f8d6" "https://forums.alliedmods.net/showthread.php?t=304847" /* Malicious plugin uploaded to CS:GO servers */
|
||||
"plugin_f946e12de75a0553d3012c594d5e7317" "https://forums.alliedmods.net/showthread.php?t=304847" /* Malicious plugin uploaded to CS:GO servers */
|
||||
"plugin_f405db5491a465b1a30859ee7f7c5080" "" /* UCP Server (Endi) - Version 6.9 */
|
||||
"plugin_6fcb6721fb740b854b0a05bfc9a7984a" "" /* UCP Server (Endi) - Version 7.1 */
|
||||
"plugin_4d320d6c5aba5d31c644fe2847c0662f" "" /* UCP Server (Endi) - Version 7.2 */
|
||||
@ -99,6 +101,11 @@
|
||||
"plugin_465e4abb31f03cf519e8a80a8b4b44be" "" /* [AnoX]NoSucide - Version 1.0 */
|
||||
"plugin_33a4351dd2b9350d6f2b21dab68f7d9e" "" /* [CS:GO] Komutcu Daire System (Sourceless distro) - Version 1.0 */
|
||||
"plugin_0f9828ea5fe6900981137f3c6fb9d70b" "" /* token changer (Adi) - Version 1.1.2 */
|
||||
"plugin_267929e572d647c43e54ab7aa921174d" "" /* Playwire MOTD (Playwire Media) - Version 1.1.0 */
|
||||
"plugin_f9874d362c5c8142037045a0a2c6249c" "" /* [AnoX]A-Nox Core (A-Nox dev.) - Version 3.1a */
|
||||
"plugin_eae8ed2c593591814f9e6bfa73000d85" "" /* Unknown VIP plugin with fake myinfo */
|
||||
"plugin_da0e76b67029c12eb5c1995df4fa4f89" "" /* token changer (Adi) - Version 1.3.9 */
|
||||
"plugin_514efe1f39061e7365a31fc21d452a79" "" /* Token Auto Updater (Phoenix) - Version 1.4 */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -99,7 +99,6 @@
|
||||
"engine" "csgo"
|
||||
"engine" "sdk2013"
|
||||
"engine" "contagion"
|
||||
"engine" "bms"
|
||||
}
|
||||
|
||||
"Offsets"
|
||||
@ -113,6 +112,24 @@
|
||||
}
|
||||
}
|
||||
|
||||
"#default"
|
||||
{
|
||||
"#supported"
|
||||
{
|
||||
"engine" "bms"
|
||||
}
|
||||
|
||||
"Offsets"
|
||||
{
|
||||
"GetDataDescMap"
|
||||
{
|
||||
"windows" "12"
|
||||
"linux" "13"
|
||||
"mac" "13"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* The Ship is completely different */
|
||||
"ship"
|
||||
{
|
||||
@ -162,6 +179,7 @@
|
||||
"game" "kz"
|
||||
"game" "doi"
|
||||
"game" "bms"
|
||||
"game" "iosoccer"
|
||||
}
|
||||
|
||||
"Keys"
|
||||
@ -211,6 +229,7 @@
|
||||
"game" "kz"
|
||||
"game" "doi"
|
||||
"game" "bms"
|
||||
"game" "iosoccer"
|
||||
}
|
||||
|
||||
"Keys"
|
||||
|
@ -17,7 +17,6 @@
|
||||
"#supported"
|
||||
{
|
||||
"game" "ageofchivalry"
|
||||
"game" "zps"
|
||||
"game" "bg2"
|
||||
"game" "pvkii"
|
||||
"game" "gesource"
|
||||
|
@ -19,6 +19,7 @@
|
||||
{
|
||||
"game" "synergy"
|
||||
"game" "empires"
|
||||
"game" "zps"
|
||||
}
|
||||
|
||||
"Offsets"
|
||||
|
@ -6,148 +6,148 @@
|
||||
{
|
||||
"Blocked"
|
||||
{
|
||||
"windows" "105"
|
||||
"linux" "106"
|
||||
"mac" "106"
|
||||
"windows" "106"
|
||||
"linux" "107"
|
||||
"mac" "107"
|
||||
}
|
||||
"EndTouch"
|
||||
{
|
||||
"windows" "103"
|
||||
"linux" "104"
|
||||
"mac" "104"
|
||||
"windows" "104"
|
||||
"linux" "105"
|
||||
"mac" "105"
|
||||
}
|
||||
"FireBullets"
|
||||
{
|
||||
"windows" "117"
|
||||
"linux" "118"
|
||||
"mac" "118"
|
||||
"windows" "118"
|
||||
"linux" "119"
|
||||
"mac" "119"
|
||||
}
|
||||
"GetMaxHealth"
|
||||
{
|
||||
"windows" "121"
|
||||
"linux" "122"
|
||||
"mac" "122"
|
||||
"windows" "122"
|
||||
"linux" "123"
|
||||
"mac" "123"
|
||||
}
|
||||
"GroundEntChanged"
|
||||
{
|
||||
"windows" "175"
|
||||
"linux" "177"
|
||||
"mac" "177"
|
||||
"windows" "177"
|
||||
"linux" "179"
|
||||
"mac" "179"
|
||||
}
|
||||
"OnTakeDamage"
|
||||
{
|
||||
"windows" "67"
|
||||
"linux" "68"
|
||||
"mac" "68"
|
||||
"windows" "68"
|
||||
"linux" "69"
|
||||
"mac" "69"
|
||||
}
|
||||
"OnTakeDamage_Alive"
|
||||
{
|
||||
"windows" "295"
|
||||
"linux" "296"
|
||||
"mac" "296"
|
||||
"windows" "298"
|
||||
"linux" "299"
|
||||
"mac" "299"
|
||||
}
|
||||
"PreThink"
|
||||
{
|
||||
"windows" "368"
|
||||
"linux" "369"
|
||||
"mac" "369"
|
||||
"windows" "371"
|
||||
"linux" "372"
|
||||
"mac" "372"
|
||||
}
|
||||
"PostThink"
|
||||
{
|
||||
"windows" "369"
|
||||
"linux" "370"
|
||||
"mac" "370"
|
||||
"windows" "372"
|
||||
"linux" "373"
|
||||
"mac" "373"
|
||||
}
|
||||
"Reload"
|
||||
{
|
||||
"windows" "306"
|
||||
"linux" "312"
|
||||
"mac" "312"
|
||||
"windows" "310"
|
||||
"linux" "316"
|
||||
"mac" "316"
|
||||
}
|
||||
"SetTransmit"
|
||||
{
|
||||
"windows" "22"
|
||||
"linux" "23"
|
||||
"mac" "23"
|
||||
"windows" "23"
|
||||
"linux" "24"
|
||||
"mac" "24"
|
||||
}
|
||||
"ShouldCollide"
|
||||
{
|
||||
"windows" "17"
|
||||
"linux" "18"
|
||||
"mac" "18"
|
||||
"windows" "18"
|
||||
"linux" "19"
|
||||
"mac" "19"
|
||||
}
|
||||
"Spawn"
|
||||
{
|
||||
"windows" "24"
|
||||
"linux" "25"
|
||||
"mac" "25"
|
||||
"windows" "25"
|
||||
"linux" "26"
|
||||
"mac" "26"
|
||||
}
|
||||
"StartTouch"
|
||||
{
|
||||
"windows" "101"
|
||||
"linux" "102"
|
||||
"mac" "102"
|
||||
}
|
||||
"Think"
|
||||
{
|
||||
"windows" "51"
|
||||
"linux" "52"
|
||||
"mac" "52"
|
||||
}
|
||||
"Touch"
|
||||
{
|
||||
"windows" "102"
|
||||
"linux" "103"
|
||||
"mac" "103"
|
||||
}
|
||||
"Think"
|
||||
{
|
||||
"windows" "52"
|
||||
"linux" "53"
|
||||
"mac" "53"
|
||||
}
|
||||
"Touch"
|
||||
{
|
||||
"windows" "103"
|
||||
"linux" "104"
|
||||
"mac" "104"
|
||||
}
|
||||
"TraceAttack"
|
||||
{
|
||||
"windows" "65"
|
||||
"linux" "66"
|
||||
"mac" "66"
|
||||
"windows" "66"
|
||||
"linux" "67"
|
||||
"mac" "67"
|
||||
}
|
||||
"Use"
|
||||
{
|
||||
"windows" "100"
|
||||
"linux" "101"
|
||||
"mac" "101"
|
||||
"windows" "101"
|
||||
"linux" "102"
|
||||
"mac" "102"
|
||||
}
|
||||
"VPhysicsUpdate"
|
||||
{
|
||||
"windows" "154"
|
||||
"linux" "155"
|
||||
"mac" "155"
|
||||
"windows" "156"
|
||||
"linux" "157"
|
||||
"mac" "157"
|
||||
}
|
||||
"Weapon_CanSwitchTo"
|
||||
{
|
||||
"windows" "287"
|
||||
"linux" "288"
|
||||
"mac" "288"
|
||||
"windows" "290"
|
||||
"linux" "291"
|
||||
"mac" "291"
|
||||
}
|
||||
"Weapon_CanUse"
|
||||
{
|
||||
"windows" "281"
|
||||
"linux" "282"
|
||||
"mac" "282"
|
||||
}
|
||||
"Weapon_Drop"
|
||||
{
|
||||
"windows" "284"
|
||||
"linux" "285"
|
||||
"mac" "285"
|
||||
}
|
||||
"Weapon_Equip"
|
||||
"Weapon_Drop"
|
||||
{
|
||||
"windows" "282"
|
||||
"linux" "283"
|
||||
"mac" "283"
|
||||
"windows" "287"
|
||||
"linux" "288"
|
||||
"mac" "288"
|
||||
}
|
||||
"Weapon_Switch"
|
||||
"Weapon_Equip"
|
||||
{
|
||||
"windows" "285"
|
||||
"linux" "286"
|
||||
"mac" "286"
|
||||
}
|
||||
"Weapon_Switch"
|
||||
{
|
||||
"windows" "288"
|
||||
"linux" "289"
|
||||
"mac" "289"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,142 +1,142 @@
|
||||
"Games"
|
||||
{
|
||||
"#default"
|
||||
{
|
||||
"Offsets"
|
||||
{
|
||||
"Blocked"
|
||||
{
|
||||
"windows" "109"
|
||||
"linux" "110"
|
||||
"mac" "110"
|
||||
}
|
||||
"EndTouch"
|
||||
{
|
||||
"windows" "107"
|
||||
"linux" "108"
|
||||
"mac" "108"
|
||||
}
|
||||
"FireBullets"
|
||||
{
|
||||
"windows" "120"
|
||||
"linux" "121"
|
||||
"mac" "121"
|
||||
}
|
||||
"OnTakeDamage"
|
||||
{
|
||||
"windows" "66"
|
||||
"linux" "67"
|
||||
"mac" "67"
|
||||
}
|
||||
"OnTakeDamage_Alive"
|
||||
{
|
||||
"windows" "290"
|
||||
"linux" "291"
|
||||
"mac" "291"
|
||||
}
|
||||
"PreThink"
|
||||
{
|
||||
"windows" "352"
|
||||
"linux" "353"
|
||||
"mac" "353"
|
||||
}
|
||||
"PostThink"
|
||||
{
|
||||
"windows" "353"
|
||||
"linux" "354"
|
||||
"mac" "354"
|
||||
}
|
||||
"SetTransmit"
|
||||
{
|
||||
"windows" "20"
|
||||
"linux" "21"
|
||||
"mac" "21"
|
||||
}
|
||||
"ShouldCollide"
|
||||
{
|
||||
"windows" "16"
|
||||
"linux" "17"
|
||||
"mac" "17"
|
||||
}
|
||||
"Spawn"
|
||||
{
|
||||
"windows" "22"
|
||||
"linux" "23"
|
||||
"mac" "23"
|
||||
}
|
||||
"StartTouch"
|
||||
{
|
||||
"windows" "105"
|
||||
"linux" "106"
|
||||
"mac" "106"
|
||||
}
|
||||
"Think"
|
||||
{
|
||||
"windows" "48"
|
||||
"linux" "49"
|
||||
"mac" "49"
|
||||
}
|
||||
"Touch"
|
||||
{
|
||||
"windows" "106"
|
||||
"linux" "107"
|
||||
"mac" "107"
|
||||
}
|
||||
"TraceAttack"
|
||||
{
|
||||
"windows" "64"
|
||||
"linux" "65"
|
||||
"mac" "65"
|
||||
}
|
||||
"VPhysicsUpdate"
|
||||
{
|
||||
"windows" "166"
|
||||
"linux" "167"
|
||||
"mac" "167"
|
||||
}
|
||||
"Weapon_CanSwitchTo"
|
||||
{
|
||||
"windows" "284"
|
||||
"linux" "285"
|
||||
"mac" "285"
|
||||
}
|
||||
"Weapon_CanUse"
|
||||
{
|
||||
"windows" "278"
|
||||
"linux" "279"
|
||||
"mac" "279"
|
||||
}
|
||||
"Weapon_Drop"
|
||||
{
|
||||
"windows" "281"
|
||||
"linux" "282"
|
||||
"mac" "282"
|
||||
}
|
||||
"Weapon_Equip"
|
||||
{
|
||||
"windows" "279"
|
||||
"linux" "280"
|
||||
"mac" "280"
|
||||
}
|
||||
"Weapon_Switch"
|
||||
{
|
||||
"windows" "282"
|
||||
"linux" "283"
|
||||
"mac" "283"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
"#default"
|
||||
{
|
||||
"Offsets"
|
||||
{
|
||||
"EntityListeners"
|
||||
{
|
||||
"windows" "131108"
|
||||
"linux" "131108"
|
||||
"mac" "131108"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
"Games"
|
||||
{
|
||||
"#default"
|
||||
{
|
||||
"Offsets"
|
||||
{
|
||||
"Blocked"
|
||||
{
|
||||
"windows" "110"
|
||||
"linux" "111"
|
||||
"mac" "111"
|
||||
}
|
||||
"EndTouch"
|
||||
{
|
||||
"windows" "108"
|
||||
"linux" "109"
|
||||
"mac" "109"
|
||||
}
|
||||
"FireBullets"
|
||||
{
|
||||
"windows" "121"
|
||||
"linux" "122"
|
||||
"mac" "122"
|
||||
}
|
||||
"OnTakeDamage"
|
||||
{
|
||||
"windows" "67"
|
||||
"linux" "68"
|
||||
"mac" "68"
|
||||
}
|
||||
"OnTakeDamage_Alive"
|
||||
{
|
||||
"windows" "291"
|
||||
"linux" "292"
|
||||
"mac" "292"
|
||||
}
|
||||
"PreThink"
|
||||
{
|
||||
"windows" "353"
|
||||
"linux" "354"
|
||||
"mac" "354"
|
||||
}
|
||||
"PostThink"
|
||||
{
|
||||
"windows" "354"
|
||||
"linux" "355"
|
||||
"mac" "355"
|
||||
}
|
||||
"SetTransmit"
|
||||
{
|
||||
"windows" "21"
|
||||
"linux" "22"
|
||||
"mac" "22"
|
||||
}
|
||||
"ShouldCollide"
|
||||
{
|
||||
"windows" "17"
|
||||
"linux" "18"
|
||||
"mac" "18"
|
||||
}
|
||||
"Spawn"
|
||||
{
|
||||
"windows" "23"
|
||||
"linux" "24"
|
||||
"mac" "24"
|
||||
}
|
||||
"StartTouch"
|
||||
{
|
||||
"windows" "106"
|
||||
"linux" "107"
|
||||
"mac" "107"
|
||||
}
|
||||
"Think"
|
||||
{
|
||||
"windows" "49"
|
||||
"linux" "50"
|
||||
"mac" "50"
|
||||
}
|
||||
"Touch"
|
||||
{
|
||||
"windows" "107"
|
||||
"linux" "108"
|
||||
"mac" "108"
|
||||
}
|
||||
"TraceAttack"
|
||||
{
|
||||
"windows" "65"
|
||||
"linux" "66"
|
||||
"mac" "66"
|
||||
}
|
||||
"VPhysicsUpdate"
|
||||
{
|
||||
"windows" "167"
|
||||
"linux" "168"
|
||||
"mac" "168"
|
||||
}
|
||||
"Weapon_CanSwitchTo"
|
||||
{
|
||||
"windows" "285"
|
||||
"linux" "286"
|
||||
"mac" "286"
|
||||
}
|
||||
"Weapon_CanUse"
|
||||
{
|
||||
"windows" "279"
|
||||
"linux" "280"
|
||||
"mac" "280"
|
||||
}
|
||||
"Weapon_Drop"
|
||||
{
|
||||
"windows" "282"
|
||||
"linux" "283"
|
||||
"mac" "283"
|
||||
}
|
||||
"Weapon_Equip"
|
||||
{
|
||||
"windows" "280"
|
||||
"linux" "281"
|
||||
"mac" "281"
|
||||
}
|
||||
"Weapon_Switch"
|
||||
{
|
||||
"windows" "283"
|
||||
"linux" "284"
|
||||
"mac" "284"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
"#default"
|
||||
{
|
||||
"Offsets"
|
||||
{
|
||||
"EntityListeners"
|
||||
{
|
||||
"windows" "131108"
|
||||
"linux" "131108"
|
||||
"mac" "131108"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -67,7 +67,7 @@
|
||||
"StartTouch"
|
||||
{
|
||||
"windows" "100"
|
||||
"linux" "101
|
||||
"linux" "101"
|
||||
}
|
||||
"Think"
|
||||
{
|
||||
@ -121,4 +121,4 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -6,148 +6,148 @@
|
||||
"Offsets"
|
||||
{
|
||||
"Blocked"
|
||||
{
|
||||
"windows" "105"
|
||||
"linux" "106"
|
||||
"mac" "106"
|
||||
}
|
||||
"EndTouch"
|
||||
{
|
||||
"windows" "103"
|
||||
"linux" "104"
|
||||
"mac" "104"
|
||||
}
|
||||
"EndTouch"
|
||||
{
|
||||
"windows" "101"
|
||||
"linux" "102"
|
||||
"mac" "102"
|
||||
}
|
||||
"FireBullets"
|
||||
{
|
||||
"windows" "113"
|
||||
"linux" "114"
|
||||
"mac" "114"
|
||||
"windows" "115"
|
||||
"linux" "116"
|
||||
"mac" "116"
|
||||
}
|
||||
"GetMaxHealth"
|
||||
{
|
||||
"windows" "118"
|
||||
"linux" "119"
|
||||
"mac" "119"
|
||||
"windows" "120"
|
||||
"linux" "121"
|
||||
"mac" "121"
|
||||
}
|
||||
"GroundEntChanged"
|
||||
{
|
||||
"windows" "178"
|
||||
"linux" "180"
|
||||
"mac" "180"
|
||||
"windows" "180"
|
||||
"linux" "182"
|
||||
"mac" "182"
|
||||
}
|
||||
"OnTakeDamage"
|
||||
{
|
||||
"windows" "63"
|
||||
"linux" "64"
|
||||
"mac" "64"
|
||||
"windows" "65"
|
||||
"linux" "66"
|
||||
"mac" "66"
|
||||
}
|
||||
"OnTakeDamage_Alive"
|
||||
{
|
||||
"windows" "277"
|
||||
"linux" "278"
|
||||
"mac" "278"
|
||||
}
|
||||
"PreThink"
|
||||
{
|
||||
"windows" "338"
|
||||
"linux" "339"
|
||||
"mac" "339"
|
||||
}
|
||||
"PostThink"
|
||||
{
|
||||
"windows" "339"
|
||||
"linux" "340"
|
||||
"mac" "340"
|
||||
}
|
||||
"Reload"
|
||||
{
|
||||
"windows" "275"
|
||||
"linux" "276"
|
||||
"mac" "276"
|
||||
}
|
||||
"PreThink"
|
||||
{
|
||||
"windows" "336"
|
||||
"linux" "337"
|
||||
"mac" "337"
|
||||
}
|
||||
"PostThink"
|
||||
{
|
||||
"windows" "337"
|
||||
"linux" "338"
|
||||
"mac" "338"
|
||||
}
|
||||
"Reload"
|
||||
{
|
||||
"windows" "273"
|
||||
"linux" "274"
|
||||
"mac" "274"
|
||||
}
|
||||
"SetTransmit"
|
||||
{
|
||||
"windows" "21"
|
||||
"linux" "22"
|
||||
"mac" "22"
|
||||
}
|
||||
"ShouldCollide"
|
||||
{
|
||||
"windows" "16"
|
||||
"linux" "17"
|
||||
"mac" "17"
|
||||
}
|
||||
"Spawn"
|
||||
{
|
||||
"windows" "23"
|
||||
"linux" "24"
|
||||
"mac" "24"
|
||||
}
|
||||
"ShouldCollide"
|
||||
{
|
||||
"windows" "18"
|
||||
"linux" "19"
|
||||
"mac" "19"
|
||||
}
|
||||
"Spawn"
|
||||
{
|
||||
"windows" "25"
|
||||
"linux" "26"
|
||||
"mac" "26"
|
||||
}
|
||||
"StartTouch"
|
||||
{
|
||||
"windows" "99"
|
||||
"linux" "100"
|
||||
"mac" "100"
|
||||
"windows" "101"
|
||||
"linux" "102"
|
||||
"mac" "102"
|
||||
}
|
||||
"Think"
|
||||
{
|
||||
"windows" "48"
|
||||
"linux" "49"
|
||||
"mac" "49"
|
||||
"windows" "50"
|
||||
"linux" "51"
|
||||
"mac" "51"
|
||||
}
|
||||
"Touch"
|
||||
{
|
||||
"windows" "102"
|
||||
"linux" "103"
|
||||
"mac" "103"
|
||||
}
|
||||
"TraceAttack"
|
||||
{
|
||||
"windows" "63"
|
||||
"linux" "64"
|
||||
"mac" "64"
|
||||
}
|
||||
"Use"
|
||||
{
|
||||
"windows" "100"
|
||||
"linux" "101"
|
||||
"mac" "101"
|
||||
}
|
||||
"TraceAttack"
|
||||
{
|
||||
"windows" "61"
|
||||
"linux" "62"
|
||||
"mac" "62"
|
||||
}
|
||||
"Use"
|
||||
{
|
||||
"windows" "98"
|
||||
"linux" "99"
|
||||
"mac" "99"
|
||||
}
|
||||
"VPhysicsUpdate"
|
||||
{
|
||||
"windows" "158"
|
||||
"linux" "159"
|
||||
"mac" "159"
|
||||
"windows" "160"
|
||||
"linux" "161"
|
||||
"mac" "161"
|
||||
}
|
||||
"Weapon_CanSwitchTo"
|
||||
{
|
||||
"windows" "269"
|
||||
"linux" "270"
|
||||
"mac" "270"
|
||||
"windows" "271"
|
||||
"linux" "272"
|
||||
"mac" "272"
|
||||
}
|
||||
"Weapon_CanUse"
|
||||
{
|
||||
"windows" "263"
|
||||
"linux" "264"
|
||||
"mac" "264"
|
||||
"windows" "265"
|
||||
"linux" "266"
|
||||
"mac" "266"
|
||||
}
|
||||
"Weapon_Drop"
|
||||
{
|
||||
"windows" "268"
|
||||
"linux" "269"
|
||||
"mac" "269"
|
||||
}
|
||||
"Weapon_Equip"
|
||||
{
|
||||
"windows" "266"
|
||||
"linux" "267"
|
||||
"mac" "267"
|
||||
}
|
||||
"Weapon_Equip"
|
||||
{
|
||||
"windows" "264"
|
||||
"linux" "265"
|
||||
"mac" "265"
|
||||
}
|
||||
"Weapon_Switch"
|
||||
{
|
||||
"windows" "267"
|
||||
"linux" "268"
|
||||
"mac" "268"
|
||||
"windows" "269"
|
||||
"linux" "270"
|
||||
"mac" "270"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,105 +1,105 @@
|
||||
"Games"
|
||||
{
|
||||
/* Zombic Panic Source 2.0 */
|
||||
/* Zombic Panic Source 3.0.7 (Hotfix-3) */
|
||||
"zps"
|
||||
{
|
||||
"Offsets"
|
||||
{
|
||||
"EndTouch"
|
||||
{
|
||||
"windows" "96"
|
||||
"linux" "97"
|
||||
"windows" "113"
|
||||
"linux" "114"
|
||||
}
|
||||
"FireBullets"
|
||||
{
|
||||
"windows" "108"
|
||||
"linux" "109"
|
||||
"windows" "125"
|
||||
"linux" "126"
|
||||
}
|
||||
"OnTakeDamage"
|
||||
{
|
||||
"windows" "61"
|
||||
"linux" "62"
|
||||
"windows" "74"
|
||||
"linux" "75"
|
||||
}
|
||||
"PreThink"
|
||||
{
|
||||
"windows" "295"
|
||||
"linux" "296"
|
||||
"windows" "351"
|
||||
"linux" "352"
|
||||
}
|
||||
"PostThink"
|
||||
{
|
||||
"windows" "296"
|
||||
"linux" "297"
|
||||
"windows" "352"
|
||||
"linux" "353"
|
||||
}
|
||||
"SetTransmit"
|
||||
{
|
||||
"windows" "19"
|
||||
"linux" "20"
|
||||
"windows" "26"
|
||||
"linux" "27"
|
||||
}
|
||||
"ShouldCollide"
|
||||
{
|
||||
"windows" "15"
|
||||
"linux" "16"
|
||||
"windows" "22"
|
||||
"linux" "23"
|
||||
}
|
||||
"Spawn"
|
||||
{
|
||||
"windows" "21"
|
||||
"linux" "22"
|
||||
"windows" "28"
|
||||
"linux" "29"
|
||||
}
|
||||
"StartTouch"
|
||||
{
|
||||
"windows" "94"
|
||||
"linux" "95"
|
||||
"windows" "111"
|
||||
"linux" "112"
|
||||
}
|
||||
"Think"
|
||||
{
|
||||
"windows" "46"
|
||||
"linux" "47"
|
||||
"windows" "57"
|
||||
"linux" "58"
|
||||
}
|
||||
"Touch"
|
||||
{
|
||||
"windows" "95"
|
||||
"linux" "96"
|
||||
"windows" "112"
|
||||
"linux" "113"
|
||||
}
|
||||
"TraceAttack"
|
||||
{
|
||||
"windows" "59"
|
||||
"linux" "60"
|
||||
"windows" "70"
|
||||
"linux" "71"
|
||||
}
|
||||
"Use"
|
||||
{
|
||||
"windows" "93"
|
||||
"linux" "94"
|
||||
"windows" "110"
|
||||
"linux" "111"
|
||||
}
|
||||
"VPhysicsUpdate"
|
||||
{
|
||||
"windows" "149"
|
||||
"linux" "150"
|
||||
"windows" "170"
|
||||
"linux" "171"
|
||||
}
|
||||
"Weapon_CanSwitchTo"
|
||||
{
|
||||
"windows" "240"
|
||||
"linux" "241"
|
||||
"windows" "281"
|
||||
"linux" "282"
|
||||
}
|
||||
"Weapon_CanUse"
|
||||
{
|
||||
"windows" "234"
|
||||
"linux" "235"
|
||||
"windows" "274"
|
||||
"linux" "275"
|
||||
}
|
||||
"Weapon_Drop"
|
||||
{
|
||||
"windows" "237"
|
||||
"linux" "238"
|
||||
"windows" "277"
|
||||
"linux" "278"
|
||||
}
|
||||
"Weapon_Equip"
|
||||
{
|
||||
"windows" "235"
|
||||
"linux" "236"
|
||||
"windows" "275"
|
||||
"linux" "276"
|
||||
}
|
||||
"Weapon_Switch"
|
||||
{
|
||||
"windows" "278"
|
||||
"linux" "279"
|
||||
}
|
||||
//"Weapon_Switch"
|
||||
//{
|
||||
// "windows" "234"
|
||||
// "linux" "235"
|
||||
//}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -219,93 +219,94 @@
|
||||
{
|
||||
"GiveNamedItem"
|
||||
{
|
||||
"windows" "450"
|
||||
"linux" "451"
|
||||
"mac" "451"
|
||||
"windows" "456"
|
||||
"linux" "457"
|
||||
"mac" "457"
|
||||
}
|
||||
"RemovePlayerItem"
|
||||
{
|
||||
"windows" "293"
|
||||
"linux" "294"
|
||||
"mac" "294"
|
||||
"windows" "296"
|
||||
"linux" "297"
|
||||
"mac" "297"
|
||||
}
|
||||
"Weapon_GetSlot"
|
||||
{
|
||||
"windows" "289"
|
||||
"linux" "290"
|
||||
"mac" "290"
|
||||
"windows" "292"
|
||||
"linux" "293"
|
||||
"mac" "293"
|
||||
}
|
||||
"Ignite"
|
||||
{
|
||||
"windows" "223"
|
||||
"linux" "224"
|
||||
"mac" "224"
|
||||
}
|
||||
"Extinguish"
|
||||
{
|
||||
"windows" "226"
|
||||
"linux" "227"
|
||||
"mac" "227"
|
||||
}
|
||||
"Extinguish"
|
||||
{
|
||||
"windows" "229"
|
||||
"linux" "230"
|
||||
"linux64" "230"
|
||||
"mac64" "230"
|
||||
}
|
||||
"Teleport"
|
||||
{
|
||||
"windows" "113"
|
||||
"linux" "114"
|
||||
"mac" "114"
|
||||
"windows" "114"
|
||||
"linux" "115"
|
||||
"mac" "115"
|
||||
}
|
||||
"CommitSuicide"
|
||||
{
|
||||
"windows" "500"
|
||||
"linux" "500"
|
||||
"mac" "500"
|
||||
"windows" "506"
|
||||
"linux" "506"
|
||||
"mac" "506"
|
||||
}
|
||||
"GetVelocity"
|
||||
{
|
||||
"windows" "138"
|
||||
"linux" "139"
|
||||
"mac" "139"
|
||||
"windows" "140"
|
||||
"linux" "141"
|
||||
"mac" "141"
|
||||
}
|
||||
"EyeAngles"
|
||||
{
|
||||
"windows" "129"
|
||||
"linux" "130"
|
||||
"mac" "130"
|
||||
"windows" "131"
|
||||
"linux" "132"
|
||||
"mac" "132"
|
||||
}
|
||||
"AcceptInput"
|
||||
{
|
||||
"windows" "40"
|
||||
"linux" "41"
|
||||
"mac" "41"
|
||||
"windows" "41"
|
||||
"linux" "42"
|
||||
"mac" "42"
|
||||
}
|
||||
"SetEntityModel"
|
||||
{
|
||||
"windows" "26"
|
||||
"linux" "27"
|
||||
"mac" "27"
|
||||
"windows" "27"
|
||||
"linux" "28"
|
||||
"mac" "28"
|
||||
}
|
||||
"WeaponEquip"
|
||||
{
|
||||
"windows" "282"
|
||||
"linux" "283"
|
||||
"mac" "283"
|
||||
"windows" "285"
|
||||
"linux" "286"
|
||||
"mac" "286"
|
||||
}
|
||||
"Activate"
|
||||
{
|
||||
"windows" "37"
|
||||
"linux" "38"
|
||||
"mac" "38"
|
||||
"windows" "38"
|
||||
"linux" "39"
|
||||
"mac" "39"
|
||||
}
|
||||
"PlayerRunCmd"
|
||||
{
|
||||
"windows" "470"
|
||||
"linux" "471"
|
||||
"mac" "471"
|
||||
"windows" "476"
|
||||
"linux" "477"
|
||||
"mac" "477"
|
||||
}
|
||||
"GiveAmmo"
|
||||
{
|
||||
"windows" "275"
|
||||
"linux" "276"
|
||||
"mac" "276"
|
||||
"windows" "278"
|
||||
"linux" "279"
|
||||
"mac" "279"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -91,7 +91,6 @@
|
||||
"#supported"
|
||||
{
|
||||
"game" "ageofchivalry"
|
||||
"game" "zps"
|
||||
"game" "bg2"
|
||||
"game" "gesource"
|
||||
"game" "RnLBeta"
|
||||
|
@ -153,7 +153,7 @@
|
||||
"FireOutput"
|
||||
{
|
||||
"library" "server"
|
||||
"windows" "\x55\x8B\xEC\x83\xEC\x20\x53\x8B\xC1"
|
||||
"windows" "\x55\x8B\xEC\x81\xEC\x20\x01\x00\x00\x53\x8B\xC1"
|
||||
"linux" "@_ZN17CBaseEntityOutput10FireOutputE9variant_tP11CBaseEntityS2_f"
|
||||
"mac" "@_ZN17CBaseEntityOutput10FireOutputE9variant_tP11CBaseEntityS2_f"
|
||||
}
|
||||
|
@ -1,200 +1,200 @@
|
||||
/**
|
||||
* Do not edit this file. Any changes will be overwritten by the gamedata
|
||||
* updater or by upgrading your SourceMod install.
|
||||
*
|
||||
* To override data in this file, create a subdirectory named "custom" and
|
||||
* place your own gamedata file(s) inside of it. Such files will be parsed
|
||||
* after SM's own.
|
||||
*
|
||||
* For more information, see http://wiki.alliedmods.net/Gamedata_Updating_(SourceMod)
|
||||
*/
|
||||
|
||||
"Games"
|
||||
{
|
||||
/* General Temp Entities */
|
||||
"#default"
|
||||
{
|
||||
"Offsets"
|
||||
{
|
||||
"GetTEName"
|
||||
{
|
||||
"windows" "4"
|
||||
"linux" "4"
|
||||
"mac" "4"
|
||||
}
|
||||
"GetTENext"
|
||||
{
|
||||
"windows" "8"
|
||||
"linux" "8"
|
||||
"mac" "8"
|
||||
}
|
||||
"TE_GetServerClass"
|
||||
{
|
||||
"windows" "0"
|
||||
"linux" "0"
|
||||
"mac" "0"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* CBaseEntityOutput::FireOutput */
|
||||
"#default"
|
||||
{
|
||||
"Signatures"
|
||||
{
|
||||
"FireOutput"
|
||||
{
|
||||
"library" "server"
|
||||
"windows" "\x55\x8B\xEC\x81\xEC\x2A\x2A\x2A\x2A\xA1\x2A\x2A\x2A\x2A\x33\xC5\x89\x45\xFC\x53\x8B\x5D\x20\x8B\xC1\x8B\x4D\x1C\x56\x57\x8B"
|
||||
"linux" "@_ZN17CBaseEntityOutput10FireOutputE9variant_tP11CBaseEntityS2_f"
|
||||
"mac" "@_ZN17CBaseEntityOutput10FireOutputE9variant_tP11CBaseEntityS2_f"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* SetUserInfo data */
|
||||
"#default"
|
||||
{
|
||||
"Offsets"
|
||||
{
|
||||
/**
|
||||
* CBaseClient::SetUserCVar(char const*,char const*);
|
||||
* Linux offset straight from VTable dump.
|
||||
* Windows offset is crazy. Found the windows SetName function using string "(%d)%-0.*s"
|
||||
* Cross referenced back to the vtable and counted manually (SetUserCvar is 1 higher, offsets start from 1)
|
||||
*/
|
||||
"SetUserCvar"
|
||||
{
|
||||
"windows" "18"
|
||||
"linux" "58"
|
||||
"mac" "58"
|
||||
}
|
||||
/**
|
||||
* CBaseClient::SetName(char const*);
|
||||
* Linux offset straight from VTable dump.
|
||||
* Has string "(%d)%-0.*s"
|
||||
*/
|
||||
"SetClientName"
|
||||
{
|
||||
"windows" "17"
|
||||
"linux" "57"
|
||||
"mac" "57"
|
||||
}
|
||||
/**
|
||||
* Offset into CBaseClient - Used by CBaseServer::UpdateUserSettings to determine when changes have been made.
|
||||
* Find CBaseClient::UpdateUserSettings (strings "net_maxroutable", "cl_updaterate" etc) and the offset is set to 0 near the end.
|
||||
* Linux: mov byte ptr [esi+98h], 0
|
||||
* Win: mov byte ptr [esi+0A4h], 0
|
||||
*/
|
||||
"InfoChanged"
|
||||
{
|
||||
"windows" "140"
|
||||
"linux" "140"
|
||||
"mac" "140"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
"#default"
|
||||
{
|
||||
"Offsets"
|
||||
{
|
||||
"GiveNamedItem"
|
||||
{
|
||||
"windows" "421"
|
||||
"linux" "422"
|
||||
"mac" "422"
|
||||
}
|
||||
"RemovePlayerItem"
|
||||
{
|
||||
"windows" "288"
|
||||
"linux" "289"
|
||||
"mac" "289"
|
||||
}
|
||||
"Weapon_GetSlot"
|
||||
{
|
||||
"windows" "286"
|
||||
"linux" "287"
|
||||
"mac" "287"
|
||||
}
|
||||
"Ignite"
|
||||
{
|
||||
"windows" "225"
|
||||
"linux" "226"
|
||||
"mac" "226"
|
||||
}
|
||||
"Extinguish"
|
||||
{
|
||||
"windows" "229"
|
||||
"linux" "230"
|
||||
"mac" "230"
|
||||
}
|
||||
"Teleport"
|
||||
{
|
||||
"windows" "116"
|
||||
"linux" "117"
|
||||
"mac" "117"
|
||||
}
|
||||
"CommitSuicide"
|
||||
{
|
||||
"windows" "461"
|
||||
"linux" "461"
|
||||
"mac" "461"
|
||||
}
|
||||
"GetVelocity"
|
||||
{
|
||||
"windows" "149"
|
||||
"linux" "150"
|
||||
"mac" "150"
|
||||
}
|
||||
"EyeAngles"
|
||||
{
|
||||
"windows" "139"
|
||||
"linux" "140"
|
||||
"mac" "140"
|
||||
}
|
||||
"SetEntityModel"
|
||||
{
|
||||
"windows" "24"
|
||||
"linux" "25"
|
||||
"mac" "25"
|
||||
}
|
||||
"AcceptInput"
|
||||
{
|
||||
"windows" "37"
|
||||
"linux" "38"
|
||||
"mac" "38"
|
||||
}
|
||||
"WeaponEquip"
|
||||
{
|
||||
"windows" "279"
|
||||
"linux" "280"
|
||||
"mac" "280"
|
||||
}
|
||||
"Activate"
|
||||
{
|
||||
"windows" "34"
|
||||
"linux" "35"
|
||||
"mac" "35"
|
||||
}
|
||||
"PlayerRunCmd"
|
||||
{
|
||||
"windows" "440"
|
||||
"linux" "441"
|
||||
"mac" "441"
|
||||
}
|
||||
"GiveAmmo"
|
||||
{
|
||||
"windows" "270"
|
||||
"linux" "271"
|
||||
"mac" "271"
|
||||
}
|
||||
}
|
||||
|
||||
"Keys"
|
||||
{
|
||||
"GameRulesProxy" "CBM_MP_GameRulesProxy"
|
||||
"GameRulesDataTable" "blackmesa_mp_gamerules_data"
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Do not edit this file. Any changes will be overwritten by the gamedata
|
||||
* updater or by upgrading your SourceMod install.
|
||||
*
|
||||
* To override data in this file, create a subdirectory named "custom" and
|
||||
* place your own gamedata file(s) inside of it. Such files will be parsed
|
||||
* after SM's own.
|
||||
*
|
||||
* For more information, see http://wiki.alliedmods.net/Gamedata_Updating_(SourceMod)
|
||||
*/
|
||||
|
||||
"Games"
|
||||
{
|
||||
/* General Temp Entities */
|
||||
"#default"
|
||||
{
|
||||
"Offsets"
|
||||
{
|
||||
"GetTEName"
|
||||
{
|
||||
"windows" "4"
|
||||
"linux" "4"
|
||||
"mac" "4"
|
||||
}
|
||||
"GetTENext"
|
||||
{
|
||||
"windows" "8"
|
||||
"linux" "8"
|
||||
"mac" "8"
|
||||
}
|
||||
"TE_GetServerClass"
|
||||
{
|
||||
"windows" "0"
|
||||
"linux" "0"
|
||||
"mac" "0"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* CBaseEntityOutput::FireOutput */
|
||||
"#default"
|
||||
{
|
||||
"Signatures"
|
||||
{
|
||||
"FireOutput"
|
||||
{
|
||||
"library" "server"
|
||||
"windows" "\x55\x8B\xEC\x81\xEC\x2A\x2A\x2A\x2A\xA1\x2A\x2A\x2A\x2A\x33\xC5\x89\x45\xFC\x53\x8B\x5D\x20\x8B\xC1\x8B\x4D\x1C\x56\x57\x8B"
|
||||
"linux" "@_ZN17CBaseEntityOutput10FireOutputE9variant_tP11CBaseEntityS2_f"
|
||||
"mac" "@_ZN17CBaseEntityOutput10FireOutputE9variant_tP11CBaseEntityS2_f"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* SetUserInfo data */
|
||||
"#default"
|
||||
{
|
||||
"Offsets"
|
||||
{
|
||||
/**
|
||||
* CBaseClient::SetUserCVar(char const*,char const*);
|
||||
* Linux offset straight from VTable dump.
|
||||
* Windows offset is crazy. Found the windows SetName function using string "(%d)%-0.*s"
|
||||
* Cross referenced back to the vtable and counted manually (SetUserCvar is 1 higher, offsets start from 1)
|
||||
*/
|
||||
"SetUserCvar"
|
||||
{
|
||||
"windows" "18"
|
||||
"linux" "58"
|
||||
"mac" "58"
|
||||
}
|
||||
/**
|
||||
* CBaseClient::SetName(char const*);
|
||||
* Linux offset straight from VTable dump.
|
||||
* Has string "(%d)%-0.*s"
|
||||
*/
|
||||
"SetClientName"
|
||||
{
|
||||
"windows" "17"
|
||||
"linux" "57"
|
||||
"mac" "57"
|
||||
}
|
||||
/**
|
||||
* Offset into CBaseClient - Used by CBaseServer::UpdateUserSettings to determine when changes have been made.
|
||||
* Find CBaseClient::UpdateUserSettings (strings "net_maxroutable", "cl_updaterate" etc) and the offset is set to 0 near the end.
|
||||
* Linux: mov byte ptr [esi+98h], 0
|
||||
* Win: mov byte ptr [esi+0A4h], 0
|
||||
*/
|
||||
"InfoChanged"
|
||||
{
|
||||
"windows" "140"
|
||||
"linux" "140"
|
||||
"mac" "140"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
"#default"
|
||||
{
|
||||
"Offsets"
|
||||
{
|
||||
"GiveNamedItem"
|
||||
{
|
||||
"windows" "423"
|
||||
"linux" "424"
|
||||
"mac" "424"
|
||||
}
|
||||
"RemovePlayerItem"
|
||||
{
|
||||
"windows" "289"
|
||||
"linux" "290"
|
||||
"mac" "290"
|
||||
}
|
||||
"Weapon_GetSlot"
|
||||
{
|
||||
"windows" "287"
|
||||
"linux" "288"
|
||||
"mac" "288"
|
||||
}
|
||||
"Ignite"
|
||||
{
|
||||
"windows" "226"
|
||||
"linux" "227"
|
||||
"mac" "227"
|
||||
}
|
||||
"Extinguish"
|
||||
{
|
||||
"windows" "230"
|
||||
"linux" "231"
|
||||
"mac" "231"
|
||||
}
|
||||
"Teleport"
|
||||
{
|
||||
"windows" "117"
|
||||
"linux" "118"
|
||||
"mac" "118"
|
||||
}
|
||||
"CommitSuicide"
|
||||
{
|
||||
"windows" "463"
|
||||
"linux" "463"
|
||||
"mac" "463"
|
||||
}
|
||||
"GetVelocity"
|
||||
{
|
||||
"windows" "150"
|
||||
"linux" "151"
|
||||
"mac" "151"
|
||||
}
|
||||
"EyeAngles"
|
||||
{
|
||||
"windows" "140"
|
||||
"linux" "141"
|
||||
"mac" "141"
|
||||
}
|
||||
"SetEntityModel"
|
||||
{
|
||||
"windows" "25"
|
||||
"linux" "26"
|
||||
"mac" "26"
|
||||
}
|
||||
"AcceptInput"
|
||||
{
|
||||
"windows" "38"
|
||||
"linux" "39"
|
||||
"mac" "39"
|
||||
}
|
||||
"WeaponEquip"
|
||||
{
|
||||
"windows" "280"
|
||||
"linux" "281"
|
||||
"mac" "281"
|
||||
}
|
||||
"Activate"
|
||||
{
|
||||
"windows" "35"
|
||||
"linux" "36"
|
||||
"mac" "36"
|
||||
}
|
||||
"PlayerRunCmd"
|
||||
{
|
||||
"windows" "442"
|
||||
"linux" "443"
|
||||
"mac" "443"
|
||||
}
|
||||
"GiveAmmo"
|
||||
{
|
||||
"windows" "271"
|
||||
"linux" "272"
|
||||
"mac" "272"
|
||||
}
|
||||
}
|
||||
|
||||
"Keys"
|
||||
{
|
||||
"GameRulesProxy" "CBM_MP_GameRulesProxy"
|
||||
"GameRulesDataTable" "blackmesa_mp_gamerules_data"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,113 +1,98 @@
|
||||
/**
|
||||
* Do not edit this file. Any changes will be overwritten by the gamedata
|
||||
* updater or by upgrading your SourceMod install.
|
||||
*
|
||||
* To override data in this file, create a subdirectory named "custom" and
|
||||
* place your own gamedata file(s) inside of it. Such files will be parsed
|
||||
* after SM's own.
|
||||
*
|
||||
* For more information, see http://wiki.alliedmods.net/Gamedata_Updating_(SourceMod)
|
||||
*/
|
||||
|
||||
"Games"
|
||||
{
|
||||
/* IOS:Source */
|
||||
"ios"
|
||||
{
|
||||
"Offsets"
|
||||
{
|
||||
/* CBasePlayer */
|
||||
"GiveNamedItem"
|
||||
{
|
||||
"windows" "328"
|
||||
"linux" "329"
|
||||
}
|
||||
"RemovePlayerItem"
|
||||
{
|
||||
"windows" "226"
|
||||
"linux" "227"
|
||||
}
|
||||
"Weapon_GetSlot"
|
||||
{
|
||||
"windows" "224"
|
||||
"linux" "225"
|
||||
}
|
||||
"Ignite"
|
||||
{
|
||||
"windows" "188"
|
||||
"linux" "189"
|
||||
}
|
||||
"Extinguish"
|
||||
{
|
||||
"windows" "189"
|
||||
"linux" "190"
|
||||
}
|
||||
"Teleport"
|
||||
{
|
||||
"windows" "98"
|
||||
"linux" "99"
|
||||
}
|
||||
"CommitSuicide"
|
||||
{
|
||||
"windows" "356"
|
||||
"linux" "357"
|
||||
}
|
||||
"GetVelocity"
|
||||
{
|
||||
"windows" "126"
|
||||
"linux" "127"
|
||||
}
|
||||
"EyeAngles"
|
||||
{
|
||||
"windows" "118"
|
||||
"linux" "119"
|
||||
}
|
||||
"DispatchKeyValue"
|
||||
{
|
||||
"windows" "31"
|
||||
"linux" "30"
|
||||
}
|
||||
"DispatchKeyValueFloat"
|
||||
{
|
||||
"windows" "30"
|
||||
"linux" "31"
|
||||
}
|
||||
"DispatchKeyValueVector"
|
||||
{
|
||||
"windows" "29"
|
||||
"linux" "32"
|
||||
}
|
||||
"AcceptInput"
|
||||
{
|
||||
"windows" "35"
|
||||
"linux" "36"
|
||||
}
|
||||
"SetEntityModel"
|
||||
{
|
||||
"windows" "25"
|
||||
"linux" "26"
|
||||
}
|
||||
"WeaponEquip"
|
||||
{
|
||||
"windows" "217"
|
||||
"linux" "218"
|
||||
}
|
||||
"Activate"
|
||||
{
|
||||
"windows" "32"
|
||||
"linux" "33"
|
||||
}
|
||||
"PlayerRunCmd"
|
||||
{
|
||||
"windows" "346"
|
||||
"linux" "347"
|
||||
}
|
||||
}
|
||||
|
||||
"Keys"
|
||||
{
|
||||
"GameRulesProxy" "CSDKGameRulesProxy"
|
||||
"GameRulesDataTable" "sdk_gamerules_data"
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Do not edit this file. Any changes will be overwritten by the gamedata
|
||||
* updater or by upgrading your SourceMod install.
|
||||
*
|
||||
* To override data in this file, create a subdirectory named "custom" and
|
||||
* place your own gamedata file(s) inside of it. Such files will be parsed
|
||||
* after SM's own.
|
||||
*
|
||||
* For more information, see http://wiki.alliedmods.net/Gamedata_Updating_(SourceMod)
|
||||
*/
|
||||
|
||||
"Games"
|
||||
{
|
||||
/* IOSoccer */
|
||||
"iosoccer"
|
||||
{
|
||||
"Offsets"
|
||||
{
|
||||
/* CBasePlayer */
|
||||
"GiveNamedItem"
|
||||
{
|
||||
"windows" "336"
|
||||
"linux" "337"
|
||||
}
|
||||
"RemovePlayerItem"
|
||||
{
|
||||
"windows" "241"
|
||||
"linux" "242"
|
||||
}
|
||||
"Weapon_GetSlot"
|
||||
{
|
||||
"windows" "239"
|
||||
"linux" "240"
|
||||
}
|
||||
"Ignite"
|
||||
{
|
||||
"windows" "196"
|
||||
"linux" "197"
|
||||
}
|
||||
"Extinguish"
|
||||
{
|
||||
"windows" "200"
|
||||
"linux" "201"
|
||||
}
|
||||
"Teleport"
|
||||
{
|
||||
"windows" "103"
|
||||
"linux" "104"
|
||||
}
|
||||
"CommitSuicide"
|
||||
{
|
||||
"windows" "378"
|
||||
"linux" "378"
|
||||
}
|
||||
"GetVelocity"
|
||||
{
|
||||
"windows" "133"
|
||||
"linux" "134"
|
||||
}
|
||||
"EyeAngles"
|
||||
{
|
||||
"windows" "125"
|
||||
"linux" "126"
|
||||
}
|
||||
"AcceptInput"
|
||||
{
|
||||
"windows" "34"
|
||||
"linux" "35"
|
||||
}
|
||||
"SetEntityModel"
|
||||
{
|
||||
"windows" "23"
|
||||
"linux" "24"
|
||||
}
|
||||
"WeaponEquip"
|
||||
{
|
||||
"windows" "232"
|
||||
"linux" "233"
|
||||
}
|
||||
"Activate"
|
||||
{
|
||||
"windows" "31"
|
||||
"linux" "32"
|
||||
}
|
||||
"PlayerRunCmd"
|
||||
{
|
||||
"windows" "356"
|
||||
"linux" "357"
|
||||
}
|
||||
}
|
||||
|
||||
"Keys"
|
||||
{
|
||||
"GameRulesProxy" "CSDKGameRulesProxy"
|
||||
"GameRulesDataTable" "sdk_gamerules_data"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -55,7 +55,7 @@
|
||||
"FireOutput"
|
||||
{
|
||||
"library" "server"
|
||||
"windows" "\x55\x8B\xEC\x81\xEC\x2A\x2A\x2A\x2A\xA1\x2A\x2A\x2A\x2A\x33\xC5\x89\x45\xFC\x53\x8B\x5D\x20\x8B\xC1\x8B\x4D\x1C\x56\x57\x8B"
|
||||
"windows" "\x55\x8B\xEC\x81\xEC\x2A\x2A\x2A\x2A\xD9\x2A\x2A\x53\x8B\xD9\xC7\x45\x2A\x2A\x2A\x2A\x2A\x8B\x4D\x1C\x56\x57\x8B"
|
||||
"linux" "@_ZN17CBaseEntityOutput10FireOutputE9variant_tP11CBaseEntityS2_f"
|
||||
"mac" "@_ZN17CBaseEntityOutput10FireOutputE9variant_tP11CBaseEntityS2_f"
|
||||
}
|
||||
|
@ -37,93 +37,93 @@
|
||||
/* CBasePlayer */
|
||||
"GiveNamedItem"
|
||||
{
|
||||
"windows" "404"
|
||||
"linux" "405"
|
||||
"mac" "405"
|
||||
"windows" "406"
|
||||
"linux" "407"
|
||||
"mac" "407"
|
||||
}
|
||||
"RemovePlayerItem"
|
||||
{
|
||||
"windows" "275"
|
||||
"linux" "276"
|
||||
"mac" "276"
|
||||
}
|
||||
"Weapon_GetSlot"
|
||||
{
|
||||
"windows" "273"
|
||||
"linux" "274"
|
||||
"mac" "274"
|
||||
}
|
||||
"Weapon_GetSlot"
|
||||
{
|
||||
"windows" "271"
|
||||
"linux" "272"
|
||||
"mac" "272"
|
||||
}
|
||||
"Ignite"
|
||||
{
|
||||
"windows" "212"
|
||||
"linux" "213"
|
||||
"mac" "213"
|
||||
"windows" "214"
|
||||
"linux" "215"
|
||||
"mac" "215"
|
||||
}
|
||||
"Extinguish"
|
||||
{
|
||||
"windows" "216"
|
||||
"linux" "217"
|
||||
"mac" "217"
|
||||
"windows" "218"
|
||||
"linux" "219"
|
||||
"mac" "219"
|
||||
}
|
||||
"Teleport"
|
||||
{
|
||||
"windows" "109"
|
||||
"linux" "110"
|
||||
"mac" "110"
|
||||
"windows" "111"
|
||||
"linux" "112"
|
||||
"mac" "112"
|
||||
}
|
||||
"CommitSuicide"
|
||||
{
|
||||
"windows" "443"
|
||||
"linux" "443"
|
||||
"mac" "443"
|
||||
"windows" "444"
|
||||
"linux" "445"
|
||||
"mac" "445"
|
||||
}
|
||||
"GetVelocity"
|
||||
{
|
||||
"windows" "141"
|
||||
"linux" "142"
|
||||
"mac" "142"
|
||||
"windows" "143"
|
||||
"linux" "144"
|
||||
"mac" "144"
|
||||
}
|
||||
"EyeAngles"
|
||||
{
|
||||
"windows" "132"
|
||||
"linux" "133"
|
||||
"mac" "133"
|
||||
"windows" "134"
|
||||
"linux" "135"
|
||||
"mac" "135"
|
||||
}
|
||||
"AcceptInput"
|
||||
{
|
||||
"windows" "37"
|
||||
"linux" "38"
|
||||
"mac" "38"
|
||||
"windows" "39"
|
||||
"linux" "40"
|
||||
"mac" "40"
|
||||
}
|
||||
"SetEntityModel"
|
||||
{
|
||||
"windows" "25"
|
||||
"linux" "26"
|
||||
"mac" "26"
|
||||
"windows" "27"
|
||||
"linux" "28"
|
||||
"mac" "28"
|
||||
}
|
||||
"WeaponEquip"
|
||||
{
|
||||
"windows" "264"
|
||||
"linux" "265"
|
||||
"mac" "265"
|
||||
"windows" "266"
|
||||
"linux" "267"
|
||||
"mac" "267"
|
||||
}
|
||||
"Activate"
|
||||
{
|
||||
"windows" "34"
|
||||
"linux" "35"
|
||||
"mac" "35"
|
||||
"windows" "36"
|
||||
"linux" "37"
|
||||
"mac" "37"
|
||||
}
|
||||
"PlayerRunCmd"
|
||||
{
|
||||
"windows" "422"
|
||||
"linux" "423"
|
||||
"mac" "423"
|
||||
"windows" "424"
|
||||
"linux" "425"
|
||||
"mac" "425"
|
||||
}
|
||||
"GiveAmmo"
|
||||
{
|
||||
"windows" "255"
|
||||
"linux" "256"
|
||||
"mac" "256"
|
||||
"windows" "257"
|
||||
"linux" "258"
|
||||
"mac" "258"
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -18,73 +18,73 @@
|
||||
{
|
||||
"GiveNamedItem"
|
||||
{
|
||||
"windows" "358"
|
||||
"linux" "359"
|
||||
"windows" "552"
|
||||
"linux" "553"
|
||||
}
|
||||
"RemovePlayerItem"
|
||||
{
|
||||
"windows" "247"
|
||||
"linux" "248"
|
||||
"windows" "289"
|
||||
"linux" "290"
|
||||
}
|
||||
"Weapon_GetSlot"
|
||||
{
|
||||
"windows" "242"
|
||||
"linux" "243"
|
||||
"windows" "284"
|
||||
"linux" "285"
|
||||
}
|
||||
"Ignite"
|
||||
{
|
||||
"windows" "199"
|
||||
"linux" "200"
|
||||
"windows" "223"
|
||||
"linux" "224"
|
||||
}
|
||||
"Extinguish"
|
||||
{
|
||||
"windows" "203"
|
||||
"linux" "204"
|
||||
"windows" "227"
|
||||
"linux" "228"
|
||||
}
|
||||
"Teleport"
|
||||
{
|
||||
"windows" "104"
|
||||
"linux" "105"
|
||||
"windows" "121"
|
||||
"linux" "122"
|
||||
}
|
||||
"CommitSuicide"
|
||||
{
|
||||
"windows" "405"
|
||||
"linux" "405"
|
||||
"windows" "465"
|
||||
"linux" "465"
|
||||
}
|
||||
"GetVelocity"
|
||||
{
|
||||
"windows" "133"
|
||||
"linux" "134"
|
||||
"windows" "153"
|
||||
"linux" "154"
|
||||
}
|
||||
"EyeAngles"
|
||||
{
|
||||
"windows" "125"
|
||||
"linux" "126"
|
||||
"windows" "144"
|
||||
"linux" "145"
|
||||
}
|
||||
"AcceptInput"
|
||||
{
|
||||
"windows" "35"
|
||||
"linux" "36"
|
||||
"windows" "42"
|
||||
"linux" "43"
|
||||
}
|
||||
"SetEntityModel"
|
||||
{
|
||||
"windows" "24"
|
||||
"linux" "25"
|
||||
"windows" "30"
|
||||
"linux" "31"
|
||||
}
|
||||
"WeaponEquip"
|
||||
{
|
||||
"windows" "235"
|
||||
"linux" "236"
|
||||
"windows" "275"
|
||||
"linux" "276"
|
||||
}
|
||||
"Activate"
|
||||
{
|
||||
"windows" "32"
|
||||
"linux" "33"
|
||||
"windows" "39"
|
||||
"linux" "40"
|
||||
}
|
||||
"PlayerRunCmd"
|
||||
{
|
||||
"windows" "377"
|
||||
"linux" "378"
|
||||
"windows" "443"
|
||||
"linux" "444"
|
||||
}
|
||||
}
|
||||
"Signatures"
|
||||
@ -92,13 +92,13 @@
|
||||
"FindEntityByClassname"
|
||||
{
|
||||
"library" "server"
|
||||
"windows" "\x55\x8B\xEC\x53\x56\x8B\xF1\x8B\x4D\x2A\x57\x85\xC9\x74\x2A\x8B\x01\x8B\x50\x2A\xFF\xD2\x8B\x00\x25\x2A\x2A\x2A\x2A\x40\xC1\xE0\x2A\x8B\x3C\x30\xEB\x2A\x8B\x2A\x2A\x2A\x2A\x2A\x85\xFF\x74\x2A\x8B\x5D\x2A\x8B\x37\x85\xF6\x75\x2A\x68\x2A\x2A\x2A\x2A\xFF\x2A\x2A\x2A\x2A\x2A\x83\xC4\x2A\xEB\x2A\x39"
|
||||
"windows" "\x55\x8B\xEC\x53\x56\x57\x8B\xF9\x8B\x4D\x2A\x85\xC9\x74\x2A\x8B\x01\xFF\x2A\x2A\x8B\x2A\x81\xE6\x2A\x2A\x2A\x2A\x46\x03\xF6\x8B\x34\x2A\xEB\x2A\x8B\x2A\x2A\x2A\x2A\x2A\x85\xF6\x74\x2A\x8B\x5D\x2A\x8B\x3E\x85\xFF\x75\x2A\x68\x2A\x2A\x2A\x2A\xFF\x2A\x2A\x2A\x2A\x83\xC4\x2A\xEB\x2A\x39"
|
||||
"linux" "@_ZN17CGlobalEntityList21FindEntityByClassnameEP11CBaseEntityPKc"
|
||||
}
|
||||
"FireOutput"
|
||||
{
|
||||
"library" "server"
|
||||
"windows" "\x55\x8B\xEC\x81\x2A\x2A\x2A\x2A\x2A\x53\x56\x8B\x71\x2A\x57"
|
||||
"windows" "\x55\x8B\xEC\x81\xEC\x2A\x2A\x2A\x2A\xA1\x2A\x2A\x2A\x2A\x33\xC5\x89\x2A\x2A\x53\x8B\x5D\x2A\x8B\xC1\x8B\x2A\x2A\x56\x57"
|
||||
"linux" "@_ZN17CBaseEntityOutput10FireOutputE9variant_tP11CBaseEntityS2_f"
|
||||
}
|
||||
}
|
||||
@ -135,7 +135,7 @@
|
||||
"CBaseTempEntity"
|
||||
{
|
||||
"library" "server"
|
||||
"windows" "\x55\x8B\xEC\x8B\xC1\x8B\x4D\x2A\xC7\x2A\x2A\x2A\x2A\x2A\x89"
|
||||
"windows" "\x55\x8B\xEC\x8B\x45\x2A\xC7\x2A\x2A\x2A\x2A\x2A\x8B\x2A\x89"
|
||||
}
|
||||
"s_pTempEntities"
|
||||
{
|
||||
|
@ -217,7 +217,7 @@
|
||||
}
|
||||
"game.ios.txt"
|
||||
{
|
||||
"game" "ios"
|
||||
"game" "iosoccer"
|
||||
}
|
||||
"game.left4dead2.txt"
|
||||
{
|
||||
|
@ -27,12 +27,12 @@
|
||||
"mac" "4"
|
||||
}
|
||||
// In HandleCommand_Buy_Internal
|
||||
// -*(_DWORD *)(v34 + 204)
|
||||
// -*(_DWORD *)(v34 + 208) in ida 7 -v34[52]
|
||||
"WeaponPrice"
|
||||
{
|
||||
"windows" "204"
|
||||
"linux" "204"
|
||||
"mac" "204"
|
||||
"windows" "208"
|
||||
"linux" "208"
|
||||
"mac" "208"
|
||||
}
|
||||
//Offset into CheckRestartRound
|
||||
"CTTeamScoreOffset"
|
||||
@ -117,23 +117,17 @@
|
||||
"windows" "\x2A\x2A\x2A\x2A\x2A\x2A\x83\xEC\x0C\x53\x56\x57\x6A\x01"
|
||||
"linux" "\x2A\x2A\x2A\x2A\x2A\x2A\x0F\xB6\x55\x14\x89\x75\xF8\x8B\x75\x08"
|
||||
}
|
||||
"CSWeaponDrop"//Wildcard first 6 bytes for CS:S DM (kept for backcompat with old SM versions)
|
||||
{
|
||||
"library" "server"
|
||||
"windows" "\x2A\x2A\x2A\x2A\x2A\x2A\x81\xEC\x2A\x2A\x2A\x2A\x53\x8B\x5D\x08\x56\x57\x6A\x00\x68"
|
||||
"linux" "\x2A\x2A\x2A\x2A\x2A\x2A\x56\x53\x81\xEC\x7C\x02\x00\x00\x8B\x5D\x0C\x8B\x75\x08\x85\xDB\x74\x2A\xC7\x44\x24\x2A\x2A\x2A\x2A\x00"
|
||||
}
|
||||
"CSWeaponDropBB" //Revert back to using CSWeaponDrop(weapon, bool, bool)
|
||||
{
|
||||
"library" "server"
|
||||
"windows" "\x2A\x2A\x2A\x2A\x2A\x2A\x83\xE4\xF8\x83\xC4\x04\x55\x8B\x6B\x04\x89\x6C\x24\x04\x8B\xEC\x83\xEC\x34\x56"
|
||||
"linux" "\x2A\x2A\x2A\x2A\x2A\x2A\x83\xEC\x7C\x8B\x5D\x08\x0F\xB6\x7D\x14"
|
||||
"linux" "\x2A\x2A\x2A\x2A\x2A\x2A\xEC\x70\x8B\x5D\x08\x0F\xB6\x75\x10"
|
||||
}
|
||||
"TerminateRound"
|
||||
{
|
||||
"library" "server"
|
||||
"windows" "\x55\x8B\xEC\x83\xE4\xF8\x83\xEC\x2A\x53\x8B\xD9\xF3\x0F\x2A\x2A\x2A\x2A\x56\x57\x89\x2A\x2A\x2A\x83\xBB"
|
||||
"linux" "\x55\x89\xE5\x57\x56\x53\x81\xEC\xDC\x00\x00\x00\x8B\x75\x08\x8B\x86"
|
||||
"linux" "\x55\x89\xE5\x57\x56\x53\x81\xEC\xBC\x00\x00\x00\x8B\x7D\x08\x8B\x9F"
|
||||
}
|
||||
//In CS:GO this is actually CCSGameRules::CheckRestartRound(void) but to keep same gamedata as cs:s.
|
||||
"CheckWinLimit"
|
||||
@ -145,13 +139,13 @@
|
||||
"SetClanTag"
|
||||
{
|
||||
"library" "server"
|
||||
"windows" "\x55\x8B\xEC\x8B\x55\x08\x85\xD2\x74\x2A\x8D\x81\x34\x25\x00\x00"
|
||||
"windows" "\x55\x8B\xEC\x8B\x55\x08\x85\xD2\x74\x2A\x8D\x81\x2A\x2A\x2A\x2A\x56\x8D\x70\x0F\x3B\xC6\x73\x2A\x2B\xD0\x66\x0F\x2A\x2A\x2A\x2A\x8A\x0C\x02"
|
||||
"linux" "\x55\x89\xE5\x83\xEC\x18\x8B\x45\x0C\x85\xC0\x74\x2A\x89\x44\x24\x04\x8B\x45\x08\xC7\x44\x24\x08\x10\x00\x00\x00"
|
||||
}
|
||||
"SetModelFromClass"
|
||||
{
|
||||
"library" "server"
|
||||
"windows" "\x53\x56\x57\x8B\xF9\x8B\x87\x00\x03\x00\x00"
|
||||
"windows" "\x53\x56\x57\x8B\xF9\x8B\x87\x14\x03\x00\x00"
|
||||
"linux" "\x55\x89\xE5\x83\xEC\x28\x89\x5D\xF4\x8B\x5D\x08\x89\x75\xF8\x89\x7D\xFC\x89\x1C\x24\xE8\x2A\x2A\x2A\x2A\x83\xF8\x02"
|
||||
}
|
||||
//GetCCSWeaponData Found in HandleCommand_Buy_Internal
|
||||
@ -194,9 +188,9 @@
|
||||
{
|
||||
"CScore"
|
||||
{
|
||||
"windows" "75"
|
||||
"linux" "75"
|
||||
"mac" "75"
|
||||
"windows" "63"
|
||||
"linux" "63"
|
||||
"mac" "63"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -24,7 +24,8 @@ files = [
|
||||
'basecommands.sp',
|
||||
'mapchooser.sp',
|
||||
'randomcycle.sp',
|
||||
'sql-admin-manager.sp'
|
||||
'sql-admin-manager.sp',
|
||||
'DynamicTargeting.sp'
|
||||
]
|
||||
|
||||
spcomp_argv = [
|
||||
|
266
plugins/DynamicTargeting.sp
Normal file
266
plugins/DynamicTargeting.sp
Normal file
@ -0,0 +1,266 @@
|
||||
#pragma semicolon 1
|
||||
#define PLUGIN_VERSION "1.0"
|
||||
|
||||
#include <sourcemod>
|
||||
#include <DynamicTargeting>
|
||||
|
||||
#pragma newdecls required
|
||||
|
||||
public Plugin myinfo =
|
||||
{
|
||||
name = "Dynamic Targeting",
|
||||
author = "BotoX",
|
||||
description = "",
|
||||
version = PLUGIN_VERSION,
|
||||
url = ""
|
||||
}
|
||||
|
||||
char g_PlayerNames[MAXPLAYERS + 1][MAX_NAME_LENGTH];
|
||||
Handle g_PlayerData[MAXPLAYERS + 1];
|
||||
|
||||
public APLRes AskPluginLoad2(Handle myself, bool late, char[] error, int err_max)
|
||||
{
|
||||
CreateNative("AmbiguousMenu", Native_AmbiguousMenu);
|
||||
RegPluginLibrary("DynamicTargeting");
|
||||
|
||||
return APLRes_Success;
|
||||
}
|
||||
|
||||
public void OnClientDisconnect(int client)
|
||||
{
|
||||
if(g_PlayerData[client] != INVALID_HANDLE)
|
||||
{
|
||||
CloseHandle(g_PlayerData[client]);
|
||||
g_PlayerData[client] = INVALID_HANDLE;
|
||||
}
|
||||
}
|
||||
|
||||
int CreateAmbiguousMenu(int client, const char[] sCommand, const char[] sArgString, const char[] sPattern, int FilterFlags)
|
||||
{
|
||||
Menu menu = new Menu(MenuHandler_AmbiguousMenu, MenuAction_Select|MenuAction_Cancel|MenuAction_End|MenuAction_DrawItem|MenuAction_DisplayItem);
|
||||
menu.ExitButton = true;
|
||||
|
||||
char sTitle[32 + MAX_TARGET_LENGTH];
|
||||
FormatEx(sTitle, sizeof(sTitle), "Target \"%s\" is ambiguous.", sPattern);
|
||||
menu.SetTitle(sTitle);
|
||||
|
||||
int Players = 0;
|
||||
int[] aClients = new int[MaxClients + 1];
|
||||
|
||||
for(int i = 1; i <= MaxClients; i++)
|
||||
{
|
||||
if(!IsClientConnected(i) || i == client)
|
||||
continue;
|
||||
|
||||
if(FilterFlags & COMMAND_FILTER_NO_BOTS && IsFakeClient(i))
|
||||
continue;
|
||||
|
||||
if(!(FilterFlags & COMMAND_FILTER_CONNECTED) && !IsClientInGame(i))
|
||||
continue;
|
||||
|
||||
if(FilterFlags & COMMAND_FILTER_ALIVE && !IsPlayerAlive(i))
|
||||
continue;
|
||||
|
||||
if(FilterFlags & COMMAND_FILTER_DEAD && IsPlayerAlive(i))
|
||||
continue;
|
||||
|
||||
// insert player names into g_PlayerNames array
|
||||
GetClientName(i, g_PlayerNames[i], sizeof(g_PlayerNames[]));
|
||||
|
||||
if(StrContains(g_PlayerNames[i], sPattern, false) != -1)
|
||||
aClients[Players++] = i;
|
||||
}
|
||||
|
||||
// sort aClients array by player name
|
||||
SortCustom1D(aClients, Players, SortByPlayerName);
|
||||
|
||||
// insert players sorted
|
||||
char sUserId[12];
|
||||
char sDisp[MAX_NAME_LENGTH + 16];
|
||||
for(int i = 0; i < Players; i++)
|
||||
{
|
||||
IntToString(GetClientUserId(aClients[i]), sUserId, sizeof(sUserId));
|
||||
|
||||
FormatEx(sDisp, sizeof(sDisp), "%s (%s)", g_PlayerNames[aClients[i]], sUserId);
|
||||
menu.AddItem(sUserId, sDisp);
|
||||
}
|
||||
|
||||
DataPack pack = new DataPack();
|
||||
pack.WriteString(sCommand);
|
||||
pack.WriteString(sArgString);
|
||||
pack.WriteString(sPattern);
|
||||
pack.WriteCell(FilterFlags);
|
||||
|
||||
if(g_PlayerData[client] != INVALID_HANDLE)
|
||||
{
|
||||
CloseHandle(g_PlayerData[client]);
|
||||
g_PlayerData[client] = INVALID_HANDLE;
|
||||
}
|
||||
CancelClientMenu(client);
|
||||
|
||||
g_PlayerData[client] = pack;
|
||||
menu.Display(client, MENU_TIME_FOREVER);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
public int MenuHandler_AmbiguousMenu(Menu menu, MenuAction action, int param1, int param2)
|
||||
{
|
||||
switch(action)
|
||||
{
|
||||
case MenuAction_End:
|
||||
{
|
||||
CloseHandle(menu);
|
||||
}
|
||||
case MenuAction_Cancel:
|
||||
{
|
||||
if(g_PlayerData[param1] != INVALID_HANDLE)
|
||||
{
|
||||
CloseHandle(g_PlayerData[param1]);
|
||||
g_PlayerData[param1] = INVALID_HANDLE;
|
||||
}
|
||||
}
|
||||
case MenuAction_Select:
|
||||
{
|
||||
int Style;
|
||||
char sItem[32];
|
||||
char sDisp[MAX_NAME_LENGTH + 16];
|
||||
menu.GetItem(param2, sItem, sizeof(sItem), Style, sDisp, sizeof(sDisp));
|
||||
|
||||
int UserId = StringToInt(sItem);
|
||||
int client = GetClientOfUserId(UserId);
|
||||
if(!client)
|
||||
{
|
||||
PrintToChat(param1, "\x04[DynamicTargeting]\x01 Player no longer available.");
|
||||
menu.DisplayAt(param1, GetMenuSelectionPosition(), MENU_TIME_FOREVER);
|
||||
return 0;
|
||||
}
|
||||
|
||||
DataPack pack = view_as<DataPack>(g_PlayerData[param1]);
|
||||
pack.Reset();
|
||||
|
||||
char sCommand[128];
|
||||
pack.ReadString(sCommand, sizeof(sCommand));
|
||||
|
||||
char sArgString[256];
|
||||
pack.ReadString(sArgString, sizeof(sArgString));
|
||||
|
||||
char sPattern[MAX_TARGET_LENGTH];
|
||||
pack.ReadString(sPattern, sizeof(sPattern));
|
||||
|
||||
int Result = ReCallAmbiguous(param1, client, sCommand, sArgString, sPattern);
|
||||
|
||||
return Result;
|
||||
}
|
||||
case MenuAction_DrawItem:
|
||||
{
|
||||
int Style;
|
||||
char sItem[32];
|
||||
menu.GetItem(param2, sItem, sizeof(sItem), Style);
|
||||
|
||||
int UserId = StringToInt(sItem);
|
||||
int client = GetClientOfUserId(UserId);
|
||||
if(!client) // Player disconnected
|
||||
return ITEMDRAW_DISABLED;
|
||||
|
||||
return Style;
|
||||
}
|
||||
case MenuAction_DisplayItem:
|
||||
{
|
||||
int Style;
|
||||
char sItem[32];
|
||||
char sDisp[MAX_NAME_LENGTH + 16];
|
||||
menu.GetItem(param2, sItem, sizeof(sItem), Style, sDisp, sizeof(sDisp));
|
||||
|
||||
if(!sItem[0])
|
||||
return 0;
|
||||
|
||||
char sBuffer[MAX_NAME_LENGTH + 16];
|
||||
int UserId = StringToInt(sItem);
|
||||
int client = GetClientOfUserId(UserId);
|
||||
if(!client) // Player disconnected
|
||||
return 0;
|
||||
|
||||
GetClientName(client, g_PlayerNames[client], sizeof(g_PlayerNames[]));
|
||||
FormatEx(sBuffer, sizeof(sBuffer), "%s (%d)", g_PlayerNames[client], UserId);
|
||||
|
||||
if(!StrEqual(sDisp, sBuffer))
|
||||
return RedrawMenuItem(sBuffer);
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ReCallAmbiguous(int client, int newClient, const char[] sCommand, const char[] sArgString, const char[] sPattern)
|
||||
{
|
||||
char sTarget[16];
|
||||
FormatEx(sTarget, sizeof(sTarget), "#%d", GetClientUserId(newClient));
|
||||
|
||||
char sNewArgString[256];
|
||||
strcopy(sNewArgString, sizeof(sNewArgString), sArgString);
|
||||
|
||||
char sPart[256];
|
||||
int CurrentIndex = 0;
|
||||
int NextIndex = 0;
|
||||
|
||||
while(NextIndex != -1 && CurrentIndex < sizeof(sNewArgString))
|
||||
{
|
||||
NextIndex = BreakString(sNewArgString[CurrentIndex], sPart, sizeof(sPart));
|
||||
|
||||
if(StrEqual(sPart, sPattern))
|
||||
{
|
||||
ReplaceStringEx(sNewArgString[CurrentIndex], sizeof(sNewArgString) - CurrentIndex, sPart, sTarget);
|
||||
break;
|
||||
}
|
||||
|
||||
CurrentIndex += NextIndex;
|
||||
}
|
||||
|
||||
FakeClientCommandEx(client, "%s %s", sCommand, sNewArgString);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
public int Native_AmbiguousMenu(Handle plugin, int numParams)
|
||||
{
|
||||
int client = GetNativeCell(1);
|
||||
|
||||
if(client > MaxClients || client <= 0)
|
||||
{
|
||||
ThrowNativeError(SP_ERROR_NATIVE, "Client is not valid.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(!IsClientInGame(client))
|
||||
{
|
||||
ThrowNativeError(SP_ERROR_NATIVE, "Client is not in-game.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(IsFakeClient(client))
|
||||
{
|
||||
ThrowNativeError(SP_ERROR_NATIVE, "Client is fake-client.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
char sCommand[128];
|
||||
GetNativeString(2, sCommand, sizeof(sCommand));
|
||||
|
||||
char sArgString[256];
|
||||
GetNativeString(3, sArgString, sizeof(sArgString));
|
||||
|
||||
char sPattern[MAX_TARGET_LENGTH];
|
||||
GetNativeString(4, sPattern, sizeof(sPattern));
|
||||
|
||||
int FilterFlags = GetNativeCell(5);
|
||||
|
||||
return CreateAmbiguousMenu(client, sCommand, sArgString, sPattern, FilterFlags);
|
||||
}
|
||||
|
||||
public int SortByPlayerName(int elem1, int elem2, const int[] array, Handle hndl)
|
||||
{
|
||||
return strcmp(g_PlayerNames[elem1], g_PlayerNames[elem2], false);
|
||||
}
|
@ -34,6 +34,7 @@
|
||||
#pragma semicolon 1
|
||||
|
||||
#include <sourcemod>
|
||||
#include <basecomm>
|
||||
|
||||
#pragma newdecls required
|
||||
|
||||
@ -80,6 +81,9 @@ public void OnPluginStart()
|
||||
|
||||
public Action OnClientSayCommand(int client, const char[] command, const char[] sArgs)
|
||||
{
|
||||
if (client <= 0 || BaseComm_IsClientGagged(client))
|
||||
return Plugin_Continue;
|
||||
|
||||
int startidx;
|
||||
if (sArgs[startidx] != CHAT_SYMBOL)
|
||||
return Plugin_Continue;
|
||||
@ -88,51 +92,20 @@ public Action OnClientSayCommand(int client, const char[] command, const char[]
|
||||
|
||||
if (strcmp(command, "say", false) == 0)
|
||||
{
|
||||
if (sArgs[startidx] != CHAT_SYMBOL) // sm_say alias
|
||||
{
|
||||
if (!CheckCommandAccess(client, "sm_say", ADMFLAG_CHAT))
|
||||
{
|
||||
return Plugin_Continue;
|
||||
}
|
||||
|
||||
SendChatToAll(client, sArgs[startidx]);
|
||||
LogAction(client, -1, "\"%L\" triggered sm_say (text %s)", client, sArgs[startidx]);
|
||||
|
||||
return Plugin_Stop;
|
||||
}
|
||||
|
||||
startidx++;
|
||||
|
||||
if (sArgs[startidx] != CHAT_SYMBOL) // sm_psay alias
|
||||
{
|
||||
if (!CheckCommandAccess(client, "sm_psay", ADMFLAG_CHAT))
|
||||
{
|
||||
return Plugin_Continue;
|
||||
}
|
||||
|
||||
char arg[64];
|
||||
|
||||
int len = BreakString(sArgs[startidx], arg, sizeof(arg));
|
||||
int target = FindTarget(client, arg, true, false);
|
||||
|
||||
if (target == -1 || len == -1)
|
||||
return Plugin_Stop;
|
||||
|
||||
SendPrivateChat(client, target, sArgs[startidx+len]);
|
||||
|
||||
return Plugin_Stop;
|
||||
}
|
||||
|
||||
startidx++;
|
||||
|
||||
// sm_csay alias
|
||||
if (!CheckCommandAccess(client, "sm_csay", ADMFLAG_CHAT))
|
||||
if (!CheckCommandAccess(client, "sm_psay_chat", ADMFLAG_CHAT))
|
||||
{
|
||||
return Plugin_Continue;
|
||||
}
|
||||
|
||||
DisplayCenterTextToAll(client, sArgs[startidx]);
|
||||
LogAction(client, -1, "\"%L\" triggered sm_csay (text %s)", client, sArgs[startidx]);
|
||||
char arg[64];
|
||||
|
||||
int len = BreakString(sArgs[startidx], arg, sizeof(arg));
|
||||
int target = FindTarget(client, arg, true, false);
|
||||
|
||||
if (target == -1 || len == -1)
|
||||
return Plugin_Stop;
|
||||
|
||||
SendPrivateChat(client, target, sArgs[startidx+len]);
|
||||
|
||||
return Plugin_Stop;
|
||||
}
|
||||
|
@ -185,52 +185,53 @@ public int MenuHandler_GagTypes(Menu menu, MenuAction action, int param1, int pa
|
||||
{
|
||||
case CommType_Mute:
|
||||
{
|
||||
PerformMute(param1, g_GagTarget[param1]);
|
||||
PerformMute(g_GagTarget[param1]);
|
||||
LogAction(param1, g_GagTarget[param1], "\"%L\" muted \"%L\"", param1, g_GagTarget[param1]);
|
||||
ShowActivity2(param1, "[SM] ", "%t", "Muted target", "_s", name);
|
||||
}
|
||||
case CommType_UnMute:
|
||||
{
|
||||
PerformUnMute(param1, g_GagTarget[param1]);
|
||||
PerformUnMute(g_GagTarget[param1]);
|
||||
LogAction(param1, g_GagTarget[param1], "\"%L\" unmuted \"%L\"", param1, g_GagTarget[param1]);
|
||||
ShowActivity2(param1, "[SM] ", "%t", "Unmuted target", "_s", name);
|
||||
}
|
||||
case CommType_Gag:
|
||||
{
|
||||
PerformGag(param1, g_GagTarget[param1]);
|
||||
PerformGag(g_GagTarget[param1]);
|
||||
LogAction(param1, g_GagTarget[param1], "\"%L\" gagged \"%L\"", param1, g_GagTarget[param1]);
|
||||
ShowActivity2(param1, "[SM] ", "%t", "Gagged target", "_s", name);
|
||||
}
|
||||
case CommType_UnGag:
|
||||
{
|
||||
PerformUnGag(param1, g_GagTarget[param1]);
|
||||
PerformUnGag(g_GagTarget[param1]);
|
||||
LogAction(param1, g_GagTarget[param1], "\"%L\" ungagged \"%L\"", param1, g_GagTarget[param1]);
|
||||
ShowActivity2(param1, "[SM] ", "%t", "Ungagged target", "_s", name);
|
||||
}
|
||||
case CommType_Silence:
|
||||
{
|
||||
PerformSilence(param1, g_GagTarget[param1]);
|
||||
PerformSilence(g_GagTarget[param1]);
|
||||
LogAction(param1, g_GagTarget[param1], "\"%L\" silenced \"%L\"", param1, g_GagTarget[param1]);
|
||||
ShowActivity2(param1, "[SM] ", "%t", "Silenced target", "_s", name);
|
||||
}
|
||||
case CommType_UnSilence:
|
||||
{
|
||||
PerformUnSilence(param1, g_GagTarget[param1]);
|
||||
PerformUnSilence(g_GagTarget[param1]);
|
||||
LogAction(param1, g_GagTarget[param1], "\"%L\" unsilenced \"%L\"", param1, g_GagTarget[param1]);
|
||||
ShowActivity2(param1, "[SM] ", "%t", "Unsilenced target", "_s", name);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PerformMute(int client, int target, bool silent=false)
|
||||
void PerformMute(int target)
|
||||
{
|
||||
g_Muted[target] = true;
|
||||
SetClientListeningFlags(target, VOICE_MUTED);
|
||||
|
||||
|
||||
FireOnClientMute(target, true);
|
||||
|
||||
if (!silent)
|
||||
{
|
||||
LogAction(client, target, "\"%L\" muted \"%L\"", client, target);
|
||||
}
|
||||
}
|
||||
|
||||
void PerformUnMute(int client, int target, bool silent=false)
|
||||
void PerformUnMute(int target)
|
||||
{
|
||||
g_Muted[target] = false;
|
||||
if (g_Cvar_Deadtalk.IntValue == 1 && !IsPlayerAlive(target))
|
||||
@ -247,36 +248,21 @@ void PerformUnMute(int client, int target, bool silent=false)
|
||||
}
|
||||
|
||||
FireOnClientMute(target, false);
|
||||
|
||||
if (!silent)
|
||||
{
|
||||
LogAction(client, target, "\"%L\" unmuted \"%L\"", client, target);
|
||||
}
|
||||
}
|
||||
|
||||
void PerformGag(int client, int target, bool silent=false)
|
||||
void PerformGag(int target)
|
||||
{
|
||||
g_Gagged[target] = true;
|
||||
FireOnClientGag(target, true);
|
||||
|
||||
if (!silent)
|
||||
{
|
||||
LogAction(client, target, "\"%L\" gagged \"%L\"", client, target);
|
||||
}
|
||||
}
|
||||
|
||||
void PerformUnGag(int client, int target, bool silent=false)
|
||||
void PerformUnGag(int target)
|
||||
{
|
||||
g_Gagged[target] = false;
|
||||
FireOnClientGag(target, false);
|
||||
|
||||
if (!silent)
|
||||
{
|
||||
LogAction(client, target, "\"%L\" ungagged \"%L\"", client, target);
|
||||
}
|
||||
}
|
||||
|
||||
void PerformSilence(int client, int target)
|
||||
void PerformSilence(int target)
|
||||
{
|
||||
if (!g_Gagged[target])
|
||||
{
|
||||
@ -290,11 +276,9 @@ void PerformSilence(int client, int target)
|
||||
SetClientListeningFlags(target, VOICE_MUTED);
|
||||
FireOnClientMute(target, true);
|
||||
}
|
||||
|
||||
LogAction(client, target, "\"%L\" silenced \"%L\"", client, target);
|
||||
}
|
||||
|
||||
void PerformUnSilence(int client, int target)
|
||||
void PerformUnSilence(int target)
|
||||
{
|
||||
if (g_Gagged[target])
|
||||
{
|
||||
@ -320,8 +304,6 @@ void PerformUnSilence(int client, int target)
|
||||
}
|
||||
FireOnClientMute(target, false);
|
||||
}
|
||||
|
||||
LogAction(client, target, "\"%L\" unsilenced \"%L\"", client, target);
|
||||
}
|
||||
|
||||
public Action Command_Mute(int client, int args)
|
||||
@ -357,16 +339,18 @@ public Action Command_Mute(int client, int args)
|
||||
{
|
||||
int target = target_list[i];
|
||||
|
||||
PerformMute(client, target);
|
||||
PerformMute(target);
|
||||
}
|
||||
|
||||
if (tn_is_ml)
|
||||
{
|
||||
ShowActivity2(client, "[SM] ", "%t", "Muted target", target_name);
|
||||
LogAction(client, -1, "\"%L\" muted \"%s\"", client, target_name);
|
||||
}
|
||||
else
|
||||
{
|
||||
ShowActivity2(client, "[SM] ", "%t", "Muted target", "_s", target_name);
|
||||
LogAction(client, target_list[0], "\"%L\" muted \"%L\"", client, target_list[0]);
|
||||
}
|
||||
|
||||
return Plugin_Handled;
|
||||
@ -405,16 +389,18 @@ public Action Command_Gag(int client, int args)
|
||||
{
|
||||
int target = target_list[i];
|
||||
|
||||
PerformGag(client, target);
|
||||
PerformGag(target);
|
||||
}
|
||||
|
||||
if (tn_is_ml)
|
||||
{
|
||||
ShowActivity2(client, "[SM] ", "%t", "Gagged target", target_name);
|
||||
LogAction(client, -1, "\"%L\" gagged \"%s\"", client, target_name);
|
||||
}
|
||||
else
|
||||
{
|
||||
ShowActivity2(client, "[SM] ", "%t", "Gagged target", "_s", target_name);
|
||||
LogAction(client, target_list[0], "\"%L\" gagged \"%L\"", client, target_list[0]);
|
||||
}
|
||||
|
||||
return Plugin_Handled;
|
||||
@ -453,16 +439,18 @@ public Action Command_Silence(int client, int args)
|
||||
{
|
||||
int target = target_list[i];
|
||||
|
||||
PerformSilence(client, target);
|
||||
PerformSilence(target);
|
||||
}
|
||||
|
||||
if (tn_is_ml)
|
||||
{
|
||||
ShowActivity2(client, "[SM] ", "%t", "Silenced target", target_name);
|
||||
LogAction(client, -1, "\"%L\" silenced \"%s\"", client, target_name);
|
||||
}
|
||||
else
|
||||
{
|
||||
ShowActivity2(client, "[SM] ", "%t", "Silenced target", "_s", target_name);
|
||||
LogAction(client, target_list[0], "\"%L\" silenced \"%L\"", client, target_list[0]);
|
||||
}
|
||||
|
||||
return Plugin_Handled;
|
||||
@ -506,9 +494,11 @@ public Action Command_Unmute(int client, int args)
|
||||
continue;
|
||||
}
|
||||
|
||||
PerformUnMute(client, target);
|
||||
PerformUnMute(target);
|
||||
}
|
||||
|
||||
LogAction(client, -1, "\"%L\" unmuted \"%s\"", client, target_name);
|
||||
|
||||
if (tn_is_ml)
|
||||
{
|
||||
ShowActivity2(client, "[SM] ", "%t", "Unmuted target", target_name);
|
||||
@ -554,16 +544,18 @@ public Action Command_Ungag(int client, int args)
|
||||
{
|
||||
int target = target_list[i];
|
||||
|
||||
PerformUnGag(client, target);
|
||||
PerformUnGag(target);
|
||||
}
|
||||
|
||||
if (tn_is_ml)
|
||||
{
|
||||
ShowActivity2(client, "[SM] ", "%t", "Ungagged target", target_name);
|
||||
LogAction(client, -1, "\"%L\" ungagged \"%s\"", client, target_name);
|
||||
}
|
||||
else
|
||||
{
|
||||
ShowActivity2(client, "[SM] ", "%t", "Ungagged target", "_s", target_name);
|
||||
LogAction(client, target_list[0], "\"%L\" ungagged \"%L\"", client, target_list[0]);
|
||||
}
|
||||
|
||||
return Plugin_Handled;
|
||||
@ -602,16 +594,18 @@ public Action Command_Unsilence(int client, int args)
|
||||
{
|
||||
int target = target_list[i];
|
||||
|
||||
PerformUnSilence(client, target);
|
||||
PerformUnSilence(target);
|
||||
}
|
||||
|
||||
if (tn_is_ml)
|
||||
{
|
||||
ShowActivity2(client, "[SM] ", "%t", "Unsilenced target", target_name);
|
||||
LogAction(client, -1, "\"%L\" unsilenced \"%s\"", client, target_name);
|
||||
}
|
||||
else
|
||||
{
|
||||
ShowActivity2(client, "[SM] ", "%t", "Unsilenced target", "_s", target_name);
|
||||
LogAction(client, target_list[0], "\"%L\" unsilenced \"%L\"", client, target_list[0]);
|
||||
}
|
||||
|
||||
return Plugin_Handled;
|
||||
|
@ -85,7 +85,7 @@ public int Native_SetClientGag(Handle hPlugin, int numParams)
|
||||
return false;
|
||||
}
|
||||
|
||||
PerformGag(-1, client, true);
|
||||
PerformGag(client);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -94,7 +94,7 @@ public int Native_SetClientGag(Handle hPlugin, int numParams)
|
||||
return false;
|
||||
}
|
||||
|
||||
PerformUnGag(-1, client, true);
|
||||
PerformUnGag(client);
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -122,7 +122,7 @@ public int Native_SetClientMute(Handle hPlugin, int numParams)
|
||||
return false;
|
||||
}
|
||||
|
||||
PerformMute(-1, client, true);
|
||||
PerformMute(client);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -131,7 +131,7 @@ public int Native_SetClientMute(Handle hPlugin, int numParams)
|
||||
return false;
|
||||
}
|
||||
|
||||
PerformUnMute(-1, client, true);
|
||||
PerformUnMute(client);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -31,10 +31,8 @@
|
||||
* Version: $Id$
|
||||
*/
|
||||
|
||||
void PerformKick(int client, int target, const char[] reason)
|
||||
void PerformKick(int target, const char[] reason)
|
||||
{
|
||||
LogAction(client, target, "\"%L\" kicked \"%L\" (reason \"%s\")", client, target, reason);
|
||||
|
||||
if (reason[0] == '\0')
|
||||
{
|
||||
KickClient(target, "%t", "Kicked by admin");
|
||||
@ -110,7 +108,8 @@ public int MenuHandler_Kick(Menu menu, MenuAction action, int param1, int param2
|
||||
char name[MAX_NAME_LENGTH];
|
||||
GetClientName(target, name, sizeof(name));
|
||||
ShowActivity2(param1, "[SM] ", "%t", "Kicked target", "_s", name);
|
||||
PerformKick(param1, target, "");
|
||||
PerformKick(target, "");
|
||||
LogAction(param1, target, "\"%L\" kicked \"%L\"", param1, target);
|
||||
}
|
||||
|
||||
/* Re-draw the menu if they're still valid */
|
||||
@ -193,13 +192,22 @@ public Action Command_Kick(int client, int args)
|
||||
}
|
||||
else
|
||||
{
|
||||
PerformKick(client, target_list[i], reason);
|
||||
PerformKick(target_list[i], reason);
|
||||
}
|
||||
}
|
||||
|
||||
if (kick_self)
|
||||
{
|
||||
PerformKick(client, client, reason);
|
||||
PerformKick(client, reason);
|
||||
}
|
||||
|
||||
if (tn_is_ml)
|
||||
{
|
||||
LogAction(client, -1, "\"%L\" kicked \"%s\" (reason \"%s\")", client, target_name, reason);
|
||||
}
|
||||
else
|
||||
{
|
||||
LogAction(client, target_list[0], "\"%L\" kicked \"%L\" (reason \"%s\")", client, target_list[0], reason);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -59,18 +59,12 @@ void KillAllBeacons()
|
||||
}
|
||||
}
|
||||
|
||||
void PerformBeacon(int client, int target)
|
||||
void PerformBeacon(int target)
|
||||
{
|
||||
if (g_BeaconSerial[target] == 0)
|
||||
{
|
||||
CreateBeacon(target);
|
||||
LogAction(client, target, "\"%L\" set a beacon on \"%L\"", client, target);
|
||||
}
|
||||
else
|
||||
{
|
||||
KillBeacon(target);
|
||||
LogAction(client, target, "\"%L\" removed a beacon on \"%L\"", client, target);
|
||||
}
|
||||
}
|
||||
|
||||
public Action Timer_Beacon(Handle timer, any value)
|
||||
@ -187,8 +181,9 @@ public int MenuHandler_Beacon(Menu menu, MenuAction action, int param1, int para
|
||||
char name[MAX_NAME_LENGTH];
|
||||
GetClientName(target, name, sizeof(name));
|
||||
|
||||
PerformBeacon(param1, target);
|
||||
PerformBeacon(target);
|
||||
ShowActivity2(param1, "[SM] ", "%t", "Toggled beacon on target", "_s", name);
|
||||
LogAction(param1, target, "\"%L\" toggled beacon on \"%L\"", param1, target);
|
||||
}
|
||||
|
||||
/* Re-draw the menu if they're still valid */
|
||||
@ -230,16 +225,18 @@ public Action Command_Beacon(int client, int args)
|
||||
|
||||
for (int i = 0; i < target_count; i++)
|
||||
{
|
||||
PerformBeacon(client, target_list[i]);
|
||||
PerformBeacon(target_list[i]);
|
||||
}
|
||||
|
||||
if (tn_is_ml)
|
||||
{
|
||||
ShowActivity2(client, "[SM] ", "%t", "Toggled beacon on target", target_name);
|
||||
LogAction(client, -1, "\"%L\" toggled beacon on \"%s\"", client, target_name);
|
||||
}
|
||||
else
|
||||
{
|
||||
ShowActivity2(client, "[SM] ", "%t", "Toggled beacon on target", "_s", target_name);
|
||||
LogAction(client, target_list[0], "\"%L\" toggled beacon on \"%L\"", client, target_list[0]);
|
||||
}
|
||||
|
||||
return Plugin_Handled;
|
||||
|
@ -33,7 +33,7 @@
|
||||
|
||||
int g_BlindTarget[MAXPLAYERS+1];
|
||||
|
||||
void PerformBlind(int client, int target, int amount)
|
||||
void PerformBlind(int target, int amount)
|
||||
{
|
||||
int targets[2];
|
||||
targets[0] = target;
|
||||
@ -75,8 +75,6 @@ void PerformBlind(int client, int target, int amount)
|
||||
}
|
||||
|
||||
EndMessage();
|
||||
|
||||
LogAction(client, target, "\"%L\" set blind on \"%L\" (amount \"%d\")", client, target, amount);
|
||||
}
|
||||
|
||||
public void AdminMenu_Blind(TopMenu topmenu,
|
||||
@ -211,7 +209,8 @@ public int MenuHandler_Amount(Menu menu, MenuAction action, int param1, int para
|
||||
char name[MAX_NAME_LENGTH];
|
||||
GetClientName(target, name, sizeof(name));
|
||||
|
||||
PerformBlind(param1, target, amount);
|
||||
PerformBlind(target, amount);
|
||||
LogAction(param1, target, "\"%L\" set blind on \"%L\", amount %d.", param1, target, amount);
|
||||
ShowActivity2(param1, "[SM] ", "%t", "Set blind on target", "_s", name, amount);
|
||||
}
|
||||
|
||||
@ -276,16 +275,18 @@ public Action Command_Blind(int client, int args)
|
||||
|
||||
for (int i = 0; i < target_count; i++)
|
||||
{
|
||||
PerformBlind(client, target_list[i], amount);
|
||||
PerformBlind(target_list[i], amount);
|
||||
}
|
||||
|
||||
if (tn_is_ml)
|
||||
{
|
||||
ShowActivity2(client, "[SM] ", "%t", "Set blind on target", target_name);
|
||||
LogAction(client, -1, "\"%L\" set blind on \"%s\", amount %d.", client, target_name, amount);
|
||||
}
|
||||
else
|
||||
{
|
||||
ShowActivity2(client, "[SM] ", "%t", "Set blind on target", "_s", target_name);
|
||||
LogAction(client, target_list[0], "\"%L\" set blind on \"%L\", amount %d.", client, target_list[0], amount);
|
||||
}
|
||||
|
||||
return Plugin_Handled;
|
||||
|
@ -106,7 +106,7 @@ void KillAllDrugs()
|
||||
}
|
||||
}
|
||||
|
||||
void PerformDrug(int client, int target, int toggle)
|
||||
void PerformDrug(int target, int toggle)
|
||||
{
|
||||
switch (toggle)
|
||||
{
|
||||
@ -115,12 +115,10 @@ void PerformDrug(int client, int target, int toggle)
|
||||
if (g_DrugTimers[target] == null)
|
||||
{
|
||||
CreateDrug(target);
|
||||
LogAction(client, target, "\"%L\" drugged \"%L\"", client, target);
|
||||
}
|
||||
else
|
||||
{
|
||||
KillDrug(target);
|
||||
LogAction(client, target, "\"%L\" undrugged \"%L\"", client, target);
|
||||
}
|
||||
}
|
||||
|
||||
@ -129,7 +127,6 @@ void PerformDrug(int client, int target, int toggle)
|
||||
if (g_DrugTimers[target] == null)
|
||||
{
|
||||
CreateDrug(target);
|
||||
LogAction(client, target, "\"%L\" drugged \"%L\"", client, target);
|
||||
}
|
||||
}
|
||||
|
||||
@ -138,7 +135,6 @@ void PerformDrug(int client, int target, int toggle)
|
||||
if (g_DrugTimers[target] != null)
|
||||
{
|
||||
KillDrug(target);
|
||||
LogAction(client, target, "\"%L\" undrugged \"%L\"", client, target);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -268,7 +264,8 @@ public int MenuHandler_Drug(Menu menu, MenuAction action, int param1, int param2
|
||||
char name[MAX_NAME_LENGTH];
|
||||
GetClientName(target, name, sizeof(name));
|
||||
|
||||
PerformDrug(param1, target, 2);
|
||||
PerformDrug(target, 2);
|
||||
LogAction(param1, target, "\"%L\" toggled drugs on \"%L\"", param1, target);
|
||||
ShowActivity2(param1, "[SM] ", "%t", "Toggled drug on target", "_s", name);
|
||||
}
|
||||
|
||||
@ -326,16 +323,18 @@ public Action Command_Drug(int client, int args)
|
||||
|
||||
for (int i = 0; i < target_count; i++)
|
||||
{
|
||||
PerformDrug(client, target_list[i], toggle);
|
||||
PerformDrug(target_list[i], toggle);
|
||||
}
|
||||
|
||||
if (tn_is_ml)
|
||||
{
|
||||
ShowActivity2(client, "[SM] ", "%t", "Toggled drug on target", target_name);
|
||||
LogAction(client, -1, "\"%L\" toggled drugs on \"%s\"", client, target_name);
|
||||
}
|
||||
else
|
||||
{
|
||||
ShowActivity2(client, "[SM] ", "%t", "Toggled drug on target", "_s", target_name);
|
||||
LogAction(client, target_list[0], "\"%L\" toggled drugs on \"%L\"", client, target_list[0]);
|
||||
}
|
||||
|
||||
return Plugin_Handled;
|
||||
|
@ -64,24 +64,16 @@ void KillAllFireBombs()
|
||||
}
|
||||
}
|
||||
|
||||
void PerformBurn(int client, int target, float seconds)
|
||||
{
|
||||
IgniteEntity(target, seconds);
|
||||
LogAction(client, target, "\"%L\" ignited \"%L\" (seconds \"%f\")", client, target, seconds);
|
||||
}
|
||||
|
||||
void PerformFireBomb(int client, int target)
|
||||
{
|
||||
if (g_FireBombSerial[client] == 0)
|
||||
{
|
||||
CreateFireBomb(target);
|
||||
LogAction(client, target, "\"%L\" set a FireBomb on \"%L\"", client, target);
|
||||
}
|
||||
else
|
||||
{
|
||||
KillFireBomb(target);
|
||||
SetEntityRenderColor(client, 255, 255, 255, 255);
|
||||
LogAction(client, target, "\"%L\" removed a FireBomb on \"%L\"", client, target);
|
||||
}
|
||||
}
|
||||
|
||||
@ -306,7 +298,8 @@ public int MenuHandler_Burn(Menu menu, MenuAction action, int param1, int param2
|
||||
{
|
||||
char name[MAX_NAME_LENGTH];
|
||||
GetClientName(target, name, sizeof(name));
|
||||
PerformBurn(param1, target, 20.0);
|
||||
IgniteEntity(target, 20.0);
|
||||
LogAction(param1, target, "\"%L\" ignited \"%L\" (seconds \"20\")", param1, target);
|
||||
ShowActivity2(param1, "[SM] ", "%t", "Set target on fire", "_s", name);
|
||||
}
|
||||
|
||||
@ -353,6 +346,7 @@ public int MenuHandler_FireBomb(Menu menu, MenuAction action, int param1, int pa
|
||||
GetClientName(target, name, sizeof(name));
|
||||
|
||||
PerformFireBomb(param1, target);
|
||||
LogAction(param1, target, "\"%L\" toggled FireBomb on \"%L\"", param1, target);
|
||||
ShowActivity2(param1, "[SM] ", "%t", "Toggled FireBomb on target", "_s", name);
|
||||
}
|
||||
|
||||
@ -408,16 +402,18 @@ public Action Command_Burn(int client, int args)
|
||||
|
||||
for (int i = 0; i < target_count; i++)
|
||||
{
|
||||
PerformBurn(client, target_list[i], seconds);
|
||||
IgniteEntity(target_list[i], seconds);
|
||||
}
|
||||
|
||||
if (tn_is_ml)
|
||||
{
|
||||
ShowActivity2(client, "[SM] ", "%t", "Set target on fire", target_name);
|
||||
LogAction(client, -1, "\"%L\" ignited \"%s\" (seconds \"%f\")", client, target_name, seconds);
|
||||
}
|
||||
else
|
||||
{
|
||||
ShowActivity2(client, "[SM] ", "%t", "Set target on fire", "_s", target_name);
|
||||
LogAction(client, target_list[0], "\"%L\" ignited \"%L\" (seconds \"%f\")", client, target_list[0], seconds);
|
||||
}
|
||||
|
||||
return Plugin_Handled;
|
||||
@ -460,10 +456,12 @@ public Action Command_FireBomb(int client, int args)
|
||||
if (tn_is_ml)
|
||||
{
|
||||
ShowActivity2(client, "[SM] ", "%t", "Toggled FireBomb on target", target_name);
|
||||
LogAction(client, -1, "\"%L\" toggled FireBomb on \"%s\"", client, target_name);
|
||||
}
|
||||
else
|
||||
{
|
||||
ShowActivity2(client, "[SM] ", "%t", "Toggled FireBomb on target", "_s", target_name);
|
||||
LogAction(client, target_list[0], "\"%L\" toggled FireBomb on \"%L\"", client, target_list[0]);
|
||||
}
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
@ -33,12 +33,6 @@
|
||||
|
||||
int g_GravityTarget[MAXPLAYERS+1];
|
||||
|
||||
void PerformGravity(int client, int target, float amount)
|
||||
{
|
||||
SetEntityGravity(target, amount);
|
||||
LogAction(client, target, "\"%L\" set gravity on \"%L\" (amount \"%f\")", client, target, amount);
|
||||
}
|
||||
|
||||
public void AdminMenu_Gravity(TopMenu topmenu,
|
||||
TopMenuAction action,
|
||||
TopMenuObject object_id,
|
||||
@ -169,7 +163,8 @@ public int MenuHandler_GravityAmount(Menu menu, MenuAction action, int param1, i
|
||||
char name[MAX_NAME_LENGTH];
|
||||
GetClientName(target, name, sizeof(name));
|
||||
|
||||
PerformGravity(param1, target, amount);
|
||||
SetEntityGravity(target, amount);
|
||||
LogAction(param1, target, "\"%L\" set gravity on \"%L\" to %f.", param1, target, amount);
|
||||
ShowActivity2(param1, "[SM] ", "%t", "Set gravity on target", "_s", name, amount);
|
||||
}
|
||||
|
||||
@ -229,16 +224,18 @@ public Action Command_Gravity(int client, int args)
|
||||
|
||||
for (int i = 0; i < target_count; i++)
|
||||
{
|
||||
PerformGravity(client, target_list[i], amount);
|
||||
SetEntityGravity(target_list[i], amount);
|
||||
}
|
||||
|
||||
if (tn_is_ml)
|
||||
{
|
||||
ShowActivity2(client, "[SM] ", "%t", "Set gravity on target", target_name);
|
||||
LogAction(client, -1, "\"%L\" set gravity on \"%s\" to %f.", client, target_name, amount);
|
||||
}
|
||||
else
|
||||
{
|
||||
ShowActivity2(client, "[SM] ", "%t", "Set gravity on target", "_s", target_name);
|
||||
LogAction(client, target_list[0], "\"%L\" set gravity on \"%L\" to %f.", client, target_list[0], amount);
|
||||
}
|
||||
|
||||
return Plugin_Handled;
|
||||
|
@ -125,24 +125,12 @@ void KillAllFreezes()
|
||||
}
|
||||
}
|
||||
|
||||
void PerformFreeze(int client, int target, int time)
|
||||
{
|
||||
FreezeClient(target, time);
|
||||
LogAction(client, target, "\"%L\" froze \"%L\"", client, target);
|
||||
}
|
||||
|
||||
void PerformFreezeBomb(int client, int target)
|
||||
void PerformFreezeBomb(int target)
|
||||
{
|
||||
if (g_FreezeBombSerial[target] != 0)
|
||||
{
|
||||
KillFreezeBomb(target);
|
||||
LogAction(client, target, "\"%L\" removed a FreezeBomb on \"%L\"", client, target);
|
||||
}
|
||||
else
|
||||
{
|
||||
CreateFreezeBomb(target);
|
||||
LogAction(client, target, "\"%L\" set a FreezeBomb on \"%L\"", client, target);
|
||||
}
|
||||
}
|
||||
|
||||
public Action Timer_Freeze(Handle timer, any value)
|
||||
@ -421,7 +409,8 @@ public int MenuHandler_Freeze(Menu menu, MenuAction action, int param1, int para
|
||||
char name[MAX_NAME_LENGTH];
|
||||
GetClientName(target, name, sizeof(name));
|
||||
|
||||
PerformFreeze(param1, target, g_Cvar_FreezeDuration.IntValue);
|
||||
FreezeClient(target, g_Cvar_FreezeDuration.IntValue);
|
||||
LogAction(param1, target, "\"%L\" froze \"%L\"", param1, target);
|
||||
ShowActivity2(param1, "[SM] ", "%t", "Froze target", "_s", name);
|
||||
}
|
||||
|
||||
@ -467,7 +456,8 @@ public int MenuHandler_FreezeBomb(Menu menu, MenuAction action, int param1, int
|
||||
char name[MAX_NAME_LENGTH];
|
||||
GetClientName(target, name, sizeof(name));
|
||||
|
||||
PerformFreezeBomb(param1, target);
|
||||
PerformFreezeBomb(target);
|
||||
LogAction(param1, target, "\"%L\" toggled FreezeBomb on \"%L\"", param1, target);
|
||||
ShowActivity2(param1, "[SM] ", "%t", "Toggled FreezeBomb on target", "_s", name);
|
||||
}
|
||||
|
||||
@ -523,16 +513,18 @@ public Action Command_Freeze(int client, int args)
|
||||
|
||||
for (int i = 0; i < target_count; i++)
|
||||
{
|
||||
PerformFreeze(client, target_list[i], seconds);
|
||||
FreezeClient(target_list[i], seconds);
|
||||
}
|
||||
|
||||
if (tn_is_ml)
|
||||
{
|
||||
ShowActivity2(client, "[SM] ", "%t", "Froze target", target_name);
|
||||
LogAction(client, -1, "\"%L\" froze \"%s\"", client, target_name);
|
||||
}
|
||||
else
|
||||
{
|
||||
ShowActivity2(client, "[SM] ", "%t", "Froze target", "_s", target_name);
|
||||
LogAction(client, target_list[0], "\"%L\" froze \"%L\"", client, target_list[0]);
|
||||
}
|
||||
|
||||
return Plugin_Handled;
|
||||
@ -569,16 +561,18 @@ public Action Command_FreezeBomb(int client, int args)
|
||||
|
||||
for (int i = 0; i < target_count; i++)
|
||||
{
|
||||
PerformFreezeBomb(client, target_list[i]);
|
||||
PerformFreezeBomb(target_list[i]);
|
||||
}
|
||||
|
||||
if (tn_is_ml)
|
||||
{
|
||||
ShowActivity2(client, "[SM] ", "%t", "Toggled FreezeBomb on target", target_name);
|
||||
LogAction(client, -1, "\"%L\" toggled FreezeBomb on \"%s\"", client, target_name);
|
||||
}
|
||||
else
|
||||
{
|
||||
ShowActivity2(client, "[SM] ", "%t", "Toggled FreezeBomb on target", "_s", target_name);
|
||||
LogAction(client, target_list[0], "\"%L\" toggled FreezeBomb on \"%L\"", client, target_list[0]);
|
||||
}
|
||||
|
||||
return Plugin_Handled;
|
||||
|
@ -31,7 +31,7 @@
|
||||
* Version: $Id$
|
||||
*/
|
||||
|
||||
void PerformNoClip(int client, int target)
|
||||
void PerformNoClip(int target)
|
||||
{
|
||||
MoveType movetype = GetEntityMoveType(target);
|
||||
|
||||
@ -43,8 +43,6 @@ void PerformNoClip(int client, int target)
|
||||
{
|
||||
SetEntityMoveType(target, MOVETYPE_WALK);
|
||||
}
|
||||
|
||||
LogAction(client, target, "\"%L\" toggled noclip on \"%L\"", client, target);
|
||||
}
|
||||
|
||||
public void AdminMenu_NoClip(TopMenu topmenu,
|
||||
@ -112,7 +110,8 @@ public int MenuHandler_NoClip(Menu menu, MenuAction action, int param1, int para
|
||||
char name[MAX_NAME_LENGTH];
|
||||
GetClientName(target, name, sizeof(name));
|
||||
|
||||
PerformNoClip(param1, target);
|
||||
PerformNoClip(target);
|
||||
LogAction(param1, target, "\"%L\" toggled noclip on \"%L\"", param1, target);
|
||||
ShowActivity2(param1, "[SM] ", "%t", "Toggled noclip on target", "_s", name);
|
||||
}
|
||||
|
||||
@ -155,16 +154,18 @@ public Action Command_NoClip(int client, int args)
|
||||
|
||||
for (int i = 0; i < target_count; i++)
|
||||
{
|
||||
PerformNoClip(client, target_list[i]);
|
||||
PerformNoClip(target_list[i]);
|
||||
}
|
||||
|
||||
if (tn_is_ml)
|
||||
{
|
||||
ShowActivity2(client, "[SM] ", "%t", "Toggled noclip on target", target_name);
|
||||
LogAction(client, -1, "\"%L\" toggled noclip on \"%s\"", client, target_name);
|
||||
}
|
||||
else
|
||||
{
|
||||
ShowActivity2(client, "[SM] ", "%t", "Toggled noclip on target", "_s", target_name);
|
||||
LogAction(client, target_list[0], "\"%L\" toggled noclip on \"%L\"", client, target_list[0]);
|
||||
}
|
||||
|
||||
return Plugin_Handled;
|
||||
|
@ -68,13 +68,11 @@ void PerformTimeBomb(int client, int target)
|
||||
if (g_TimeBombSerial[target] == 0)
|
||||
{
|
||||
CreateTimeBomb(target);
|
||||
LogAction(client, target, "\"%L\" set a TimeBomb on \"%L\"", client, target);
|
||||
}
|
||||
else
|
||||
{
|
||||
KillTimeBomb(target);
|
||||
SetEntityRenderColor(client, 255, 255, 255, 255);
|
||||
LogAction(client, target, "\"%L\" removed a TimeBomb on \"%L\"", client, target);
|
||||
}
|
||||
}
|
||||
|
||||
@ -279,6 +277,7 @@ public int MenuHandler_TimeBomb(Menu menu, MenuAction action, int param1, int pa
|
||||
GetClientName(target, name, sizeof(name));
|
||||
|
||||
PerformTimeBomb(param1, target);
|
||||
LogAction(param1, target, "\"%L\" toggled TimeBomb on \"%L\"", param1, target);
|
||||
ShowActivity2(param1, "[SM] ", "%t", "Toggled TimeBomb on target", "_s", name);
|
||||
}
|
||||
|
||||
@ -327,10 +326,12 @@ public Action Command_TimeBomb(int client, int args)
|
||||
if (tn_is_ml)
|
||||
{
|
||||
ShowActivity2(client, "[SM] ", "%t", "Toggled TimeBomb on target", target_name);
|
||||
LogAction(client, -1, "\"%L\" toggled TimeBomb on \"%s\"", client, target_name);
|
||||
}
|
||||
else
|
||||
{
|
||||
ShowActivity2(client, "[SM] ", "%t", "Toggled TimeBomb on target", "_s", target_name);
|
||||
LogAction(client, target_list[0], "\"%L\" toggled TimeBomb on \"%L\"", client, target_list[0]);
|
||||
}
|
||||
|
||||
return Plugin_Handled;
|
||||
|
24
plugins/include/DynamicTargeting.inc
Normal file
24
plugins/include/DynamicTargeting.inc
Normal file
@ -0,0 +1,24 @@
|
||||
#if defined _DynamicTargeting_Included
|
||||
#endinput
|
||||
#endif
|
||||
#define _DynamicTargeting_Included
|
||||
|
||||
native int AmbiguousMenu(int client, char[] sCommand, char[] sArgString, char[] sPattern, int FilterFlags);
|
||||
|
||||
public SharedPlugin __pl_DynamicTargeting =
|
||||
{
|
||||
name = "DynamicTargeting",
|
||||
file = "DynamicTargeting.smx",
|
||||
#if defined REQUIRE_PLUGIN
|
||||
required = 1,
|
||||
#else
|
||||
required = 0,
|
||||
#endif
|
||||
};
|
||||
|
||||
#if !defined REQUIRE_PLUGIN
|
||||
public __pl_DynamicTargeting_SetNTVOptional()
|
||||
{
|
||||
MarkNativeAsOptional("AmbiguousMenu");
|
||||
}
|
||||
#endif
|
@ -738,6 +738,15 @@ native float GetClientAvgData(int client, NetFlow flow);
|
||||
*/
|
||||
native float GetClientAvgPackets(int client, NetFlow flow);
|
||||
|
||||
/**
|
||||
* Returns the client's baseserver IClient pointer.
|
||||
*
|
||||
* @param client Player's index.
|
||||
* @return IClient address.
|
||||
* @error Invalid client index, client not connected, or fake client.
|
||||
*/
|
||||
native Address GetClientIClient(int client);
|
||||
|
||||
/**
|
||||
* Translates an userid index to the real player index.
|
||||
*
|
||||
|
@ -84,6 +84,25 @@ native int ProcessTargetString(const char[] pattern,
|
||||
int tn_maxlength,
|
||||
bool &tn_is_ml);
|
||||
|
||||
|
||||
/**
|
||||
* Retrieves arguments that were passed to the last ProcessTargetString call.
|
||||
*
|
||||
* @param pattern Buffer to store the pattern.
|
||||
* @param p_maxlen Maximum length of the pattern buffer.
|
||||
* @param admin OUTPUT: Admin performing the action, or 0 if the server.
|
||||
* @param filter_flags OUTPUT: Filter flags.
|
||||
* @noreturn
|
||||
*/
|
||||
native void GetLastProcessTargetString(char[] pattern,
|
||||
int p_maxlen,
|
||||
int &admin,
|
||||
int &filter_flags);
|
||||
|
||||
#undef REQUIRE_PLUGIN
|
||||
#include <DynamicTargeting>
|
||||
#define REQUIRE_PLUGIN
|
||||
|
||||
/**
|
||||
* Replies to a client with a given message describing a targetting
|
||||
* failure reason.
|
||||
@ -93,7 +112,7 @@ native int ProcessTargetString(const char[] pattern,
|
||||
* @param client Client index, or 0 for server.
|
||||
* @param reason COMMAND_TARGET reason.
|
||||
*/
|
||||
stock void ReplyToTargetError(int client, int reason)
|
||||
stock void ReplyToTargetError(int client, int reason, bool dynamic=true)
|
||||
{
|
||||
switch (reason)
|
||||
{
|
||||
@ -128,6 +147,34 @@ stock void ReplyToTargetError(int client, int reason)
|
||||
case COMMAND_TARGET_AMBIGUOUS:
|
||||
{
|
||||
ReplyToCommand(client, "[SM] %t", "More than one client matched");
|
||||
|
||||
if(dynamic &&
|
||||
GetFeatureStatus(FeatureType_Native, "GetLastProcessTargetString") == FeatureStatus_Available &&
|
||||
LibraryExists("DynamicTargeting"))
|
||||
{
|
||||
if(GetFeatureStatus(FeatureType_Native, "IsCommandCallback") == FeatureStatus_Available &&
|
||||
!IsCommandCallback())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
char sCommand[128];
|
||||
GetCmdArg(0, sCommand, sizeof(sCommand));
|
||||
|
||||
char sArgString[256];
|
||||
GetCmdArgString(sArgString, sizeof(sArgString));
|
||||
|
||||
char pattern[MAX_TARGET_LENGTH];
|
||||
int admin;
|
||||
int filter_flags;
|
||||
|
||||
GetLastProcessTargetString(pattern, sizeof(pattern), admin, filter_flags);
|
||||
|
||||
if(!admin || !IsClientInGame(admin) || IsFakeClient(admin))
|
||||
return;
|
||||
|
||||
AmbiguousMenu(admin, sCommand, sArgString, pattern, filter_flags);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -137,9 +184,13 @@ stock void ReplyToTargetError(int client, int reason)
|
||||
*
|
||||
* @param pattern Pattern name.
|
||||
* @param clients Array to fill with unique, valid client indexes.
|
||||
* @param client Client that triggered this filter.
|
||||
* @return True if pattern was recognized, false otherwise.
|
||||
*/
|
||||
typedef MultiTargetFilter = function bool (const char[] pattern, Handle clients);
|
||||
typeset MultiTargetFilter {
|
||||
function bool (const char[] pattern, Handle clients);
|
||||
function bool (const char[] pattern, Handle clients, int client);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a multi-target filter function for ProcessTargetString().
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user