/*
* shavit's Timer - Core
* by: shavit, rtldg, KiD Fearless, GAMMA CASE, Technoblazed, carnifex, ofirgall, Nairda, Extan, rumour, olivia, Nickelony, sh4hrazad, BoomShotKapow, strafe
*
* This file is part of shavit's Timer (https://github.com/shavitush/bhoptimer)
*
*
* 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 .
*
*/
#include
#include
#include
#include
#include
#include
#include
#define DEBUG 0
#include
#undef REQUIRE_PLUGIN
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#pragma newdecls required
#pragma semicolon 1
// game type (CS:S/CS:GO/TF2)
EngineVersion gEV_Type = Engine_Unknown;
bool gB_Protobuf = false;
// hook stuff
DynamicHook gH_AcceptInput; // used for hooking player_speedmod's AcceptInput
DynamicHook gH_TeleportDhook = null;
Address gI_TF2PreventBunnyJumpingAddr = Address_Null;
// database handle
Database gH_SQL = null;
int gI_Driver = Driver_unknown;
// forwards
Handle gH_Forwards_Start = null;
Handle gH_Forwards_StartPre = null;
Handle gH_Forwards_Stop = null;
Handle gH_Forwards_StopPre = null;
Handle gH_Forwards_FinishPre = null;
Handle gH_Forwards_Finish = null;
Handle gH_Forwards_OnRestartPre = null;
Handle gH_Forwards_OnRestart = null;
Handle gH_Forwards_OnEndPre = null;
Handle gH_Forwards_OnEnd = null;
Handle gH_Forwards_OnPause = null;
Handle gH_Forwards_OnResume = null;
Handle gH_Forwards_OnStyleCommandPre = null;
Handle gH_Forwards_OnStyleChanged = null;
Handle gH_Forwards_OnTrackChanged = null;
Handle gH_Forwards_OnChatConfigLoaded = null;
Handle gH_Forwards_OnUserCmdPre = null;
Handle gH_Forwards_OnTimeIncrement = null;
Handle gH_Forwards_OnTimeIncrementPost = null;
Handle gH_Forwards_OnTimescaleChanged = null;
Handle gH_Forwards_OnTimeOffsetCalculated = null;
Handle gH_Forwards_OnProcessMovement = null;
Handle gH_Forwards_OnProcessMovementPost = null;
// player timer variables
timer_snapshot_t gA_Timers[MAXPLAYERS+1];
bool gB_Auto[MAXPLAYERS+1];
// 0 is in air, 1 or greater is on ground, -1 means client was on ground with zero...ish... velocity
int gI_FirstTouchedGroundForStartTimer[MAXPLAYERS+1];
int gI_LastTickcount[MAXPLAYERS+1];
// these are here until the compiler bug is fixed
float gF_PauseOrigin[MAXPLAYERS+1][3];
float gF_PauseAngles[MAXPLAYERS+1][3];
float gF_PauseVelocity[MAXPLAYERS+1][3];
// potentially temporary more effective hijack angles
int gI_HijackFrames[MAXPLAYERS+1];
float gF_HijackedAngles[MAXPLAYERS+1][2];
// used for offsets
float gF_SmallestDist[MAXPLAYERS + 1];
float gF_Origin[MAXPLAYERS + 1][2][3];
float gF_Fraction[MAXPLAYERS + 1];
// cookies
Handle gH_StyleCookie = null;
Handle gH_AutoBhopCookie = null;
Cookie gH_IHateMain = null;
// late load
bool gB_Late = false;
bool gB_Linux = false;
// modules
bool gB_Eventqueuefix = false;
bool gB_Zones = false;
bool gB_ReplayPlayback = false;
bool gB_Rankings = false;
bool gB_HUD = false;
bool gB_AdminMenu = false;
TopMenu gH_AdminMenu = null;
TopMenuObject gH_TimerCommands = INVALID_TOPMENUOBJECT;
// cvars
Convar gCV_Restart = null;
Convar gCV_Pause = null;
Convar gCV_PauseMovement = null;
Convar gCV_BlockPreJump = null;
Convar gCV_NoZAxisSpeed = null;
Convar gCV_VelocityTeleport = null;
Convar gCV_DefaultStyle = null;
Convar gCV_NoChatSound = null;
Convar gCV_SimplerLadders = null;
Convar gCV_UseOffsets = null;
Convar gCV_TimeInMessages;
Convar gCV_DebugOffsets = null;
Convar gCV_SaveIps = null;
Convar gCV_HijackTeleportAngles = null;
// cached cvars
int gI_DefaultStyle = 0;
bool gB_StyleCookies = true;
// table prefix
char gS_MySQLPrefix[32];
// server side
ConVar sv_accelerate = null;
ConVar sv_airaccelerate = null;
ConVar sv_autobunnyhopping = null;
ConVar sv_enablebunnyhopping = null;
ConVar sv_friction = null;
// chat settings
chatstrings_t gS_ChatStrings;
// misc cache
int gI_ClientProcessingMovement = 0;
bool gB_StopChatSound = false;
bool gB_HookedJump = false;
char gS_LogPath[PLATFORM_MAX_PATH];
char gS_DeleteMap[MAXPLAYERS+1][PLATFORM_MAX_PATH];
int gI_WipePlayerID[MAXPLAYERS+1];
char gS_Verification[MAXPLAYERS+1][8];
bool gB_CookiesRetrieved[MAXPLAYERS+1];
float gF_ZoneAiraccelerate[MAXPLAYERS+1];
float gF_ZoneSpeedLimit[MAXPLAYERS+1];
float gF_ZoneStartSpeedLimit[MAXPLAYERS+1];
int gI_LastPrintedSteamID[MAXPLAYERS+1];
// kz support
bool gB_KZMap[TRACKS_SIZE];
#include // down here to get includes from replay-playback & to inherit gB_ReplayPlayback
public Plugin myinfo =
{
name = "[shavit] Core",
author = "shavit, rtldg, KiD Fearless, GAMMA CASE, Technoblazed, carnifex, ofirgall, Nairda, Extan, rumour, olivia, Nickelony, sh4hrazad, BoomShotKapow, strafe",
description = "The core for shavit's bhop timer.",
version = SHAVIT_VERSION,
url = "https://github.com/shavitush/bhoptimer"
}
public APLRes AskPluginLoad2(Handle myself, bool late, char[] error, int err_max)
{
#if SOURCEMOD_V_MAJOR == 1 && SOURCEMOD_V_MINOR >= 11
#else
MarkNativeAsOptional("Int64ToString");
MarkNativeAsOptional("StringToInt64");
#endif
new Convar("shavit_core_log_sql", "0", "Whether to log SQL queries from the timer.", 0, true, 0.0, true, 1.0);
Bhopstats_CreateNatives();
Shavit_Style_Settings_Natives();
CreateNative("Shavit_CanPause", Native_CanPause);
CreateNative("Shavit_ChangeClientStyle", Native_ChangeClientStyle);
CreateNative("Shavit_FinishMap", Native_FinishMap);
CreateNative("Shavit_GetBhopStyle", Native_GetBhopStyle);
CreateNative("Shavit_GetChatStrings", Native_GetChatStrings);
CreateNative("Shavit_GetChatStringsStruct", Native_GetChatStringsStruct);
CreateNative("Shavit_GetClientJumps", Native_GetClientJumps);
CreateNative("Shavit_GetClientTime", Native_GetClientTime);
CreateNative("Shavit_GetClientTrack", Native_GetClientTrack);
CreateNative("Shavit_GetDatabase", Native_GetDatabase);
CreateNative("Shavit_GetPerfectJumps", Native_GetPerfectJumps);
CreateNative("Shavit_GetStrafeCount", Native_GetStrafeCount);
CreateNative("Shavit_GetSync", Native_GetSync);
CreateNative("Shavit_GetZoneOffset", Native_GetZoneOffset);
CreateNative("Shavit_GetDistanceOffset", Native_GetDistanceOffset);
CreateNative("Shavit_GetTimerStatus", Native_GetTimerStatus);
CreateNative("Shavit_IsKZMap", Native_IsKZMap);
CreateNative("Shavit_IsPaused", Native_IsPaused);
CreateNative("Shavit_IsPracticeMode", Native_IsPracticeMode);
CreateNative("Shavit_LoadSnapshot", Native_LoadSnapshot);
CreateNative("Shavit_LogMessage", Native_LogMessage);
CreateNative("Shavit_MarkKZMap", Native_MarkKZMap);
CreateNative("Shavit_PauseTimer", Native_PauseTimer);
CreateNative("Shavit_PrintToChat", Native_PrintToChat);
CreateNative("Shavit_PrintToChatAll", Native_PrintToChatAll);
CreateNative("Shavit_RestartTimer", Native_RestartTimer);
CreateNative("Shavit_ResumeTimer", Native_ResumeTimer);
CreateNative("Shavit_SaveSnapshot", Native_SaveSnapshot);
CreateNative("Shavit_SetPracticeMode", Native_SetPracticeMode);
CreateNative("Shavit_StartTimer", Native_StartTimer);
CreateNative("Shavit_StopChatSound", Native_StopChatSound);
CreateNative("Shavit_StopTimer", Native_StopTimer);
CreateNative("Shavit_GetClientTimescale", Native_GetClientTimescale);
CreateNative("Shavit_SetClientTimescale", Native_SetClientTimescale);
CreateNative("Shavit_GetAvgVelocity", Native_GetAvgVelocity);
CreateNative("Shavit_GetMaxVelocity", Native_GetMaxVelocity);
CreateNative("Shavit_SetAvgVelocity", Native_SetAvgVelocity);
CreateNative("Shavit_SetMaxVelocity", Native_SetMaxVelocity);
CreateNative("Shavit_ShouldProcessFrame", Native_ShouldProcessFrame);
CreateNative("Shavit_GotoEnd", Native_GotoEnd);
CreateNative("Shavit_UpdateLaggedMovement", Native_UpdateLaggedMovement);
CreateNative("Shavit_PrintSteamIDOnce", Native_PrintSteamIDOnce);
// registers library, check "bool LibraryExists(const char[] name)" in order to use with other plugins
RegPluginLibrary("shavit");
gB_Late = late;
return APLRes_Success;
}
public void OnPluginStart()
{
// forwards
gH_Forwards_Start = CreateGlobalForward("Shavit_OnStart", ET_Ignore, Param_Cell, Param_Cell);
gH_Forwards_StartPre = CreateGlobalForward("Shavit_OnStartPre", ET_Event, Param_Cell, Param_Cell, Param_CellByRef);
gH_Forwards_Stop = CreateGlobalForward("Shavit_OnStop", ET_Event, Param_Cell, Param_Cell);
gH_Forwards_StopPre = CreateGlobalForward("Shavit_OnStopPre", ET_Event, Param_Cell, Param_Cell);
gH_Forwards_FinishPre = CreateGlobalForward("Shavit_OnFinishPre", ET_Hook, Param_Cell, Param_Array);
gH_Forwards_Finish = CreateGlobalForward("Shavit_OnFinish", ET_Event, Param_Cell, Param_Cell, Param_Cell, Param_Cell, Param_Cell, Param_Cell, Param_Cell, Param_Cell, Param_Cell, Param_Cell, Param_Cell, Param_Cell);
gH_Forwards_OnRestartPre = CreateGlobalForward("Shavit_OnRestartPre", ET_Event, Param_Cell, Param_Cell);
gH_Forwards_OnRestart = CreateGlobalForward("Shavit_OnRestart", ET_Ignore, Param_Cell, Param_Cell);
gH_Forwards_OnEndPre = CreateGlobalForward("Shavit_OnEndPre", ET_Event, Param_Cell, Param_Cell);
gH_Forwards_OnEnd = CreateGlobalForward("Shavit_OnEnd", ET_Event, Param_Cell, Param_Cell);
gH_Forwards_OnPause = CreateGlobalForward("Shavit_OnPause", ET_Event, Param_Cell, Param_Cell);
gH_Forwards_OnResume = CreateGlobalForward("Shavit_OnResume", ET_Event, Param_Cell, Param_Cell);
gH_Forwards_OnStyleCommandPre = CreateGlobalForward("Shavit_OnStyleCommandPre", ET_Event, Param_Cell, Param_Cell, Param_Cell, Param_Cell);
gH_Forwards_OnStyleChanged = CreateGlobalForward("Shavit_OnStyleChanged", ET_Event, Param_Cell, Param_Cell, Param_Cell, Param_Cell, Param_Cell);
gH_Forwards_OnTrackChanged = CreateGlobalForward("Shavit_OnTrackChanged", ET_Event, Param_Cell, Param_Cell, Param_Cell);
gH_Forwards_OnChatConfigLoaded = CreateGlobalForward("Shavit_OnChatConfigLoaded", ET_Event);
gH_Forwards_OnUserCmdPre = CreateGlobalForward("Shavit_OnUserCmdPre", ET_Event, Param_Cell, Param_CellByRef, Param_CellByRef, Param_Array, Param_Array, Param_Cell, Param_Cell, Param_Cell, Param_Array, Param_Array);
gH_Forwards_OnTimeIncrement = CreateGlobalForward("Shavit_OnTimeIncrement", ET_Event, Param_Cell, Param_Array, Param_CellByRef, Param_Array);
gH_Forwards_OnTimeIncrementPost = CreateGlobalForward("Shavit_OnTimeIncrementPost", ET_Event, Param_Cell, Param_Cell, Param_Array);
gH_Forwards_OnTimescaleChanged = CreateGlobalForward("Shavit_OnTimescaleChanged", ET_Event, Param_Cell, Param_Cell, Param_Cell);
gH_Forwards_OnTimeOffsetCalculated = CreateGlobalForward("Shavit_OnTimeOffsetCalculated", ET_Event, Param_Cell, Param_Cell, Param_Cell, Param_Cell);
gH_Forwards_OnProcessMovement = CreateGlobalForward("Shavit_OnProcessMovement", ET_Event, Param_Cell);
gH_Forwards_OnProcessMovementPost = CreateGlobalForward("Shavit_OnProcessMovementPost", ET_Event, Param_Cell);
Bhopstats_CreateForwards();
Shavit_Style_Settings_Forwards();
LoadTranslations("shavit-core.phrases");
LoadTranslations("shavit-common.phrases");
// game types
gEV_Type = GetEngineVersion();
gB_Protobuf = (GetUserMessageType() == UM_Protobuf);
sv_autobunnyhopping = FindConVar("sv_autobunnyhopping");
if (sv_autobunnyhopping)
{
sv_autobunnyhopping.BoolValue = false;
sv_autobunnyhopping.AddChangeHook(OnConVarChanged);
}
if (gEV_Type != Engine_CSGO && gEV_Type != Engine_CSS && gEV_Type != Engine_TF2)
{
SetFailState("This plugin was meant to be used in CS:S, CS:GO and TF2 *only*.");
}
LoadDHooks();
// hooks
gB_HookedJump = HookEventEx("player_jump", Player_Jump);
HookEvent("player_death", Player_Death);
HookEvent("player_team", Player_Death);
HookEvent("player_spawn", Player_Death);
// commands START
// style
RegConsoleCmd("sm_style", Command_Style, "Choose your bhop style.");
RegConsoleCmd("sm_styles", Command_Style, "Choose your bhop style.");
RegConsoleCmd("sm_diff", Command_Style, "Choose your bhop style.");
RegConsoleCmd("sm_difficulty", Command_Style, "Choose your bhop style.");
gH_StyleCookie = RegClientCookie("shavit_style", "Style cookie", CookieAccess_Protected);
// timer start
RegConsoleCmd("sm_start", Command_StartTimer, "Start your timer.");
RegConsoleCmd("sm_r", Command_StartTimer, "Start your timer.");
RegConsoleCmd("sm_restart", Command_StartTimer, "Start your timer.");
RegConsoleCmd("sm_m", Command_StartTimer, "Start your timer on the main track.");
RegConsoleCmd("sm_main", Command_StartTimer, "Start your timer on the main track.");
RegConsoleCmd("sm_ihate!main", Command_IHateMain, "If you really hate !main :(((");
gH_IHateMain = new Cookie("shavit_mainhater", "If you really hate !main :(((", CookieAccess_Protected);
RegConsoleCmd("sm_b", Command_StartTimer, "Start your timer on the bonus track.");
RegConsoleCmd("sm_bonus", Command_StartTimer, "Start your timer on the bonus track.");
for (int i = Track_Bonus; i <= Track_Bonus_Last; i++)
{
char cmd[10], helptext[50];
FormatEx(cmd, sizeof(cmd), "sm_b%d", i);
FormatEx(helptext, sizeof(helptext), "Start your timer on the bonus %d track.", i);
RegConsoleCmd(cmd, Command_StartTimer, helptext);
}
// teleport to end
RegConsoleCmd("sm_end", Command_TeleportEnd, "Teleport to endzone.");
RegConsoleCmd("sm_bend", Command_TeleportEnd, "Teleport to endzone of the bonus track.");
RegConsoleCmd("sm_bonusend", Command_TeleportEnd, "Teleport to endzone of the bonus track.");
// timer stop
RegConsoleCmd("sm_stop", Command_StopTimer, "Stop your timer.");
// timer pause / resume
RegConsoleCmd("sm_pause", Command_TogglePause, "Toggle pause.");
RegConsoleCmd("sm_unpause", Command_TogglePause, "Toggle pause.");
RegConsoleCmd("sm_resume", Command_TogglePause, "Toggle pause");
// autobhop toggle
RegConsoleCmd("sm_auto", Command_AutoBhop, "Toggle autobhop.");
RegConsoleCmd("sm_autobhop", Command_AutoBhop, "Toggle autobhop.");
gH_AutoBhopCookie = RegClientCookie("shavit_autobhop", "Autobhop cookie", CookieAccess_Protected);
// Timescale commandssssssssss
RegConsoleCmd("sm_timescale", Command_Timescale, "Sets your timescale on TAS styles.");
RegConsoleCmd("sm_ts", Command_Timescale, "Sets your timescale on TAS styles.");
RegConsoleCmd("sm_timescaleplus", Command_TimescalePlus, "Adds the value to your current timescale.");
RegConsoleCmd("sm_tsplus", Command_TimescalePlus, "Adds the value to your current timescale.");
RegConsoleCmd("sm_timescaleminus", Command_TimescaleMinus, "Subtracts the value from your current timescale.");
RegConsoleCmd("sm_tsminus", Command_TimescaleMinus, "Subtracts the value from your current timescale.");
#if DEBUG
RegConsoleCmd("sm_finishtest", Command_FinishTest);
RegConsoleCmd("sm_fling", Command_Fling);
#endif
// admin
RegAdminCmd("sm_deletemap", Command_DeleteMap, ADMFLAG_ROOT, "Deletes all map data. Usage: sm_deletemap