More return struct fixes. Add Vector and Vector * return support. Change vfunc_call to use template. Update makefile
This commit is contained in:
		
							parent
							
								
									e07e2286cb
								
							
						
					
					
						commit
						c5b8d2fecb
					
				
							
								
								
									
										2
									
								
								Makefile
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								Makefile
									
									
									
									
									
								
							| @ -24,7 +24,7 @@ PROJECT = dhooks | |||||||
| #Uncomment for Metamod: Source enabled extension
 | #Uncomment for Metamod: Source enabled extension
 | ||||||
| USEMETA = true | USEMETA = true | ||||||
| 
 | 
 | ||||||
| OBJECTS = sdk/smsdk_ext.cpp extension.cpp vhook.cpp $(SMSDK)/public/jit/x86/assembler-x86.cpp listeners.cpp natives.cpp vfunc_call.cpp | OBJECTS = sdk/smsdk_ext.cpp extension.cpp vhook.cpp $(SMSDK)/public/jit/x86/assembler-x86.cpp listeners.cpp natives.cpp | ||||||
| 
 | 
 | ||||||
| ##############################################
 | ##############################################
 | ||||||
| ### CONFIGURE ANY OTHER FLAGS/OPTIONS HERE ###
 | ### CONFIGURE ANY OTHER FLAGS/OPTIONS HERE ###
 | ||||||
|  | |||||||
| @ -886,7 +886,6 @@ | |||||||
|     <ClCompile Include="..\extension.cpp" /> |     <ClCompile Include="..\extension.cpp" /> | ||||||
|     <ClCompile Include="..\listeners.cpp" /> |     <ClCompile Include="..\listeners.cpp" /> | ||||||
|     <ClCompile Include="..\natives.cpp" /> |     <ClCompile Include="..\natives.cpp" /> | ||||||
|     <ClCompile Include="..\vfunc_call.cpp" /> |  | ||||||
|     <ClCompile Include="..\vhook.cpp" /> |     <ClCompile Include="..\vhook.cpp" /> | ||||||
|     <ClCompile Include="..\sdk\smsdk_ext.cpp" /> |     <ClCompile Include="..\sdk\smsdk_ext.cpp" /> | ||||||
|   </ItemGroup> |   </ItemGroup> | ||||||
|  | |||||||
| @ -11,7 +11,6 @@ | |||||||
|     </ClCompile> |     </ClCompile> | ||||||
|     <ClCompile Include="..\natives.cpp" /> |     <ClCompile Include="..\natives.cpp" /> | ||||||
|     <ClCompile Include="..\listeners.cpp" /> |     <ClCompile Include="..\listeners.cpp" /> | ||||||
|     <ClCompile Include="..\vfunc_call.cpp" /> |  | ||||||
|   </ItemGroup> |   </ItemGroup> | ||||||
|   <ItemGroup> |   <ItemGroup> | ||||||
|     <ClInclude Include="..\extension.h"> |     <ClInclude Include="..\extension.h"> | ||||||
|  | |||||||
							
								
								
									
										56
									
								
								natives.cpp
									
									
									
									
									
								
							
							
						
						
									
										56
									
								
								natives.cpp
									
									
									
									
									
								
							| @ -947,6 +947,58 @@ cell_t Native_GetParamObjectPtrString(IPluginContext *pContext, const cell_t *pa | |||||||
| 	} | 	} | ||||||
| 	return 1; | 	return 1; | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | // DHookGetReturnVector(Handle:hReturn, Float:vec[3])
 | ||||||
