Add some safety for Object params. Add gamedata and test plugin!
This commit is contained in:
		
							parent
							
								
									c3fcdbb7db
								
							
						
					
					
						commit
						c7a075fd8e
					
				
							
								
								
									
										22
									
								
								natives.cpp
									
									
									
									
									
								
							
							
						
						
									
										22
									
								
								natives.cpp
									
									
									
									
									
								
							| @ -94,20 +94,28 @@ cell_t Native_AddParam(IPluginContext *pContext, const cell_t *params) | ||||
| 
 | ||||
| 	info.type = (HookParamType)params[2]; | ||||
| 
 | ||||
| 	if(params[0] >= 3 && params[3] != -1) | ||||
| 	if(params[0] >= 4) | ||||
| 	{ | ||||
| 		info.size = params[3]; | ||||
| 
 | ||||
| 		if(params[0] >= 4) | ||||
| 		{ | ||||
| 			info.flag = params[4]; | ||||
| 		} | ||||
| 		info.flag = params[4]; | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		info.flag = PASSFLAG_BYVAL; | ||||
| 	} | ||||
| 
 | ||||
| 	if(params[0] >= 3 && params[3] != -1) | ||||
| 	{ | ||||
| 		info.size = params[3]; | ||||
| 	} | ||||
| 	else if(info.type == HookParamType_Object) | ||||
| 	{ | ||||
| 		return pContext->ThrowNativeError("Object param being set with no size"); | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		info.size = GetParamTypeSize(info.type); | ||||
| 	} | ||||
| 
 | ||||
| 	info.pass_type = GetParamTypePassType(info.type); | ||||
| 	setup->params.AddToTail(info); | ||||
| 
 | ||||
