View Single Post
Old 08/04/2014, 09:51 AM   #13
Join Date: Mar 2009
Location: United Kingdom
Posts: 2,260
Reputation: 333
Default Re: Southclaw's & Pottus's Anti-cheat patches

Originally Posted by ****** View Post
Could I make a request (partially a suggestion). You explicitly mention that this should be included before YSI, and I agree, but there are a few things to be aware of with that:

1) You say you can use y_iterate, but if you include these patches before YSI the "foreach" macro won't yet exist and that code will never be used even if it is included later.

2) y_hooks in YSI 4.0 is awkward to deal with in terms of orderings. Currently y_hooks hooks always come before ALS hooks, even if they appear later in source code, the ordering is changed (or, more accurately, set) at run-time, not compile-time. I have a solution to this that will be released shortly (I am now back home), but the solution requires some co-operation from other library developers that want their code to come before any y_hooks code. "Breaking" an ALS chain is tricky as you need to be able to detect the chain, but this can be done. I want to try and figure out an even better way of specifying ordering, but for now this is the best I have come up with. Instead of your current hooking method use:

pawn Code:
// This function has two purposes - defines 3 states, and declares your ALS prefix.
// You seem to use different prefixes for each callback though, I'm not sure that's a
// good idea and will make detection MUCH harder.
forward @@@_AC();
// The function is never called, but can be found by the "@@@_" prefix.
public @@@_AC() <AC_state : AC_state1> {}
public @@@_AC() <AC_state : AC_state2> {}
public @@@_AC() <AC_state : AC_state3> {}

#define AC_FORWARD%0(%1) \
    forward%0(%1); \
    public%0(%1)<> return 0; \
    public%0(%1)<AC_state : AC_state1> return 0

// Now this is a normal callback.
public OnPlayerDisconnect(playerid, reason)
    // And this is the hook, no wrapping of any kind required.
    return AC_OnPlayerDisconnect(playerid, reason);

#if defined _ALS_OnPlayerDisconnect
    #undef OnPlayerDisconnect
    #define _ALS_OnPlayerDisconnect
#define OnPlayerDisconnect(%0) AC_OnPlayerDisconnect(%0) <AC_state : AC_state2>

AC_FORWARD AC_OnPlayerDisconnect(playerid, reason);

Using that, the order hooks are done in becomes:

- State-based hooks.
- y_hooks.
- ALS hooks.
- Public function.

If you need me to explain the issues in more depth, or would like to discuss alternate solutions (I would), feel free to contact me here or on IRC. This is a VERY brief post on the issue, and I wish there was a better way. Note that you also need:

pawn Code:
state AC_state : AC_state2;

Somewhere to make the whole thing work, but you could add that to every callback, I just prefer doing it in OnGameModeInit (etc).

Other than that, nice.
They already did when they first posted: "- Patches are to be designed to be included BEFORE YSI"
Kyle is offline   Reply With Quote