[Tutorial] High-ping kicker + /setping command.
#1

Hello everyone, today i will show you how to create a Ping-Limit and a /setping(limit) command!
You will need these following things:Alright, now after you've "installed" the zCMD include, and the sscanf include/plugin, we will start scripting.
But well, before we start, you will need these color defines!

pawn Code:
#define COLOR_RED 0xAA3333AA
#define COLOR_YELLOW 0xFFFF00AA
Add them at your other defines, as a local variable.
Alright, now let's really start scripting.


You will need this
pawn Code:
new MPing = 250;
Set it as a local variable(Before any callbacks).
That will set that MaxPing to 250 as a default.
Alright.. now, on the "OnPlayerSpawn" callback you will want to add this:
pawn Code:
SetTimerEx("PingTimer", 10000, true, "i", playerid);
That will start a 10 second timer, 'scanning' for people who have over 250(Or over the /setping limit..) ping.
I set it to "OnPlayerSpawn" so players don't get auto-kicked when they connect(The 65k ping bug)
Well, for me i didn't have any lag..

Now, we will need to forward the PingTimer

pawn Code:
forward PingTimer();
   
    public PingTimer()
    {
        for(new i = 0; i < MAX_PLAYERS; i ++)
           {
              if(IsPlayerConnected(i))
              {
                  if(!IsPlayerAdmin(i))
                  {
                    new ping = GetPlayerPing(i);
                    if(ping > MPing)
                    {
                        new name[MAX_PLAYER_NAME];
                        GetPlayerName(i, name, sizeof(name));
                        new string[128];
                        new plrIP[16];
                        GetPlayerIp(i, plrIP, sizeof(plrIP));
                        format(string, sizeof(string), "* %s[%d] has been auto-kicked for having a high ping [%d/%d]", name, i, ping, MPing);
                        SendClientMessageToAll(COLOR_YELLOW, string);
                        SetTimerEx("KickTimer", 1000, false, "i", i);
                    }
                }
            }
        }
        return 1;
}
Alright, let me try to explain it to you(Even though I'm not so great at this, but i will at-least try ):

pawn Code:
forward PingTimer();
forwarding the PingTimer function

pawn Code:
public PingTimer()
Making it a callback/function

pawn Code:
for(new i = 0; i < MAX_PLAYERS; i ++)
           {
              if(IsPlayerConnected(i))
              {
                  if(!IsPlayerAdmin(i))
Loops trough the players
If the looped player is connect but is NOT a RCON Admin

pawn Code:
new ping = GetPlayerPing(i);
                    if(ping > MPing)
Checks if the Player Ping is bigger than the MaxPing(either default, or the one set with /setping)

pawn Code:
new name[MAX_PLAYER_NAME];
                        GetPlayerName(i, name, sizeof(name));
                        new string[128];
                        format(string, sizeof(string), "* %s[%d] has been auto-kicked for having a high ping [%d/%d]", name, i, ping, MPing);
                        SendClientMessageToAll(COLOR_YELLOW, string);
                        SetTimerEx("KickTimer", 1000, false, "i", i);
If the players ping is bigger than the maxPing
then
1) We will get the players name, to format a message(new name[MAX_PLAYERNAME]; ... GetPlayerName(i, name ....)
2) A message will be formated: PlayerName[PlayerID] has been auto-kicked for having a high ping [HisPing/PingLimit]
3) It will send the message to everyone on the server
4) It will start the KickTimer

KICKTIMER:
pawn Code:
public KickTimer(playerid)
{
    Kick(playerid);
    return 1;
}
Now, the /setping command
pawn Code:
CMD:setping(playerid, params[]) {
    if(!IsPlayerAdmin(playerid)) return SendClientMessage(playerid, COLOR_RED, "[ADMIN] - Only admins can use this command!");
    new string[128];
    new newlimit;
    if(sscanf(params, "i", newlimit)) return SendClientMessage(playerid, COLOR_RED, "[USAGE] - /setping [PING-LIMIT]");
    MPing = newlimit;
    new pName[MAX_PLAYER_NAME];
    GetPlayerName(playerid, pName, sizeof(pName));
    format(string, sizeof(string), "[ADMIN] - %s[%d] has used SETPING - New limit - %i", pName, playerid, newlimit);
    SendMessageToAdmins(string);
    format(string, sizeof(string), "[PING] - Admin %s[%d] has changed the ping-limit to %i!", pName, playerid, newlimit);
    SendClientMessageToAll(COLOR_YELLOW, string);
    return 1;
}
Alright, i will try to explain it to you.
pawn Code:
CMD:setping(playerid, params[]) {
If a player types "/setping", the following will happen:
pawn Code:
if(!IsPlayerAdmin(playerid)) return SendClientMessage(playerid, COLOR_RED, "[ADMIN] - Only admins can use this command!");
1) If he is NOT a RCON Admins(/rcon login ....), then he will receive the message seen above.
pawn Code:
new string[128];
    new newlimit;
    if(sscanf(params, "i", newlimit)) return SendClientMessage(playerid, COLOR_RED, "[USAGE] - /setping [PING-LIMIT]");