|  | ||||
							
								
								
									
										77
									
								
								sourcemod/gamedata/dhooks-test.games.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										77
									
								
								sourcemod/gamedata/dhooks-test.games.txt
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,77 @@ | ||||
| "Games" | ||||
| { | ||||
| 	"cstrike" | ||||
| 	{ | ||||
| 		"Keys" | ||||
| 		{ | ||||
| 			"EngineInterface"	"VEngineServer021" | ||||
| 		} | ||||
| 		"Signatures" | ||||
| 		{ | ||||
| 			"CreateInterface" | ||||
| 			{ | ||||
| 				"library"		"engine" | ||||
| 				"windows"		"@CreateInterface" | ||||
| 				"linux"			"@CreateInterface" | ||||
| 			} | ||||
| 		} | ||||
| 		"Offsets" | ||||
| 		{ | ||||
| 			"BloodColor" | ||||
| 			{ | ||||
| 				"windows"	"68" | ||||
| 				"linux"		"69" | ||||
| 			} | ||||
| 			"GetModelName" | ||||
| 			{ | ||||
| 				"windows"	"7" | ||||
| 				"linux"		"8" | ||||
| 			} | ||||
| 			"GetMaxs" | ||||
| 			{ | ||||
| 				"windows"	"337" | ||||
| 				"linux"		"338" | ||||
| 			} | ||||
| 			"CanUse" | ||||
| 			{ | ||||
| 				"windows"	"258" | ||||
| 				"linux"		"259" | ||||
| 			} | ||||
| 			"CanHaveAmmo" | ||||
| 			{ | ||||
| 				"windows"	"97" | ||||
| 				"linux"		"97" | ||||
| 			} | ||||
| 			"SetModel" | ||||
| 			{ | ||||
| 				"windows"	"24" | ||||
| 				"linux"		"25" | ||||
| 			} | ||||
| 			"GetMaxPlayerSpeed" | ||||
| 			{ | ||||
| 				"windows"	"436" | ||||
| 				"linux"		"437" | ||||
| 			} | ||||
| 			"GiveAmmo" | ||||
| 			{ | ||||
| 				"windows"	"250" | ||||
| 				"linux"		"251" | ||||
| 			} | ||||
| 			"OnTakeDamage" | ||||
| 			{ | ||||
| 				"windows"	"62" | ||||
| 				"linux"		"63" | ||||
| 			} | ||||
| 			"ClientPrintf" | ||||
| 			{ | ||||
| 				"windows"	"45" | ||||
| 				"linux"		"45" | ||||
| 			} | ||||
| 			"AcceptInput" | ||||
| 			{ | ||||
| 				"windows"	"36" | ||||
| 				"linux"		"37" | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										281
									
								
								sourcemod/scripting/dhooks-test.sp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										281
									
								
								sourcemod/scripting/dhooks-test.sp
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,281 @@ | ||||
| #pragma semicolon 1 | ||||
| #include <sourcemod> | ||||
| #include <sdktools> | ||||
| #include <dhooks> | ||||
| 
 | ||||
| // int CBaseCombatCharacter::BloodColor(void) | ||||
| new Handle:hBloodColor; | ||||
| 
 | ||||
| // bool CBaseCombatCharacter::Weapon_CanUse(CBaseCombatWeapon *) | ||||
| new Handle:hHookCanUse; | ||||
| 
 | ||||
| // Vector CBasePlayer::GetPlayerMaxs() | ||||
| new Handle:hGetMaxs; | ||||
| 
 | ||||
| // string_t CBaseEntity::GetModelName(void) | ||||
| new Handle:hGetModelName; | ||||
| 
 | ||||
| // bool CGameRules::CanHaveAmmo(CBaseCombatCharacter *, int) | ||||
| new Handle:hCanHaveAmmo; | ||||
| 
 | ||||
| // void CBaseEntity::SetModel(char  const*) | ||||
| new Handle:hSetModel; | ||||
| 
 | ||||
| //float CCSPlayer::GetPlayerMaxSpeed() | ||||
| new Handle:hGetSpeed; | ||||
| 
 | ||||
| //int CCSPlayer::OnTakeDamage(CTakeDamageInfo const&) | ||||
| new Handle:hTakeDamage; | ||||
| 
 | ||||
| // bool CBaseEntity::AcceptInput(char  const*, CBaseEntity*, CBaseEntity*, variant_t, int) | ||||
| new Handle:hAcceptInput; | ||||
| 
 | ||||
| //int CBaseCombatCharacter::GiveAmmo(int, int, bool) | ||||
| new Handle:hGiveAmmo; | ||||
| 
 | ||||
| // CVEngineServer::ClientPrintf(edict_t *, char  const*) | ||||
| new Handle:hClientPrintf; | ||||
| 
 | ||||
| public OnPluginStart() | ||||
| { | ||||
| 	new Handle:temp = LoadGameConfigFile("dhooks-test.games"); | ||||
| 	 | ||||
| 	if(temp == INVALID_HANDLE) | ||||
| 	{ | ||||
| 		SetFailState("Why you no has gamedata?"); | ||||
| 	} | ||||
| 	 | ||||
| 	new offset; | ||||
| 	 | ||||
| 	offset = GameConfGetOffset(temp, "BloodColor"); | ||||
| 	hBloodColor = DHookCreate(offset, HookType_Entity, ReturnType_Int, ThisPointer_CBaseEntity, BloodColorPost); | ||||
| 	 | ||||
| 	offset = GameConfGetOffset(temp, "GetModelName"); | ||||
| 	hGetModelName = DHookCreate(offset, HookType_Entity, ReturnType_String, ThisPointer_CBaseEntity, GetModelName); | ||||
| 	 | ||||
| 	offset = GameConfGetOffset(temp, "GetMaxs"); | ||||
| 	hGetMaxs = DHookCreate(offset, HookType_Entity, ReturnType_Vector, ThisPointer_Ignore, GetMaxsPost); | ||||
| 	 | ||||
| 	offset = GameConfGetOffset(temp, "CanUse"); | ||||
| 	hHookCanUse = DHookCreate(offset, HookType_Entity, ReturnType_Bool, ThisPointer_CBaseEntity, CanUsePost); | ||||
| 	DHookAddParam(hHookCanUse, HookParamType_CBaseEntity); | ||||
| 	 | ||||
| 	offset = GameConfGetOffset(temp, "CanHaveAmmo"); | ||||
| 	hCanHaveAmmo = DHookCreate(offset, HookType_GameRules, ReturnType_Bool, ThisPointer_Ignore, CanHaveAmmoPost); | ||||
| 	DHookAddParam(hCanHaveAmmo, HookParamType_CBaseEntity); | ||||
| 	DHookAddParam(hCanHaveAmmo, HookParamType_Int); | ||||
| 	 | ||||
| 	offset = GameConfGetOffset(temp, "SetModel"); | ||||
| 	hSetModel = DHookCreate(offset, HookType_Entity, ReturnType_Void, ThisPointer_CBaseEntity, SetModel); | ||||
| 	DHookAddParam(hSetModel, HookParamType_CharPtr); | ||||
| 	 | ||||
| 	offset = GameConfGetOffset(temp, "AcceptInput"); | ||||
| 	hAcceptInput = DHookCreate(offset, HookType_Entity, ReturnType_Bool, ThisPointer_CBaseEntity, AcceptInput); | ||||
| 	DHookAddParam(hAcceptInput, HookParamType_CharPtr); | ||||
| 	DHookAddParam(hAcceptInput, HookParamType_CBaseEntity); | ||||
| 	DHookAddParam(hAcceptInput, HookParamType_CBaseEntity); | ||||
| 	DHookAddParam(hAcceptInput, HookParamType_Object, 20); //varaint_t is a union of 12 (float[3]) plus two int type params 12 + 8 = 20 | ||||
| 	DHookAddParam(hAcceptInput, HookParamType_Int); | ||||
| 		 | ||||
| 	offset = GameConfGetOffset(temp, "GetMaxPlayerSpeed"); | ||||
| 	hGetSpeed = DHookCreate(offset, HookType_Entity, ReturnType_Float, ThisPointer_CBaseEntity, GetMaxPlayerSpeedPost); | ||||
| 		 | ||||
| 	offset = GameConfGetOffset(temp, "GiveAmmo"); | ||||
| 	hGiveAmmo = DHookCreate(offset, HookType_Entity, ReturnType_Int, ThisPointer_CBaseEntity, GiveAmmo); | ||||
| 	DHookAddParam(hGiveAmmo, HookParamType_Int); | ||||
| 	DHookAddParam(hGiveAmmo, HookParamType_Int); | ||||
| 	DHookAddParam(hGiveAmmo, HookParamType_Bool); | ||||
| 		 | ||||
| 	offset = GameConfGetOffset(temp, "OnTakeDamage"); | ||||
| 	hTakeDamage = DHookCreate(offset, HookType_Entity, ReturnType_Int, ThisPointer_CBaseEntity, OnTakeDamage); | ||||
| 	DHookAddParam(hTakeDamage, HookParamType_ObjectPtr, -1, DHookPass_ByRef); | ||||
| 	 | ||||
| 	DHookAddEntityListener(ListenType_Created, EntityCreated); | ||||
| 	 | ||||
| 	//Add client printf hook this requires effort | ||||
| 	StartPrepSDKCall(SDKCall_Static); | ||||
| 	if(!PrepSDKCall_SetFromConf(temp, SDKConf_Signature, "CreateInterface")) | ||||
| 	{ | ||||
| 		SetFailState("Failed to get CreateInterface"); | ||||
| 		CloseHandle(temp); | ||||
| 	} | ||||
| 	 | ||||
| 	PrepSDKCall_AddParameter(SDKType_String, SDKPass_Pointer); | ||||
| 	PrepSDKCall_AddParameter(SDKType_PlainOldData, SDKPass_Pointer, VDECODE_FLAG_ALLOWNULL); | ||||
| 	PrepSDKCall_SetReturnInfo(SDKType_PlainOldData, SDKPass_Plain); | ||||
| 	 | ||||
| 	new String:interface[64]; | ||||
| 	if(!GameConfGetKeyValue(temp, "EngineInterface", interface, sizeof(interface))) | ||||
| 	{ | ||||
| 		SetFailState("Failed to get engine interface name"); | ||||
| 		CloseHandle(temp); | ||||
| 	} | ||||
| 	 | ||||
| 	new Handle:call = EndPrepSDKCall(); | ||||
| 	new Address:addr = SDKCall(call, interface, 0); | ||||
| 	CloseHandle(call); | ||||
| 	 | ||||
| 	if(!addr) | ||||
| 	{ | ||||
| 		SetFailState("Failed to get engine ptr"); | ||||
| 	} | ||||
| 	 | ||||
| 	offset = GameConfGetOffset(temp, "ClientPrintf"); | ||||
| 	hClientPrintf = DHookCreate(offset, HookType_Raw, ReturnType_Void, ThisPointer_Ignore, Hook_ClientPrintf); | ||||
| 	DHookAddParam(hClientPrintf, HookParamType_Edict); | ||||
| 	DHookAddParam(hClientPrintf, HookParamType_CharPtr); | ||||
| 	DHookRaw(hClientPrintf, false, addr); | ||||
| 	 | ||||
| 	CloseHandle(temp); | ||||
| 	 | ||||
| } | ||||
| 
 | ||||
| public MRESReturn:Hook_ClientPrintf(Handle:hParams) | ||||
| { | ||||
| 	new client = DHookGetParam(hParams, 1); | ||||
| 	decl String:buffer[1024]; | ||||
| 	DHookGetParamString(hParams, 2, buffer, sizeof(buffer)); | ||||
| 	PrintToChat(client, "BUFFER %s", buffer); | ||||
| 	return MRES_Ignored; | ||||
| } | ||||
| 
 | ||||
| public MRESReturn:AcceptInput(this, Handle:hReturn, Handle:hParams) | ||||
| { | ||||
| 	new String:command[128]; | ||||
| 	DHookGetParamString(hParams, 1, command, sizeof(command)); | ||||
| 	new type = DHookGetParamObjectPtrVar(hParams, 4, 16,ObjectValueType_Int); | ||||
| 	new String:wtf[128]; | ||||
| 	DHookGetParamObjectPtrString(hParams, 4, 0, ObjectValueType_String, wtf, sizeof(wtf)); | ||||
| 	PrintToServer("Command %s Type %i String %s", command, type, wtf); | ||||
| 	DHookSetReturn(hReturn, false); | ||||
| 	return MRES_Supercede; | ||||
| } | ||||
| 
 | ||||
| public OnMapStart() | ||||
| { | ||||
| 	//Hook Gamerules function in map start | ||||
| 	DHookGamerules(hCanHaveAmmo, true, RemovalCB); | ||||
| } | ||||
| 
 | ||||
| public OnClientPutInServer(client) | ||||
| { | ||||
| 	DHookEntity(hSetModel, false, client, RemovalCB); | ||||
| 	DHookEntity(hHookCanUse, true, client, RemovalCB); | ||||
| 	DHookEntity(hGetSpeed, true, client, RemovalCB); | ||||
| 	DHookEntity(hGiveAmmo, false, client); | ||||
| 	DHookEntity(hGetModelName, true, client); | ||||
| 	DHookEntity(hTakeDamage, false, client); | ||||
| 	DHookEntity(hGetMaxs, true, client, RemovalCB); | ||||
| 	DHookEntity(hBloodColor, true, client); | ||||
| } | ||||
| 
 | ||||
| public EntityCreated(entity, const String:classname[]) | ||||
| { | ||||
| 	if(strcmp(classname, "point_servercommand") == 0) | ||||
| 	{ | ||||
| 		DHookEntity(hAcceptInput, false, entity); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| //int CCSPlayer::OnTakeDamage(CTakeDamageInfo const&) | ||||
| public MRESReturn:OnTakeDamage(this, Handle:hReturn, Handle:hParams) | ||||
| { | ||||
| 	PrintToServer("DHooksHacks = Victim %i, Attacker %i, Inflictor %i, Damage %f", this, DHookGetParamObjectPtrVar(hParams, 1, 40, ObjectValueType_Ehandle), DHookGetParamObjectPtrVar(hParams, 1, 36, ObjectValueType_Ehandle), DHookGetParamObjectPtrVar(hParams, 1, 48, ObjectValueType_Float)); | ||||
| 	 | ||||
| 	if(this <= MaxClients && this > 0 && !IsFakeClient(this)) | ||||
| 	{ | ||||
| 		DHookSetParamObjectPtrVar(hParams, 1, 48, ObjectValueType_Float, 0.0); | ||||
| 		PrintToChat(this, "Pimping your hp"); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // int CBaseCombatCharacter::GiveAmmo(int, int, bool) | ||||
| public MRESReturn:GiveAmmo(this, Handle:hReturn, Handle:hParams) | ||||
| { | ||||
| 	PrintToChat(this, "Giving %i of %i supress %i", DHookGetParam(hParams, 1), DHookGetParam(hParams, 2), DHookGetParam(hParams, 3)); | ||||
| 	return MRES_Ignored; | ||||
| } | ||||
| 
 | ||||
| // void CBaseEntity::SetModel(char  const*) | ||||
| public MRESReturn:SetModel(this, Handle:hParams) | ||||
| { | ||||
| 	//Change all bot skins to phoenix one | ||||
| 	if(IsFakeClient(this)) | ||||
| 	{ | ||||
| 		DHookSetParamString(hParams, 1, "models/player/t_phoenix.mdl"); | ||||
| 		return MRES_ChangedHandled; | ||||
| 	} | ||||
| 	return MRES_Ignored; | ||||
| } | ||||
| 
 | ||||
| //float CCSPlayer::GetPlayerMaxSpeed() | ||||
| public MRESReturn:GetMaxPlayerSpeedPost(this, Handle:hReturn) | ||||
| { | ||||
| 	//Make bots slow | ||||
| 	if(IsFakeClient(this)) | ||||
| 	{ | ||||
| 		DHookSetReturn(hReturn, 100.0); | ||||
| 		return MRES_Override; | ||||
| 	} | ||||
| 	return MRES_Ignored; | ||||
| } | ||||
| 
 | ||||
| // bool CGameRules::CanHaveAmmo(CBaseCombatCharacter *, int) | ||||
| public MRESReturn:CanHaveAmmoPost(Handle:hReturn, Handle:hParams) | ||||
| { | ||||
| 	PrintToServer("Can has ammo? %s %i", DHookGetReturn(hReturn)?"true":"false", DHookGetParam(hParams, 2)); | ||||
| 	return MRES_Ignored; | ||||
| } | ||||
| 
 | ||||
| // string_t CBaseEntity::GetModelName(void) | ||||
| public MRESReturn:GetModelName(this, Handle:hReturn) | ||||
| { | ||||
| 	new String:returnval[128]; | ||||
| 	DHookGetReturnString(hReturn, returnval, sizeof(returnval)); | ||||
| 	 | ||||
| 	if(IsFakeClient(this)) | ||||
| 	{ | ||||
| 		PrintToServer("It is a bot, Model should be: models/player/t_phoenix.mdl It is %s", returnval); | ||||
| 	} | ||||
| 	 | ||||
| 	return MRES_Ignored; | ||||
| } | ||||
| 
 | ||||
| // Vector CBasePlayer::GetPlayerMaxs() | ||||
| public MRESReturn:GetMaxsPost(Handle:hReturn) | ||||
| { | ||||
| 	new Float:vec[3]; | ||||
| 	DHookGetReturnVector(hReturn, vec); | ||||
| 	PrintToServer("Get maxes %.3f, %.3f, %.3f", vec[0], vec[1], vec[2]); | ||||
| 	 | ||||
| 	return MRES_Ignored; | ||||
| } | ||||
| 
 | ||||
| // bool CBaseCombatCharacter::Weapon_CanUse(CBaseCombatWeapon *) | ||||
| public MRESReturn:CanUsePost(this, Handle:hReturn, Handle:hParams) | ||||
| { | ||||
| 	//Bots get nothing. | ||||
| 	if(IsFakeClient(this)) | ||||
| 	{ | ||||
| 		DHookSetReturn(hReturn, false); | ||||
| 		return MRES_Override; | ||||
| 	} | ||||
| 	return MRES_Ignored; | ||||
| } | ||||
| 
 | ||||
| // int CBaseCombatCharacter::BloodColor(void) | ||||
| public MRESReturn:BloodColorPost(this, Handle:hReturn) | ||||
| { | ||||
| 	//Change the bots blood color to goldish yellow | ||||
| 	if(IsFakeClient(this)) | ||||
| 	{ | ||||
| 		DHookSetReturn(hReturn, 2); | ||||
| 		return MRES_Supercede; | ||||
| 	} | ||||
| 	return MRES_Ignored; | ||||
| } | ||||
| 
 | ||||
| public RemovalCB(hookid) | ||||
| { | ||||
| 	PrintToServer("Removed hook %i", hookid); | ||||
| } | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user