#pragma semicolon 1 #pragma newdecls required #include #include #include #define PLUGIN_AUTHOR "jenz" #define PLUGIN_VERSION "1.1" public Plugin myinfo = { name = "nosteam bhop blocker", author = PLUGIN_AUTHOR, description = "handicaps nosteamers from bhopping (they mostly cheat) ", version = PLUGIN_VERSION, url = "" }; bool bhop_restricted_nosteamer[MAXPLAYERS + 1]; int buttons_old[MAXPLAYERS + 1]; int flags_old[MAXPLAYERS + 1]; Database g_hDatabase; ConVar g_hCvar_TriggerVelocity; ConVar g_hCvar_SlowedVelocity; public void OnPluginStart() { g_hCvar_TriggerVelocity = CreateConVar("sm_nosteam_bhop_trigger_velocity", "300", "Horizontal velocity at which nosteamers will be slowed during bhop.", FCVAR_NONE, true, 0.0); g_hCvar_SlowedVelocity = CreateConVar("sm_nosteam_bhop_slowed_velocity", "200", "Horizontal velocity which nosteamers will be slowed to.", FCVAR_NONE, true, 0.0); AutoExecConfig(); } public void OnConfigsExecuted() { if (!g_hDatabase) Database.Connect(SQL_OnDatabaseConnect, "bot_surfing"); } public void SQL_OnDatabaseConnect(Database db, const char[] error, any data) { if(!db || strlen(error)) { LogError("Database error: %s", error); return; } g_hDatabase = db; char sQuery[512]; Format(sQuery, sizeof(sQuery), "CREATE TABLE IF NOT EXISTS bhop_whitelist (`steam_auth` VARCHAR(32) NOT NULL, `name` VARCHAR(64) NOT NULL, PRIMARY KEY (`steam_auth`))"); g_hDatabase.Query(SQL_OnConnectFinished, sQuery, _, DBPrio_High); } public void SQL_OnConnectFinished(Database db, DBResultSet results, const char[] error, any data) { if(!db || strlen(error)) { LogError("Database error: %s", error); return; } for(int i = 1; i <= MaxClients; i++) { if (IsClientConnected(i) && IsClientAuthorized(i)) { char sAuthID[32]; GetClientAuthId(i, AuthId_Steam2, sAuthID, sizeof(sAuthID)); OnClientAuthorized(i, sAuthID); } } } public void OnClientAuthorized(int client, const char[] sAuthID) { if (!IsFakeClient(client) && !IsClientSourceTV(client) && !PM_IsPlayerSteam(client)) { bhop_restricted_nosteamer[client] = true; buttons_old[client] = 0; flags_old[client] = 0; char sQuery[512]; Format(sQuery, sizeof(sQuery), "SELECT * FROM bhop_whitelist WHERE steam_auth = '%s'", sAuthID); g_hDatabase.Query(SQL_OnQueryCompleted, sQuery, GetClientSerial(client)); } else bhop_restricted_nosteamer[client] = false; } public void SQL_OnQueryCompleted(Database db, DBResultSet results, const char[] error, any data) { if (!db || strlen(error)) { LogError("Query error: %s", error); return; } int client; if ((client = GetClientFromSerial(data)) == 0) return; if (results.RowCount && results.FetchRow()) { int iFieldNum; results.FieldNameToNum("name", iFieldNum); char sName[MAX_NAME_LENGTH]; results.FetchString(iFieldNum, sName, sizeof(sName)); bhop_restricted_nosteamer[client] = false; LogMessage("%L was found as \'%s\' on the whitelist and therefore will be allowed to bhop", client, sName); } } public void OnClientDisconnect(int client) { bhop_restricted_nosteamer[client] = false; buttons_old[client] = 0; flags_old[client] = 0; } public void OnPlayerRunCmdPost(int client, int buttons, int impulse, const float vel[3], const float angles[3], int weapon, int subtype, int cmdnum, int tickcount, int seed, const int mouse[2]) { if (!IsValidClient(client) || !IsPlayerAlive(client) || !bhop_restricted_nosteamer[client]) return; if (!(buttons_old[client] & IN_JUMP) && (!(buttons & IN_JUMP))) { flags_old[client] = GetEntityFlags(client); return; } if (buttons_old[client] & IN_JUMP) { if (!(buttons & IN_JUMP)) if (GetEntityFlags(client) & FL_ONGROUND) buttons_old[client] = buttons; return; } if (!(flags_old[client] & FL_ONGROUND)) return; float vVel[3]; GetEntPropVector(client, Prop_Data, "m_vecVelocity", vVel); float fVelocity = SquareRoot(Pow(vVel[0], 2.0) + Pow(vVel[1], 2.0)); if (fVelocity > g_hCvar_TriggerVelocity.FloatValue) { float fNormalized[3]; fNormalized[0] = vVel[0] / fVelocity; fNormalized[1] = vVel[1] / fVelocity; fNormalized[2] = 0.0; float fTargetVelocity = g_hCvar_SlowedVelocity.FloatValue; float fFinal[3]; fFinal[0] = fNormalized[0] * fTargetVelocity; fFinal[1] = fNormalized[1] * fTargetVelocity; fFinal[2] = vVel[2]; TeleportEntity(client, NULL_VECTOR, NULL_VECTOR, fFinal); } buttons_old[client] = buttons; } stock int IsValidClient(int client, bool nobots = true) { if (client <= 0 || client > MaxClients || !IsClientConnected(client) || (nobots && IsFakeClient(client))) return false; return IsClientInGame(client); }