It is surely not easy, you need to have a good understanding of how the virtual machine works. I'll give you a sample which will help you to modify it to your needs:
Код:
HOOKED_FUNCTION_NAME(STATIC_PARAMETERS_HERE, {Float, _}: ...)
{
static str[SIZE_OF_STRING_HERE], args;
if ((args = numargs()) == NUMBER_OF_STATIC_PARAMETERS_HERE)
{
// Call directly the function, it doesn't have arguments to format
return FUNCTION_NAME(STATIC_PARAMETERS_HERE);
}
while (--args > NUMBER_OF_STATIC_PARAMETERS_HERE - 1)
{
// Load the address relative to the parameter.
// pri = [FRM]
#emit LCTRL 5
// Add 12 to skip to the parameters.
#emit ADD.C 12
// Add the offset to the argument.
#emit LOAD.alt args
// alt <<= 2;
#emit SHL.C.alt 2
// Add the result.
#emit ADD
// Load the address.
#emit LOAD.I
// Push.
#emit PUSH.pri
}
// Push the parameters for "format" function (in reverse).
// format[]
#emit PUSH.S string
// len
#emit PUSH.C SIZE_OF_STRING_HERE
// output[]
#emit PUSH.C str
// Push the number of arguments (stored in address 8) and call native "format"
#emit LOAD.S.pri 8
#emit ADD.C 8
#emit PUSH.pri
#emit SYSREQ.C format
// Restore the stack and heap.
#emit LCTRL 5
#emit SCTRL 4
return FUNCTION_NAME(STATIC_PARAMETERS_HERE_EXCEPT_LAST_STRING, str);
}
and because of the sysreq bug, include:
pawn Код:
forward _SYSREQ_fix_();
public _SYSREQ_fix_()
{
format("", 0, "");
}
so it won't crash the compiler. So basically, you have to change the orange text only (add the static parameters, the number of them and the size of the string). An example now with 2 static parameters (
db and
query):
Код:
DBResult: db_queryf(DB: db, query[], {Float, _}: ...)
{
static str[1024], args;
if ((args = numargs()) == 2)
{
return db_query(db, query);
}
while (--args > 1)
{
#emit LCTRL 5
#emit ADD.C 12
#emit LOAD.alt args
#emit SHL.C.alt 2
#emit ADD
#emit LOAD.I
#emit PUSH.pri
}
#emit PUSH.S query
#emit PUSH.C 1024
#emit PUSH.C str
#emit LOAD.S.pri 8
#emit ADD.C 8
#emit PUSH.pri
#emit SYSREQ.C format
#emit LCTRL 5
#emit SCTRL 4
return db_query(db, str);
}
You can hopefully create your own functions with formatting easily. For more related to
#emit, read the tutorials and the PAWN Implementer Guide (even though the directive itself is not documented, you can find about opcodes, mnemonics and semantics).