94 lines
		
	
	
		
			2.5 KiB
		
	
	
	
		
			SourcePawn
		
	
	
	
	
	
			
		
		
	
	
			94 lines
		
	
	
		
			2.5 KiB
		
	
	
	
		
			SourcePawn
		
	
	
	
	
	
| #include <sourcemod>
 | |
| #include <sdktools>
 | |
| #include <CSSFixes>
 | |
| #include <dhooks>
 | |
| 
 | |
| #pragma semicolon 1
 | |
| #pragma newdecls required
 | |
| 
 | |
| public Plugin myinfo =
 | |
| {
 | |
| 	name 			= "AntiLagSwitch",
 | |
| 	author 			= "BotoX",
 | |
| 	description 	= "",
 | |
| 	version 		= "0.0",
 | |
| 	url 			= ""
 | |
| };
 | |
| 
 | |
| Handle g_hProcessUsercmds;
 | |
| Handle g_hRunNullCommand;
 | |
| 
 | |
| int g_LastProcessed[MAXPLAYERS + 1];
 | |
| 
 | |
| public void OnPluginStart()
 | |
| {
 | |
| 	Handle hGameConf = LoadGameConfigFile("AntiLagSwitch.games");
 | |
| 	if(!hGameConf)
 | |
| 		SetFailState("Failed to load AntiLagSwitch gamedata.");
 | |
| 
 | |
| 	// void CBasePlayer::RunNullCommand( void )
 | |
| 	StartPrepSDKCall(SDKCall_Player);
 | |
| 	if(!PrepSDKCall_SetFromConf(hGameConf, SDKConf_Signature, "RunNullCommand"))
 | |
| 		SetFailState("PrepSDKCall_SetFromConf(hGameConf, SDKConf_Signature, \"RunNullCommand\" failed!");
 | |
| 
 | |
| 	g_hRunNullCommand = EndPrepSDKCall();
 | |
| 
 | |
| 	int Offset = GameConfGetOffset(hGameConf, "ProcessUsercmds");
 | |
| 	if(Offset == -1)
 | |
| 		SetFailState("Failed to find ProcessUsercmds offset");
 | |
| 
 | |
| 	/* void CBasePlayer::ProcessUsercmds( CUserCmd *cmds, int numcmds, int totalcmds,
 | |
| 	int dropped_packets, bool paused ) */
 | |
| 	g_hProcessUsercmds = DHookCreate(Offset, HookType_Entity, ReturnType_Void, ThisPointer_CBaseEntity, Hook_ProcessUsercmds);
 | |
| 	if(g_hProcessUsercmds == INVALID_HANDLE)
 | |
| 		SetFailState("Failed to DHookCreate ProcessUsercmds");
 | |
| 
 | |
| 	DHookAddParam(g_hProcessUsercmds, HookParamType_ObjectPtr);	// 1 - CUserCmd *cmds
 | |
| 	DHookAddParam(g_hProcessUsercmds, HookParamType_Int);		// 2 - int numcmds
 | |
| 	DHookAddParam(g_hProcessUsercmds, HookParamType_Int);		// 3 - int totalcmds
 | |
| 	DHookAddParam(g_hProcessUsercmds, HookParamType_Int);		// 4 - int dropped_packets
 | |
| 	DHookAddParam(g_hProcessUsercmds, HookParamType_Bool);		// 5 - bool paused
 | |
| 
 | |
| 	delete hGameConf;
 | |
| 
 | |
| 	// Late load.
 | |
| 	for(int client = 1; client <= MaxClients; client++)
 | |
| 	{
 | |
| 		if(IsClientInGame(client))
 | |
| 			OnClientPutInServer(client);
 | |
| 	}
 | |
| }
 | |
| 
 | |
| public void OnClientPutInServer(int client)
 | |
| {
 | |
| 	DHookEntity(g_hProcessUsercmds, true, client);
 | |
| 	g_LastProcessed[client] = GetGameTickCount();
 | |
| }
 | |
| 
 | |
| public void OnClientDisconnect(int client)
 | |
| {
 | |
| 	g_LastProcessed[client] = 0;
 | |
| }
 | |
| 
 | |
| public void OnPrePlayerThinkFunctions()
 | |
| {
 | |
| 	int minimum = GetGameTickCount() - 32;
 | |
| 	for(int client = 1; client <= MaxClients; client++)
 | |
| 	{
 | |
| 		if(IsClientInGame(client) && (IsFakeClient(client) || g_LastProcessed[client] < minimum))
 | |
| 		{
 | |
| 			RunNullCommand(client);
 | |
| 		}
 | |
| 	}
 | |
| }
 | |
| 
 | |
| public MRESReturn Hook_ProcessUsercmds(int client, Handle hParams)
 | |
| {
 | |
| 	g_LastProcessed[client] = GetGameTickCount();
 | |
| }
 | |
| 
 | |
| int RunNullCommand(int client)
 | |
| {
 | |
| 	return SDKCall(g_hRunNullCommand, client);
 | |
| }
 |