05.09.2013, 16:17
Hello, I have made 2 anti dialog hack includes of my own, one for gamemodes and another for filterscripts. The include for gamemodes is this:
As you can see, it just hooks the function ShowPlayerDialog to store the dialog id in a variable and it also hooks the callback OnDialogResponse to compare the variable to the id of the dialog that has actually been responded to, so if both dialog ids are different it forces the player to timeout.
And the include for filterscripts is this:
Which is only another hook for the function ShowPlayerDialog that uses CallRemoteFunction to call the hooked function in the gamemode instead.
The problem I have is that a lot of players are forced to timeout every day, so I highly doubt they all are hackers, instead I think most of them are false detections. The most curious thing is that the supposedly hacked dialog is almost always the same, I know it because each forced timeout is printed to the console and it's almost always like this:
Now you might wonder: which dialog is 24? ok, I have all dialog ids in an enum:
And id 24 corresponds to "spawnprotdialogid". Here's a screenshot of that dialog:
I have tried to recreate the bug myself a few times, both from admin and non-admin accounts, but haven't had this issue. And of course my anti dialog hack include is in top of the gamemode, before any calls to ShowPlayerDialog.
As a note, although I have created an include for filterscripts, none of my filterscripts uses dialogs, only my gamemode does.
pawn Код:
#if defined _antidialoghack_included
#endinput
#endif
#define _antidialoghack_included
#include <a_samp>
new stock lastdialogid[MAX_PLAYERS];
forward showplayerdialogpublic(playerid, dialogid, style, caption[], info[], button1[], button2[]);
public showplayerdialogpublic(playerid, dialogid, style, caption[], info[], button1[], button2[])
// This function is public so it can be called from filterscripts with CallRemoteFunction.
{
lastdialogid[playerid] = dialogid;
return ShowPlayerDialog(playerid, dialogid, style, caption, info, button1, button2);
}
#if defined _ALS_ShowPlayerDialog
#undef ShowPlayerDialog
#else
#define _ALS_ShowPlayerDialog
#endif
#define ShowPlayerDialog showplayerdialogpublic
// This hooks the function ShowPlayerDialog, so every time it's called the variable
// lastdialogid will be set for that player.
static gandiha_HasCB[2];
public OnGameModeInit()
{
gandiha_HasCB[0] = funcidx("andiha_OnDialogResponse") != -1;
gandiha_HasCB[1] = funcidx("andiha_OnPlayerConnect") != -1;
if (funcidx("andiha_OnGameModeInit") != -1)
{
return CallLocalFunction("andiha_OnGameModeInit", "");
}
return 1;
}
#if defined _ALS_OnGameModeInit
#undef OnGameModeInit
#else
#define _ALS_OnGameModeInit
#endif
#define OnGameModeInit andiha_OnGameModeInit
forward andiha_OnGameModeInit();
public OnDialogResponse(playerid, dialogid, response, listitem, inputtext[])
{
if(dialogid != lastdialogid[playerid])
{
new string[120];
format(string, sizeof(string), "hacking dialogs. Dialog responded to: %i, last shown dialog: %i", dialogid, lastdialogid[playerid]);
if( !IsPlayerAdmin(playerid) )
{
forcetimeout(playerid, string); // This is a function from another include
// that forces a player to timeout. Check this forum thread:
// https://sampforum.blast.hk/showthread.php?tid=178575
}
else
{
format(string, sizeof(string), "You have been detected %s", string);
SendClientMessage(playerid, red, string);
}
}
lastdialogid[playerid] = -1; // This is because when you call ShowPlayerDialog
// with -1 as dialogid parameter, it closes all dialogs for that player. And
// when you response to a dialog, that dialog is closed in your screen, so
// it's as if ShowPlayerDialog had been called with -1.
if (gandiha_HasCB[0])
{
return CallLocalFunction("andiha_OnDialogResponse", "iiiis",playerid, dialogid, response, listitem, inputtext[0] ? inputtext : "\1\0");
}
return 1;
}
#if defined _ALS_OnDialogResponse
#undef OnDialogResponse
#else
#define _ALS_OnDialogResponse
#endif
#define OnDialogResponse andiha_OnDialogResponse
forward andiha_OnDialogResponse(playerid, dialogid, response, listitem, inputtext[]);
public OnPlayerConnect(playerid)
{
ShowPlayerDialog(playerid, -1, DIALOG_STYLE_MSGBOX, "", "", "", "");
// This will close any dialogs that the player could have in his screen (for
// example if he timed out while having an open dialog and then reconnected).
if (gandiha_HasCB[1])
{
return CallLocalFunction("andiha_OnPlayerConnect", "i",playerid);
}
return 1;
}
#if defined _ALS_OnPlayerConnect
#undef OnPlayerConnect
#else
#define _ALS_OnPlayerConnect
#endif
#define OnPlayerConnect andiha_OnPlayerConnect
forward andiha_OnPlayerConnect(playerid);
And the include for filterscripts is this:
pawn Код:
#if defined _antidialoghack_included
#endinput
#endif
#define _antidialoghack_included
#include <a_samp>
stock showplayerdialog2(playerid, dialogid, style, caption[], info[], button1[], button2[])
{
if( CallRemoteFunction("showplayerdialogpublic", "iiissss", playerid, dialogid, style, caption, info, button1, button2) )
{
return 1;
// If CallRemoteFunction returns a value it's because the public hooked function in the
// gamemode has been successfully called, and therefore we don't have to call it in
// the filterscript.
}
return ShowPlayerDialog(playerid, dialogid, style, caption, info, button1, button2);
// If these lines are reached it's because the public hooked function in the gamemode hasn't
// been called, so we just call the standard function normally.
}
#if defined _ALS_ShowPlayerDialog
#undef ShowPlayerDialog
#else
#define _ALS_ShowPlayerDialog
#endif
#define ShowPlayerDialog showplayerdialog2
The problem I have is that a lot of players are forced to timeout every day, so I highly doubt they all are hackers, instead I think most of them are false detections. The most curious thing is that the supposedly hacked dialog is almost always the same, I know it because each forced timeout is printed to the console and it's almost always like this:
Код:
Sergo_Men (7) has been forced to timeout, reason: hacking dialogs. Dialog responded to: 24, last shown dialog: -1
pawn Код:
enum
{
commandslist,
spawnmodedialogid,
languagedialogid,
weaponsdialogid,
meleedialogid,
pistolsdialogid,
shotgunsdialogid,
submachinesdialogid,
assaultwepsdialogid,
riflesdialogid,
powerfuldialogid,
thrownwepsdialogid,
coughingdialogid,
vehiclesdialogid,
carsdialogid,
sportcarsdialogid,
offroaddialogid,
bikesdialogid,
planesdialogid,
helisdialogid,
fourdoorsdialogid,
helpdialogid,
rulesdialogid,
kickdialogid,
spawnprotdialog,
howtoplaydialog,
rcdialogid,
admincommandsdialog
}
I have tried to recreate the bug myself a few times, both from admin and non-admin accounts, but haven't had this issue. And of course my anti dialog hack include is in top of the gamemode, before any calls to ShowPlayerDialog.
As a note, although I have created an include for filterscripts, none of my filterscripts uses dialogs, only my gamemode does.