|  | cell_t Native_GetReturnVector(IPluginContext *pContext, const cell_t *params) | ||||||
|  | { | ||||||
|  | 	HookReturnStruct *returnStruct; | ||||||
|  | 
 | ||||||
|  | 	if(!GetHandleIfValidOrError(g_HookReturnHandle, (void **)&returnStruct, pContext, params[1])) | ||||||
|  | 	{ | ||||||
|  | 		return 0; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	cell_t *buffer; | ||||||
|  | 	pContext->LocalToPhysAddr(params[2], &buffer); | ||||||
|  | 
 | ||||||
|  | 	if(returnStruct->type == ReturnType_Vector || returnStruct->type == ReturnType_VectorPtr) | ||||||
|  | 	{ | ||||||
|  | 		buffer[0] = sp_ftoc((*(Vector **)returnStruct->orgResult)->x); | ||||||
|  | 		buffer[1] = sp_ftoc((*(Vector **)returnStruct->orgResult)->y); | ||||||
|  | 		buffer[2] = sp_ftoc((*(Vector **)returnStruct->orgResult)->z); | ||||||
|  | 
 | ||||||
|  | 		return 1; | ||||||
|  | 	} | ||||||
|  | 	return pContext->ThrowNativeError("Return type is not a vector type"); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | //DHookSetReturnVector(Handle:hReturn, Float:vec[3])
 | ||||||
|  | cell_t Native_SetReturnVector(IPluginContext *pContext, const cell_t *params) | ||||||
|  | { | ||||||
|  | 	HookReturnStruct *returnStruct; | ||||||
|  | 
 | ||||||
|  | 	if(!GetHandleIfValidOrError(g_HookReturnHandle, (void **)&returnStruct, pContext, params[1])) | ||||||
|  | 	{ | ||||||
|  | 		return 0; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	cell_t *buffer; | ||||||
|  | 	pContext->LocalToPhysAddr(params[2], &buffer); | ||||||
|  | 
 | ||||||
|  | 	if(returnStruct->type == ReturnType_Vector || returnStruct->type == ReturnType_VectorPtr) | ||||||
|  | 	{ | ||||||
|  | 		if(*(Vector **)returnStruct->newResult != NULL) | ||||||
|  | 		{ | ||||||
|  | 			delete *(Vector **)returnStruct->newResult; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		*(Vector **)returnStruct->newResult = new Vector(sp_ctof(buffer[0]), sp_ctof(buffer[1]), sp_ctof(buffer[2])); | ||||||
|  | 
 | ||||||
|  | 		return 1; | ||||||
|  | 	} | ||||||
|  | 	return pContext->ThrowNativeError("Return type is not a vector type"); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| //native bool:DHookIsNullParam(Handle:hParams, num);
 | //native bool:DHookIsNullParam(Handle:hParams, num);
 | ||||||
| cell_t Native_IsNullParam(IPluginContext *pContext, const cell_t *params) | cell_t Native_IsNullParam(IPluginContext *pContext, const cell_t *params) | ||||||
| { | { | ||||||
| @ -986,8 +1038,8 @@ sp_nativeinfo_t g_Natives[] = | |||||||
| 	{"DHookSetReturn",						Native_SetReturn}, | 	{"DHookSetReturn",						Native_SetReturn}, | ||||||
| 	{"DHookSetParam",						Native_SetParam}, | 	{"DHookSetParam",						Native_SetParam}, | ||||||
| 	{"DHookGetParamVector",					Native_GetParamVector}, | 	{"DHookGetParamVector",					Native_GetParamVector}, | ||||||
| 	/*{"DHookGetReturnVector",				Native_GetReturnVector},
 | 	{"DHookGetReturnVector",				Native_GetReturnVector}, | ||||||
| 	{"DHookSetReturnVector",				Native_SetReturnVector},*/ | 	{"DHookSetReturnVector",				Native_SetReturnVector}, | ||||||
| 	{"DHookSetParamVector",					Native_SetParamVector}, | 	{"DHookSetParamVector",					Native_SetParamVector}, | ||||||
| 	{"DHookGetParamString",					Native_GetParamString}, | 	{"DHookGetParamString",					Native_GetParamString}, | ||||||
| 	{"DHookGetReturnString",				Native_GetReturnString}, | 	{"DHookGetReturnString",				Native_GetReturnString}, | ||||||
|  | |||||||
							
								
								
									
										130
									
								
								vfunc_call.h
									
									
									
									
									
								
							
							
						
						
									
										130
									
								
								vfunc_call.h
									
									
									
									
									
								
							| @ -2,6 +2,134 @@ | |||||||
| #define _INCLUDE_VFUNC_CALL_H_ | #define _INCLUDE_VFUNC_CALL_H_ | ||||||
| 
 | 
 | ||||||
| #include "vhook.h" | #include "vhook.h" | ||||||
|  | #include "extension.h" | ||||||
|  | 
 | ||||||
|  | #define PARAMINFO_SWITCH(passType) \ | ||||||
|  | 		paramInfo[i].flags = dg->params.Element(i).flag; \ | ||||||
|  | 		paramInfo[i].size = dg->params.Element(i).size; \ | ||||||
|  | 		paramInfo[i].type = passType; | ||||||
|  | 
 | ||||||
|  | #define VSTK_PARAM_SWITCH(paramType) \ | ||||||
|  | 		if(paramStruct->isChanged[i]) \ | ||||||
|  | 		{ \ | ||||||
|  | 			*(paramType *)vptr = (paramType)(paramStruct->newParams[i]); \ | ||||||
|  | 		} \ | ||||||
|  | 		else \ | ||||||
|  | 		{ \ | ||||||
|  | 			*(paramType *)vptr = (paramType)(paramStruct->orgParams[i]); \ | ||||||
|  | 		} \ | ||||||
|  | 		if(i + 1 != dg->params.Count()) \ | ||||||
|  | 		{ \ | ||||||
|  | 			vptr += dg->params.Element(i).size; \ | ||||||
|  | 		} \ | ||||||
|  | 		break; | ||||||
|  | #define VSTK_PARAM_SWITCH_FLOAT() \ | ||||||
|  | 		if(paramStruct->isChanged[i]) \ | ||||||
|  | 		{ \ | ||||||
|  | 			*(float *)vptr = *(float *)(paramStruct->newParams[i]); \ | ||||||
|  | 		} \ | ||||||
|  | 		else \ | ||||||
|  | 		{ \ | ||||||
|  | 			*(float *)vptr = *(float *)(paramStruct->orgParams[i]); \ | ||||||
|  | 		} \ | ||||||
|  | 		if(i + 1 != dg->params.Count()) \ | ||||||
|  | 		{ \ | ||||||
|  | 			vptr += dg->params.Element(i).size; \ | ||||||
|  | 		} \ | ||||||
|  | 		break; | ||||||
|  | 
 | ||||||
|  | template <class T> | ||||||
|  | T CallVFunction(DHooksCallback *dg, HookParamsStruct *paramStruct, void *iface) | ||||||
|  | { | ||||||
|  | 	SourceMod::PassInfo *paramInfo = NULL; | ||||||
|  | 	SourceMod::PassInfo returnInfo; | ||||||
|  | 
 | ||||||
|  | 	if(dg->returnType != ReturnType_Void) | ||||||
|  | 	{ | ||||||
|  | 		returnInfo.flags = dg->returnFlag; | ||||||
|  | 		returnInfo.size = sizeof(T); | ||||||
|  | 		if( dg->returnType != ReturnType_Vector) | ||||||
|  | 		{ | ||||||
|  | 			returnInfo.type = PassType_Basic; | ||||||
|  | 		} | ||||||
|  | 		else | ||||||
|  | 		{ | ||||||
|  | 			returnInfo.type = PassType_Object; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	ICallWrapper *pCall; | ||||||
|  | 
 | ||||||
|  | 	size_t size = GetStackArgsSize(dg); | ||||||
|  | 
 | ||||||
|  | 	unsigned char *vstk = (unsigned char *)malloc(sizeof(void *) + size); | ||||||
|  | 	unsigned char *vptr = vstk; | ||||||
|  | 
 | ||||||
|  | 	*(void **)vptr = iface; | ||||||
|  | 
 | ||||||
|  | 	if(paramStruct) | ||||||
|  | 	{ | ||||||
|  | 		vptr += sizeof(void *); | ||||||
|  | 		paramInfo = (SourceMod::PassInfo *)malloc(sizeof(SourceMod::PassInfo) * dg->params.Count()); | ||||||
|  | 		for(int i = 0; i < dg->params.Count(); i++) | ||||||
|  | 		{ | ||||||
|  | 			switch(dg->params.Element(i).type) | ||||||
|  | 			{ | ||||||
|  | 				case HookParamType_Int: | ||||||
|  | 					PARAMINFO_SWITCH(PassType_Basic); | ||||||
|  | 					VSTK_PARAM_SWITCH(int); | ||||||
|  | 				case HookParamType_Bool: | ||||||
|  | 					PARAMINFO_SWITCH(PassType_Basic); | ||||||
|  | 					VSTK_PARAM_SWITCH(cell_t); | ||||||
|  | 				case HookParamType_Float: | ||||||
|  | 					PARAMINFO_SWITCH(PassType_Float); | ||||||
|  | 					VSTK_PARAM_SWITCH_FLOAT(); | ||||||
|  | 				case HookParamType_String: | ||||||
|  | 					PARAMINFO_SWITCH(PassType_Object); | ||||||
|  | 					VSTK_PARAM_SWITCH(int); | ||||||
|  | 				case HookParamType_StringPtr: | ||||||
|  | 					PARAMINFO_SWITCH(PassType_Basic); | ||||||
|  | 					VSTK_PARAM_SWITCH(string_t *); | ||||||
|  | 				case HookParamType_CharPtr: | ||||||
|  | 					PARAMINFO_SWITCH(PassType_Basic); | ||||||
|  | 					VSTK_PARAM_SWITCH(char *); | ||||||
|  | 				case HookParamType_VectorPtr: | ||||||
|  | 					PARAMINFO_SWITCH(PassType_Basic); | ||||||
|  | 					VSTK_PARAM_SWITCH(Vector *); | ||||||
|  | 				case HookParamType_CBaseEntity: | ||||||
|  | 					PARAMINFO_SWITCH(PassType_Basic); | ||||||
|  | 					VSTK_PARAM_SWITCH(CBaseEntity *); | ||||||
|  | 				case HookParamType_Edict: | ||||||
|  | 					PARAMINFO_SWITCH(PassType_Basic); | ||||||
|  | 					VSTK_PARAM_SWITCH(edict_t *); | ||||||
|  | 				default: | ||||||
|  | 					PARAMINFO_SWITCH(PassType_Basic); | ||||||
|  | 					VSTK_PARAM_SWITCH(void *); | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	T ret = 0; | ||||||
|  | 	if(dg->returnType == ReturnType_Void) | ||||||
|  | 	{ | ||||||
|  | 		pCall = g_pBinTools->CreateVCall(dg->offset, 0, 0, NULL, paramInfo, dg->params.Count()); | ||||||
|  | 		pCall->Execute(vstk, NULL); | ||||||
|  | 	} | ||||||
|  | 	else | ||||||
|  | 	{ | ||||||
|  | 		pCall = g_pBinTools->CreateVCall(dg->offset, 0, 0, &returnInfo, paramInfo, dg->params.Count()); | ||||||
|  | 		pCall->Execute(vstk, &ret); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	pCall->Destroy(); | ||||||
|  | 	free(vstk); | ||||||
|  | 
 | ||||||
|  | 	if(paramInfo != NULL) | ||||||
|  | 	{ | ||||||
|  | 		free(paramInfo); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return ret; | ||||||
|  | } | ||||||
| 
 | 
 | ||||||
| void *CallVFunction(DHooksCallback *dg, HookParamsStruct *paramStruct, void *iface); |  | ||||||
| #endif | #endif | ||||||
|  | |||||||
							
								
								
									
										193
									
								
								vhook.cpp
									
									
									
									
									
								
							
							
						
						
									
										193
									
								
								vhook.cpp
									
									
									
									
									
								
							| @ -53,6 +53,10 @@ DHooksManager::DHooksManager(HookSetup *setup, void *iface, IPluginFunction *rem | |||||||
| 	{ | 	{ | ||||||
| 		protoInfo.SetReturnType(sizeof(string_t), SourceHook::PassInfo::PassType_Object, setup->returnFlag, NULL, NULL, NULL, NULL);//We have to be 4 really... or else RIP
 | 		protoInfo.SetReturnType(sizeof(string_t), SourceHook::PassInfo::PassType_Object, setup->returnFlag, NULL, NULL, NULL, NULL);//We have to be 4 really... or else RIP
 | ||||||
| 	} | 	} | ||||||
|  | 	else if(this->callback->returnType == ReturnType_Vector) | ||||||
|  | 	{ | ||||||
|  | 		protoInfo.SetReturnType(sizeof(Vector), SourceHook::PassInfo::PassType_Object, setup->returnFlag, NULL, NULL, NULL, NULL); | ||||||
|  | 	} | ||||||
| 	else | 	else | ||||||
| 	{ | 	{ | ||||||
| 		protoInfo.SetReturnType(sizeof(void *), SourceHook::PassInfo::PassType_Basic, setup->returnFlag, NULL, NULL, NULL, NULL); | 		protoInfo.SetReturnType(sizeof(void *), SourceHook::PassInfo::PassType_Basic, setup->returnFlag, NULL, NULL, NULL, NULL); | ||||||
| @ -105,16 +109,29 @@ size_t GetStackArgsSize(DHooksCallback *dg) | |||||||
| 	{ | 	{ | ||||||
| 		res += dg->params.Element(i).size; | 		res += dg->params.Element(i).size; | ||||||
| 	} | 	} | ||||||
|  | 
 | ||||||
|  | 	if(dg->returnType == ReturnType_Vector)//Account for result vector ptr.
 | ||||||
|  | 	{ | ||||||
|  | 		res += sizeof(void *); | ||||||
|  | 	} | ||||||
| 	return res; | 	return res; | ||||||
| } | } | ||||||
| HookParamsStruct *GetParamStruct(DHooksCallback *dg, void **argStack, size_t argStackSize) | HookParamsStruct *GetParamStruct(DHooksCallback *dg, void **argStack, size_t argStackSize) | ||||||
| { | { | ||||||
| 	HookParamsStruct *params = new HookParamsStruct(); | 	HookParamsStruct *params = new HookParamsStruct(); | ||||||
| 	params->dg = dg; | 	params->dg = dg; | ||||||
|  | 	if(dg->returnType != ReturnType_Vector) | ||||||
|  | 	{ | ||||||
| 		params->orgParams = (void **)malloc(argStackSize); | 		params->orgParams = (void **)malloc(argStackSize); | ||||||
|  | 		memcpy(params->orgParams, argStack, argStackSize); | ||||||
|  | 	} | ||||||
|  | 	else //Offset result ptr
 | ||||||
|  | 	{ | ||||||
|  | 		params->orgParams = (void **)malloc(argStackSize-sizeof(void *)); | ||||||
|  | 		memcpy(params->orgParams, argStack+sizeof(void *), argStackSize); | ||||||
|  | 	} | ||||||
| 	params->newParams = (void **)malloc(dg->params.Count() * sizeof(void *)); | 	params->newParams = (void **)malloc(dg->params.Count() * sizeof(void *)); | ||||||
| 	params->isChanged = (bool *)malloc(dg->params.Count() * sizeof(bool)); | 	params->isChanged = (bool *)malloc(dg->params.Count() * sizeof(bool)); | ||||||
| 	memcpy(params->orgParams, argStack, argStackSize); |  | ||||||
| 	for(int i = 0; i < dg->params.Count(); i++) | 	for(int i = 0; i < dg->params.Count(); i++) | ||||||
| 	{ | 	{ | ||||||
| 		params->newParams[i] = NULL; | 		params->newParams[i] = NULL; | ||||||
| @ -128,6 +145,7 @@ HookReturnStruct *GetReturnStruct(DHooksCallback *dg) | |||||||
| 	res->isChanged = false; | 	res->isChanged = false; | ||||||
| 	res->type = dg->returnType; | 	res->type = dg->returnType; | ||||||
| 	res->newResult = malloc(sizeof(void *)); | 	res->newResult = malloc(sizeof(void *)); | ||||||
|  | 	*(void **)res->newResult = NULL; | ||||||
| 	res->orgResult = malloc(sizeof(void *)); | 	res->orgResult = malloc(sizeof(void *)); | ||||||
| 
 | 
 | ||||||
| 	if(g_SHPtr->GetOrigRet() && dg->post) | 	if(g_SHPtr->GetOrigRet() && dg->post) | ||||||
| @ -137,7 +155,6 @@ HookReturnStruct *GetReturnStruct(DHooksCallback *dg) | |||||||
| 			case ReturnType_String: | 			case ReturnType_String: | ||||||
| 				*(string_t *)res->orgResult = META_RESULT_ORIG_RET(string_t); | 				*(string_t *)res->orgResult = META_RESULT_ORIG_RET(string_t); | ||||||
| 				break; | 				break; | ||||||
| 			//ReturnType_Vector,
 |  | ||||||
| 			case ReturnType_Int: | 			case ReturnType_Int: | ||||||
| 				*(int *)res->orgResult = META_RESULT_ORIG_RET(int); | 				*(int *)res->orgResult = META_RESULT_ORIG_RET(int); | ||||||
| 				break; | 				break; | ||||||
| @ -147,7 +164,14 @@ HookReturnStruct *GetReturnStruct(DHooksCallback *dg) | |||||||
| 			case ReturnType_Float: | 			case ReturnType_Float: | ||||||
| 				*(float *)res->orgResult = META_RESULT_ORIG_RET(float); | 				*(float *)res->orgResult = META_RESULT_ORIG_RET(float); | ||||||
| 				break; | 				break; | ||||||
|  | 			case ReturnType_Vector: | ||||||
|  | 			{ | ||||||
|  | 				Vector vec = META_RESULT_ORIG_RET(Vector); | ||||||
|  | 				*(Vector **)res->orgResult = new Vector(vec); | ||||||
|  | 				break; | ||||||
|  | 			} | ||||||
| 			default: | 			default: | ||||||
|  | 				*(void **)res->orgResult = malloc(sizeof(void **)); | ||||||
| 				*(void **)res->orgResult = META_RESULT_ORIG_RET(void *); | 				*(void **)res->orgResult = META_RESULT_ORIG_RET(void *); | ||||||
| 				break; | 				break; | ||||||
| 		} | 		} | ||||||
| @ -264,7 +288,7 @@ void *Callback(DHooksCallback *dg, void **argStack) | |||||||
| 			g_SHPtr->DoRecall(); | 			g_SHPtr->DoRecall(); | ||||||
| 			g_SHPtr->SetRes(MRES_SUPERCEDE); | 			g_SHPtr->SetRes(MRES_SUPERCEDE); | ||||||
| 			mres = MRES_SUPERCEDE; | 			mres = MRES_SUPERCEDE; | ||||||
| 			ret = CallVFunction(dg, paramStruct, g_SHPtr->GetIfacePtr()); | 			ret = CallVFunction<void *>(dg, paramStruct, g_SHPtr->GetIfacePtr()); | ||||||
| 			break; | 			break; | ||||||
| 		case MRES_ChangedOverride: | 		case MRES_ChangedOverride: | ||||||
| 			if(dg->returnType != ReturnType_Void) | 			if(dg->returnType != ReturnType_Void) | ||||||
| @ -284,7 +308,7 @@ void *Callback(DHooksCallback *dg, void **argStack) | |||||||
| 			g_SHPtr->DoRecall(); | 			g_SHPtr->DoRecall(); | ||||||
| 			g_SHPtr->SetRes(MRES_SUPERCEDE); | 			g_SHPtr->SetRes(MRES_SUPERCEDE); | ||||||
| 			mres = MRES_SUPERCEDE; | 			mres = MRES_SUPERCEDE; | ||||||
| 			CallVFunction(dg, paramStruct, g_SHPtr->GetIfacePtr()); | 			CallVFunction<void *>(dg, paramStruct, g_SHPtr->GetIfacePtr()); | ||||||
| 			break; | 			break; | ||||||
| 		case MRES_Override: | 		case MRES_Override: | ||||||
| 			if(dg->returnType != ReturnType_Void) | 			if(dg->returnType != ReturnType_Void) | ||||||
| @ -418,7 +442,7 @@ void *Callback_float(DHooksCallback *dg, void **argStack) | |||||||
| 			g_SHPtr->DoRecall(); | 			g_SHPtr->DoRecall(); | ||||||
| 			g_SHPtr->SetRes(MRES_SUPERCEDE); | 			g_SHPtr->SetRes(MRES_SUPERCEDE); | ||||||
| 			mres = MRES_SUPERCEDE; | 			mres = MRES_SUPERCEDE; | ||||||
| 			ret = CallVFunction(dg, paramStruct, g_SHPtr->GetIfacePtr()); | 			*(float *)ret = CallVFunction<float>(dg, paramStruct, g_SHPtr->GetIfacePtr()); | ||||||
| 			break; | 			break; | ||||||
| 		case MRES_ChangedOverride: | 		case MRES_ChangedOverride: | ||||||
| 			if(dg->returnType != ReturnType_Void) | 			if(dg->returnType != ReturnType_Void) | ||||||
| @ -438,7 +462,7 @@ void *Callback_float(DHooksCallback *dg, void **argStack) | |||||||
| 			g_SHPtr->DoRecall(); | 			g_SHPtr->DoRecall(); | ||||||
| 			g_SHPtr->SetRes(MRES_SUPERCEDE); | 			g_SHPtr->SetRes(MRES_SUPERCEDE); | ||||||
| 			mres = MRES_SUPERCEDE; | 			mres = MRES_SUPERCEDE; | ||||||
| 			CallVFunction(dg, paramStruct, g_SHPtr->GetIfacePtr()); | 			CallVFunction<float>(dg, paramStruct, g_SHPtr->GetIfacePtr()); | ||||||
| 			break; | 			break; | ||||||
| 		case MRES_Override: | 		case MRES_Override: | ||||||
| 			if(dg->returnType != ReturnType_Void) | 			if(dg->returnType != ReturnType_Void) | ||||||
| @ -497,3 +521,160 @@ void *Callback_float(DHooksCallback *dg, void **argStack) | |||||||
| 	} | 	} | ||||||
| 	return *(float *)ret; | 	return *(float *)ret; | ||||||
| } | } | ||||||
|  | Vector *Callback_vector(DHooksCallback *dg, void **argStack, size_t *argsizep) | ||||||
|  | { | ||||||
|  | 	Vector *vec_result = (Vector *)argStack[0]; // Save the result
 | ||||||
|  | 
 | ||||||
|  | 	HookReturnStruct *returnStruct = NULL; | ||||||
|  | 	HookParamsStruct *paramStruct = NULL; | ||||||
|  | 	Handle_t rHndl; | ||||||
|  | 	Handle_t pHndl; | ||||||
|  | 
 | ||||||
|  | 	#ifndef __linux__ | ||||||
|  | 	*argsizep = GetStackArgsSize(dg); | ||||||
|  | 	#else | ||||||
|  | 	size_t argsize = GetStackArgsSize(dg); | ||||||
|  | 	#endif | ||||||
|  | 
 | ||||||
|  | 	if(dg->thisType == ThisPointer_CBaseEntity || dg->thisType == ThisPointer_Address) | ||||||
|  | 	{ | ||||||
|  | 		dg->plugin_callback->PushCell(GetThisPtr(g_SHPtr->GetIfacePtr(), dg->thisType)); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	returnStruct = GetReturnStruct(dg); | ||||||
|  | 	rHndl = handlesys->CreateHandle(g_HookReturnHandle, returnStruct, dg->plugin_callback->GetParentRuntime()->GetDefaultContext()->GetIdentity(), myself->GetIdentity(), NULL); | ||||||
|  | 
 | ||||||
|  | 	if(!rHndl) | ||||||
|  | 	{ | ||||||
|  | 		dg->plugin_callback->Cancel(); | ||||||
|  | 		if(returnStruct) | ||||||
|  | 		{ | ||||||
|  | 			delete returnStruct; | ||||||
|  | 		} | ||||||
|  | 		g_SHPtr->SetRes(MRES_IGNORED); | ||||||
|  | 		return NULL; | ||||||
|  | 	} | ||||||
|  | 	dg->plugin_callback->PushCell(rHndl); | ||||||
|  | 
 | ||||||
|  | 	#ifndef __linux__ | ||||||
|  | 	if(*argsizep > 0) | ||||||
|  | 	{ | ||||||
|  | 		paramStruct = GetParamStruct(dg, argStack, *argsizep); | ||||||
|  | 	#else | ||||||
|  | 	if(argsize > 0) | ||||||
|  | 	{ | ||||||
|  | 		paramStruct = GetParamStruct(dg, argStack, argsize); | ||||||
|  | 	#endif | ||||||
|  | 		pHndl = handlesys->CreateHandle(g_HookParamsHandle, paramStruct, dg->plugin_callback->GetParentRuntime()->GetDefaultContext()->GetIdentity(), myself->GetIdentity(), NULL); | ||||||
|  | 		if(!pHndl) | ||||||
|  | 		{ | ||||||
|  | 			dg->plugin_callback->Cancel(); | ||||||
|  | 			if(returnStruct) | ||||||
|  | 			{ | ||||||
|  | 				delete returnStruct; | ||||||
|  | 			} | ||||||
|  | 			if(paramStruct) | ||||||
|  | 			{ | ||||||
|  | 				delete paramStruct; | ||||||
|  | 			} | ||||||
|  | 			g_SHPtr->SetRes(MRES_IGNORED); | ||||||
|  | 			return NULL; | ||||||
|  | 		} | ||||||
|  | 		dg->plugin_callback->PushCell(pHndl); | ||||||
|  | 	} | ||||||
|  | 	cell_t result = (cell_t)MRES_Ignored; | ||||||
|  | 	META_RES mres = MRES_IGNORED; | ||||||
|  | 	dg->plugin_callback->Execute(&result); | ||||||
|  | 
 | ||||||
|  | 	void *ret = g_SHPtr->GetOverrideRetPtr(); | ||||||
|  | 	ret = vec_result; | ||||||
|  | 	switch((MRESReturn)result) | ||||||
|  | 	{ | ||||||
|  | 		case MRES_Handled: | ||||||
|  | 		case MRES_ChangedHandled: | ||||||
|  | 			g_SHPtr->DoRecall(); | ||||||
|  | 			g_SHPtr->SetRes(MRES_SUPERCEDE); | ||||||
|  | 			mres = MRES_SUPERCEDE; | ||||||
|  | 			*vec_result = CallVFunction<Vector>(dg, paramStruct, g_SHPtr->GetIfacePtr()); | ||||||
|  | 			break; | ||||||
|  | 		case MRES_ChangedOverride: | ||||||
|  | 			if(dg->returnType != ReturnType_Void) | ||||||
|  | 			{ | ||||||
|  | 				if(returnStruct->isChanged) | ||||||
|  | 				{ | ||||||
|  | 					*vec_result = **(Vector **)returnStruct->newResult; | ||||||
|  | 				} | ||||||
|  | 				else //Throw an error if no override was set
 | ||||||
|  | 				{ | ||||||
|  | 					g_SHPtr->SetRes(MRES_IGNORED); | ||||||
|  | 					mres = MRES_IGNORED; | ||||||
|  | 					dg->plugin_callback->GetParentRuntime()->GetDefaultContext()->ThrowNativeError("Tried to override return value without return value being set"); | ||||||
|  | 					break; | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
|  | 			g_SHPtr->DoRecall(); | ||||||
|  | 			g_SHPtr->SetRes(MRES_SUPERCEDE); | ||||||
|  | 			mres = MRES_SUPERCEDE; | ||||||
|  | 			CallVFunction<Vector>(dg, paramStruct, g_SHPtr->GetIfacePtr()); | ||||||
|  | 			break; | ||||||
|  | 		case MRES_Override: | ||||||
|  | 			if(dg->returnType != ReturnType_Void) | ||||||
|  | 			{ | ||||||
|  | 				if(returnStruct->isChanged) | ||||||
|  | 				{ | ||||||
|  | 					g_SHPtr->SetRes(MRES_OVERRIDE); | ||||||
|  | 					mres = MRES_OVERRIDE; | ||||||
|  | 					*vec_result = **(Vector **)returnStruct->newResult; | ||||||
|  | 				} | ||||||
|  | 				else //Throw an error if no override was set
 | ||||||
|  | 				{ | ||||||
|  | 					g_SHPtr->SetRes(MRES_IGNORED); | ||||||
|  | 					mres = MRES_IGNORED; | ||||||
|  | 					dg->plugin_callback->GetParentRuntime()->GetDefaultContext()->ThrowNativeError("Tried to override return value without return value being set"); | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
|  | 			break; | ||||||
|  | 		case MRES_Supercede: | ||||||
|  | 			if(dg->returnType != ReturnType_Void) | ||||||
|  | 			{ | ||||||
|  | 				if(returnStruct->isChanged) | ||||||
|  | 				{ | ||||||
|  | 					g_SHPtr->SetRes(MRES_SUPERCEDE); | ||||||
|  | 					mres = MRES_SUPERCEDE; | ||||||
|  | 					*vec_result = **(Vector **)returnStruct->newResult; | ||||||
|  | 				} | ||||||
|  | 				else //Throw an error if no override was set
 | ||||||
|  | 				{ | ||||||
|  | 					g_SHPtr->SetRes(MRES_IGNORED); | ||||||
|  | 					mres = MRES_IGNORED; | ||||||
|  | 					dg->plugin_callback->GetParentRuntime()->GetDefaultContext()->ThrowNativeError("Tried to override return value without return value being set"); | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
|  | 			break; | ||||||
|  | 		default: | ||||||
|  | 			g_SHPtr->SetRes(MRES_IGNORED); | ||||||
|  | 			mres = MRES_IGNORED; | ||||||
|  | 			break; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	HandleSecurity sec(dg->plugin_callback->GetParentRuntime()->GetDefaultContext()->GetIdentity(), myself->GetIdentity()); | ||||||
|  | 
 | ||||||
|  | 	if(returnStruct) | ||||||
|  | 	{ | ||||||
|  | 		handlesys->FreeHandle(rHndl, &sec); | ||||||
|  | 	} | ||||||
|  | 	if(paramStruct) | ||||||
|  | 	{ | ||||||
|  | 		handlesys->FreeHandle(pHndl, &sec); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if(dg->returnType == ReturnType_Void || mres <= MRES_HANDLED) | ||||||
|  | 	{ | ||||||
|  | 		META_CONPRINT("Returning now\n"); | ||||||
|  | 		vec_result->x = 0; | ||||||
|  | 		vec_result->y = 0; | ||||||
|  | 		vec_result->z = 0; | ||||||
|  | 		return vec_result; | ||||||
|  | 	} | ||||||
|  | 	return vec_result; | ||||||
|  | } | ||||||
|  | |||||||
							
								
								
									
										41
									
								
								vhook.h
									
									
									
									
									
								
							
							
						
						
									
										41
									
								
								vhook.h
									
									
									
									
									
								
							| @ -91,7 +91,7 @@ class HookReturnStruct | |||||||
| public: | public: | ||||||
| 	~HookReturnStruct() | 	~HookReturnStruct() | ||||||
| 	{ | 	{ | ||||||
| 		if(this->type != ReturnType_CharPtr && this->type != ReturnType_StringPtr) | 		if(this->type != ReturnType_CharPtr && this->type != ReturnType_StringPtr && this->type != ReturnType_Vector && this->type != ReturnType_VectorPtr) | ||||||
| 		{ | 		{ | ||||||
| 			free(this->newResult); | 			free(this->newResult); | ||||||
| 		} | 		} | ||||||
| @ -105,6 +105,18 @@ public: | |||||||
| 			{ | 			{ | ||||||
| 				delete *(string_t **)this->newResult; | 				delete *(string_t **)this->newResult; | ||||||
| 			} | 			} | ||||||
|  | 			else if(this->type == ReturnType_Vector || this->type == ReturnType_VectorPtr) | ||||||
|  | 			{ | ||||||
|  | 				delete *(Vector **)this->newResult; | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 		if(this->type == ReturnType_Vector || this->type == ReturnType_VectorPtr) | ||||||
|  | 		{ | ||||||
|  | 			delete *(Vector **)this->orgResult; | ||||||
|  | 		} | ||||||
|  | 		else if(this->type != ReturnType_String && this->type != ReturnType_Int && this->type != ReturnType_Bool && this->type != ReturnType_Float) | ||||||
|  | 		{ | ||||||
|  | 			free(*(void **)this->orgResult); | ||||||
| 		} | 		} | ||||||
| 		free(this->orgResult); | 		free(this->orgResult); | ||||||
| 	} | 	} | ||||||
| @ -149,6 +161,7 @@ public: | |||||||
| #ifndef __linux__ | #ifndef __linux__ | ||||||
| void *Callback(DHooksCallback *dg, void **stack, size_t *argsizep); | void *Callback(DHooksCallback *dg, void **stack, size_t *argsizep); | ||||||
| float Callback_float(DHooksCallback *dg, void **stack, size_t *argsizep); | float Callback_float(DHooksCallback *dg, void **stack, size_t *argsizep); | ||||||
|  | Vector *Callback_vector(DHooksCallback *dg, void **stack, size_t *argsizep); | ||||||
| #else | #else | ||||||
| void *Callback(DHooksCallback *dg, void **stack); | void *Callback(DHooksCallback *dg, void **stack); | ||||||
| float Callback_float(DHooksCallback *dg, void **stack); | float Callback_float(DHooksCallback *dg, void **stack); | ||||||
| @ -181,23 +194,35 @@ static void *GenerateThunk(ReturnType type) | |||||||
| 	return base; | 	return base; | ||||||
| } | } | ||||||
| #else | #else | ||||||
|  | // HUGE THANKS TO BAILOPAN (dvander)!
 | ||||||
| static void *GenerateThunk(ReturnType type) | static void *GenerateThunk(ReturnType type) | ||||||
| { | { | ||||||
| 	MacroAssemblerX86 masm; | 	MacroAssemblerX86 masm; | ||||||
|  | 	static const size_t kStackNeeded = (3 + 1) * 4; // 3 args max, 1 locals max
 | ||||||
|  | 	static const size_t kReserve = ke::Align(kStackNeeded+8, 16)-8; | ||||||
| 
 | 
 | ||||||
| 	masm.push(ebp); | 	masm.push(ebp); | ||||||
| 	masm.movl(ebp, esp); | 	masm.movl(ebp, esp); | ||||||
| 	masm.subl(esp, 4); | 	masm.subl(esp, kReserve); | ||||||
| 	masm.push(esp); | 	masm.lea(eax, Operand(esp, 3 * 4)); // ptr to 2nd var after argument space
 | ||||||
| 	masm.lea(eax, Operand(ebp, 8)); | 	masm.movl(Operand(esp, 2 * 4), eax); // set the ptr as the third argument
 | ||||||
| 	masm.push(eax); | 	masm.lea(eax, Operand(ebp, 8)); // grab the incoming caller argument vector
 | ||||||
| 	masm.push(ecx); | 	masm.movl(Operand(esp, 1 * 4), eax); // set that as the 2nd argument
 | ||||||
|  | 	masm.movl(Operand(esp, 0 * 4), ecx); // set |this| as the 1st argument
 | ||||||
| 	if(type == ReturnType_Float) | 	if(type == ReturnType_Float) | ||||||
|  | 	{ | ||||||
| 		masm.call(ExternalAddress(Callback_float)); | 		masm.call(ExternalAddress(Callback_float)); | ||||||
|  | 	} | ||||||
|  | 	else if(type == ReturnType_Vector) | ||||||
|  | 	{ | ||||||
|  | 		masm.call(ExternalAddress(Callback_vector)); | ||||||
|  | 	} | ||||||
| 	else | 	else | ||||||
|  | 	{ | ||||||
| 		masm.call(ExternalAddress(Callback)); | 		masm.call(ExternalAddress(Callback)); | ||||||
| 	masm.addl(esp, 12); | 	} | ||||||
| 	masm.pop(ecx); // grab arg size
 | 	masm.movl(ecx, Operand(esp, 3*4)); | ||||||
|  | 	masm.addl(esp, kReserve); | ||||||
| 	masm.pop(ebp); // restore ebp
 | 	masm.pop(ebp); // restore ebp
 | ||||||
| 	masm.pop(edx); // grab return address in edx
 | 	masm.pop(edx); // grab return address in edx
 | ||||||
| 	masm.addl(esp, ecx); // remove arguments
 | 	masm.addl(esp, ecx); // remove arguments
 | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user