[Tutorial] How to lock your gamemode whilst ingame
#1

Hi there. This simple tutorial will show you how to lock your server in-game.

This is handy for 2 easy reasons:

- Maintenance.
- Hack defense.


What this system does is that you type one command, and everybody other than administrators will be kicked. This can be used for maintaining a server, or defending peoples accounts against hackers.

Before you start scripting this tutorial, I must warn you that you will need these plugins/includes:
- Zeex' ZCMD [Click for download]


Okay, now that you've got ZCMD we can get right into creating this script.

For any complete noobs at SA-MP scripting, you can include ZCMD into your script by doing this:
pawn Код:
#include <zcmd>

Make a variable somewhere above the command:
pawn Код:
new serverLocked = 0;
Now, we can create the structure for our LOCK command:
pawn Код:
COMMAND:lockserver(playerid, params[])
{
    return 1;
}
By the way, instead of doing 'COMMAND:' you can also use these methods:

pawn Код:
CMD:lockserver(playerid, params[])
{
    return 1;
}

command(lockserver, playerid, params[])
{
    return 1;
}
Alright, now that the basic structure for the command has been programmed, we can now begin to set some permissions. My script will only have admins be locking the server, as it can be a serious thing for big servers:
pawn Код:
COMMAND:lockserver(playerid, params[])
{
    if(IsPlayerAdmin(playerid))
    {
       
    }
    else return SendClientMessage(playerid, -1, "* This command is prohibited of access to regular players.");
    return 1;
}
An 'else return' statement is in place so the player can be notified the command is prohibited for them.

Now, we must make a loop to check what players are administrators and what players are not administrators:
pawn Код:
COMMAND:lockserver(playerid, params[])
{
    if(IsPlayerAdmin(playerid))
    {
        for(new i = 0; i < MAX_PLAYERS; i++)
        {
            if(!IsPlayerAdmin(i)) Kick(playerid); // you can use KickWithMessage if you want, I'm just using Kick() for the sake of time.
           
        }
    }
    else return SendClientMessage(playerid, -1, "* This command is prohibited of access to regular players.");
    return 1;
}
Okay, now that players who are not admins are kicked, we can proceed to check whether the server is already locked. This is just to make sure no errors can happen. Wrap your for statement in this.
pawn Код:
COMMAND:lockserver(playerid, params[])
{
    if(IsPlayerAdmin(playerid))
    {
        if(serverLocked == 0)
        {
            for(new i = 0; i < MAX_PLAYERS; i++)
            {
                if(!IsPlayerAdmin(i)) Kick(i); // you can use KickWithMessage if you want, I'm just using Kick() for the sake of time.
               
                SendClientMessage(i, -1, "[MESSAGE] The server has just been locked. If you disconnect, you will not be able to reconnect until the server is unlocked.");
            }
        }
        else return SendClientMessage(playerid, -1, "** The server is already locked!");
    }
    else return SendClientMessage(playerid, -1, "* This command is prohibited of access to regular players.");
    return 1;
}
Finally, we'll set the Rcon commands and state the server is locked:
pawn Код:
COMMAND:lockserver(playerid, params[])
{
    if(IsPlayerAdmin(playerid))
    {
        if(serverLocked == 0)
        {
            for(new i = 0; i < MAX_PLAYERS; i++)
            {
                if(!IsPlayerAdmin(i)) Kick(playerid); // you can use KickWithMessage if you want, I'm just using Kick() for the sake of time.
               
                SendClientMessage(i, -1, "[MESSAGE] The server has just been locked. If you disconnect, you will not be able to reconnect until the server is unlocked.");
               
                // the rcon commands to set password etc
                SendRconCommand("hostname [LOCKED] Server Name");
                SendRconCommand("password ab!##dmandieAMCUNE3918784MCOAKCNanchedBMIDCL"); // Make the pass difficult
            }
        }
        else return SendClientMessage(playerid, -1, "** The server is already locked!");
    }
    else return SendClientMessage(playerid, -1, "* This command is prohibited of access to regular players.");
    return 1;
}
Here's the /unlockserver command if you want it:
pawn Код:
COMMAND:unlockserver(playerid, params[])
{
    if(IsPlayerAdmin(playerid))
    {
        if(serverLocked == 1)
        {
            serverLocked = 0;
            SendRconCommand("hostname Server Name");
            SendRconCommand("password 0");
        }
    }
}

Note: This was used with the RCON Admin system, you can use your own system if you wish.
Please tell me if I've done something wrong and don't complain about it, thanks.
Reply
#2

Good Job +REP
Reply
#3

^spammer

Anyway it looks good but your explanation could do with some work, some people may not understand what a for loop is.
Reply
#4

Good job - I really needed something like this since hackers would join my server and come in and hack .. thanks !
Reply
#5

Thanks guys.

NewerthRoleplay, I do not expect those who come here to not know the most frequently used functions.
If a player is not sure about something in which I have made, they can contact me via topic or PM to seek assistance. Thank you for your constructive criticism nevertheless.
Reply
#6

I never knew a simple command could be classified as a tutorial.
Reply
#7

"A tutorial is a method of transferring knowledge and may be used as a part of a learning process." - Wikipedia.
"a tutorial seeks to teach by example and supply the information to complete a certain task." - Wikipedia.

So yeah, it is classed as a tutorial.
Reply
#8

Change "if(!IsPlayerAdmin(i))" to if(IsPlayerConnected(i) && !IsPlayerAdmin(i))

- More efficient this way...
Reply
#9

No it isn't. The player has to be connected in order for the script to kick them, therefore including that function would be useless.

Your method is inefficient.
Reply
#10

Quote:
Originally Posted by Inverse
Посмотреть сообщение
Change "if(!IsPlayerAdmin(i))" to if(IsPlayerConnected(i) && !IsPlayerAdmin(i))

- More efficient this way...
Quote:
Originally Posted by sammp
Посмотреть сообщение
No it isn't. The player has to be connected in order for the script to kick them, therefore including that function would be useless.

Your method is inefficient.
pawn Код:
for (new i = 0; i < MAX_PLAYERS; i++)
{
    if (!IsPlayerConnected(i))
        continue; //'i' not connected - Break current 'round' and start the next 'round' of the loop (i++)
   
    if (!IsPlayerAdmin(i)) Kick(i);
}
That would be the best way -excluding foreach off course-.

What if you have 2 players online (and MAX_PLAYERS is defined as 500). It will try to kick atleast 498 players (if not connected, a player also isn't a RCON admin). By using 'continue', you will break the current 'round' of the loop and continue futher with the statement (which is 'i++').
Also, the if (IsPlayerConnected(i) && !IsPlayerAdmin(i)) is not ineffecient, because the server now won't try to kick a player whom is offline. Yet, my way would be the best way.

Quote:

if(!IsPlayerAdmin(i)) Kick(playerid); // you can use KickWithMessage if you want, I'm just using Kick() for the sake of time.

Hehehe. And the time you saved was entirely spilled to that comment haha
Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)