01.02.2014, 11:48
(
Последний раз редактировалось Lordzy; 13.09.2014 в 15:52.
)
OPRL - OnPlayerRconLogin
v1.3 update released! (RECOMMENDED)
So basically, most of them had been using "OnRconLoginAttempt" and IP tracing to detect RCON login and in case if there's any system like second RCON login. It's not completely efficient because it would return multiple users in case if they're playing with same IP addresses. This include is a simple one and it provides a callback called OnPlayerRconLogin which gets called to the certain player who has logged in as RCON.v1.3 update released! (RECOMMENDED)
I've actually released a snippet version of this on Useful Snippets earlier and here's the post. But here's an include version which can be used easily by the server coders.
The version 1.2 of this include has been released which uses the callback "OnRconLoginAttempt" callback but in a way that player ID is being returned according to the one who has logged in. It will work same as version 1, however I suggest everyone to use v1.2 as it don't add repeating timers or use OnPlayerUpdate. Thanks to Konstantinos for suggesting a new method in making this include better!
If you had been using previous version of OPRL (other than OPRL3.inc), please consider using the latest version of this include (OPRL3.inc) as it's mainly a security update. Changes done over this include can be found under change logs.
Hooked Callbacks
v1.3 (Latest)
pawn Код:
OnFilterScriptInit
OnGameModeInit
OnRconLoginAttempt
OnPlayerConnect
pawn Код:
#if defined FILTERSCRIPT
OnFilterScriptInit
#else
OnGameModeInit();
#endif
OnRconLoginAttempt
pawn Код:
#if defined FILTERSCRIPT
OnFilterScriptInit();
OnFilterScriptExit();
#else
OnGameModeInit();
OnGameModeExit();
#endif
#if !defined OPRL_USE_TIMER
OnPlayerUpdate(playerid);
#endif
Changelogs
Код:
v1.3 (RECOMMENDED) (13-09-2014) • Defining of FILTERSCRIPT constant is no longer required before including this include in case if it's used for filterscripts. Thanks to ****** for the tip. • Removed useless timer call. • Fixed player array values while connections. • The include has been renamed from "OPRL2.inc" to "OPRL3.inc" v1.2 (02-02-2014) • Include has been optimized! Thanks to Konstantinos for showing a better method to callout "OnPlayerRconLogin" v1.0 (01-02-2014) • Initial Release
• A simple notification to everyone when a player logs in as RCON.
pawn Код:
#include <a_samp>
#include <OPRL3>
public OnPlayerRconLogin(playerid)
{
new
Lname[MAX_PLAYER_NAME],
string[128];
GetPlayerName(playerid, Lname, sizeof(Lname));
format(string, sizeof(string), "<RCON LOGIN> : %s (ID:%d) has logged in as RCON Administrator!", Lname, playerid);
SendClientMessageToAll(-1, string);
printf(string); //Not actually required as it debugs itself, however just adding it as it's an example.
return 1;
}
This is not just an example but also created in a filterscript way which gives performs efficient than other Second RCON systems I've seen. As it uses OnPlayerRconLogin, it ensures that the second RCON login confirmation is sent only to the player who RCON logged in, not others who got the same IP address.
◘ Configurations
- Change SECOND_RCON_DIALOG to the Dialog ID of the second RCON.
- Change SECOND_RCON_PASS to your second RCON password. Default password is testing
- Change MAX_FALSE_2RCON_ATTEMPTS to maximum wrong second rcon login attempts. Default is set to 3.
- Change MAX_HOLD_SECONDS to the max seconds a player could stay online as RCON without logging into second RCON.
pawn Код:
/*______________________________________________________________________________
Lordz's Second RCON System!
Copyright© - 2014 "SecondRCON"
Author : Lordz™ AKA Lordzy
NOTE:
This script is created as a filterscript, mainly as an example for the include
"OPRL" AKA "OnPlayerRconLogin". This script ensures that the second RCON request
is only sent to the player who RCON logins, not to the players who got the same
IP address.
______________________________________________________________________________*/
#include <a_samp>
#include <OPRL3>
new
bool:RCON2LoggedIn[MAX_PLAYERS],
RCON2WrongLogins[MAX_PLAYERS];
#define SECOND_RCON_DIALOG 1126 //Dialog ID of the second RCON.
#define SECOND_RCON_PASS "testing" //Second RCON password, you can change it but keep it in quotes.
#define MAX_FALSE_2RCON_ATTEMPTS 3 //Maximum number of second RCON fails.
#define MAX_HOLD_SECONDS 120 //Maximum seconds in which a player could stay as RCON without confirming second RCON.
public OnPlayerConnect(playerid)
{
if(IsPlayerAdmin(playerid)) RCON2LoggedIn[playerid] = true;
else RCON2LoggedIn[playerid] = false;
RCON2WrongLogins[playerid] = 0;
return 1;
}
public OnFilterScriptInit()
{
for(new i; i< GetMaxPlayers(); i++)
{
if(!IsPlayerConnected(i)) continue;
if(IsPlayerAdmin(i)) RCON2LoggedIn[i] = true;
else RCON2LoggedIn[i] = false;
RCON2WrongLogins[i] = 0;
}
printf("-------------------------------------------------");
printf(" OnPlayerRconLogin - Second RCON system");
printf(" Loaded!");
printf("-------------------------------------------------");
return 1;
}
public OnPlayerRconLogin(playerid)
{
if(RCON2LoggedIn[playerid] == false)
{
SendClientMessage(playerid, -1, "{FF0000}Server : {880088}Before playing as RCON Administrator, please login to the second RCON option too.");
ShowPlayerDialog(playerid, SECOND_RCON_DIALOG, DIALOG_STYLE_INPUT, "Second RCON Login", "Hello,\nBefore accessing RCON, please login to the second RCON.", "Login", "");
SetTimerEx("DetectSecondRconLogin", 1000*MAX_HOLD_SECONDS, false, "d", playerid);
}
return 1;
}
public OnDialogResponse(playerid, dialogid, response, listitem, inputtext[])
{
if(dialogid == SECOND_RCON_DIALOG)
{
if(response)
{
if(!strlen(inputtext))
{
RCON2WrongLogins[playerid]++;
new
string[128];
if(RCON2WrongLogins[playerid] >= MAX_FALSE_2RCON_ATTEMPTS)
{
new
Lname[MAX_PLAYER_NAME];
GetPlayerName(playerid, Lname, sizeof(Lname));
format(string, sizeof(string), "%s (ID:%d) has been automatically kicked from the server! (Reason : %d/%d)", Lname, playerid, RCON2WrongLogins[playerid], MAX_FALSE_2RCON_ATTEMPTS);
SendClientMessageToAll(0xFF0000FF, string);
return SetTimerEx("KickPlayer", 150, false, "d", playerid);
}
format(string, sizeof(string), "ERROR! The previous second RCON given was incorrect! (Warnings : %d/%d)", RCON2WrongLogins[playerid], MAX_FALSE_2RCON_ATTEMPTS);
SendClientMessage(playerid, 0xFF0000FF, string);
return ShowPlayerDialog(playerid, SECOND_RCON_DIALOG, DIALOG_STYLE_INPUT, "Second RCON Login", "Hello,\nBefore accessing RCON, please login to the second RCON.", "Login", "");
}
if(!strcmp(inputtext, SECOND_RCON_PASS, false))
{
GameTextForPlayer(playerid, "~G~ACCESS GRANTED!", 2000, 3);
PlayerPlaySound(playerid, 1057, 0.0, 0.0, 0.0);
RCON2LoggedIn[playerid] = true;
return 1;
}
else if(strcmp(inputtext, SECOND_RCON_PASS, false))
{
RCON2WrongLogins[playerid]++;
new
string[128];
if(RCON2WrongLogins[playerid] >= MAX_FALSE_2RCON_ATTEMPTS)
{
new
Lname[MAX_PLAYER_NAME];
GetPlayerName(playerid, Lname, sizeof(Lname));
format(string, sizeof(string), "%s (ID:%d) has been automatically kicked from the server! (Reason : Wrong RCON logins | %d/%d)", Lname, playerid, RCON2WrongLogins[playerid], MAX_FALSE_2RCON_ATTEMPTS);
SendClientMessageToAll(0xFF0000FF, string);
return SetTimerEx("KickPlayer", 150, false, "d", playerid);
}
format(string, sizeof(string), "ERROR! The previous second RCON given was incorrect! (Warnings : %d/%d)", RCON2WrongLogins[playerid], MAX_FALSE_2RCON_ATTEMPTS);
SendClientMessage(playerid, 0xFF0000FF, string);
return ShowPlayerDialog(playerid, SECOND_RCON_DIALOG, DIALOG_STYLE_INPUT, "Second RCON Login", "Hello,\nBefore accessing RCON, please login to the second RCON.", "Login", "");
}
}
if(!response)
{
new
string[128],
Lname[MAX_PLAYER_NAME];
format(string, sizeof(string), "%s (ID:%d) has been automatically kicked from the server! (Reason : Wrong RCON login)", Lname, playerid);
SendClientMessageToAll(0xFF000FF, string);
return SetTimerEx("KickPlayer", 150, false, "d", playerid);
}
}
return 1;
}
forward KickPlayer(playerid);
forward DetectSecondRconLogin(playerid);
public DetectSecondRconLogin(playerid)
{
if(IsPlayerAdmin(playerid))
{
if(RCON2LoggedIn[playerid] == false)
{
new
Lname[MAX_PLAYER_NAME],
string[128];
GetPlayerName(playerid, Lname, sizeof(Lname));
format(string, sizeof(string), "%s (ID:%d) has been automatically kicked from the server! (Reason : Delayed RCON confirmation)", Lname, playerid);
SendClientMessageToAll(0xFF0000FF, string);
return SetTimerEx("KickPlayer", 150, false, "d", playerid);
}
}
return 1;
}
public KickPlayer(playerid) return Kick(playerid);
Tutorial
https://sampforum.blast.hk/showthread.php?tid=499455
It's found on the "PART 2" of that tutorial.
Notes
• You must define FILTERSCRIPT before including this one in case if it's a filterscript. It's because of the hooking methods used in the include.
• The reason why I've kept an extra define in toggling OnPlayerUpdate mode or Timer mode is because if the player is logged in but if OnPlayerUpdate isn't being called due to any glitches or cheats, a timer is always efficient.
• If there's any mistake, feel free to point out.
• If there's any suggestion to improve this include, feel free to point out.
Thanks to
Konstantinos for suggesting a better method for the OPRL call.
****** for suggesting a better hook method to handle both filterscripts and gamemodes easily.
Downloads
GitHub - Examples and Include (Complete Project)
PasteBin - Include Only
Regards,
Lordzy.