[Include] OPRL.inc - OnPlayerRconLogin : Calls out when a player logs in as RCON, not an IP.
#1

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.

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
v1.2 (Outdated version)
pawn Код:
#if defined FILTERSCRIPT
OnFilterScriptInit
#else
OnGameModeInit();
#endif
OnRconLoginAttempt
v1.0 (Outdated version)
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
Examples

• 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;
}
• Second RCON system. (FilterScript version)

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.
Reply


Messages In This Thread

Forum Jump:


Users browsing this thread: 1 Guest(s)