2) We will need a string, to format messages.
new newlimit; = Will be the new ping limit that we will write in.
pawn Code:
if(sscanf(params, "i", newlimit)) return SendClientMessage(playerid, COLOR_RED, "[USAGE] - /setping [PING-LIMIT]");
If he just typed "/setping", he will receive the message seen above.
3) If all of the needed things were done (/setping NewLimitHere, and if he is a RCON Admin):
pawn Code:
MPing = newlimit;
This will set the MaxPing limit to the limit typed above (/setping newlimit)
4)
pawn Code:
new pName[MAX_PLAYER_NAME];
    GetPlayerName(playerid, pName, sizeof(pName));
    format(string, sizeof(string), "[ADMIN] - %s[%d] has used SETPING - New limit - %i", pName, playerid, newlimit);
    SendMessageToAdmins(string);
    format(string, sizeof(string), "[PING] - Admin %s[%d] has changed the ping-limit to %i!", pName, playerid, newlimit);
    SendClientMessageToAll(COLOR_YELLOW, string);

pawn Code:
new pName[MAX_PLAYER_NAME];
    GetPlayerName(playerid, pName, sizeof(pName));
This will get the players(admins) name, so we can use the %s[%d](PlayerName[PlayerID]) in the message format.

pawn Code:
format(string, sizeof(string), "[ADMIN] - %s[%d] has used SETPING - New limit - %i", pName, playerid, newlimit);
    SendMessageToAdmins(string);
    format(string, sizeof(string), "[PING] - Admin %s[%d] has changed the ping-limit to %i!", pName, playerid, newlimit);
    SendClientMessageToAll(COLOR_YELLOW, string);
These will format the messages, and will send the formatted message to the online RCON Admins.

Here's the STOCK for the "SendMessageToAdmins"

pawn Code:
stock SendMessageToAdmins(text[])
{
    for(new i = 0; i < MAX_PLAYERS; i++)//loops trough players
    {
        if(IsPlayerAdmin(i)) //if is a RCON password
        {
            SendClientMessage(i, 0xCA3FBFAA, text);//he will receive the message.
        }
    }
}
Everything in order:
pawn Code:
//Local variable
new MPing = 250;//Sets default Max-Ping to 250



//OnPlayerSpawn
SetTimerEx("PingTimer", 10000, true, "i", playerid);//Starts the Timer that will check if a players ping is greater(more) than the max-ping limit
 

 
    //==============[ANTI-PING TIMER]==============
    forward PingTimer(); //forwards the timer : According to wiki: 'So the server can 'see' it'
   
    public PingTimer() //The timer function
        {
            for(new i = 0; i < MAX_PLAYERS; i ++)//loops through the players
                   {
                          if(IsPlayerConnected(i)) //if is connect
                          {
                                  if(!IsPlayerAdmin(i)) //if he is NOT a RCON admin
                                  {
                                    new ping = GetPlayerPing(i);
                                    if(ping > MPing) //if his ping is greater(higher) than the Ping Limit
                                    {
                                            new name[MAX_PLAYER_NAME]; //Gets the players name
                                                GetPlayerName(i, name, sizeof(name));
                                                new string[128]; //creating a string
                                        format(string, sizeof(string), "* %s[%d] has been auto-kicked for having a high ping [%d/%d]", name, i, ping, MPing); //formatting a message
                                        SendClientMessageToAll(COLOR_YELLOW, string); //sending the message to everyone
                                        SetTimerEx("KickTimer", 1000, false, "i", i); //starting the kick timer
                                    }
                                }
                        }
                }
                return 1;
}

//KICK TIMER
public KickTimer(playerid)
{
    Kick(playerid);//Kicks the player
    return 1;
}


//CMD
CMD:setping(playerid, params[]) {
        if(!IsPlayerAdmin(playerid)) return SendClientMessage(playerid, COLOR_RED, "[ADMIN] - Only admins can use this command!");//If the person who is not a RCON admin he will receive this message ^
        new string[128]; //creating a string
        new newlimit; //new ping limit
        if(sscanf(params, "i", newlimit)) return SendClientMessage(playerid, COLOR_RED, "[USAGE] - /setping [PING-LIMIT]"); //if he typed '/setping' he will receive the message above
        MPing = newlimit; //If there were no errors etc then the MPing(maxping) will be set to what he wrote in /setping NewLimitHere
        new pName[MAX_PLAYER_NAME]; //Gets players name
    GetPlayerName(playerid, pName, sizeof(pName));
    format(string, sizeof(string), "[ADMIN] - %s[%d] has used SETPING - New limit - %i", pName, playerid, newlimit); //formats a message
    SendMessageToAdmins(string); //sends the message to the online admins
        format(string, sizeof(string), "[PING] - Admin %s[%d] has changed the ping-limit to %i!", pName, playerid, newlimit); //formats another message
        SendClientMessageToAll(COLOR_YELLOW, string); //sends message to everyone
        return 1;
}

//SendMessageToAdmins stock
stock SendMessageToAdmins(text[])
{
    for(new i = 0; i < MAX_PLAYERS; i++)//loops through the players
    {
        if(IsPlayerAdmin(i))//if he is a RCON admins
        {
            SendClientMessage(i, 0xCA3FBFAA, text);//he will receive this message
        }
    }
}
Reply
#2

Teaching is very good
Reply
#3

Why you're declaring "playerid" parameter in function? Do you actually know what you're doing?
Reply
#4

sometimes there's lag spikes, so it's best to check their ping for a while and see if it changes rather than kicking them the exact moment
Reply
#5

Quote:
Originally Posted by Riddick94
View Post
Why you're declaring "playerid" parameter in function? Do you actually know what you're doing?
[sarcasm]No, of course i don't know what I'm doing, it's not like i checked the wiki site or anything[/sarcasm]
Reply
#6

You don't need 'playerid' in the following function/callback if you're looping for all players.
Reply


Forum Jump:


Users browsing this thread: 3 Guest(s)