initial commit: change in oryx is only outcommenting KickClient. Change in oryx-scroll is changing the message send to the native
This commit is contained in:
parent
153f1c28ce
commit
2c5820dd3d
38
oryx-mini-edit/scripting/include/bTimes-tas.inc
Normal file
38
oryx-mini-edit/scripting/include/bTimes-tas.inc
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
#if defined _tas_included
|
||||||
|
#endinput
|
||||||
|
#endif
|
||||||
|
#define _tas_included
|
||||||
|
|
||||||
|
native bool TAS_InEditMode(int client);
|
||||||
|
|
||||||
|
native bool TAS_IsPaused(int client);
|
||||||
|
|
||||||
|
native ArrayList TAS_GetRunHandle(int client);
|
||||||
|
|
||||||
|
native int TAS_GetCurrentFrame(int client);
|
||||||
|
|
||||||
|
forward void OnTASPauseChanged(int client, bool paused);
|
||||||
|
|
||||||
|
forward void OnTASFrameRecorded(int client, int frame);
|
||||||
|
|
||||||
|
public SharedPlugin __pl_tas =
|
||||||
|
{
|
||||||
|
name = "tas",
|
||||||
|
file = "bTimes-tas.smx",
|
||||||
|
#if defined REQUIRE_PLUGIN
|
||||||
|
required = 1,
|
||||||
|
#else
|
||||||
|
required = 0,
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#if !defined REQUIRE_PLUGIN
|
||||||
|
public void __pl_tas_SetNTVOptional()
|
||||||
|
{
|
||||||
|
MarkNativeAsOptional("TAS_InEditMode");
|
||||||
|
MarkNativeAsOptional("TAS_IsPaused");
|
||||||
|
MarkNativeAsOptional("TAS_GetRunHandle");
|
||||||
|
MarkNativeAsOptional("TAS_GetCurrentFrame");
|
||||||
|
}
|
||||||
|
#endif
|
89
oryx-mini-edit/scripting/include/bTimes-timer_hack.inc
Normal file
89
oryx-mini-edit/scripting/include/bTimes-timer_hack.inc
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
#if defined _btimes_timer_included
|
||||||
|
#endinput
|
||||||
|
#endif
|
||||||
|
#define _btimes_timer_included
|
||||||
|
|
||||||
|
enum styleConfig
|
||||||
|
{
|
||||||
|
String:Name[32],
|
||||||
|
String:Name_Short[32],
|
||||||
|
bool:Enabled,
|
||||||
|
bool:TempEnabled,
|
||||||
|
bool:AllowType[2],
|
||||||
|
bool:Freestyle,
|
||||||
|
bool:Freestyle_Unrestrict,
|
||||||
|
bool:Freestyle_EzHop,
|
||||||
|
bool:Freestyle_Auto,
|
||||||
|
bool:Auto,
|
||||||
|
bool:EzHop,
|
||||||
|
Float:Gravity,
|
||||||
|
Float:RunSpeed,
|
||||||
|
Float:MaxVel,
|
||||||
|
Float:MinFps,
|
||||||
|
bool:CalcSync,
|
||||||
|
bool:Prevent_Left,
|
||||||
|
bool:Prevent_Right,
|
||||||
|
bool:Prevent_Back,
|
||||||
|
bool:Prevent_Forward,
|
||||||
|
bool:Require_Left,
|
||||||
|
bool:Require_Right,
|
||||||
|
bool:Require_Back,
|
||||||
|
bool:Require_Forward,
|
||||||
|
bool:Hud_Style,
|
||||||
|
bool:Hud_Strafes,
|
||||||
|
bool:Hud_Jumps,
|
||||||
|
bool:Count_Left_Strafe,
|
||||||
|
bool:Count_Right_Strafe,
|
||||||
|
bool:Count_Back_Strafe,
|
||||||
|
bool:Count_Forward_Strafe,
|
||||||
|
bool:Ghost_Use[2],
|
||||||
|
bool:Ghost_Save[2],
|
||||||
|
Float:PreSpeed,
|
||||||
|
Float:SlowedSpeed,
|
||||||
|
bool:Special,
|
||||||
|
String:Special_Key[32],
|
||||||
|
bool:GunJump,
|
||||||
|
String:GunJump_Weapon[64],
|
||||||
|
bool:UnrealPhys,
|
||||||
|
AirAcceleration,
|
||||||
|
bool:EnableBunnyhopping,
|
||||||
|
StyleConfig
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Gets a client's style (Normal, Sideways, etc..).
|
||||||
|
*
|
||||||
|
* @param client Client index
|
||||||
|
*
|
||||||
|
* @return The client's style.
|
||||||
|
*/
|
||||||
|
native int GetClientStyle(int client);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Gets the complete configuration for a specified style.
|
||||||
|
*
|
||||||
|
* @param Style The style to get a configuration for.
|
||||||
|
* @param Properties The buffer to store all the style properties, (properties are listed in the StyleConfig enum)
|
||||||
|
*
|
||||||
|
* @return True if the style exists, false otherwise.
|
||||||
|
*/
|
||||||
|
native bool Style_GetConfig(int Style, any Properties[StyleConfig]);
|
||||||
|
|
||||||
|
public SharedPlugin __pl_btimes_timer =
|
||||||
|
{
|
||||||
|
name = "timer",
|
||||||
|
file = "bTimes-timer.smx",
|
||||||
|
#if defined REQUIRE_PLUGIN
|
||||||
|
required = 1
|
||||||
|
#else
|
||||||
|
required = 0
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
#if !defined REQUIRE_PLUGIN
|
||||||
|
public void __pl_btimes_timer_SetNTVOptional()
|
||||||
|
{
|
||||||
|
MarkNativeAsOptional("GetClientStyle");
|
||||||
|
MarkNativeAsOptional("Style_GetConfig");
|
||||||
|
}
|
||||||
|
#endif
|
484
oryx-mini-edit/scripting/include/dhooks.inc
Normal file
484
oryx-mini-edit/scripting/include/dhooks.inc
Normal file
@ -0,0 +1,484 @@
|
|||||||
|
// code by Dr!fter https://forums.alliedmods.net/showthread.php?t=180114
|
||||||
|
|
||||||
|
#if defined _dhooks_included
|
||||||
|
#endinput
|
||||||
|
#endif
|
||||||
|
#define _dhooks_included
|
||||||
|
|
||||||
|
enum ObjectValueType
|
||||||
|
{
|
||||||
|
ObjectValueType_Int = 0,
|
||||||
|
ObjectValueType_Bool,
|
||||||
|
ObjectValueType_Ehandle,
|
||||||
|
ObjectValueType_Float,
|
||||||
|
ObjectValueType_CBaseEntityPtr,
|
||||||
|
ObjectValueType_IntPtr,
|
||||||
|
ObjectValueType_BoolPtr,
|
||||||
|
ObjectValueType_EhandlePtr,
|
||||||
|
ObjectValueType_FloatPtr,
|
||||||
|
ObjectValueType_Vector,
|
||||||
|
ObjectValueType_VectorPtr,
|
||||||
|
ObjectValueType_CharPtr,
|
||||||
|
ObjectValueType_String
|
||||||
|
};
|
||||||
|
|
||||||
|
enum ListenType
|
||||||
|
{
|
||||||
|
ListenType_Created,
|
||||||
|
ListenType_Deleted
|
||||||
|
};
|
||||||
|
|
||||||
|
enum ReturnType
|
||||||
|
{
|
||||||
|
ReturnType_Unknown,
|
||||||
|
ReturnType_Void,
|
||||||
|
ReturnType_Int,
|
||||||
|
ReturnType_Bool,
|
||||||
|
ReturnType_Float,
|
||||||
|
ReturnType_String, //Note this is a string_t
|
||||||
|
ReturnType_StringPtr, //Note this is a string_t *
|
||||||
|
ReturnType_CharPtr,
|
||||||
|
ReturnType_Vector,
|
||||||
|
ReturnType_VectorPtr,
|
||||||
|
ReturnType_CBaseEntity,
|
||||||
|
ReturnType_Edict
|
||||||
|
};
|
||||||
|
|
||||||
|
enum HookParamType
|
||||||
|
{
|
||||||
|
HookParamType_Unknown,
|
||||||
|
HookParamType_Int,
|
||||||
|
HookParamType_Bool,
|
||||||
|
HookParamType_Float,
|
||||||
|
HookParamType_String, //Note this is a string_t
|
||||||
|
HookParamType_StringPtr, //Note this is a string_t *
|
||||||
|
HookParamType_CharPtr,
|
||||||
|
HookParamType_VectorPtr,
|
||||||
|
HookParamType_CBaseEntity,
|
||||||
|
HookParamType_ObjectPtr,
|
||||||
|
HookParamType_Edict,
|
||||||
|
HookParamType_Object
|
||||||
|
};
|
||||||
|
|
||||||
|
enum ThisPointerType
|
||||||
|
{
|
||||||
|
ThisPointer_Ignore,
|
||||||
|
ThisPointer_CBaseEntity,
|
||||||
|
ThisPointer_Address
|
||||||
|
};
|
||||||
|
|
||||||
|
enum HookType
|
||||||
|
{
|
||||||
|
HookType_Entity,
|
||||||
|
HookType_GameRules,
|
||||||
|
HookType_Raw
|
||||||
|
};
|
||||||
|
|
||||||
|
enum MRESReturn
|
||||||
|
{
|
||||||
|
MRES_ChangedHandled = -2, // Use changed values and return MRES_Handled
|
||||||
|
MRES_ChangedOverride, // Use changed values and return MRES_Override
|
||||||
|
MRES_Ignored, // plugin didn't take any action
|
||||||
|
MRES_Handled, // plugin did something, but real function should still be called
|
||||||
|
MRES_Override, // call real function, but use my return value
|
||||||
|
MRES_Supercede // skip real function; use my return value
|
||||||
|
};
|
||||||
|
|
||||||
|
enum DHookPassFlag
|
||||||
|
{
|
||||||
|
DHookPass_ByVal = (1<<0),
|
||||||
|
DHookPass_ByRef = (1<<1)
|
||||||
|
};
|
||||||
|
|
||||||
|
typeset ListenCB
|
||||||
|
{
|
||||||
|
//Deleted
|
||||||
|
function void (int entity);
|
||||||
|
|
||||||
|
//Created
|
||||||
|
function void (int entity, const char[] classname);
|
||||||
|
};
|
||||||
|
|
||||||
|
typeset DHookRemovalCB
|
||||||
|
{
|
||||||
|
function void (int hookid);
|
||||||
|
};
|
||||||
|
typeset DHookCallback
|
||||||
|
{
|
||||||
|
//Function Example: void Ham::Test() with this pointer ignore
|
||||||
|
function MRESReturn ();
|
||||||
|
|
||||||
|
//Function Example: void Ham::Test() with this pointer passed
|
||||||
|
function MRESReturn (int pThis);
|
||||||
|
|
||||||
|
//Function Example: void Ham::Test(int cake) with this pointer ignore
|
||||||
|
function MRESReturn (Handle hParams);
|
||||||
|
|
||||||
|
//Function Example: void Ham::Test(int cake) with this pointer passed
|
||||||
|
function MRESReturn (int pThis, Handle hParams);
|
||||||
|
|
||||||
|
//Function Example: int Ham::Test() with this pointer ignore
|
||||||
|
function MRESReturn (Handle hReturn);
|
||||||
|
|
||||||
|
//Function Example: int Ham::Test() with this pointer passed
|
||||||
|
function MRESReturn (int pThis, Handle hReturn);
|
||||||
|
|
||||||
|
//Function Example: int Ham::Test(int cake) with this pointer ignore
|
||||||
|
function MRESReturn (Handle hReturn, Handle hParams);
|
||||||
|
|
||||||
|
//Function Example: int Ham::Test(int cake) with this pointer passed
|
||||||
|
function MRESReturn (int pThis, Handle hReturn, Handle hParams);
|
||||||
|
|
||||||
|
//Address NOW
|
||||||
|
|
||||||
|
//Function Example: void Ham::Test() with this pointer passed
|
||||||
|
function MRESReturn (Address pThis);
|
||||||
|
|
||||||
|
//Function Example: void Ham::Test(int cake) with this pointer passed
|
||||||
|
function MRESReturn (Address pThis, Handle hParams);
|
||||||
|
|
||||||
|
//Function Example: int Ham::Test() with this pointer passed
|
||||||
|
function MRESReturn (Address pThis, Handle hReturn);
|
||||||
|
|
||||||
|
//Function Example: int Ham::Test(int cake) with this pointer passed
|
||||||
|
function MRESReturn (Address pThis, Handle hReturn, Handle hParams);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Adds an entity listener hook
|
||||||
|
*
|
||||||
|
* @param type Type of listener to add
|
||||||
|
* @param callback Callback to use
|
||||||
|
*
|
||||||
|
* @noreturn
|
||||||
|
*/
|
||||||
|
native void DHookAddEntityListener(ListenType type, ListenCB callback);
|
||||||
|
|
||||||
|
/* Removes an entity listener hook
|
||||||
|
*
|
||||||
|
* @param type Type of listener to remove
|
||||||
|
* @param callback Callback this listener was using
|
||||||
|
*
|
||||||
|
* @return True if one was removed false otherwise.
|
||||||
|
*/
|
||||||
|
native bool DHookRemoveEntityListener(ListenType type, ListenCB callback);
|
||||||
|
|
||||||
|
/* Creates a hook
|
||||||
|
*
|
||||||
|
* @param offset vtable offset for function to hook
|
||||||
|
* @param hooktype Type of hook
|
||||||
|
* @param returntype Type type of return
|
||||||
|
* @param thistype Type of this pointer or ignore (ignore can be used if not needed)
|
||||||
|
* @param callback Callback function
|
||||||
|
*
|
||||||
|
* @return Returns setup handle for the hook or INVALID_HANDLE.
|
||||||
|
*/
|
||||||
|
native Handle DHookCreate(int offset, HookType hooktype, ReturnType returntype, ThisPointerType thistype, DHookCallback callback);
|
||||||
|
|
||||||
|
/* Adds param to a hook setup
|
||||||
|
*
|
||||||
|
* @param setup Setup handle to add the param to.
|
||||||
|
* @param type Param type
|
||||||
|
* @param size Used for Objects (not Object ptr) to define the size of the object.
|
||||||
|
* @param flag Used to change the pass type.
|
||||||
|
*
|
||||||
|
* @error Invalid setup handle or too many params added (request upping the max in thread)
|
||||||
|
* @noreturn
|
||||||
|
*/
|
||||||
|
native void DHookAddParam(Handle setup, HookParamType type, int size=-1, DHookPassFlag flag=DHookPass_ByVal);
|
||||||
|
//native DHookAddParam(Handle:setup, HookParamType:type);
|
||||||
|
|
||||||
|
/* Hook entity
|
||||||
|
*
|
||||||
|
* @param setup Setup handle to use to add the hook.
|
||||||
|
* @param post True to make the hook a post hook. (If you need to change the retunr value or need the return value use a post hook! If you need to change params and return use a pre and post hook!)
|
||||||
|
* @param entity Entity index to hook on.
|
||||||
|
* @param removalcb Callback for when the hook is removed (Entity hooks are auto-removed on entity destroyed and will call this callback)
|
||||||
|
*
|
||||||
|
* @error Invalid setup handle, invalid entity or invalid hook type.
|
||||||
|
* @return -1 on fail a hookid on success
|
||||||
|
*/
|
||||||
|
native int DHookEntity(Handle setup, bool post, int entity, DHookRemovalCB removalcb=INVALID_FUNCTION);
|
||||||
|
|
||||||
|
/* Hook gamerules
|
||||||
|
*
|
||||||
|
* @param setup Setup handle to use to add the hook.
|
||||||
|
* @param post True to make the hook a post hook. (If you need to change the retunr value or need the return value use a post hook! If you need to change params and return use a pre and post hook!)
|
||||||
|
* @param removalcb Callback for when the hook is removed (Game rules hooks are auto-removed on map end and will call this callback)
|
||||||
|
*
|
||||||
|
* @error Invalid setup handle, failing to get gamerules pointer or invalid hook type.
|
||||||
|
* @return -1 on fail a hookid on success
|
||||||
|
*/
|
||||||
|
native int DHookGamerules(Handle setup, bool post, DHookRemovalCB removalcb=INVALID_FUNCTION);
|
||||||
|
|
||||||
|
/* Hook a raw pointer
|
||||||
|
*
|
||||||
|
* @param setup Setup handle to use to add the hook.
|
||||||
|
* @param post True to make the hook a post hook. (If you need to change the retunr value or need the return value use a post hook! If you need to change params and return use a pre and post hook!)
|
||||||
|
* @param addr This pointer address.
|
||||||
|
* @param removalcb Callback for when the hook is removed (Entity hooks are auto-removed on entity destroyed and will call this callback)
|
||||||
|
*
|
||||||
|
* @error Invalid setup handle, invalid address or invalid hook type.
|
||||||
|
* @return -1 on fail a hookid on success
|
||||||
|
*/
|
||||||
|
native int DHookRaw(Handle setup, bool post, Address addr, DHookRemovalCB removalcb=INVALID_FUNCTION);
|
||||||
|
|
||||||
|
/* Remove hook by hook id
|
||||||
|
*
|
||||||
|
* @param hookid Hook id to remove
|
||||||
|
*
|
||||||
|
* @return true on success false otherwise
|
||||||
|
* @note This will not fire the removal callback!
|
||||||
|
*/
|
||||||
|
native bool DHookRemoveHookID(int hookid);
|
||||||
|
|
||||||
|
/* Get param value (Only use for: int, entity, bool or float param types)
|
||||||
|
*
|
||||||
|
* @param hParams Handle to params structure
|
||||||
|
* @param num Param number to get. (Example if the function has 2 params and you need the value of the first param num would be 1. 0 Will return the number of params stored)
|
||||||
|
*
|
||||||
|
* @error Invalid handle. Invalid param number. Invalid param type.
|
||||||
|
* @return value if num greater than 0. If 0 returns paramcount.
|
||||||
|
*/
|
||||||
|
native any DHookGetParam(Handle hParams, int num);
|
||||||
|
|
||||||
|
/* Get vector param value
|
||||||
|
*
|
||||||
|
* @param hParams Handle to params structure
|
||||||
|
* @param num Param number to get. (Example if the function has 2 params and you need the value of the first param num would be 1.)
|
||||||
|
* @param vec Vector buffer to store result.
|
||||||
|
*
|
||||||
|
* @error Invalid handle. Invalid param number. Invalid param type.
|
||||||
|
* @noreturn
|
||||||
|
*/
|
||||||
|
native void DHookGetParamVector(Handle hParams, int num, float vec[3]);
|
||||||
|
|
||||||
|
/* Get string param value
|
||||||
|
*
|
||||||
|
* @param hParams Handle to params structure
|
||||||
|
* @param num Param number to get. (Example if the function has 2 params and you need the value of the first param num would be 1.)
|
||||||
|
* @param buffer String buffer to store result
|
||||||
|
* @param size Buffer size
|
||||||
|
*
|
||||||
|
* @error Invalid handle. Invalid param number. Invalid param type.
|
||||||
|
* @noreturn
|
||||||
|
*/
|
||||||
|
native void DHookGetParamString(Handle hParams, int num, char[] buffer, int size);
|
||||||
|
|
||||||
|
/* Set param value (Only use for: int, entity, bool or float param types)
|
||||||
|
*
|
||||||
|
* @param hParams Handle to params structure
|
||||||
|
* @params num Param number to set (Example if the function has 2 params and you need to set the value of the first param num would be 1.)
|
||||||
|
* @param value Value to set it as (only pass int, bool, float or entity index)
|
||||||
|
*
|
||||||
|
* @error Invalid handle. Invalid param number. Invalid param type.
|
||||||
|
* @noreturn
|
||||||
|
*/
|
||||||
|
native void DHookSetParam(Handle hParams, int num, any value);
|
||||||
|
|
||||||
|
/* Set vector param value
|
||||||
|
*
|
||||||
|
* @param hParams Handle to params structure
|
||||||
|
* @params num Param number to set (Example if the function has 2 params and you need to set the value of the first param num would be 1.)
|
||||||
|
* @param vec Value to set vector as.
|
||||||
|
*
|
||||||
|
* @error Invalid handle. Invalid param number. Invalid param type.
|
||||||
|
* @noreturn
|
||||||
|
*/
|
||||||
|
native void DHookSetParamVector(Handle hParams, int num, float vec[3]);
|
||||||
|
|
||||||
|
/* Set string param value
|
||||||
|
*
|
||||||
|
* @param hParams Handle to params structure
|
||||||
|
* @params num Param number to set (Example if the function has 2 params and you need to set the value of the first param num would be 1.)
|
||||||
|
* @param value Value to set string as.
|
||||||
|
*
|
||||||
|
* @error Invalid handle. Invalid param number. Invalid param type.
|
||||||
|
* @noreturn
|
||||||
|
*/
|
||||||
|
native void DHookSetParamString(Handle hParams, int num, char[] value);
|
||||||
|
|
||||||
|
/* Get return value (Only use for: int, entity, bool or float return types)
|
||||||
|
*
|
||||||
|
* @param hReturn Handle to return structure
|
||||||
|
*
|
||||||
|
* @error Invalid Handle, invalid type.
|
||||||
|
* @return Returns default value if prehook returns actual value if post hook.
|
||||||
|
*/
|
||||||
|
native any DHookGetReturn(Handle hReturn);
|
||||||
|
|
||||||
|
/* Get return vector value
|
||||||
|
*
|
||||||
|
* @param hReturn Handle to return structure
|
||||||
|
* @param vec Vector buffer to store result in. (In pre hooks will be default value (0.0,0.0,0.0))
|
||||||
|
*
|
||||||
|
* @error Invalid Handle, invalid type.
|
||||||
|
* @noreturn
|
||||||
|
*/
|
||||||
|
native void DHookGetReturnVector(Handle hReturn, float vec[3]);
|
||||||
|
|
||||||
|
/* Get return string value
|
||||||
|
*
|
||||||
|
* @param hReturn Handle to return structure
|
||||||
|
* @param buffer String buffer to store result in. (In pre hooks will be default value "")
|
||||||
|
* @param size String buffer size
|
||||||
|
*
|
||||||
|
* @error Invalid Handle, invalid type.
|
||||||
|
* @noreturn
|
||||||
|
*/
|
||||||
|
native void DHookGetReturnString(Handle hReturn, char[] buffer, int size);
|
||||||
|
|
||||||
|
/* Set return value (Only use for: int, entity, bool or float return types)
|
||||||
|
*
|
||||||
|
* @param hReturn Handle to return structure
|
||||||
|
* @param value Value to set return as
|
||||||
|
*
|
||||||
|
* @error Invalid Handle, invalid type.
|
||||||
|
* @noreturn
|
||||||
|
*/
|
||||||
|
native void DHookSetReturn(Handle hReturn, any value);
|
||||||
|
|
||||||
|
/* Set return vector value
|
||||||
|
*
|
||||||
|
* @param hReturn Handle to return structure
|
||||||
|
* @param vec Value to set return vector as
|
||||||
|
*
|
||||||
|
* @error Invalid Handle, invalid type.
|
||||||
|
* @noreturn
|
||||||
|
*/
|
||||||
|
native void DHookSetReturnVector(Handle hReturn, float vec[3]);
|
||||||
|
|
||||||
|
/* Set return string value
|
||||||
|
*
|
||||||
|
* @param hReturn Handle to return structure
|
||||||
|
* @param value Value to set return string as
|
||||||
|
*
|
||||||
|
* @error Invalid Handle, invalid type.
|
||||||
|
* @noreturn
|
||||||
|
*/
|
||||||
|
native void DHookSetReturnString(Handle hReturn, char[] value);
|
||||||
|
|
||||||
|
//WE SHOULD WRAP THESE AROUND STOCKS FOR NON PTR AS WE SUPPORT BOTH WITH THESE NATIVE'S
|
||||||
|
|
||||||
|
/* Gets an objects variable value
|
||||||
|
*
|
||||||
|
* @param hParams Handle to params structure
|
||||||
|
* @param num Param number to get.
|
||||||
|
* @param offset Offset within the object to the var to get.
|
||||||
|
* @param type Type of var it is
|
||||||
|
*
|
||||||
|
* @error Invalid handle. Invalid param number. Invalid param type. Invalid Object type.
|
||||||
|
* @return Value of the objects var. If EHANDLE type or entity returns entity index.
|
||||||
|
*/
|
||||||
|
native any DHookGetParamObjectPtrVar(Handle hParams, int num, int offset, ObjectValueType type);
|
||||||
|
|
||||||
|
/* Sets an objects variable value
|
||||||
|
*
|
||||||
|
* @param hParams Handle to params structure
|
||||||
|
* @param num Param number to set.
|
||||||
|
* @param offset Offset within the object to the var to set.
|
||||||
|
* @param type Type of var it is
|
||||||
|
* @param value The value to set the var to.
|
||||||
|
*
|
||||||
|
* @error Invalid handle. Invalid param number. Invalid param type. Invalid Object type.
|
||||||
|
* @noreturn
|
||||||
|
*/
|
||||||
|
native void DHookSetParamObjectPtrVar(Handle hParams, int num, int offset, ObjectValueType type, any value);
|
||||||
|
|
||||||
|
/* Gets an objects vector variable value
|
||||||
|
*
|
||||||
|
* @param hParams Handle to params structure
|
||||||
|
* @param num Param number to get.
|
||||||
|
* @param offset Offset within the object to the var to get.
|
||||||
|
* @param type Type of var it is
|
||||||
|
* @param buffer Buffer to store the result vector
|
||||||
|
*
|
||||||
|
* @error Invalid handle. Invalid param number. Invalid param type. Invalid Object type.
|
||||||
|
* @noreturn
|
||||||
|
*/
|
||||||
|
native void DHookGetParamObjectPtrVarVector(Handle hParams, int num, int offset, ObjectValueType type, float buffer[3]);
|
||||||
|
|
||||||
|
/* Sets an objects vector variable value
|
||||||
|
*
|
||||||
|
* @param hParams Handle to params structure
|
||||||
|
* @param num Param number to set.
|
||||||
|
* @param offset Offset within the object to the var to set.
|
||||||
|
* @param type Type of var it is
|
||||||
|
* @param value The value to set the vector var to.
|
||||||
|
*
|
||||||
|
* @error Invalid handle. Invalid param number. Invalid param type. Invalid Object type.
|
||||||
|
* @noreturn
|
||||||
|
*/
|
||||||
|
native void DHookSetParamObjectPtrVarVector(Handle hParams, int num, int offset, ObjectValueType type, float value[3]);
|
||||||
|
|
||||||
|
/* Gets an objects string variable value
|
||||||
|
*
|
||||||
|
* @param hParams Handle to params structure
|
||||||
|
* @param num Param number to get.
|
||||||
|
* @param offset Offset within the object to the var to get.
|
||||||
|
* @param type Type of var it is
|
||||||
|
* @param buffer Buffer to store the result vector
|
||||||
|
* @param size Size of the buffer
|
||||||
|
*
|
||||||
|
* @error Invalid handle. Invalid param number. Invalid param type. Invalid Object type.
|
||||||
|
* @noreturn
|
||||||
|
*/
|
||||||
|
native void DHookGetParamObjectPtrString(Handle hParams, int num, int offset, ObjectValueType type, char[] buffer, int size);
|
||||||
|
|
||||||
|
/* Checks if a pointer param is null
|
||||||
|
*
|
||||||
|
* @param hParams Handle to params structure
|
||||||
|
* @param num Param number to check.
|
||||||
|
*
|
||||||
|
* @error Non pointer param
|
||||||
|
* @return True if null false otherwise.
|
||||||
|
*/
|
||||||
|
native bool DHookIsNullParam(Handle hParams, int num);
|
||||||
|
|
||||||
|
public Extension __ext_dhooks =
|
||||||
|
{
|
||||||
|
name = "dhooks",
|
||||||
|
file = "dhooks.ext",
|
||||||
|
#if defined AUTOLOAD_EXTENSIONS
|
||||||
|
autoload = 1,
|
||||||
|
#else
|
||||||
|
autoload = 0,
|
||||||
|
#endif
|
||||||
|
#if defined REQUIRE_EXTENSIONS
|
||||||
|
required = 1,
|
||||||
|
#else
|
||||||
|
required = 0,
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
#if !defined REQUIRE_EXTENSIONS
|
||||||
|
public void __ext_dhooks_SetNTVOptional()
|
||||||
|
{
|
||||||
|
MarkNativeAsOptional("DHookAddEntityListener");
|
||||||
|
MarkNativeAsOptional("DHookRemoveEntityListener");
|
||||||
|
MarkNativeAsOptional("DHookCreate");
|
||||||
|
MarkNativeAsOptional("DHookAddParam");
|
||||||
|
MarkNativeAsOptional("DHookEntity");
|
||||||
|
MarkNativeAsOptional("DHookGamerules");
|
||||||
|
MarkNativeAsOptional("DHookRaw");
|
||||||
|
MarkNativeAsOptional("DHookRemoveHookID");
|
||||||
|
MarkNativeAsOptional("DHookGetParam");
|
||||||
|
MarkNativeAsOptional("DHookGetParamVector");
|
||||||
|
MarkNativeAsOptional("DHookGetParamString");
|
||||||
|
MarkNativeAsOptional("DHookSetParam");
|
||||||
|
MarkNativeAsOptional("DHookSetParamVector");
|
||||||
|
MarkNativeAsOptional("DHookSetParamString");
|
||||||
|
MarkNativeAsOptional("DHookGetReturn");
|
||||||
|
MarkNativeAsOptional("DHookGetReturnVector");
|
||||||
|
MarkNativeAsOptional("DHookGetReturnString");
|
||||||
|
MarkNativeAsOptional("DHookSetReturn");
|
||||||
|
MarkNativeAsOptional("DHookSetReturnVector");
|
||||||
|
MarkNativeAsOptional("DHookSetReturnString");
|
||||||
|
MarkNativeAsOptional("DHookGetParamObjectPtrVar");
|
||||||
|
MarkNativeAsOptional("DHookSetParamObjectPtrVar");
|
||||||
|
MarkNativeAsOptional("DHookGetParamObjectPtrVarVector");
|
||||||
|
MarkNativeAsOptional("DHookSetParamObjectPtrVarVector");
|
||||||
|
MarkNativeAsOptional("DHookIsNullParam");
|
||||||
|
MarkNativeAsOptional("DHookGetParamObjectPtrString");
|
||||||
|
}
|
||||||
|
#endif
|
156
oryx-mini-edit/scripting/include/oryx.inc
Normal file
156
oryx-mini-edit/scripting/include/oryx.inc
Normal file
@ -0,0 +1,156 @@
|
|||||||
|
/* Oryx AC: collects and analyzes statistics to find some cheaters in CS:S, CS:GO, and TF2 bunnyhop.
|
||||||
|
* Copyright (C) 2018 Nolan O.
|
||||||
|
* Copyright (C) 2018 shavit.
|
||||||
|
*
|
||||||
|
* This program 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.
|
||||||
|
*
|
||||||
|
* 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 <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if defined _oryx_included
|
||||||
|
#endinput
|
||||||
|
#endif
|
||||||
|
#define _oryx_included
|
||||||
|
|
||||||
|
#define ORYX_VERSION "1.3.1"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List of current detection descriptions:
|
||||||
|
*
|
||||||
|
* "Acute TR formatter"
|
||||||
|
* "+left/right bypasser"
|
||||||
|
* "Prestrafe tool"
|
||||||
|
* "Average strafe too close to 0"
|
||||||
|
* "Too many perfect strafes"
|
||||||
|
* "Movement config"
|
||||||
|
* "Unsynchronised movement"
|
||||||
|
* "Invalid wish velocity"
|
||||||
|
* "Script on scroll"
|
||||||
|
* "Hyperscroll"
|
||||||
|
*/
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
TRIGGER_LOW, // Reachable by skilled players occasionally. Not always necessary before a med detect.
|
||||||
|
TRIGGER_MEDIUM, // Reachable by skilled players by unlikely chance.
|
||||||
|
TRIGGER_HIGH, // Only theoretically reachable by the aligning of stars by the gods.
|
||||||
|
TRIGGER_HIGH_NOKICK, // This should really only be used for a follow up definitive detection.
|
||||||
|
TRIGGER_DEFINITIVE, // Non-skill-based detection type. 100% sure detection.
|
||||||
|
TRIGGER_TEST // Allows you to develop new detections on live servers with minimal side effects.
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when Oryx gets triggered on a client.
|
||||||
|
*
|
||||||
|
* @param client Client entity index.
|
||||||
|
* @param level Level of detection as defined in the above enum.
|
||||||
|
* @param cheat Short description or name of the cheat being detected. 32 cells char array.
|
||||||
|
* @return Plugin_Continue to do nothing. Plugin_Changed to modify values. Plugin_Handled to abort kicks. Plugin_Stop to completely ignore the trigger.
|
||||||
|
*/
|
||||||
|
forward Action Oryx_OnTrigger(int client, int &level, char[] cheat);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Call to activate Oryx's trigger procedure (logging, kicking, admin notifications, etc..).
|
||||||
|
*
|
||||||
|
* @param client Client entity index.
|
||||||
|
* @param level Level of detection as defined in the above enum.
|
||||||
|
* @param cheat Short description or name of the cheat being detected.
|
||||||
|
* @return Return value of the Oryx_OnTrigger forward.
|
||||||
|
*/
|
||||||
|
native Action Oryx_Trigger(int client, int level, const char[] cheat);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prints a message to admins' chat.
|
||||||
|
*
|
||||||
|
* @param format Formatting rules.
|
||||||
|
* @param any Variable number of format parameters.
|
||||||
|
* @noreturn
|
||||||
|
*/
|
||||||
|
native void Oryx_PrintToAdmins(const char[] format, any ...);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prints a message to admins' console.
|
||||||
|
*
|
||||||
|
* @param format Formatting rules.
|
||||||
|
* @param any Variable number of format parameters.
|
||||||
|
* @noreturn
|
||||||
|
*/
|
||||||
|
native void Oryx_PrintToAdminsConsole(const char[] format, any ...);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Logs an entry to Oryx's log file.
|
||||||
|
*
|
||||||
|
* @param format Formatting rules.
|
||||||
|
* @param any Variable number of format parameters.
|
||||||
|
* @noreturn
|
||||||
|
*/
|
||||||
|
native void Oryx_LogMessage(const char[] format, any ...);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if f1 is inbetween a specified threshold of f12.
|
||||||
|
*
|
||||||
|
* @param f1 First value.
|
||||||
|
* @param f2 Second value.
|
||||||
|
* @param frac Used as a threshold of f2 for f1 to be within.
|
||||||
|
* @return True if the test passed.
|
||||||
|
*/
|
||||||
|
native bool Oryx_WithinThreshold(float f1, float f2, float threshold);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if the player has permissions to bypass Oryx.
|
||||||
|
* Will return false if `oryx_allow_bypass` is set to 0.
|
||||||
|
* With bhoptimer or bTimes v1.8.3, will return true for styles with the `oryx_bypass` special flag.
|
||||||
|
* For bTimes2, will return true if the player is in edit mode (rewind/fastforward etc).
|
||||||
|
*
|
||||||
|
* @param client Client index.
|
||||||
|
* @return True if the player can bypass the anticheat.
|
||||||
|
*/
|
||||||
|
native bool Oryx_CanBypass(int client);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A tiny function to veify if the player fits gameplay.
|
||||||
|
*
|
||||||
|
* @param client Client entity index.
|
||||||
|
* @param watrer Check for water level?
|
||||||
|
* @return True if the test passed.
|
||||||
|
*/
|
||||||
|
stock bool IsLegalMoveType(int client, bool water = true)
|
||||||
|
{
|
||||||
|
MoveType iMoveType = GetEntityMoveType(client);
|
||||||
|
|
||||||
|
return (!water || GetEntProp(client, Prop_Data, "m_nWaterLevel") < 2) &&
|
||||||
|
(GetEntityFlags(client) & FL_ATCONTROLS) == 0 &&
|
||||||
|
(iMoveType == MOVETYPE_WALK || iMoveType == MOVETYPE_ISOMETRIC || iMoveType == MOVETYPE_LADDER);
|
||||||
|
}
|
||||||
|
|
||||||
|
public SharedPlugin __pl_oryx =
|
||||||
|
{
|
||||||
|
name = "oryx",
|
||||||
|
file = "oryx.smx",
|
||||||
|
#if defined REQUIRE_PLUGIN
|
||||||
|
required = 1
|
||||||
|
#else
|
||||||
|
required = 0
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
#if !defined REQUIRE_PLUGIN
|
||||||
|
public void __pl_oryx_SetNTVOptional()
|
||||||
|
{
|
||||||
|
MarkNativeAsOptional("Oryx_CanBypass");
|
||||||
|
MarkNativeAsOptional("Oryx_LogMessage");
|
||||||
|
MarkNativeAsOptional("Oryx_PrintToAdmins");
|
||||||
|
MarkNativeAsOptional("Oryx_PrintToAdminsConsole");
|
||||||
|
MarkNativeAsOptional("Oryx_Trigger");
|
||||||
|
MarkNativeAsOptional("Oryx_WithinThreshold");
|
||||||
|
}
|
||||||
|
#endif
|
2880
oryx-mini-edit/scripting/include/shavit.inc
Normal file
2880
oryx-mini-edit/scripting/include/shavit.inc
Normal file
File diff suppressed because it is too large
Load Diff
690
oryx-mini-edit/scripting/oryx-scroll.sp
Normal file
690
oryx-mini-edit/scripting/oryx-scroll.sp
Normal file
@ -0,0 +1,690 @@
|
|||||||
|
/* Oryx AC: collects and analyzes statistics to find some cheaters in CS:S, CS:GO, and TF2 bunnyhop.
|
||||||
|
* Copyright (C) 2018 shavit.
|
||||||
|
*
|
||||||
|
* This program 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.
|
||||||
|
*
|
||||||
|
* 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 <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// This module is a complete rewrite, and doesn't work like the simple one written by Rusty. //'
|
||||||
|
|
||||||
|
#include <sourcemod>
|
||||||
|
#include <sdktools>
|
||||||
|
#include <oryx>
|
||||||
|
|
||||||
|
#undef REQUIRE_PLUGIN
|
||||||
|
#include <shavit>
|
||||||
|
|
||||||
|
#pragma newdecls required
|
||||||
|
#pragma semicolon 1
|
||||||
|
|
||||||
|
// Some features from my old anticheat.
|
||||||
|
#define DESC1 "Scripted jumps (havg)" // 91%+ perf over sample size
|
||||||
|
#define DESC2 "Scripted jumps (havgp)" // 87%+ perf, consistent scrolls
|
||||||
|
#define DESC3 "Scripted jumps (patt1)" // 85%+ perf, very consistent scrolls
|
||||||
|
#define DESC4 "Scripted jumps (patt2)" // 80%+ perf, inhumanly consistent scrolls
|
||||||
|
#define DESC5 "Scripted jumps (wpatt1)" // 75%+ perf, inhumanly consistent scrolls
|
||||||
|
#define DESC6 "Scripted jumps (wpatt2)" // 85%+ perf, obviously randomized scrolls
|
||||||
|
|
||||||
|
#define DESC7 "Scripted jumps (nobf)" // 40%+ perf, no scrolls before touching the ground
|
||||||
|
#define DESC8 "Scripted jumps (bf-af)" // 55%+ perf, same number of scrolls before and after touching the ground
|
||||||
|
#define DESC9 "Scripted jumps (noaf)" // 40%+ perf, no scrolls after leaving the ground
|
||||||
|
|
||||||
|
#define DESC10 "Scroll macro (highn)" // scrolls per jump are 17+, either high perf% (80%+) or consistent scrolls
|
||||||
|
|
||||||
|
// ORYX exclusive:
|
||||||
|
#define DESC11 "Scroll cheat (interval)" // interval between scrolls is consistent (<=2, and is over 3/4 of the jumps)
|
||||||
|
|
||||||
|
// TODO: Implement this:
|
||||||
|
#define DESC12 "Scroll cheat (ticks)" // average ticks on ground are inhuman
|
||||||
|
|
||||||
|
// Decrease this to make the scroll anticheat more sensitive.
|
||||||
|
// Samples will be taken from the last X jumps' data.
|
||||||
|
// If the number is too high, logs might be cut off due to the scroll patterns being too long.
|
||||||
|
#define SAMPLE_SIZE_MIN 45
|
||||||
|
#define SAMPLE_SIZE_MAX 55
|
||||||
|
|
||||||
|
// Amount of ticks between jumps to not count one.
|
||||||
|
#define TICKS_NOT_COUNT_JUMP 8
|
||||||
|
|
||||||
|
// Maximum airtime per jump in ticks before we stop measuring. This is to prevent low-gravity style bans and players spamming their scroll wheel while falling to purposely make the anti-cheat ban them.
|
||||||
|
#define TICKS_NOT_COUNT_AIR 135
|
||||||
|
|
||||||
|
// Fill scroll stats array with junk data.
|
||||||
|
// #define DEBUG_SCROLL 50
|
||||||
|
|
||||||
|
public Plugin myinfo =
|
||||||
|
{
|
||||||
|
name = "ORYX scroll module",
|
||||||
|
author = "shavit",
|
||||||
|
description = "Advanced bunnyhop script/macro detection.",
|
||||||
|
version = ORYX_VERSION,
|
||||||
|
url = "https://github.com/shavitush/Oryx-AC"
|
||||||
|
}
|
||||||
|
|
||||||
|
ConVar sv_autobunnyhopping = null;
|
||||||
|
|
||||||
|
bool gB_AutoBunnyhopping = false;
|
||||||
|
bool gB_Shavit = false;
|
||||||
|
|
||||||
|
int gI_SampleSize = 50;
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
StatsArray_Scrolls,
|
||||||
|
StatsArray_BeforeGround,
|
||||||
|
StatsArray_AfterGround,
|
||||||
|
StatsArray_AverageTicks,
|
||||||
|
StatsArray_PerfectJump,
|
||||||
|
STATSARRAY_SIZE
|
||||||
|
}
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
State_Nothing,
|
||||||
|
State_Landing,
|
||||||
|
State_Jumping,
|
||||||
|
State_Pressing,
|
||||||
|
State_Releasing
|
||||||
|
}
|
||||||
|
|
||||||
|
// 5 cells:
|
||||||
|
// Scrolls before this jump.
|
||||||
|
// Scrolls before touching ground (33 units from ground).
|
||||||
|
// Scrolls after leaving ground (33 units from ground).
|
||||||
|
// Average ticks between each scroll input.
|
||||||
|
// Is it a perfect jump?
|
||||||
|
ArrayList gA_JumpStats[MAXPLAYERS+1];
|
||||||
|
any gA_StatsArray[MAXPLAYERS+1][STATSARRAY_SIZE];
|
||||||
|
|
||||||
|
int gI_GroundTicks[MAXPLAYERS+1];
|
||||||
|
int gI_ReleaseTick[MAXPLAYERS+1];
|
||||||
|
int gI_AirTicks[MAXPLAYERS+1];
|
||||||
|
|
||||||
|
bool gB_PreviousGround[MAXPLAYERS+1] = { true, ... }; // Initialized as trues to prevent the first data being wrong.
|
||||||
|
int gI_PreviousButtons[MAXPLAYERS+1];
|
||||||
|
int gI_CurrentJump[MAXPLAYERS+1];
|
||||||
|
|
||||||
|
char gS_LogPath[PLATFORM_MAX_PATH];
|
||||||
|
|
||||||
|
public void OnPluginStart()
|
||||||
|
{
|
||||||
|
sv_autobunnyhopping = FindConVar("sv_autobunnyhopping");
|
||||||
|
|
||||||
|
if(sv_autobunnyhopping != null)
|
||||||
|
{
|
||||||
|
sv_autobunnyhopping.AddChangeHook(OnAutoBunnyhoppingChanged);
|
||||||
|
}
|
||||||
|
|
||||||
|
for(int i = 1; i <= MaxClients; i++)
|
||||||
|
{
|
||||||
|
if(IsClientInGame(i))
|
||||||
|
{
|
||||||
|
OnClientPutInServer(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
RegConsoleCmd("scroll_stats", Command_PrintScrollStats, "Print the scroll stat buffer for a given player.");
|
||||||
|
|
||||||
|
LoadTranslations("common.phrases");
|
||||||
|
|
||||||
|
gB_Shavit = LibraryExists("shavit");
|
||||||
|
|
||||||
|
BuildPath(Path_SM, gS_LogPath, PLATFORM_MAX_PATH, "logs/oryx-ac-scroll.log");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OnMapStart()
|
||||||
|
{
|
||||||
|
gI_SampleSize = GetRandomInt(SAMPLE_SIZE_MIN, SAMPLE_SIZE_MAX);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OnClientPutInServer(int client)
|
||||||
|
{
|
||||||
|
gA_JumpStats[client] = new ArrayList(STATSARRAY_SIZE);
|
||||||
|
gI_CurrentJump[client] = 0;
|
||||||
|
ResetStatsArray(client);
|
||||||
|
|
||||||
|
#if defined DEBUG_SCROLL
|
||||||
|
gA_JumpStats[client].Resize(DEBUG_SCROLL);
|
||||||
|
|
||||||
|
for(int i = 0; i < DEBUG_SCROLL; i++)
|
||||||
|
{
|
||||||
|
int scrolls = GetRandomInt(7, 15);
|
||||||
|
int before = GetRandomInt(0, scrolls);
|
||||||
|
int after = scrolls - before;
|
||||||
|
|
||||||
|
gA_JumpStats[client].Set(i, scrolls, StatsArray_Scrolls);
|
||||||
|
gA_JumpStats[client].Set(i, before, StatsArray_BeforeGround);
|
||||||
|
gA_JumpStats[client].Set(i, after, StatsArray_AfterGround);
|
||||||
|
gA_JumpStats[client].Set(i, GetRandomInt(1, 2), StatsArray_AverageTicks);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OnClientDisconnect(int client)
|
||||||
|
{
|
||||||
|
delete gA_JumpStats[client];
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OnLibraryAdded(const char[] name)
|
||||||
|
{
|
||||||
|
if(StrEqual(name, "shavit"))
|
||||||
|
{
|
||||||
|
gB_Shavit = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OnLibraryRemoved(const char[] name)
|
||||||
|
{
|
||||||
|
if(StrEqual(name, "shavit"))
|
||||||
|
{
|
||||||
|
gB_Shavit = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OnAutoBunnyhoppingChanged(ConVar convar, const char[] oldValue, const char[] newValue)
|
||||||
|
{
|
||||||
|
gB_AutoBunnyhopping = view_as<bool>(StringToInt(newValue));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OnConfigsExecuted()
|
||||||
|
{
|
||||||
|
if(sv_autobunnyhopping != null)
|
||||||
|
{
|
||||||
|
gB_AutoBunnyhopping = sv_autobunnyhopping.BoolValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Action Command_PrintScrollStats(int client, int args)
|
||||||
|
{
|
||||||
|
if(args < 1)
|
||||||
|
{
|
||||||
|
ReplyToCommand(client, "Usage: scroll_stats <target>");
|
||||||
|
|
||||||
|
return Plugin_Handled;
|
||||||
|
}
|
||||||
|
|
||||||
|
char[] sArgs = new char[MAX_TARGET_LENGTH];
|
||||||
|
GetCmdArgString(sArgs, MAX_TARGET_LENGTH);
|
||||||
|
|
||||||
|
int target = FindTarget(client, sArgs);
|
||||||
|
|
||||||
|
if(target == -1)
|
||||||
|
{
|
||||||
|
return Plugin_Handled;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(GetSampledJumps(target) == 0)
|
||||||
|
{
|
||||||
|
ReplyToCommand(client, "\x03%N\x01 does not have recorded jump stats.", target);
|
||||||
|
|
||||||
|
return Plugin_Handled;
|
||||||
|
}
|
||||||
|
|
||||||
|
char[] sScrollStats = new char[300];
|
||||||
|
GetScrollStatsFormatted(target, sScrollStats, 300);
|
||||||
|
|
||||||
|
ReplyToCommand(client, "Scroll stats for %N: %s", target, sScrollStats);
|
||||||
|
|
||||||
|
return Plugin_Handled;
|
||||||
|
}
|
||||||
|
|
||||||
|
void GetScrollStatsFormatted(int client, char[] buffer, int maxlength)
|
||||||
|
{
|
||||||
|
FormatEx(buffer, maxlength, "%d%% perfs, %d sampled jumps: {", GetPerfectJumps(client), GetSampledJumps(client));
|
||||||
|
|
||||||
|
int iSize = gA_JumpStats[client].Length;
|
||||||
|
int iEnd = (iSize >= gI_SampleSize)? (iSize - gI_SampleSize):0;
|
||||||
|
|
||||||
|
for(int i = iSize - 1; i >= iEnd; i--)
|
||||||
|
{
|
||||||
|
Format(buffer, maxlength, "%s %d,", buffer, gA_JumpStats[client].Get(i, StatsArray_Scrolls));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Beautify the text output so that the jumps are separated inside the curly braces, without irrelevant commas.
|
||||||
|
int iPos = strlen(buffer) - 1;
|
||||||
|
|
||||||
|
if(buffer[iPos] == ',')
|
||||||
|
{
|
||||||
|
buffer[iPos] = ' ';
|
||||||
|
}
|
||||||
|
|
||||||
|
StrCat(buffer, maxlength, "}");
|
||||||
|
}
|
||||||
|
|
||||||
|
int GetSampledJumps(int client)
|
||||||
|
{
|
||||||
|
if(gA_JumpStats[client] == null)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int iSize = gA_JumpStats[client].Length;
|
||||||
|
int iEnd = (iSize >= gI_SampleSize)? (iSize - gI_SampleSize):0;
|
||||||
|
|
||||||
|
return (iSize - iEnd);
|
||||||
|
}
|
||||||
|
|
||||||
|
int GetPerfectJumps(int client)
|
||||||
|
{
|
||||||
|
int iPerfs = 0;
|
||||||
|
int iSize = gA_JumpStats[client].Length;
|
||||||
|
int iEnd = (iSize >= gI_SampleSize)? (iSize - gI_SampleSize):0;
|
||||||
|
int iTotalJumps = (iSize - iEnd);
|
||||||
|
|
||||||
|
for(int i = iSize - 1; i >= iEnd; i--)
|
||||||
|
{
|
||||||
|
if(view_as<bool>(gA_JumpStats[client].Get(i, StatsArray_PerfectJump)))
|
||||||
|
{
|
||||||
|
iPerfs++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(iTotalJumps == 0) // Don't throw a divide-by-zero error.
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return RoundToZero((float(iPerfs) / iTotalJumps) * 100);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Action OnPlayerRunCmd(int client, int &buttons)
|
||||||
|
{
|
||||||
|
if(gB_Shavit || !IsPlayerAlive(client) || IsFakeClient(client))
|
||||||
|
{
|
||||||
|
return Plugin_Continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
return SetupMove(client, buttons);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Action Shavit_OnUserCmdPre(int client, int &buttons, int &impulse, float vel[3], float angles[3], TimerStatus status, int track, int style, int mouse[2])
|
||||||
|
{
|
||||||
|
// Ignore autobhop styles.
|
||||||
|
if(Shavit_GetStyleSettingBool(style, "autobhop"))
|
||||||
|
{
|
||||||
|
return Plugin_Continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
return SetupMove(client, buttons);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ResetStatsArray(int client)
|
||||||
|
{
|
||||||
|
for(int i = 0; i < STATSARRAY_SIZE; i++)
|
||||||
|
{
|
||||||
|
gA_StatsArray[client][i] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
gI_ReleaseTick[client] = GetGameTickCount();
|
||||||
|
gI_AirTicks[client] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool TRFilter_NoPlayers(int entity, int mask, any data)
|
||||||
|
{
|
||||||
|
return (entity != view_as<int>(data) || (entity < 1 || entity > MaxClients));
|
||||||
|
}
|
||||||
|
|
||||||
|
float GetGroundDistance(int client)
|
||||||
|
{
|
||||||
|
if(GetEntPropEnt(client, Prop_Send, "m_hGroundEntity") == 0)
|
||||||
|
{
|
||||||
|
return 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
float fPosition[3];
|
||||||
|
GetClientAbsOrigin(client, fPosition);
|
||||||
|
TR_TraceRayFilter(fPosition, view_as<float>({90.0, 0.0, 0.0}), MASK_PLAYERSOLID, RayType_Infinite, TRFilter_NoPlayers, client);
|
||||||
|
|
||||||
|
float fGroundPosition[3];
|
||||||
|
|
||||||
|
if(TR_DidHit() && TR_GetEndPosition(fGroundPosition))
|
||||||
|
{
|
||||||
|
return GetVectorDistance(fPosition, fGroundPosition);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
Action SetupMove(int client, int buttons)
|
||||||
|
{
|
||||||
|
if((sv_autobunnyhopping != null && gB_AutoBunnyhopping) || Oryx_CanBypass(client))
|
||||||
|
{
|
||||||
|
return Plugin_Continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool bOnGround = ((GetEntityFlags(client) & FL_ONGROUND) > 0 || GetEntProp(client, Prop_Send, "m_nWaterLevel") >= 2);
|
||||||
|
|
||||||
|
if(bOnGround)
|
||||||
|
{
|
||||||
|
gI_GroundTicks[client]++;
|
||||||
|
}
|
||||||
|
|
||||||
|
float fAbsVelocity[3];
|
||||||
|
GetEntPropVector(client, Prop_Data, "m_vecAbsVelocity", fAbsVelocity);
|
||||||
|
|
||||||
|
float fSpeed = (SquareRoot(Pow(fAbsVelocity[0], 2.0) + Pow(fAbsVelocity[1], 2.0)));
|
||||||
|
|
||||||
|
// Player isn't really playing but is just trying to make the anticheat go nuts.
|
||||||
|
if(fSpeed > 225.0 && IsLegalMoveType(client, false))
|
||||||
|
{
|
||||||
|
CollectJumpStats(client, bOnGround, buttons, fAbsVelocity[2]);
|
||||||
|
}
|
||||||
|
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ResetStatsArray(client);
|
||||||
|
}
|
||||||
|
|
||||||
|
gB_PreviousGround[client] = bOnGround;
|
||||||
|
gI_PreviousButtons[client] = buttons;
|
||||||
|
|
||||||
|
return Plugin_Continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CollectJumpStats(int client, bool bOnGround, int buttons, float fAbsVelocityZ)
|
||||||
|
{
|
||||||
|
// States
|
||||||
|
int iGroundState = State_Nothing;
|
||||||
|
int iButtonState = State_Nothing;
|
||||||
|
|
||||||
|
if(bOnGround && !gB_PreviousGround[client])
|
||||||
|
{
|
||||||
|
iGroundState = State_Landing;
|
||||||
|
}
|
||||||
|
|
||||||
|
else if(!bOnGround && gB_PreviousGround[client])
|
||||||
|
{
|
||||||
|
iGroundState = State_Jumping;
|
||||||
|
}
|
||||||
|
|
||||||
|
if((buttons & IN_JUMP) > 0 && (gI_PreviousButtons[client] & IN_JUMP) == 0)
|
||||||
|
{
|
||||||
|
iButtonState = State_Pressing;
|
||||||
|
}
|
||||||
|
|
||||||
|
else if((buttons & IN_JUMP) == 0 && (gI_PreviousButtons[client] & IN_JUMP) > 0)
|
||||||
|
{
|
||||||
|
iButtonState = State_Releasing;
|
||||||
|
}
|
||||||
|
|
||||||
|
int iTicks = GetGameTickCount();
|
||||||
|
|
||||||
|
if(iButtonState == State_Pressing)
|
||||||
|
{
|
||||||
|
gA_StatsArray[client][StatsArray_Scrolls]++;
|
||||||
|
gA_StatsArray[client][StatsArray_AverageTicks] += (iTicks - gI_ReleaseTick[client]);
|
||||||
|
|
||||||
|
if(bOnGround)
|
||||||
|
{
|
||||||
|
if((buttons & IN_JUMP) > 0)
|
||||||
|
{
|
||||||
|
gA_StatsArray[client][StatsArray_PerfectJump] = !gB_PreviousGround[client];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
else
|
||||||
|
{
|
||||||
|
float fDistance = GetGroundDistance(client);
|
||||||
|
|
||||||
|
if(fDistance < 33.0)
|
||||||
|
{
|
||||||
|
if(fAbsVelocityZ > 0.0 && gI_CurrentJump[client] > 1)
|
||||||
|
{
|
||||||
|
// 'Inject' data into the previous recorded jump.
|
||||||
|
int iJump = (gI_CurrentJump[client] - 1);
|
||||||
|
int iAfter = gA_JumpStats[client].Get(iJump, StatsArray_AfterGround);
|
||||||
|
gA_JumpStats[client].Set(iJump, iAfter + 1, StatsArray_AfterGround);
|
||||||
|
}
|
||||||
|
|
||||||
|
else if(fAbsVelocityZ < 0.0)
|
||||||
|
{
|
||||||
|
gA_StatsArray[client][StatsArray_BeforeGround]++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
else if(iButtonState == State_Releasing)
|
||||||
|
{
|
||||||
|
gI_ReleaseTick[client] = iTicks;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!bOnGround && gI_AirTicks[client]++ > TICKS_NOT_COUNT_AIR)
|
||||||
|
{
|
||||||
|
ResetStatsArray(client);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(iGroundState == State_Landing)
|
||||||
|
{
|
||||||
|
int iScrolls = gA_StatsArray[client][StatsArray_Scrolls];
|
||||||
|
|
||||||
|
if(iScrolls == 0)
|
||||||
|
{
|
||||||
|
ResetStatsArray(client);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(gI_GroundTicks[client] < TICKS_NOT_COUNT_JUMP)
|
||||||
|
{
|
||||||
|
int iJump = gI_CurrentJump[client];
|
||||||
|
gA_JumpStats[client].Resize(iJump + 1);
|
||||||
|
|
||||||
|
gA_JumpStats[client].Set(iJump, iScrolls, StatsArray_Scrolls);
|
||||||
|
gA_JumpStats[client].Set(iJump, gA_StatsArray[client][StatsArray_BeforeGround], StatsArray_BeforeGround);
|
||||||
|
gA_JumpStats[client].Set(iJump, 0, StatsArray_AfterGround);
|
||||||
|
gA_JumpStats[client].Set(iJump, (gA_StatsArray[client][StatsArray_AverageTicks] / iScrolls), StatsArray_AverageTicks);
|
||||||
|
gA_JumpStats[client].Set(iJump, gA_StatsArray[client][StatsArray_PerfectJump], StatsArray_PerfectJump);
|
||||||
|
|
||||||
|
#if defined DEBUG
|
||||||
|
PrintToChat(client, "{ %d, %d, %d, %d, %d, %d }", gA_StatsArray[client][StatsArray_Scrolls],
|
||||||
|
gA_StatsArray[client][StatsArray_BeforeGround],
|
||||||
|
(iJump > 0)? gA_JumpStats[client].Get(iJump - 1, gA_StatsArray[client][StatsArray_AfterGround]):0,
|
||||||
|
gA_StatsArray[client][StatsArray_GroundTicks],
|
||||||
|
(gA_StatsArray[client][StatsArray_AverageTicks] / iScrolls),
|
||||||
|
gA_StatsArray[client][StatsArray_PerfectJump]);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
gI_CurrentJump[client]++;
|
||||||
|
}
|
||||||
|
|
||||||
|
gI_GroundTicks[client] = 0;
|
||||||
|
|
||||||
|
ResetStatsArray(client);
|
||||||
|
}
|
||||||
|
|
||||||
|
else if(iGroundState == State_Jumping && gI_CurrentJump[client] >= gI_SampleSize)
|
||||||
|
{
|
||||||
|
AnalyzeStats(client);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int Min(int a, int b)
|
||||||
|
{
|
||||||
|
return (a < b)? a:b;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Max(int a, int b)
|
||||||
|
{
|
||||||
|
return (a > b)? a:b;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Abs(int num)
|
||||||
|
{
|
||||||
|
return (num < 0)? -num:num;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AnalyzeStats(int client)
|
||||||
|
{
|
||||||
|
int iPerfs = GetPerfectJumps(client);
|
||||||
|
|
||||||
|
// "Pattern analysis"
|
||||||
|
int iVeryHighNumber = 0;
|
||||||
|
int iSameAsNext = 0;
|
||||||
|
int iCloseToNext = 0;
|
||||||
|
int iBadIntervals = 0;
|
||||||
|
int iLowBefores = 0;
|
||||||
|
int iLowAfters = 0;
|
||||||
|
int iSameBeforeAfter = 0;
|
||||||
|
|
||||||
|
for(int i = (gI_CurrentJump[client] - gI_SampleSize); i < gI_CurrentJump[client] - 1; i++)
|
||||||
|
{
|
||||||
|
// TODO: Cache iNextScrolls for the next time this code is ran. I'm tired and can't really think right now..
|
||||||
|
int iCurrentScrolls = gA_JumpStats[client].Get(i, StatsArray_Scrolls);
|
||||||
|
int iTicks = gA_JumpStats[client].Get(i, StatsArray_AverageTicks);
|
||||||
|
int iBefores = gA_JumpStats[client].Get(i, StatsArray_BeforeGround);
|
||||||
|
int iAfters = gA_JumpStats[client].Get(i, StatsArray_AfterGround);
|
||||||
|
|
||||||
|
if(i != gI_SampleSize - 1)
|
||||||
|
{
|
||||||
|
int iNextScrolls = gA_JumpStats[client].Get(i + 1, StatsArray_Scrolls);
|
||||||
|
|
||||||
|
if(iCurrentScrolls == iNextScrolls)
|
||||||
|
{
|
||||||
|
iSameAsNext++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(Abs(Max(iCurrentScrolls, iNextScrolls) - Min(iCurrentScrolls, iNextScrolls)) <= 2)
|
||||||
|
{
|
||||||
|
iCloseToNext++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(iCurrentScrolls >= 17)
|
||||||
|
{
|
||||||
|
iVeryHighNumber++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(iTicks <= 2)
|
||||||
|
{
|
||||||
|
iBadIntervals++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(iBefores <= 1)
|
||||||
|
{
|
||||||
|
iLowBefores++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(iAfters <= 1)
|
||||||
|
{
|
||||||
|
iLowAfters++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(iBefores == iAfters)
|
||||||
|
{
|
||||||
|
iSameBeforeAfter++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
float fIntervals = (float(iBadIntervals) / gI_SampleSize);
|
||||||
|
|
||||||
|
bool bTriggered = true;
|
||||||
|
|
||||||
|
char[] sScrollStats = new char[300];
|
||||||
|
GetScrollStatsFormatted(client, sScrollStats, 300);
|
||||||
|
|
||||||
|
char stats_desc[1024];
|
||||||
|
|
||||||
|
// Ugly code below, I know.
|
||||||
|
if(iPerfs >= 91)
|
||||||
|
{
|
||||||
|
LogToFileEx(gS_LogPath, "%L - (" ... DESC1 ... "): %s", client, sScrollStats);
|
||||||
|
Format(stats_desc, sizeof(stats_desc), "%s :\n%s", DESC1, sScrollStats);
|
||||||
|
Oryx_Trigger(client, TRIGGER_DEFINITIVE, stats_desc);
|
||||||
|
}
|
||||||
|
|
||||||
|
else if(iPerfs >= 87 && (iSameAsNext >= 13 || iCloseToNext >= 18))
|
||||||
|
{
|
||||||
|
LogToFileEx(gS_LogPath, "%L - (" ... DESC2 ... "): %s", client, sScrollStats);
|
||||||
|
Format(stats_desc, sizeof(stats_desc), "%s :\n%s", DESC2, sScrollStats);
|
||||||
|
Oryx_Trigger(client, TRIGGER_DEFINITIVE, stats_desc);
|
||||||
|
}
|
||||||
|
|
||||||
|
else if(iPerfs >= 85 && iSameAsNext >= 13)
|
||||||
|
{
|
||||||
|
LogToFileEx(gS_LogPath, "%L - (" ... DESC3 ... "): %s", client, sScrollStats);
|
||||||
|
Format(stats_desc, sizeof(stats_desc), "%s :\n%s", DESC3, sScrollStats);
|
||||||
|
Oryx_Trigger(client, TRIGGER_DEFINITIVE, stats_desc);
|
||||||
|
}
|
||||||
|
|
||||||
|
else if(iPerfs >= 80 && iSameAsNext >= 15)
|
||||||
|
{
|
||||||
|
LogToFileEx(gS_LogPath, "%L - (" ... DESC4 ... "): %s", client, sScrollStats);
|
||||||
|
Format(stats_desc, sizeof(stats_desc), "%s :\n%s", DESC4, sScrollStats);
|
||||||
|
Oryx_Trigger(client, TRIGGER_HIGH, stats_desc);
|
||||||
|
}
|
||||||
|
|
||||||
|
else if(iPerfs >= 75 && iVeryHighNumber >= 4 && iSameAsNext >= 3 && iCloseToNext >= 10)
|
||||||
|
{
|
||||||
|
LogToFileEx(gS_LogPath, "%L - (" ... DESC5 ... "): %s", client, sScrollStats);
|
||||||
|
Format(stats_desc, sizeof(stats_desc), "%s :\n%s", DESC5, sScrollStats);
|
||||||
|
Oryx_Trigger(client, TRIGGER_HIGH, stats_desc);
|
||||||
|
}
|
||||||
|
|
||||||
|
else if(iPerfs >= 85 && iCloseToNext >= 16)
|
||||||
|
{
|
||||||
|
LogToFileEx(gS_LogPath, "%L - (" ... DESC6 ... "): %s", client, sScrollStats);
|
||||||
|
Format(stats_desc, sizeof(stats_desc), "%s :\n%s", DESC6, sScrollStats);
|
||||||
|
Oryx_Trigger(client, TRIGGER_HIGH, stats_desc);
|
||||||
|
}
|
||||||
|
|
||||||
|
else if(iPerfs >= 40 && iLowBefores >= 45)
|
||||||
|
{
|
||||||
|
LogToFileEx(gS_LogPath, "%L - (" ... DESC7 ... ") (%d): %s", client, iLowBefores, sScrollStats);
|
||||||
|
Format(stats_desc, sizeof(stats_desc), "%s (%d):\n%s", DESC7, iLowBefores, sScrollStats);
|
||||||
|
Oryx_Trigger(client, TRIGGER_MEDIUM, stats_desc);
|
||||||
|
}
|
||||||
|
|
||||||
|
else if(iPerfs >= 55 && iSameBeforeAfter >= 25)
|
||||||
|
{
|
||||||
|
LogToFileEx(gS_LogPath, "%L - (" ... DESC8 ... ") (bf %d | af %d | bfaf %d): %s", client, iLowBefores, iLowAfters, iSameBeforeAfter, sScrollStats);
|
||||||
|
Format(stats_desc, sizeof(stats_desc), "%s :\n(bf %d | af %d | bfaf %d): %s", DESC8, iLowBefores, iLowAfters, iSameBeforeAfter, sScrollStats);
|
||||||
|
Oryx_Trigger(client, TRIGGER_HIGH_NOKICK, stats_desc);
|
||||||
|
}
|
||||||
|
|
||||||
|
else if(iPerfs >= 40 && iLowAfters >= 45)
|
||||||
|
{
|
||||||
|
LogToFileEx(gS_LogPath, "%L - (" ... DESC9 ... ") (%d): %s", client, iLowAfters, sScrollStats);
|
||||||
|
Format(stats_desc, sizeof(stats_desc), "%s :\n(%d): %s", DESC9, iLowAfters, sScrollStats);
|
||||||
|
Oryx_Trigger(client, TRIGGER_LOW, stats_desc);
|
||||||
|
}
|
||||||
|
|
||||||
|
else if(iVeryHighNumber >= 15 && (iCloseToNext >= 13 || iPerfs >= 80))
|
||||||
|
{
|
||||||
|
LogToFileEx(gS_LogPath, "%L - (" ... DESC10 ... "): %s", client, sScrollStats);
|
||||||
|
Format(stats_desc, sizeof(stats_desc), "%s :\n%s", DESC10, sScrollStats);
|
||||||
|
Oryx_Trigger(client, TRIGGER_HIGH, stats_desc);
|
||||||
|
}
|
||||||
|
|
||||||
|
else if(fIntervals > 0.75)
|
||||||
|
{
|
||||||
|
LogToFileEx(gS_LogPath, "%L - (" ... DESC11 ... ", intervals: %.2f): %s", client, fIntervals, sScrollStats);
|
||||||
|
Format(stats_desc, sizeof(stats_desc), "%s :\nintervals: %.2f: %s", DESC11, fIntervals, sScrollStats);
|
||||||
|
Oryx_Trigger(client, TRIGGER_MEDIUM, stats_desc);
|
||||||
|
}
|
||||||
|
|
||||||
|
else
|
||||||
|
{
|
||||||
|
bTriggered = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(bTriggered)
|
||||||
|
{
|
||||||
|
// Hard reset stats after logging, to prevent spam.
|
||||||
|
ResetStatsArray(client);
|
||||||
|
gI_CurrentJump[client] = 0;
|
||||||
|
gA_JumpStats[client].Clear();
|
||||||
|
}
|
||||||
|
}
|
414
oryx-mini-edit/scripting/oryx.sp
Normal file
414
oryx-mini-edit/scripting/oryx.sp
Normal file
@ -0,0 +1,414 @@
|
|||||||
|
/* Oryx AC: collects and analyzes statistics to find some cheaters in CS:S, CS:GO, and TF2 bunnyhop.
|
||||||
|
* Copyright (C) 2018 Nolan O.
|
||||||
|
* Copyright (C) 2018 shavit.
|
||||||
|
*
|
||||||
|
* This program 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.
|
||||||
|
*
|
||||||
|
* 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 <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <sourcemod>
|
||||||
|
#include <sdktools>
|
||||||
|
#include <oryx>
|
||||||
|
|
||||||
|
#undef REQUIRE_PLUGIN
|
||||||
|
#include <shavit>
|
||||||
|
#include <bTimes-tas>
|
||||||
|
#include <bTimes-timer_hack>
|
||||||
|
|
||||||
|
#pragma newdecls required
|
||||||
|
#pragma semicolon 1
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
Timer_None,
|
||||||
|
Timer_Shavit,
|
||||||
|
Timer_Blacky2,
|
||||||
|
Timer_Blacky183
|
||||||
|
}
|
||||||
|
|
||||||
|
int gI_Timer = Timer_None;
|
||||||
|
char gS_SpecialString[128];
|
||||||
|
|
||||||
|
ConVar gCV_AllowBypass = null;
|
||||||
|
|
||||||
|
EngineVersion gEV_Type = Engine_Unknown;
|
||||||
|
|
||||||
|
Handle gH_Forwards_OnTrigger = null;
|
||||||
|
|
||||||
|
char gS_LogPath[PLATFORM_MAX_PATH];
|
||||||
|
char gS_BeepSound[PLATFORM_MAX_PATH];
|
||||||
|
bool gB_NoSound = false;
|
||||||
|
|
||||||
|
bool gB_Testing[MAXPLAYERS+1];
|
||||||
|
bool gB_Locked[MAXPLAYERS+1];
|
||||||
|
|
||||||
|
public Plugin myinfo =
|
||||||
|
{
|
||||||
|
name = "ORYX bunnyhop anti-cheat",
|
||||||
|
author = "Rusty, shavit",
|
||||||
|
description = "Cheat detection interface.",
|
||||||
|
version = ORYX_VERSION,
|
||||||
|
url = "https://github.com/shavitush/Oryx-AC"
|
||||||
|
}
|
||||||
|
|
||||||
|
public APLRes AskPluginLoad2(Handle myself, bool late, char[] error, int err_max)
|
||||||
|
{
|
||||||
|
CreateNative("Oryx_CanBypass", Native_CanBypass);
|
||||||
|
CreateNative("Oryx_Trigger", Native_OryxTrigger);
|
||||||
|
CreateNative("Oryx_WithinThreshold", Native_WithinThreshold);
|
||||||
|
CreateNative("Oryx_PrintToAdmins", Native_PrintToAdmins);
|
||||||
|
CreateNative("Oryx_PrintToAdminsConsole", Native_PrintToAdminsConsole);
|
||||||
|
CreateNative("Oryx_LogMessage", Native_LogMessage);
|
||||||
|
|
||||||
|
// registers library, check "bool LibraryExists(const char[] name)" in order to use with other plugins
|
||||||
|
RegPluginLibrary("oryx");
|
||||||
|
|
||||||
|
return APLRes_Success;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OnAllPluginsLoaded()
|
||||||
|
{
|
||||||
|
// workaround
|
||||||
|
if(gI_Timer == Timer_None &&
|
||||||
|
GetFeatureStatus(FeatureType_Native, "GetClientStyle") == FeatureStatus_Available &&
|
||||||
|
GetFeatureStatus(FeatureType_Native, "Style_GetConfig") == FeatureStatus_Available)
|
||||||
|
{
|
||||||
|
gI_Timer = Timer_Blacky183;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OnPluginStart()
|
||||||
|
{
|
||||||
|
gH_Forwards_OnTrigger = CreateGlobalForward("Oryx_OnTrigger", ET_Event, Param_Cell, Param_CellByRef, Param_String);
|
||||||
|
|
||||||
|
gEV_Type = GetEngineVersion();
|
||||||
|
|
||||||
|
gCV_AllowBypass = CreateConVar("oryx_allow_bypass", "1", "Allow specific styles to bypass Oryx? Refer to README.md for information.", 0, true, 0.0, true, 1.0);
|
||||||
|
|
||||||
|
CreateConVar("oryx_version", ORYX_VERSION, "Plugin version.", (FCVAR_NOTIFY | FCVAR_DONTRECORD));
|
||||||
|
|
||||||
|
RegAdminCmd("sm_otest", Command_OryxTest, ADMFLAG_BAN, "Enables the TRIGGER_TEST detection level.");
|
||||||
|
RegAdminCmd("sm_lock", Command_LockPlayer, ADMFLAG_BAN, "Disables movement for a player.");
|
||||||
|
|
||||||
|
LoadTranslations("common.phrases");
|
||||||
|
|
||||||
|
BuildPath(Path_SM, gS_LogPath, PLATFORM_MAX_PATH, "logs/oryx-ac.log");
|
||||||
|
|
||||||
|
if(LibraryExists("shavit"))
|
||||||
|
{
|
||||||
|
gI_Timer = Timer_Shavit;
|
||||||
|
}
|
||||||
|
|
||||||
|
else if(LibraryExists("tas"))
|
||||||
|
{
|
||||||
|
gI_Timer = Timer_Blacky2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OnLibraryAdded(const char[] name)
|
||||||
|
{
|
||||||
|
if(StrEqual(name, "shavit"))
|
||||||
|
{
|
||||||
|
gI_Timer = Timer_Shavit;
|
||||||
|
}
|
||||||
|
|
||||||
|
else if(StrEqual(name, "tas"))
|
||||||
|
{
|
||||||
|
gI_Timer = Timer_Blacky2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OnLibraryRemoved(const char[] name)
|
||||||
|
{
|
||||||
|
if((StrEqual(name, "shavit") && gI_Timer == Timer_Shavit) ||
|
||||||
|
(StrEqual(name, "tas") && gI_Timer == Timer_Blacky2))
|
||||||
|
{
|
||||||
|
gI_Timer = Timer_None;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OnMapStart()
|
||||||
|
{
|
||||||
|
// Beep sounds.
|
||||||
|
Handle hConfig = LoadGameConfigFile("funcommands.games");
|
||||||
|
|
||||||
|
if(hConfig == null)
|
||||||
|
{
|
||||||
|
SetFailState("Unable to load game config funcommands.games");
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(GameConfGetKeyValue(hConfig, "SoundBeep", gS_BeepSound, PLATFORM_MAX_PATH))
|
||||||
|
{
|
||||||
|
PrecacheSound(gS_BeepSound, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
delete hConfig;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OnClientPutInServer(int client)
|
||||||
|
{
|
||||||
|
gB_Locked[client] = false;
|
||||||
|
gB_Testing[client] = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Action Command_OryxTest(int client, int args)
|
||||||
|
{
|
||||||
|
gB_Testing[client] = !gB_Testing[client];
|
||||||
|
ReplyToCommand(client, "Testing is %s.", (gB_Testing[client])? "on":"off");
|
||||||
|
|
||||||
|
return Plugin_Handled;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Action Command_LockPlayer(int client, int args)
|
||||||
|
{
|
||||||
|
if(args < 1)
|
||||||
|
{
|
||||||
|
ReplyToCommand(client, "Usage: sm_lock <target>");
|
||||||
|
|
||||||
|
return Plugin_Handled;
|
||||||
|
}
|
||||||
|
|
||||||
|
char[] sArgs = new char[MAX_TARGET_LENGTH];
|
||||||
|
GetCmdArgString(sArgs, MAX_TARGET_LENGTH);
|
||||||
|
|
||||||
|
int target = FindTarget(client, sArgs);
|
||||||
|
|
||||||
|
if(target == -1)
|
||||||
|
{
|
||||||
|
return Plugin_Handled;
|
||||||
|
}
|
||||||
|
|
||||||
|
gB_Locked[target] = !gB_Locked[target];
|
||||||
|
ReplyToCommand(client, "Player has been %s.", (gB_Locked[target])? "locked":"unlocked");
|
||||||
|
PrintToChat(target, "An admin has %s your ability to move!", (gB_Locked[target])? "locked":"unlocked");
|
||||||
|
|
||||||
|
return Plugin_Handled;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Action OnPlayerRunCmd(int client, int &buttons, int &impulse, float vel[3])
|
||||||
|
{
|
||||||
|
// Movement is locked, don't allow anything.
|
||||||
|
if(gB_Locked[client])
|
||||||
|
{
|
||||||
|
buttons = 0;
|
||||||
|
vel[0] = 0.0;
|
||||||
|
vel[1] = 0.0;
|
||||||
|
impulse = 0;
|
||||||
|
|
||||||
|
return Plugin_Changed;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Plugin_Continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int Native_CanBypass(Handle plugin, int numParams)
|
||||||
|
{
|
||||||
|
if(!gCV_AllowBypass.BoolValue)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int client = GetNativeCell(1);
|
||||||
|
|
||||||
|
switch(gI_Timer)
|
||||||
|
{
|
||||||
|
case Timer_Shavit:
|
||||||
|
{
|
||||||
|
Shavit_GetStyleStrings(Shavit_GetBhopStyle(client), sSpecialString, gS_SpecialString, 128);
|
||||||
|
|
||||||
|
if(StrContains(gS_SpecialString, "oryx_bypass", false) != -1)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
case Timer_Blacky2:
|
||||||
|
{
|
||||||
|
return TAS_InEditMode(client);
|
||||||
|
}
|
||||||
|
|
||||||
|
case Timer_Blacky183:
|
||||||
|
{
|
||||||
|
any styleconfig[StyleConfig];
|
||||||
|
Style_GetConfig(GetClientStyle(client), styleconfig);
|
||||||
|
|
||||||
|
if(StrContains(styleconfig[Special_Key], "oryx_bypass", false) != -1)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int Native_OryxTrigger(Handle plugin, int numParams)
|
||||||
|
{
|
||||||
|
int client = GetNativeCell(1);
|
||||||
|
int level = GetNativeCell(2);
|
||||||
|
|
||||||
|
char[] sLevel = new char[16];
|
||||||
|
char[] sCheatDescription = new char[32];
|
||||||
|
|
||||||
|
GetNativeString(3, sCheatDescription, 32);
|
||||||
|
|
||||||
|
Action result = Plugin_Continue;
|
||||||
|
Call_StartForward(gH_Forwards_OnTrigger);
|
||||||
|
Call_PushCell(client);
|
||||||
|
Call_PushCellRef(level);
|
||||||
|
Call_PushStringEx(sCheatDescription, 32, SM_PARAM_STRING_COPY, SM_PARAM_COPYBACK);
|
||||||
|
Call_Finish(result);
|
||||||
|
|
||||||
|
if(result == Plugin_Stop)
|
||||||
|
{
|
||||||
|
return view_as<int>(Plugin_Stop);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(level == TRIGGER_LOW)
|
||||||
|
{
|
||||||
|
strcopy(sLevel, 16, "LOW");
|
||||||
|
gB_NoSound = true; // Don't play the annoying beep sound for LOW detections.
|
||||||
|
}
|
||||||
|
|
||||||
|
else if(level == TRIGGER_MEDIUM)
|
||||||
|
{
|
||||||
|
strcopy(sLevel, 16, "MEDIUM");
|
||||||
|
}
|
||||||
|
|
||||||
|
else if(level == TRIGGER_HIGH)
|
||||||
|
{
|
||||||
|
strcopy(sLevel, 16, "HIGH");
|
||||||
|
|
||||||
|
if(result != Plugin_Handled)
|
||||||
|
{
|
||||||
|
//KickClient(client, "[ORYX] %s", sCheatDescription);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
else if(level == TRIGGER_HIGH_NOKICK)
|
||||||
|
{
|
||||||
|
strcopy(sLevel, 16, "HIGH-NOKICK");
|
||||||
|
}
|
||||||
|
|
||||||
|
else if(level == TRIGGER_DEFINITIVE)
|
||||||
|
{
|
||||||
|
strcopy(sLevel, 16, "DEFINITIVE");
|
||||||
|
|
||||||
|
if(result != Plugin_Handled)
|
||||||
|
{
|
||||||
|
//KickClient(client, "[ORYX] %s", sCheatDescription);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
else if(level == TRIGGER_TEST)
|
||||||
|
{
|
||||||
|
char[] sBuffer = new char[128];
|
||||||
|
Format(sBuffer, 128, "(\x03%N\x01) - %s | Level: \x04TESTING", client, sCheatDescription);
|
||||||
|
|
||||||
|
for(int i = 1; i <= MaxClients; i++)
|
||||||
|
{
|
||||||
|
if(gB_Testing[i] && IsClientInGame(i))
|
||||||
|
{
|
||||||
|
PrintToChat(i, "%s", sBuffer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return view_as<int>(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
char[] sAuth = new char[32];
|
||||||
|
GetClientAuthId(client, AuthId_Steam3, sAuth, 32);
|
||||||
|
|
||||||
|
char[] sBuffer = new char[128];
|
||||||
|
Format(sBuffer, 128, "\x03%N\x01 - \x05%s\x01 Cheat: %s | Level: %s", client, sAuth, sCheatDescription, sLevel);
|
||||||
|
Oryx_PrintToAdmins("%s", sBuffer);
|
||||||
|
|
||||||
|
LogToFileEx(gS_LogPath, "%L - Cheat: %s | Level: %s", client, sCheatDescription, sLevel);
|
||||||
|
|
||||||
|
return view_as<int>(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int Native_WithinThreshold(Handle plugin, int numParams)
|
||||||
|
{
|
||||||
|
float f1 = GetNativeCell(1);
|
||||||
|
float f2 = GetNativeCell(2);
|
||||||
|
float threshold = GetNativeCell(3);
|
||||||
|
|
||||||
|
return view_as<int>(FloatAbs(f1 - f2) <= threshold);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int Native_PrintToAdmins(Handle plugin, int numParams)
|
||||||
|
{
|
||||||
|
static int iWritten = 0; // Useless?
|
||||||
|
|
||||||
|
char[] sBuffer = new char[300];
|
||||||
|
FormatNativeString(0, 1, 2, 300, iWritten, sBuffer);
|
||||||
|
|
||||||
|
for(int i = 1; i <= MaxClients; i++)
|
||||||
|
{
|
||||||
|
if(CheckCommandAccess(i, "oryx_admin", ADMFLAG_GENERIC))
|
||||||
|
{
|
||||||
|
PrintToChat(i, "%s\x04[ORYX]\x01 %s", (gEV_Type == Engine_CSGO)? " ":"", sBuffer);
|
||||||
|
|
||||||
|
if(!gB_NoSound)
|
||||||
|
{
|
||||||
|
if(gEV_Type == Engine_CSS || gEV_Type == Engine_TF2)
|
||||||
|
{
|
||||||
|
EmitSoundToClient(i, gS_BeepSound);
|
||||||
|
}
|
||||||
|
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ClientCommand(i, "play */%s", gS_BeepSound);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
gB_NoSound = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int Native_PrintToAdminsConsole(Handle plugin, int numParams)
|
||||||
|
{
|
||||||
|
static int iWritten = 0; // Useless?
|
||||||
|
|
||||||
|
char[] sBuffer = new char[300];
|
||||||
|
FormatNativeString(0, 1, 2, 300, iWritten, sBuffer);
|
||||||
|
|
||||||
|
for(int i = 1; i <= MaxClients; i++)
|
||||||
|
{
|
||||||
|
if(CheckCommandAccess(i, "oryx_admin", ADMFLAG_GENERIC))
|
||||||
|
{
|
||||||
|
PrintToConsole(i, "[ORYX] %s", sBuffer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int Native_LogMessage(Handle plugin, int numParams)
|
||||||
|
{
|
||||||
|
char[] sPlugin = new char[32];
|
||||||
|
|
||||||
|
if(!GetPluginInfo(plugin, PlInfo_Name, sPlugin, 32))
|
||||||
|
{
|
||||||
|
GetPluginFilename(plugin, sPlugin, 32);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int iWritten = 0; // Useless?
|
||||||
|
|
||||||
|
char[] sBuffer = new char[300];
|
||||||
|
FormatNativeString(0, 1, 2, 300, iWritten, sBuffer);
|
||||||
|
|
||||||
|
LogToFileEx(gS_LogPath, "[%s] %s", sPlugin, sBuffer);
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user