initial commit
This commit is contained in:
parent
e0c32eab49
commit
eb4f6d35e0
656
AntiBhopCheat/scripting/AntiBhopCheat.sp
Normal file
656
AntiBhopCheat/scripting/AntiBhopCheat.sp
Normal file
@ -0,0 +1,656 @@
|
||||
#include <sourcemod>
|
||||
#include <sdktools>
|
||||
#include <multicolors>
|
||||
#include <SelectiveBhop>
|
||||
|
||||
#include <basic>
|
||||
#include "CJump.inc"
|
||||
#include "CStreak.inc"
|
||||
#include "CPlayer.inc"
|
||||
|
||||
#define MAX_STREAKS 10
|
||||
#define VALID_MIN_JUMPS 3
|
||||
#define VALID_MAX_TICKS 5
|
||||
#define VALID_MIN_VELOCITY 250
|
||||
|
||||
int g_aButtons[MAXPLAYERS + 1];
|
||||
bool g_bOnGround[MAXPLAYERS + 1];
|
||||
bool g_bHoldingJump[MAXPLAYERS + 1];
|
||||
bool g_bInJump[MAXPLAYERS + 1];
|
||||
|
||||
CPlayer g_aPlayers[MAXPLAYERS + 1];
|
||||
|
||||
// Api
|
||||
Handle g_hOnClientDetected;
|
||||
|
||||
char g_sStats[4096];
|
||||
|
||||
public Plugin myinfo =
|
||||
{
|
||||
name = "AntiBhopCheat",
|
||||
author = "BotoX",
|
||||
description = "Detect all kinds of bhop cheats",
|
||||
version = "0.0",
|
||||
url = ""
|
||||
};
|
||||
|
||||
|
||||
public void OnPluginStart()
|
||||
{
|
||||
LoadTranslations("common.phrases");
|
||||
|
||||
RegAdminCmd("sm_stats", Command_Stats, ADMFLAG_GENERIC, "sm_stats <#userid|name>");
|
||||
RegAdminCmd("sm_streak", Command_Streak, ADMFLAG_GENERIC, "sm_streak <#userid|name> [streak]");
|
||||
|
||||
/* Handle late load */
|
||||
for(int client = 1; client <= MaxClients; client++)
|
||||
{
|
||||
if(IsClientConnected(client))
|
||||
{
|
||||
if(IsClientInGame(client))
|
||||
OnClientPutInServer(client);
|
||||
}
|
||||
}
|
||||
|
||||
// Api
|
||||
g_hOnClientDetected = CreateGlobalForward("AntiBhopCheat_OnClientDetected", ET_Ignore, Param_Cell, Param_String, Param_String);
|
||||
}
|
||||
|
||||
public void OnClientPutInServer(int client)
|
||||
{
|
||||
g_aPlayers[client] = new CPlayer(client);
|
||||
}
|
||||
|
||||
public void OnClientDisconnect(int client)
|
||||
{
|
||||
if(g_aPlayers[client])
|
||||
{
|
||||
g_aPlayers[client].Dispose();
|
||||
g_aPlayers[client] = null;
|
||||
}
|
||||
|
||||
g_bOnGround[client] = false;
|
||||
g_bHoldingJump[client] = false;
|
||||
g_bInJump[client] = false;
|
||||
}
|
||||
|
||||
public Action OnPlayerRunCmd(int client, int &buttons)
|
||||
{
|
||||
g_aButtons[client] = buttons;
|
||||
return Plugin_Continue;
|
||||
}
|
||||
|
||||
public void OnPlayerRunCmdPost(int client, int buttons, int impulse, float vel[3], float angles[3], int weapon, int subtype, int cmdnum, int tickcount)
|
||||
{
|
||||
if(!IsPlayerAlive(client))
|
||||
return;
|
||||
|
||||
CPlayer Player = g_aPlayers[client];
|
||||
|
||||
MoveType ClientMoveType = GetEntityMoveType(client);
|
||||
bool bInWater = GetEntProp(client, Prop_Send, "m_nWaterLevel") >= 2;
|
||||
|
||||
bool bPrevOnGround = g_bOnGround[client];
|
||||
bool bOnGround = !bInWater && GetEntityFlags(client) & FL_ONGROUND;
|
||||
|
||||
bool bPrevHoldingJump = g_bHoldingJump[client];
|
||||
bool bHoldingJump = view_as<bool>(g_aButtons[client] & IN_JUMP);
|
||||
|
||||
bool bInJump = g_bInJump[client];
|
||||
|
||||
float fVecVelocity[3];
|
||||
GetEntPropVector(client, Prop_Data, "m_vecAbsVelocity", fVecVelocity);
|
||||
fVecVelocity[2] = 0.0;
|
||||
float fVelocity = GetVectorLength(fVecVelocity);
|
||||
|
||||
if(bInJump && (bInWater || ClientMoveType == MOVETYPE_LADDER || ClientMoveType == MOVETYPE_NOCLIP))
|
||||
bOnGround = true;
|
||||
|
||||
if(bOnGround)
|
||||
{
|
||||
if(!bPrevOnGround)
|
||||
{
|
||||
g_bOnGround[client] = true;
|
||||
g_bInJump[client] = false;
|
||||
if(bInJump)
|
||||
OnTouchGround(Player, tickcount, fVelocity);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(bPrevOnGround)
|
||||
g_bOnGround[client] = false;
|
||||
}
|
||||
|
||||
if(bHoldingJump)
|
||||
{
|
||||
if(!bPrevHoldingJump && !bOnGround && (bPrevOnGround || bInJump))
|
||||
{
|
||||
g_bHoldingJump[client] = true;
|
||||
g_bInJump[client] = true;
|
||||
OnPressJump(Player, tickcount, fVelocity, bPrevOnGround);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(bPrevHoldingJump)
|
||||
{
|
||||
g_bHoldingJump[client] = false;
|
||||
OnReleaseJump(Player, tickcount, fVelocity);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Release after touch ground
|
||||
|
||||
void OnTouchGround(CPlayer Player, int iTick, float fVelocity)
|
||||
{
|
||||
//PrintToServer("%d - OnTouchGround", iTick);
|
||||
|
||||
CStreak CurStreak = Player.hStreak;
|
||||
ArrayList hJumps = CurStreak.hJumps;
|
||||
CJump hJump = hJumps.Get(hJumps.Length - 1);
|
||||
|
||||
hJump.iEndTick = iTick;
|
||||
hJump.fEndVel = fVelocity;
|
||||
|
||||
int iLength = hJumps.Length;
|
||||
if(iLength == VALID_MIN_JUMPS)
|
||||
{
|
||||
CurStreak.bValid = true;
|
||||
|
||||
// Current streak is valid, push onto hStreaks ArrayList
|
||||
ArrayList hStreaks = Player.hStreaks;
|
||||
if(hStreaks.Length == MAX_STREAKS)
|
||||
{
|
||||
// Keep the last 10 streaks
|
||||
CStreak hStreak = hStreaks.Get(0);
|
||||
hStreak.Dispose();
|
||||
hStreaks.Erase(0);
|
||||
}
|
||||
hStreaks.Push(CurStreak);
|
||||
|
||||
for(int i = 0; i < iLength - 1; i++)
|
||||
{
|
||||
CJump hJump_ = hJumps.Get(i);
|
||||
DoStats(Player, CurStreak, hJump_);
|
||||
}
|
||||
}
|
||||
else if(iLength > VALID_MIN_JUMPS)
|
||||
{
|
||||
CJump hJump_ = hJumps.Get(hJumps.Length - 2);
|
||||
DoStats(Player, CurStreak, hJump_);
|
||||
}
|
||||
}
|
||||
|
||||
void OnPressJump(CPlayer Player, int iTick, float fVelocity, bool bLeaveGround)
|
||||
{
|
||||
//PrintToServer("%d - OnPressJump %d", iTick, bLeaveGround);
|
||||
|
||||
CStreak CurStreak = Player.hStreak;
|
||||
ArrayList hJumps = CurStreak.hJumps;
|
||||
CJump hJump;
|
||||
|
||||
if(bLeaveGround)
|
||||
{
|
||||
int iPrevJump = -1;
|
||||
// Check if we should start a new streak
|
||||
if(hJumps.Length)
|
||||
{
|
||||
// Last jump was more than VALID_MAX_TICKS ticks ago or not valid and fVelocity < VALID_MIN_VELOCITY
|
||||
hJump = hJumps.Get(hJumps.Length - 1);
|
||||
if(hJump.iEndTick < iTick - VALID_MAX_TICKS || fVelocity < VALID_MIN_VELOCITY)
|
||||
{
|
||||
if(CurStreak.bValid)
|
||||
{
|
||||
CurStreak.iEndTick = iTick;
|
||||
|
||||
DoStats(Player, CurStreak, hJump);
|
||||
}
|
||||
else
|
||||
CurStreak.Dispose();
|
||||
|
||||
CurStreak = new CStreak();
|
||||
Player.hStreak = CurStreak;
|
||||
hJumps = CurStreak.hJumps;
|
||||
}
|
||||
else
|
||||
{
|
||||
iPrevJump = iTick - hJump.iEndTick;
|
||||
hJump.iNextJump = iPrevJump;
|
||||
}
|
||||
}
|
||||
|
||||
hJump = new CJump();
|
||||
hJump.iStartTick = iTick;
|
||||
hJump.fStartVel = fVelocity;
|
||||
if(iPrevJump != -1)
|
||||
hJump.iPrevJump = iPrevJump;
|
||||
hJumps.Push(hJump);
|
||||
}
|
||||
else
|
||||
hJump = hJumps.Get(hJumps.Length - 1);
|
||||
|
||||
ArrayList hPresses = hJump.hPresses;
|
||||
hPresses.Push(iTick);
|
||||
}
|
||||
|
||||
void OnReleaseJump(CPlayer Player, int iTick, float fVelocity)
|
||||
{
|
||||
//PrintToServer("%d - OnReleaseJump", iTick);
|
||||
|
||||
CStreak CurStreak = Player.hStreak;
|
||||
ArrayList hJumps = CurStreak.hJumps;
|
||||
CJump hJump = hJumps.Get(hJumps.Length - 1);
|
||||
ArrayList hPresses = hJump.hPresses;
|
||||
|
||||
hPresses.Set(hPresses.Length - 1, iTick, 1);
|
||||
}
|
||||
|
||||
void DoStats(CPlayer Player, CStreak CurStreak, CJump hJump)
|
||||
{
|
||||
int client = Player.iClient;
|
||||
int aJumps[3] = {0, 0, 0};
|
||||
int iPresses = 0;
|
||||
int iTicks = 0;
|
||||
int iLastJunk = 0;
|
||||
|
||||
CurStreak.iJumps++;
|
||||
Player.iJumps++;
|
||||
|
||||
ArrayList hPresses = hJump.hPresses;
|
||||
int iStartTick = hJump.iStartTick;
|
||||
int iEndTick = hJump.iEndTick;
|
||||
int iPrevJump = hJump.iPrevJump;
|
||||
int iNextJump = hJump.iNextJump;
|
||||
|
||||
if(iPrevJump != -1)
|
||||
{
|
||||
int iPerf = iPrevJump - 1;
|
||||
if(iPerf > 2)
|
||||
iPerf = 2;
|
||||
|
||||
aJumps[iPerf]++;
|
||||
}
|
||||
|
||||
iPresses = hPresses.Length;
|
||||
iTicks = iEndTick - iStartTick;
|
||||
iLastJunk = iEndTick - hPresses.Get(iPresses - 1, 1);
|
||||
|
||||
float PressesPerTick = (iPresses * 4.0) / float(iTicks);
|
||||
if(PressesPerTick >= 0.85)
|
||||
{
|
||||
CurStreak.iHyperJumps++;
|
||||
Player.iHyperJumps++;
|
||||
}
|
||||
|
||||
if(iNextJump != -1 && iNextJump <= 1 && (iLastJunk > 5 || iPresses <= 2) && hJump.fEndVel >= 285.0)
|
||||
{
|
||||
CurStreak.iHackJumps++;
|
||||
Player.iHackJumps++;
|
||||
}
|
||||
|
||||
int aGlobalJumps[3];
|
||||
Player.GetJumps(aGlobalJumps);
|
||||
aGlobalJumps[0] += aJumps[0];
|
||||
aGlobalJumps[1] += aJumps[1];
|
||||
aGlobalJumps[2] += aJumps[2];
|
||||
Player.SetJumps(aGlobalJumps);
|
||||
|
||||
int aStreakJumps[3];
|
||||
CurStreak.GetJumps(aStreakJumps);
|
||||
aStreakJumps[0] += aJumps[0];
|
||||
aStreakJumps[1] += aJumps[1];
|
||||
aStreakJumps[2] += aJumps[2];
|
||||
CurStreak.SetJumps(aStreakJumps);
|
||||
|
||||
int iStreakJumps = CurStreak.iJumps;
|
||||
if(iStreakJumps >= 6)
|
||||
{
|
||||
float HackRatio = CurStreak.iHackJumps / float(iStreakJumps);
|
||||
if(HackRatio >= 0.85 && !Player.bFlagged)
|
||||
{
|
||||
Player.bFlagged = true;
|
||||
NotifyAdmins(client, "bhop hack streak");
|
||||
// KickClient(client, "Turn off your hack!");
|
||||
return;
|
||||
}
|
||||
|
||||
float HyperRatio = CurStreak.iHyperJumps / float(iStreakJumps);
|
||||
if(HyperRatio >= 0.85 && !Player.bFlagged)
|
||||
{
|
||||
Player.bFlagged = true;
|
||||
NotifyAdmins(client, "hyperscroll streak");
|
||||
CPrintToChat(client, "{green}[SM]{default} Turn off your bhop macro/script or hyperscroll!");
|
||||
CPrintToChat(client, "{green}[SM]{default} Your bhop has been {red}turned off{default} until the end of the map.");
|
||||
LimitBhop(client, true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
int iGlobalJumps = Player.iJumps;
|
||||
if(iGlobalJumps >= 25)
|
||||
{
|
||||
float HackRatio = Player.iHackJumps / float(iGlobalJumps);
|
||||
if(HackRatio >= 0.65 && !Player.bFlagged)
|
||||
{
|
||||
Player.bFlagged = true;
|
||||
NotifyAdmins(client, "bhop hack global");
|
||||
// KickClient(client, "Turn off your hack!");
|
||||
return;
|
||||
}
|
||||
|
||||
float HyperRatio = Player.iHyperJumps / float(iGlobalJumps);
|
||||
if(HyperRatio >= 0.50 && !Player.bFlagged)
|
||||
{
|
||||
Player.bFlagged = true;
|
||||
NotifyAdmins(client, "hyperscroll global");
|
||||
CPrintToChat(client, "{green}[SM]{default} Turn off your bhop macro/script or hyperscroll!");
|
||||
CPrintToChat(client, "{green}[SM]{default} Your bhop has been {red}turned off{default} until the end of the map.");
|
||||
LimitBhop(client, true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
NotifyAdmins(int client, const char[] sReason)
|
||||
{
|
||||
for(int i = 1; i <= MaxClients; i++)
|
||||
{
|
||||
if(IsClientInGame(i) && !IsFakeClient(i) && CheckCommandAccess(i, "sm_stats", ADMFLAG_GENERIC))
|
||||
{
|
||||
CPrintToChat(i, "{green}[SM]{default} %L has been detected for {red}%s{default}, please check your console!", client, sReason)
|
||||
PrintStats(i, client);
|
||||
PrintStreak(i, client, -1, true);
|
||||
}
|
||||
}
|
||||
|
||||
Forward_OnDetected(client, sReason, g_sStats)
|
||||
}
|
||||
|
||||
public Action Command_Stats(int client, int argc)
|
||||
{
|
||||
if(argc < 1 || argc > 2)
|
||||
{
|
||||
ReplyToCommand(client, "[SM] Usage: sm_stats <#userid|name>");
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
char sArg[65];
|
||||
char sTargetName[MAX_TARGET_LENGTH];
|
||||
int iTargets[MAXPLAYERS];
|
||||
int iTargetCount;
|
||||
bool bIsML;
|
||||
|
||||
GetCmdArg(1, sArg, sizeof(sArg));
|
||||
|
||||
if((iTargetCount = ProcessTargetString(sArg, client, iTargets, MAXPLAYERS, COMMAND_FILTER_NO_MULTI | COMMAND_FILTER_NO_IMMUNITY, sTargetName, sizeof(sTargetName), bIsML)) <= 0)
|
||||
{
|
||||
ReplyToTargetError(client, iTargetCount);
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
for(int i = 0; i < iTargetCount; i++)
|
||||
{
|
||||
PrintStats(client, iTargets[i]);
|
||||
}
|
||||
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
void PrintStats(int client, int iTarget)
|
||||
{
|
||||
PrintToConsole(client, "[SM] Bunnyhop stats for %L", iTarget);
|
||||
|
||||
CPlayer Player = g_aPlayers[iTarget];
|
||||
ArrayList hStreaks = Player.hStreaks;
|
||||
CStreak hStreak = Player.hStreak;
|
||||
int iStreaks = hStreaks.Length;
|
||||
|
||||
// Try showing latest valid streak
|
||||
if(!hStreak.bValid)
|
||||
{
|
||||
if(iStreaks)
|
||||
hStreak = hStreaks.Get(iStreaks - 1);
|
||||
}
|
||||
|
||||
int iGlobalJumps = Player.iJumps;
|
||||
float HyperRatio = Player.iHyperJumps / float(iGlobalJumps);
|
||||
float HackRatio = Player.iHackJumps / float(iGlobalJumps);
|
||||
|
||||
PrintToConsole(client, "Global jumps: %d | Hyper?: %.1f%% | Hack?: %.1f%%",
|
||||
iGlobalJumps, HyperRatio * 100.0, HackRatio * 100.0);
|
||||
|
||||
|
||||
int aGlobalJumps[3];
|
||||
Player.GetJumps(aGlobalJumps);
|
||||
|
||||
PrintToConsole(client, "Global jumps perf group (1 2 +): %1.f%% %1.f%% %1.f%%",
|
||||
(aGlobalJumps[0] / float(iGlobalJumps)) * 100.0,
|
||||
(aGlobalJumps[1] / float(iGlobalJumps)) * 100.0,
|
||||
(aGlobalJumps[2] / float(iGlobalJumps)) * 100.0);
|
||||
|
||||
|
||||
PrintToConsole(client, "more to come...");
|
||||
}
|
||||
|
||||
public Action Command_Streak(int client, int argc)
|
||||
{
|
||||
if(argc < 1 || argc > 2)
|
||||
{
|
||||
ReplyToCommand(client, "[SM] Usage: sm_streak <#userid|name> [streak]");
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
char sArg[65];
|
||||
char sArg2[8];
|
||||
char sTargetName[MAX_TARGET_LENGTH];
|
||||
int iTargets[MAXPLAYERS];
|
||||
int iTargetCount;
|
||||
bool bIsML;
|
||||
int iStreak = -1;
|
||||
|
||||
GetCmdArg(1, sArg, sizeof(sArg));
|
||||
|
||||
if(argc == 2)
|
||||
{
|
||||
GetCmdArg(2, sArg2, sizeof(sArg2));
|
||||
iStreak = StringToInt(sArg2);
|
||||
}
|
||||
|
||||
if((iTargetCount = ProcessTargetString(sArg, client, iTargets, MAXPLAYERS, COMMAND_FILTER_NO_MULTI | COMMAND_FILTER_NO_IMMUNITY, sTargetName, sizeof(sTargetName), bIsML)) <= 0)
|
||||
{
|
||||
ReplyToTargetError(client, iTargetCount);
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
for(int i = 0; i < iTargetCount; i++)
|
||||
{
|
||||
PrintStreak(client, iTargets[i], iStreak);
|
||||
}
|
||||
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
void PrintStreak(int client, int iTarget, int iStreak, bool bDetected=false)
|
||||
{
|
||||
g_sStats = "";
|
||||
|
||||
PrintToConsole(client, "[SM] Bunnyhop streak %d for %L", iStreak, iTarget);
|
||||
|
||||
if (bDetected)
|
||||
Format(g_sStats, sizeof(g_sStats), "%sBunnyhop streak %d for %L\n",
|
||||
g_sStats, iStreak, iTarget);
|
||||
|
||||
CPlayer Player = g_aPlayers[iTarget];
|
||||
ArrayList hStreaks = Player.hStreaks;
|
||||
CStreak hStreak = Player.hStreak;
|
||||
int iStreaks = hStreaks.Length;
|
||||
|
||||
// Try showing latest valid streak
|
||||
if(iStreak <= 0 && !hStreak.bValid)
|
||||
{
|
||||
if(iStreaks)
|
||||
hStreak = hStreaks.Get(iStreaks - 1);
|
||||
}
|
||||
else if(iStreak > 0)
|
||||
{
|
||||
if(iStreak > MAX_STREAKS)
|
||||
{
|
||||
ReplyToCommand(client, "[SM] Streak is out of bounds (max. %d)!", MAX_STREAKS);
|
||||
return;
|
||||
}
|
||||
|
||||
int iIndex = iStreaks - iStreak;
|
||||
if(iIndex < 0)
|
||||
{
|
||||
ReplyToCommand(client, "[SM] Only %d streaks are available for this player right now!", iStreaks);
|
||||
return;
|
||||
}
|
||||
|
||||
hStreak = hStreaks.Get(iIndex);
|
||||
}
|
||||
|
||||
int iStreakJumps = hStreak.iJumps;
|
||||
float HyperRatio = hStreak.iHyperJumps / float(iStreakJumps);
|
||||
float HackRatio = hStreak.iHackJumps / float(iStreakJumps);
|
||||
|
||||
PrintToConsole(client, "Streak jumps: %d | Hyper?: %.1f%% | Hack?: %.1f%%",
|
||||
iStreakJumps, HyperRatio * 100.0, HackRatio * 100.0);
|
||||
|
||||
if (bDetected)
|
||||
Format(g_sStats, sizeof(g_sStats), "%sStreak jumps: %d | Hyper?: %.1f%% | Hack?: %.1f%%\n",
|
||||
g_sStats, iStreakJumps, HyperRatio * 100.0, HackRatio * 100.0);
|
||||
|
||||
int aStreakJumps[3];
|
||||
hStreak.GetJumps(aStreakJumps);
|
||||
|
||||
PrintToConsole(client, "Streak jumps perf group (1 2 +): %1.f%% %1.f%% %1.f%%",
|
||||
(aStreakJumps[0] / float(iStreakJumps)) * 100.0,
|
||||
(aStreakJumps[1] / float(iStreakJumps)) * 100.0,
|
||||
(aStreakJumps[2] / float(iStreakJumps)) * 100.0);
|
||||
|
||||
if (bDetected)
|
||||
Format(g_sStats, sizeof(g_sStats), "%sStreak jumps perf group (1 2 +): %1.f%% %1.f%% %1.f%%\n",
|
||||
g_sStats,
|
||||
(aStreakJumps[0] / float(iStreakJumps)) * 100.0,
|
||||
(aStreakJumps[1] / float(iStreakJumps)) * 100.0,
|
||||
(aStreakJumps[2] / float(iStreakJumps)) * 100.0);
|
||||
|
||||
PrintToConsole(client, "#%2s %5s %7s %7s %5s %5s %8s %4s %6s %s",
|
||||
"id", " diff", " invel", " outvel", " gain", " comb", " avgdist", " num", " avg+-", "pattern");
|
||||
|
||||
if (bDetected)
|
||||
Format(g_sStats, sizeof(g_sStats), "%s#%2s %5s %7s %7s %5s %5s %8s %4s %6s %s\n",
|
||||
g_sStats, "id", " diff", " invel", " outvel", " gain", " comb", " avgdist", " num", " avg+-", "pattern");
|
||||
|
||||
ArrayList hJumps = hStreak.hJumps;
|
||||
float fPrevVel = 0.0;
|
||||
int iPrevEndTick = -1;
|
||||
|
||||
for(int i = 0; i < hJumps.Length; i++)
|
||||
{
|
||||
CJump hJump = hJumps.Get(i);
|
||||
ArrayList hPresses = hJump.hPresses;
|
||||
|
||||
float fInVel = hJump.fStartVel;
|
||||
float fOutVel = hJump.fEndVel;
|
||||
int iEndTick = hJump.iEndTick;
|
||||
|
||||
static char sPattern[256];
|
||||
int iPatternLen = 0;
|
||||
int iPrevTick = -1;
|
||||
int iTicks;
|
||||
|
||||
if(iPrevEndTick != -1)
|
||||
{
|
||||
iTicks = hJump.iStartTick - iPrevEndTick;
|
||||
for(int k = 0; k < iTicks && k < 16; k++)
|
||||
sPattern[iPatternLen++] = '|';
|
||||
}
|
||||
|
||||
float fAvgDist = 0.0;
|
||||
float fAvgDownUp = 0.0;
|
||||
|
||||
int iPresses = hPresses.Length;
|
||||
for(int j = 0; j < iPresses; j++)
|
||||
{
|
||||
int aJunkJump[2];
|
||||
hPresses.GetArray(j, aJunkJump);
|
||||
|
||||
if(iPrevTick != -1)
|
||||
{
|
||||
iTicks = aJunkJump[0] - iPrevTick;
|
||||
for(int k = 0; k < iTicks && k < 16; k++)
|
||||
sPattern[iPatternLen++] = '.';
|
||||
|
||||
fAvgDist += iTicks;
|
||||
}
|
||||
|
||||
sPattern[iPatternLen++] = '^';
|
||||
|
||||
iTicks = aJunkJump[1] - aJunkJump[0];
|
||||
for(int k = 0; k < iTicks && k < 16; k++)
|
||||
sPattern[iPatternLen++] = ',';
|
||||
|
||||
fAvgDownUp += iTicks;
|
||||
|
||||
sPattern[iPatternLen++] = 'v';
|
||||
|
||||
iPrevTick = aJunkJump[1];
|
||||
}
|
||||
|
||||
fAvgDist /= iPresses;
|
||||
fAvgDownUp /= iPresses;
|
||||
|
||||
iTicks = iEndTick - iPrevTick;
|
||||
for(int k = 0; k < iTicks && k < 16; k++)
|
||||
sPattern[iPatternLen++] = '.';
|
||||
|
||||
sPattern[iPatternLen++] = '|';
|
||||
sPattern[iPatternLen++] = '\0';
|
||||
|
||||
if(fPrevVel == 0.0)
|
||||
fPrevVel = fInVel;
|
||||
|
||||
PrintToConsole(client, "#%2d %4d%% %7.1f %7.1f %4d%% %4d%% %8.2f %4d %6.2f %s",
|
||||
i,
|
||||
fPrevVel == 0.0 ? 100 : RoundFloat((fInVel / fPrevVel) * 100.0 - 100.0),
|
||||
fInVel,
|
||||
fOutVel,
|
||||
fInVel == 0.0 ? 100 : RoundFloat((fOutVel / fInVel) * 100.0 - 100.0),
|
||||
fPrevVel == 0.0 ? 100 : RoundFloat((fOutVel / fPrevVel) * 100.0 - 100.0),
|
||||
fAvgDist,
|
||||
iPresses,
|
||||
fAvgDownUp,
|
||||
sPattern);
|
||||
|
||||
if (bDetected)
|
||||
Format(g_sStats, sizeof(g_sStats), "%s#%2d %4d%% %7.1f %7.1f %4d%% %4d%% %8.2f %4d %6.2f %s\n",
|
||||
g_sStats,
|
||||
i,
|
||||
fPrevVel == 0.0 ? 100 : RoundFloat((fInVel / fPrevVel) * 100.0 - 100.0),
|
||||
fInVel,
|
||||
fOutVel,
|
||||
fInVel == 0.0 ? 100 : RoundFloat((fOutVel / fInVel) * 100.0 - 100.0),
|
||||
fPrevVel == 0.0 ? 100 : RoundFloat((fOutVel / fPrevVel) * 100.0 - 100.0),
|
||||
fAvgDist,
|
||||
iPresses,
|
||||
fAvgDownUp,
|
||||
sPattern);
|
||||
|
||||
iPrevEndTick = iEndTick;
|
||||
fPrevVel = fOutVel;
|
||||
}
|
||||
}
|
||||
|
||||
bool Forward_OnDetected(int client, const char[] reason, const char[] stats)
|
||||
{
|
||||
Call_StartForward(g_hOnClientDetected);
|
||||
Call_PushCell(client);
|
||||
Call_PushString(reason);
|
||||
Call_PushString(stats);
|
||||
Call_Finish();
|
||||
|
||||
g_sStats = "";
|
||||
}
|
118
AntiBhopCheat/scripting/CJump.inc
Normal file
118
AntiBhopCheat/scripting/CJump.inc
Normal file
@ -0,0 +1,118 @@
|
||||
#if defined _class_cjump_
|
||||
#endinput
|
||||
#endif
|
||||
#define _class_cjump_
|
||||
|
||||
methodmap CJump < Basic
|
||||
{
|
||||
public CJump()
|
||||
{
|
||||
Basic myclass = new Basic();
|
||||
|
||||
myclass.SetInt("iStartTick", -1);
|
||||
myclass.SetInt("iEndTick", -1);
|
||||
myclass.SetFloat("fStartVel", 0.0);
|
||||
myclass.SetFloat("fEndVel", 0.0);
|
||||
|
||||
myclass.SetInt("iPrevJump", -1);
|
||||
myclass.SetInt("iNextJump", -1);
|
||||
|
||||
myclass.SetHandle("hPresses", new ArrayList(2));
|
||||
|
||||
return view_as<CJump>(myclass);
|
||||
}
|
||||
|
||||
property int iStartTick
|
||||
{
|
||||
public get()
|
||||
{
|
||||
return this.GetInt("iStartTick");
|
||||
}
|
||||
public set(int value)
|
||||
{
|
||||
this.SetInt("iStartTick", value);
|
||||
}
|
||||
}
|
||||
|
||||
property int iEndTick
|
||||
{
|
||||
public get()
|
||||
{
|
||||
return this.GetInt("iEndTick");
|
||||
}
|
||||
public set(int value)
|
||||
{
|
||||
this.SetInt("iEndTick", value);
|
||||
}
|
||||
}
|
||||
|
||||
property float fStartVel
|
||||
{
|
||||
public get()
|
||||
{
|
||||
return this.GetFloat("fStartVel");
|
||||
}
|
||||
public set(float value)
|
||||
{
|
||||
this.SetFloat("fStartVel", value);
|
||||
}
|
||||
}
|
||||
|
||||
property float fEndVel
|
||||
{
|
||||
public get()
|
||||
{
|
||||
return this.GetFloat("fEndVel");
|
||||
}
|
||||
public set(float value)
|
||||
{
|
||||
this.SetFloat("fEndVel", value);
|
||||
}
|
||||
}
|
||||
|
||||
property int iPrevJump
|
||||
{
|
||||
public get()
|
||||
{
|
||||
return this.GetInt("iPrevJump");
|
||||
}
|
||||
public set(int value)
|
||||
{
|
||||
this.SetInt("iPrevJump", value);
|
||||
}
|
||||
}
|
||||
|
||||
property int iNextJump
|
||||
{
|
||||
public get()
|
||||
{
|
||||
return this.GetInt("iNextJump");
|
||||
}
|
||||
public set(int value)
|
||||
{
|
||||
this.SetInt("iNextJump", value);
|
||||
}
|
||||
}
|
||||
|
||||
property ArrayList hPresses
|
||||
{
|
||||
public get()
|
||||
{
|
||||
return view_as<ArrayList>(this.GetHandle("hPresses"));
|
||||
}
|
||||
public set(ArrayList value)
|
||||
{
|
||||
this.SetHandle("hPresses", value);
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose(bool disposemembers=true)
|
||||
{
|
||||
if(disposemembers)
|
||||
{
|
||||
delete this.hPresses;
|
||||
}
|
||||
|
||||
delete this;
|
||||
}
|
||||
}
|
141
AntiBhopCheat/scripting/CPlayer.inc
Normal file
141
AntiBhopCheat/scripting/CPlayer.inc
Normal file
@ -0,0 +1,141 @@
|
||||
#if defined _class_cplayer_
|
||||
#endinput
|
||||
#endif
|
||||
#define _class_cplayer_
|
||||
|
||||
methodmap CPlayer < Basic
|
||||
{
|
||||
public CPlayer(int client)
|
||||
{
|
||||
Basic myclass = new Basic();
|
||||
|
||||
myclass.SetInt("iClient", client);
|
||||
myclass.SetBool("bFlagged", false);
|
||||
|
||||
myclass.SetInt("iJumps", 0);
|
||||
myclass.SetInt("iHyperJumps", 0);
|
||||
myclass.SetInt("iHackJumps", 0);
|
||||
myclass.SetArray("aJumps", {0, 0, 0}, 3);
|
||||
|
||||
myclass.SetHandle("hStreak", new CStreak());
|
||||
myclass.SetHandle("hStreaks", new ArrayList(1));
|
||||
|
||||
return view_as<CPlayer>(myclass);
|
||||
}
|
||||
|
||||
property int iClient
|
||||
{
|
||||
public get()
|
||||
{
|
||||
return this.GetInt("iClient");
|
||||
}
|
||||
public set(int value)
|
||||
{
|
||||
this.SetInt("iClient", value);
|
||||
}
|
||||
}
|
||||
|
||||
property bool bFlagged
|
||||
{
|
||||
public get()
|
||||
{
|
||||
return this.GetBool("bFlagged");
|
||||
}
|
||||
public set(bool value)
|
||||
{
|
||||
this.SetBool("bFlagged", value);
|
||||
}
|
||||
}
|
||||
|
||||
property int iJumps
|
||||
{
|
||||
public get()
|
||||
{
|
||||
return this.GetInt("iJumps");
|
||||
}
|
||||
public set(int value)
|
||||
{
|
||||
this.SetInt("iJumps", value);
|
||||
}
|
||||
}
|
||||
|
||||
property int iHyperJumps
|
||||
{
|
||||
public get()
|
||||
{
|
||||
return this.GetInt("iHyperJumps");
|
||||
}
|
||||
public set(int value)
|
||||
{
|
||||
this.SetInt("iHyperJumps", value);
|
||||
}
|
||||
}
|
||||
|
||||
property int iHackJumps
|
||||
{
|
||||
public get()
|
||||
{
|
||||
return this.GetInt("iHackJumps");
|
||||
}
|
||||
public set(int value)
|
||||
{
|
||||
this.SetInt("iHackJumps", value);
|
||||
}
|
||||
}
|
||||
|
||||
public void GetJumps(int value[3])
|
||||
{
|
||||
this.GetArray("aJumps", value, sizeof(value));
|
||||
}
|
||||
|
||||
public void SetJumps(const int value[3])
|
||||
{
|
||||
this.SetArray("aJumps", value, sizeof(value));
|
||||
}
|
||||
|
||||
property CStreak hStreak
|
||||
{
|
||||
public get()
|
||||
{
|
||||
return view_as<CStreak>(this.GetHandle("hStreak"));
|
||||
}
|
||||
public set(CStreak value)
|
||||
{
|
||||
this.SetHandle("hStreak", value);
|
||||
}
|
||||
}
|
||||
|
||||
property ArrayList hStreaks
|
||||
{
|
||||
public get()
|
||||
{
|
||||
return view_as<ArrayList>(this.GetHandle("hStreaks"));
|
||||
}
|
||||
public set(ArrayList value)
|
||||
{
|
||||
this.SetHandle("hStreaks", value);
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose(bool disposemembers=true)
|
||||
{
|
||||
if(disposemembers)
|
||||
{
|
||||
ArrayList hStreaks = this.hStreaks;
|
||||
|
||||
CStreak hStreak;
|
||||
for(int i = 0; i < hStreaks.Length; i++)
|
||||
{
|
||||
hStreak = view_as<CStreak>(hStreaks.Get(i));
|
||||
hStreak.Dispose();
|
||||
}
|
||||
|
||||
delete hStreaks;
|
||||
|
||||
if(this.hStreak != hStreak)
|
||||
this.hStreak.Dispose();
|
||||
}
|
||||
|
||||
delete this;
|
||||
}
|
||||
}
|
163
AntiBhopCheat/scripting/CStreak.inc
Normal file
163
AntiBhopCheat/scripting/CStreak.inc
Normal file
@ -0,0 +1,163 @@
|
||||
#if defined _class_cstreak_
|
||||
#endinput
|
||||
#endif
|
||||
#define _class_cstreak_
|
||||
|
||||
methodmap CStreak < Basic
|
||||
{
|
||||
public CStreak()
|
||||
{
|
||||
Basic myclass = new Basic();
|
||||
|
||||
myclass.SetBool("bValid", false);
|
||||
myclass.SetInt("iStartTick", -1);
|
||||
myclass.SetInt("iEndTick", -1);
|
||||
myclass.SetFloat("fStartVel", 0.0);
|
||||
myclass.SetFloat("fEndVel", 0.0);
|
||||
|
||||
myclass.SetInt("iJumps", 0);
|
||||
myclass.SetInt("iHyperJumps", 0);
|
||||
myclass.SetInt("iHackJumps", 0);
|
||||
myclass.SetArray("aJumps", {0, 0, 0}, 3);
|
||||
|
||||
myclass.SetHandle("hJumps", new ArrayList(1));
|
||||
|
||||
return view_as<CStreak>(myclass);
|
||||
}
|
||||
|
||||
property bool bValid
|
||||
{
|
||||
public get()
|
||||
{
|
||||
return this.GetBool("bValid");
|
||||
}
|
||||
public set(bool value)
|
||||
{
|
||||
this.SetBool("bValid", value);
|
||||
}
|
||||
}
|
||||
|
||||
property int iStartTick
|
||||
{
|
||||
public get()
|
||||
{
|
||||
return this.GetInt("iStartTick");
|
||||
}
|
||||
public set(int value)
|
||||
{
|
||||
this.SetInt("iStartTick", value);
|
||||
}
|
||||
}
|
||||
|
||||
property int iEndTick
|
||||
{
|
||||
public get()
|
||||
{
|
||||
return this.GetInt("iEndTick");
|
||||
}
|
||||
public set(int value)
|
||||
{
|
||||
this.SetInt("iEndTick", value);
|
||||
}
|
||||
}
|
||||
|
||||
property float fStartVel
|
||||
{
|
||||
public get()
|
||||
{
|
||||
return this.GetFloat("fStartVel");
|
||||
}
|
||||
public set(float value)
|
||||
{
|
||||
this.SetFloat("fStartVel", value);
|
||||
}
|
||||
}
|
||||
|
||||
property float fEndVel
|
||||
{
|
||||
public get()
|
||||
{
|
||||
return this.GetFloat("fEndVel");
|
||||
}
|
||||
public set(float value)
|
||||
{
|
||||
this.SetFloat("fEndVel", value);
|
||||
}
|
||||
}
|
||||
|
||||
property int iJumps
|
||||
{
|
||||
public get()
|
||||
{
|
||||
return this.GetInt("iJumps");
|
||||
}
|
||||
public set(int value)
|
||||
{
|
||||
this.SetInt("iJumps", value);
|
||||
}
|
||||
}
|
||||
|
||||
property int iHyperJumps
|
||||
{
|
||||
public get()
|
||||
{
|
||||
return this.GetInt("iHyperJumps");
|
||||
}
|
||||
public set(int value)
|
||||
{
|
||||
this.SetInt("iHyperJumps", value);
|
||||
}
|
||||
}
|
||||
|
||||
property int iHackJumps
|
||||
{
|
||||
public get()
|
||||
{
|
||||
return this.GetInt("iHackJumps");
|
||||
}
|
||||
public set(int value)
|
||||
{
|
||||
this.SetInt("iHackJumps", value);
|
||||
}
|
||||
}
|
||||
|
||||
public void GetJumps(int value[3])
|
||||
{
|
||||
this.GetArray("aJumps", value, sizeof(value));
|
||||
}
|
||||
|
||||
public void SetJumps(const int value[3])
|
||||
{
|
||||
this.SetArray("aJumps", value, sizeof(value));
|
||||
}
|
||||
|
||||
property ArrayList hJumps
|
||||
{
|
||||
public get()
|
||||
{
|
||||
return view_as<ArrayList>(this.GetHandle("hJumps"));
|
||||
}
|
||||
public set(ArrayList value)
|
||||
{
|
||||
this.SetHandle("hJumps", value);
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose(bool disposemembers=true)
|
||||
{
|
||||
if(disposemembers)
|
||||
{
|
||||
ArrayList hJumps = this.hJumps;
|
||||
|
||||
for(int i = 0; i < hJumps.Length; i++)
|
||||
{
|
||||
CJump hJump = view_as<CJump>(hJumps.Get(i));
|
||||
hJump.Dispose();
|
||||
}
|
||||
|
||||
delete hJumps;
|
||||
}
|
||||
|
||||
delete this;
|
||||
}
|
||||
}
|
6
AntiBhopCheat/scripting/include/AntiBhopCheat.inc
Normal file
6
AntiBhopCheat/scripting/include/AntiBhopCheat.inc
Normal file
@ -0,0 +1,6 @@
|
||||
#if defined _AntiBhopCheat_Included
|
||||
#endinput
|
||||
#endif
|
||||
#define _AntiBhopCheat_Included
|
||||
|
||||
forward void AntiBhopCheat_OnClientDetected(int client, char[] sReason, char[] sStats);
|
Loading…
Reference in New Issue
Block a user