View Single Post
Author Message
joaquimandrade
Veteran Member
Join Date: Dec 2008
Location: Portugal
Old 09-17-2009 , 01:08   Module: Orpheu (added Monster Mod support)
#1

Orpheu 2 Released (NEW)

http://forums.alliedmods.net/showthread.php?t=116393

============================================= =============================================

Orpheu 1

Update:

This module let's you now hook and call virtually any function from the mod library. Read the old description to know how to teach the module to use functions and how to find them. (The natives name is different but the process is the same)

Example plugins: http://forums.alliedmods.net/showthread.php?p=966560

http://forums.alliedmods.net/showpos...6&postcount=94
http://forums.alliedmods.net/showpos...0&postcount=95
http://forums.alliedmods.net/showpos...1&postcount=81
http://forums.alliedmods.net/showpos...7&postcount=82

Linux only

Note: if you want to use/hook functions with unknown/unimplemented argument's type you can use the type "pointer" that basically's send the variable directly. Will provide an example of this later.

Code:
const OrpheuFunction:OrpheuInvalidFunction = OrpheuFunction:-1

enum _:OrpheuReturn
{
    OrpheuIgnored = 1,
    OrpheuOverride,
    OrpheuSupercede
}

enum OrpheuHookPhase
{
    OrpheuHookPre,
    OrpheuHookPost
}

// Retrieves a function pointer based on a function name (defined on a .sig file)
native OrpheuFunction:OrpheuGetFunction(libFunctionName[]);

// Retrieves a function pointer based on a function name (defined on a .sig file). Doesn't fail if it isn't found. The purpose is to find different functions depending on the mod 
native OrpheuFunction:OrpheuTryGetFunction(libFunctionName[]);

// Hooks a function based on a pointer
native OrpheuHook:OrpheuRegisterHook(OrpheuFunction:function,myFunctionName[],OrpheuHookPhase:phase = OrpheuHookPre);

// Hooks a function based on function name (defined on a .sig file)
native OrpheuHook:OrpheuRegisterHookFromName(libFunctionName[],myFunctionName[],OrpheuHookPhase:phase = OrpheuHookPre);

// Unregister a hook
native OrpheuUnregisterHook(OrpheuHook:hook);

// Gets the current return value of a hook
native any:OrpheuGetReturn();

// Sets the return of a hook
native OrpheuSetReturn(any:...);

// Sets the value of an argument
native OrpheuSetParam(num,any:...);

// Calls a function without calling its hooks
native OrpheuCall(OrpheuFunction:function,any:...);

// Calls a function and its hooks if any
native OrpheuCallSuper(OrpheuFunction:function,any:...);

// Retrieves information about the caller of the function hooked (like its name so you can know from where the hook was called)
native OrpheuGetCallerTrace(output[],len);
Old description:

Hello. I've been working on a module that allows us to call any function from Counter Strike. The idea is: nothing is hardcoded except the handling of the variables types. It is for linux only and while it would be easy to make it work for windows, the windows binary makes it hard to locate the functions that we want so I don't plan making it for windows.

The way of how it gets functions from memory is presented here:

http://forums.alliedmods.net/showthread.php?t=37115

and worked out on here:

http://wiki.alliedmods.net/Signature_Scanning
http://www.sourcemod.net/devlog/?p=55
http://www.sourcemod.net/devlog/?p=56
http://www.sourcemod.net/devlog/?p=57

These links and jim yang are who taught me the concept.

The concept of how this and plugins are bridged was created by me. So, it should not be the best implementation of it because I just learned assembly and C++ these days.

It works as follow:

You search in the file provided in "functions.zip" for the friendly name of the function you want. Example: CBasePlayer::.Observer_SetMode(int)

This function is present in the C++ class name CBasePlayer.
It receives an int as argument.
It doesn't return a value.

Now, you search in the file provided in "dump.zip" for the name that the function has in the compiled library. In this case: Observer_SetMode__11CBasePlayeri

Now you build a file with the following data:

Code:
name "ObserverSetMode"
signature "Observer_SetMode__11CBasePlayeri"
arguments "CBasePlayer *" "int"
(Like in this case) If the function is related to an object, the type of a pointer to it is passed as the first argument. I'm planning on use vdf files later.

This file is meant to be at the folder "configs/signatures" and named *.sig. It will be automatically parsed when the server starts.

Then in a plugin you would do at plugin_init or plugin_cfg:
PHP Code:
new ObserverSetModePointer getSiggedFuncPointer("ObserverSetMode"); 
and then, anywhere:

PHP Code:
execSiggedFunc(ObserverSetModePointer,id,mode); 
Where id is the ID of a player, and mode is a number associated to the camera mode.


Restrictions: if you want to call a function associated to an object that doesn't has an associated entity in the world, you can't. Also only some types are currently implemented so you just can call functions that only have implemented types.

I want to make that it hooks functions but that is too advanced for me right now. I will try to learn it in the near future. Then, maybe it will allow to call the functions from any object by hooking the use or creation of them.

Implemented types:

Code:
"int" (available as return)
"char *"
"char const *"
"entvars_s *" (available as return)
"edict_s *" (available as return)
"Vector const &"
"Vector &"
"Vector"
"TraceResult *" (available as return)
"bool" (available as return)
"float" (available as return)
Those below share the same implementation because they share a base class (I believe that's the reason) and you can also use one name of these as the name of a not implemented equivalent type while I don't hardcode them all. Can also be used as return:

Code:
"CBasePlayer *",
"CGrenade *",
"CHEGrenade *",
"CBreakable *",
"CBaseDoor *",
"CFuncRotating *",
"CHostage *",
"CBasePlayerWeapon *",
"CBasePlayerItem *",
"CAWP *"
If anyone that knows C++ can give me a hand in implementing the types handling I will be appreciated. Also, I might need to rethink the code so it can return values that take more than one cell.

It brings as examples:

Code:
CBreakableDie.sig
CGrenade_Detonate.sig
CGrenade_Detonate2.sig
CGrenade_Detonate3.sig
ObserverSetMode.sig
RemoveAllItems.sig
RoundRespawn.sig
By the way, do not use it to replace existent functions because it will not be as faster even if optimized (due to is dynamic nature).

Sorry for posting it in an early phase but i'm doing it because I really need a hand and need to learn more C++ and Assembly so I can advance it and improve it.

Thanks to Arkshine, Connor, Stupok, AntiBots and jim yang for support and motivation.
Attached Files
File Type: zip functions.zip (191.0 KB, 848 views)
File Type: zip objdump.zip (3.10 MB, 709 views)
File Type: zip base.zip (46.9 KB, 2342 views)
File Type: zip source.zip (156.1 KB, 670 views)
File Type: so orpheu_amxx_i386.so (132.7 KB, 524 views)
__________________

Last edited by Exolent[jNr]; 02-05-2010 at 08:00.
joaquimandrade is offline