Merge pull request #486 from alliedmodders/csgo-safety
Add initial version of safety checks for CS:GO to attempt to avoid user GSLT bans.
This commit is contained in:
commit
19bcc8417d
@ -132,5 +132,18 @@
|
|||||||
* passed. You can disable this feature by setting the value to "0".
|
* passed. You can disable this feature by setting the value to "0".
|
||||||
*/
|
*/
|
||||||
"SlowScriptTimeout" "8"
|
"SlowScriptTimeout" "8"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Per "http://blog.counter-strike.net/index.php/server_guidelines/", certain plugin
|
||||||
|
* functionality will trigger all of the game server owner's Game Server Login Tokens
|
||||||
|
* (GSLTs) to get banned when executed on a Counter-Strike: Global Offensive game server.
|
||||||
|
*
|
||||||
|
* Enabling this option will block plugins from using functionality that is known to cause this.
|
||||||
|
* This option only has any effect on CS:GO. Note that this does NOT guarantee that you cannot
|
||||||
|
* receive a ban.
|
||||||
|
*
|
||||||
|
* Disable this option at your own risk.
|
||||||
|
*/
|
||||||
|
"FollowCSGOServerGuidelines" "yes"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -137,6 +137,57 @@ void CHalfLife2::OnSourceModAllInitialized_Post()
|
|||||||
{
|
{
|
||||||
InitLogicalEntData();
|
InitLogicalEntData();
|
||||||
InitCommandLine();
|
InitCommandLine();
|
||||||
|
#if SOURCE_ENGINE == SE_CSGO
|
||||||
|
m_CSGOBadList.init();
|
||||||
|
m_CSGOBadList.add("m_iItemDefinitionIndex");
|
||||||
|
m_CSGOBadList.add("m_iEntityLevel");
|
||||||
|
m_CSGOBadList.add("m_iItemIDHigh");
|
||||||
|
m_CSGOBadList.add("m_iItemIDLow");
|
||||||
|
m_CSGOBadList.add("m_iAccountID");
|
||||||
|
m_CSGOBadList.add("m_iEntityQuality");
|
||||||
|
m_CSGOBadList.add("m_bInitialized");
|
||||||
|
m_CSGOBadList.add("m_szCustomName");
|
||||||
|
m_CSGOBadList.add("m_iAttributeDefinitionIndex");
|
||||||
|
m_CSGOBadList.add("m_iRawValue32");
|
||||||
|
m_CSGOBadList.add("m_iRawInitialValue32");
|
||||||
|
m_CSGOBadList.add("m_nRefundableCurrency");
|
||||||
|
m_CSGOBadList.add("m_bSetBonus");
|
||||||
|
m_CSGOBadList.add("m_OriginalOwnerXuidLow");
|
||||||
|
m_CSGOBadList.add("m_OriginalOwnerXuidHigh");
|
||||||
|
m_CSGOBadList.add("m_nFallbackPaintKit");
|
||||||
|
m_CSGOBadList.add("m_nFallbackSeed");
|
||||||
|
m_CSGOBadList.add("m_flFallbackWear");
|
||||||
|
m_CSGOBadList.add("m_nFallbackStatTrak");
|
||||||
|
m_CSGOBadList.add("m_iCompetitiveRanking");
|
||||||
|
m_CSGOBadList.add("m_nActiveCoinRank");
|
||||||
|
m_CSGOBadList.add("m_nMusicID");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
ConfigResult CHalfLife2::OnSourceModConfigChanged(const char *key, const char *value,
|
||||||
|
ConfigSource source, char *error, size_t maxlength)
|
||||||
|
{
|
||||||
|
if (strcasecmp(key, "FollowCSGOServerGuidelines") == 0)
|
||||||
|
{
|
||||||
|
#if SOURCE_ENGINE == SE_CSGO
|
||||||
|
if (strcasecmp(value, "no") == 0)
|
||||||
|
{
|
||||||
|
m_bFollowCSGOServerGuidelines = false;
|
||||||
|
return ConfigResult_Accept;
|
||||||
|
}
|
||||||
|
else if (strcasecmp(value, "yes") == 0)
|
||||||
|
{
|
||||||
|
m_bFollowCSGOServerGuidelines = true;
|
||||||
|
return ConfigResult_Accept;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ConfigResult_Reject;
|
||||||
|
#else
|
||||||
|
return ConfigResult_Accept;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
return ConfigResult_Ignore;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CHalfLife2::InitLogicalEntData()
|
void CHalfLife2::InitLogicalEntData()
|
||||||
|
@ -36,6 +36,7 @@
|
|||||||
#include <sh_string.h>
|
#include <sh_string.h>
|
||||||
#include <sh_tinyhash.h>
|
#include <sh_tinyhash.h>
|
||||||
#include <am-utility.h>
|
#include <am-utility.h>
|
||||||
|
#include <am-hashset.h>
|
||||||
#include <am-hashmap.h>
|
#include <am-hashmap.h>
|
||||||
#include <sm_stringhashmap.h>
|
#include <sm_stringhashmap.h>
|
||||||
#include <sm_namehashset.h>
|
#include <sm_namehashset.h>
|
||||||
@ -152,6 +153,8 @@ public:
|
|||||||
void OnSourceModAllInitialized();
|
void OnSourceModAllInitialized();
|
||||||
void OnSourceModAllInitialized_Post();
|
void OnSourceModAllInitialized_Post();
|
||||||
/*void OnSourceModAllShutdown();*/
|
/*void OnSourceModAllShutdown();*/
|
||||||
|
ConfigResult OnSourceModConfigChanged(const char *key, const char *value,
|
||||||
|
ConfigSource source, char *error, size_t maxlength) override;
|
||||||
public: //IGameHelpers
|
public: //IGameHelpers
|
||||||
SendProp *FindInSendTable(const char *classname, const char *offset);
|
SendProp *FindInSendTable(const char *classname, const char *offset);
|
||||||
bool FindSendPropInfo(const char *classname, const char *offset, sm_sendprop_info_t *info);
|
bool FindSendPropInfo(const char *classname, const char *offset, sm_sendprop_info_t *info);
|
||||||
@ -220,6 +223,16 @@ private:
|
|||||||
CStack<CachedCommandInfo> m_CommandStack;
|
CStack<CachedCommandInfo> m_CommandStack;
|
||||||
Queue<DelayedKickInfo> m_DelayedKicks;
|
Queue<DelayedKickInfo> m_DelayedKicks;
|
||||||
void *m_pGetCommandLine;
|
void *m_pGetCommandLine;
|
||||||
|
#if SOURCE_ENGINE == SE_CSGO
|
||||||
|
public:
|
||||||
|
bool CanSetCSGOEntProp(const char *pszPropName)
|
||||||
|
{
|
||||||
|
return !m_bFollowCSGOServerGuidelines || !m_CSGOBadList.has(pszPropName);
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
ke::HashSet<ke::AString, detail::StringHashMapPolicy> m_CSGOBadList;
|
||||||
|
bool m_bFollowCSGOServerGuidelines = true;
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
extern CHalfLife2 g_HL2;
|
extern CHalfLife2 g_HL2;
|
||||||
|
@ -93,6 +93,15 @@ enum PropFieldType
|
|||||||
PropField_String_T, /**< Valid for Data fields. Read only! */
|
PropField_String_T, /**< Valid for Data fields. Read only! */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
inline bool CanSetPropName(const char *pszPropName)
|
||||||
|
{
|
||||||
|
#if SOURCE_ENGINE == SE_CSGO
|
||||||
|
return g_HL2.CanSetCSGOEntProp(pszPropName);
|
||||||
|
#else
|
||||||
|
return true;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
inline edict_t *BaseEntityToEdict(CBaseEntity *pEntity)
|
inline edict_t *BaseEntityToEdict(CBaseEntity *pEntity)
|
||||||
{
|
{
|
||||||
IServerUnknown *pUnk = (IServerUnknown *)pEntity;
|
IServerUnknown *pUnk = (IServerUnknown *)pEntity;
|
||||||
@ -1351,6 +1360,10 @@ static cell_t SetEntProp(IPluginContext *pContext, const cell_t *params)
|
|||||||
case Prop_Send:
|
case Prop_Send:
|
||||||
{
|
{
|
||||||
FIND_PROP_SEND(DPT_Int, "integer");
|
FIND_PROP_SEND(DPT_Int, "integer");
|
||||||
|
if (!CanSetPropName(prop))
|
||||||
|
{
|
||||||
|
return pContext->ThrowNativeError("Cannot set %s with \"FollowCSGOServerGuidelines\" option enabled.", prop);
|
||||||
|
}
|
||||||
|
|
||||||
// This isn't in CS:S yet, but will be, doesn't hurt to add now, and will save us a build later
|
// This isn't in CS:S yet, but will be, doesn't hurt to add now, and will save us a build later
|
||||||
#if SOURCE_ENGINE == SE_CSS || SOURCE_ENGINE == SE_HL2DM || SOURCE_ENGINE == SE_DODS \
|
#if SOURCE_ENGINE == SE_CSS || SOURCE_ENGINE == SE_HL2DM || SOURCE_ENGINE == SE_DODS \
|
||||||
@ -1503,6 +1516,10 @@ static cell_t SetEntPropFloat(IPluginContext *pContext, const cell_t *params)
|
|||||||
case Prop_Send:
|
case Prop_Send:
|
||||||
{
|
{
|
||||||
FIND_PROP_SEND(DPT_Float, "float");
|
FIND_PROP_SEND(DPT_Float, "float");
|
||||||
|
if (!CanSetPropName(prop))
|
||||||
|
{
|
||||||
|
return pContext->ThrowNativeError("Cannot set %s with \"FollowCSGOServerGuidelines\" option enabled.", prop);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
@ -2088,6 +2105,11 @@ static cell_t SetEntPropString(IPluginContext *pContext, const cell_t *params)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!CanSetPropName(prop))
|
||||||
|
{
|
||||||
|
return pContext->ThrowNativeError("Cannot set %s with \"FollowCSGOServerGuidelines\" option enabled.", prop);
|
||||||
|
}
|
||||||
|
|
||||||
if (bIsStringIndex)
|
if (bIsStringIndex)
|
||||||
{
|
{
|
||||||
offset += (element * (td->fieldSizeInBytes / td->fieldSize));
|
offset += (element * (td->fieldSizeInBytes / td->fieldSize));
|
||||||
|
@ -170,6 +170,15 @@ bool SDKTools::SDK_OnLoad(char *error, size_t maxlength, bool late)
|
|||||||
|
|
||||||
InitSDKToolsAPI();
|
InitSDKToolsAPI();
|
||||||
|
|
||||||
|
#if SOURCE_ENGINE == SE_CSGO
|
||||||
|
m_bFollowCSGOServerGuidelines = true;
|
||||||
|
const char *pszValue = g_pSM->GetCoreConfigValue("FollowCSGOServerGuidelines");
|
||||||
|
if (pszValue && strcasecmp(pszValue, "no") == 0)
|
||||||
|
{
|
||||||
|
m_bFollowCSGOServerGuidelines = false;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -113,8 +113,10 @@ public:
|
|||||||
void OnServerActivate(edict_t *pEdictList, int edictCount, int clientMax);
|
void OnServerActivate(edict_t *pEdictList, int edictCount, int clientMax);
|
||||||
public:
|
public:
|
||||||
bool HasAnyLevelInited() { return m_bAnyLevelInited; }
|
bool HasAnyLevelInited() { return m_bAnyLevelInited; }
|
||||||
|
bool ShouldFollowCSGOServerGuidelines() const { return m_bFollowCSGOServerGuidelines; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
bool m_bFollowCSGOServerGuidelines = false;
|
||||||
bool m_bAnyLevelInited = false;
|
bool m_bAnyLevelInited = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -144,6 +144,20 @@ static cell_t RemovePlayerItem(IPluginContext *pContext, const cell_t *params)
|
|||||||
class CEconItemView;
|
class CEconItemView;
|
||||||
static cell_t GiveNamedItem(IPluginContext *pContext, const cell_t *params)
|
static cell_t GiveNamedItem(IPluginContext *pContext, const cell_t *params)
|
||||||
{
|
{
|
||||||
|
if (g_SdkTools.ShouldFollowCSGOServerGuidelines())
|
||||||
|
{
|
||||||
|
char *pWeaponName;
|
||||||
|
pContext->LocalToString(params[2], &pWeaponName);
|
||||||
|
|
||||||
|
// Don't allow knives other than weapon_knife, weapon_knifegg, and wewapon_knife_t.
|
||||||
|
// Others follow pattern weapon_knife_*
|
||||||
|
size_t len = strlen(pWeaponName);
|
||||||
|
if (len >= 14 && strnicmp(pWeaponName, "weapon_knife_", 13) == 0 && !(pWeaponName[13] == 't' && pWeaponName[14] == '\0'))
|
||||||
|
{
|
||||||
|
return pContext->ThrowNativeError("Blocked giving of %s due to core.cfg option FollowCSGOServerGuidelines", pWeaponName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static ValveCall *pCall = NULL;
|
static ValveCall *pCall = NULL;
|
||||||
if (!pCall)
|
if (!pCall)
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user