Game Development Community

I need help with a new script.

by Sam · in Technical Issues · 03/23/2006 (3:58 pm) · 4 replies

Well, I play a game called ThinkTanks, and I enjoy scripting for the community. Sadly, I am not very advanced at scripting as I know very little terminology, and my logic lacks the correct things, as I have many errors.

I have this but it does nothing:

function GetStats(%client)
{
   if(!isObject(%client.ai))
   {
      %Client.Cadd = %client.getId();
      %Client.Ip = scrub_ip(%client.getAdress());
      %Client.Ping = %client.getPing();
   }
}

function ExcedePing(%client)
{
        if (GetPing() < $PingMaxExcede)
        {
             return;
        }
        if (%client.GetPing() >= $PingMaxExcede)
        {
             BottomPrint(%client, "Your Ping Level is to High For This Server. \r\n  Please Correct it within" SPC $TimeToCorrect SPC "seconds.",5,3);
             PringCounter(%client);
             echo(%client.namebase@ " has been marked with high ping.");
        }
}

function PingCounter(%client)
{
        while (%time <= $TimeToCorrect)
        {
              %time++;
              schedule(%time * 1000,false, "BottomPrint",%client,"PingCounter:" SPC %time@ "/" @$TimeToCorrect,3,1);
              if (%client.getPing()  < $PingMaxExcede)
                  CenterPrintAll(%client.nameBase SPC "Managed to Correct his/her Ping in Time",2,1);
                  return;
             if  (%time = $timeToCorrect-1)
                 %client.delete($ClientKickDelete);
                 CenterPrintAll(%client.nameBase SPC $clientKickDeleteGlobal,3,1);
                 return;
         }
}

This is just the things I will use in my script. I should probably tell you what I'm trying to do:

I want to make a script that kicks players if they have a high ping.

This would be a server side script, and if a clients ping exceded a certain amount, it should send them a message, saying they have "SO SO" seconds to correct thier ping, before getting kicked.

I plan on this being the main script file, and there will be a pref.cs file with the arrays controling Time, high ping level, all that jazz.

I dont know the best way to control how to have the server check it;s player's ping automaticaly, so provide something to do with that as well.

I'm thinking something along the lines of using:

function GameConnection::onConnectRequest( %client, %netAddress, %name )
{
GetStats(%client);
}

To get a record of that clients stats as well. It would record in some file, I have yet to work that out.

So, basicaly, I need help finding a way to make a script that is server side that kicks players who surpass a certain level of ping. It would give them time to correct also. I also need a way to automaticaly check a players ping, not just when they join.

All help is greatly appriciated,
Sam

#1
03/23/2006 (11:57 pm)
I did notice a spelling mistake:
Quote:
PringCounter(%client);
should be (I assume):
Quote:
PingCounter(%client);

Also all the variables in the GetStats function are local (%) so disappear when you leave the function....but you havn't done anything with them. I assume your still working on that bit (if you stick all the variables in a script object you can then save the script object in a file, or use the script objects handle to access the variables later).
The bottom function also won't work I don't think. The "while" statement will keep in going through until time<=$timeToCorrect. It won't wait 1 second to do it again. At the end of the function you need to schedule a repeat of the PingCounter function and use an "if" statement instead of a "while" one. Last thing I noticed was that both if blocks in the PingCounter function need to have {} to contain them as they are both more then one line.
function PingCounter(%client,%time)
{
        if (%time <= $TimeToCorrect)
        {
              %time++;
              schedule(%time * 1000,false, "BottomPrint",%client,"PingCounter:" SPC %time@ "/" @$TimeToCorrect,3,1);
              if (%client.getPing()  < $PingMaxExcede) 
              {
                       CenterPrintAll(%client.nameBase SPC "Managed to Correct his/her Ping in Time",2,1);
                       return;
              }
              if  (%time = $timeToCorrect-1)
              {
                      %client.delete($ClientKickDelete);
                      CenterPrintAll(%client.nameBase SPC $clientKickDeleteGlobal,3,1);
                      return;
              }
              schedule(1000,0,"PingCounter",%client,%time);
        }
}

%time can just be left blank when you initiate the function (ie just "PingCounter(%client)") and it will just be taken as 0.
#2
03/24/2006 (3:36 pm)
GREAT, thanks... I really appreciate it. I much better like this new style of loop, and I had no idea that while statements didnt wait proper time, I wasnt thinking. This is how I plan on improving the script to work and end properly:

function PingCounter(%client,%time)
{
         if  (%time = $timeToCorrect)
         {
                      %client.delete($ClientKickDelete);
                      CenterPrintAll(%client.nameBase SPC $clientKickDeleteGlobal,3,1);
                      return;
        }
        if (%time < $TimeToCorrect)
        {
              %time++;
              schedule(0,false, "BottomPrint",%client,"PingCounter:" SPC %time@ "/" @$TimeToCorrect,1,1);
              if (%client.getPing()  < $PingMaxExcede) 
              {
                       CenterPrintAll(%client.nameBase SPC "Managed to Correct his/her Ping in Time",2,1);
                       return;
              }
             schedule(1000,0,"PingCounter",%client,%time);
        }
}

That would be the timer... tell me if you notice any problems
This is what I'm thinking of useing to get the server to check itself for ping... automaticaly(Please, tell me what or why it would or wouldnt work):
ServerCheckAuto();
function ServerCheckAuto()
{
           %len = clientgroup.getCount();
           for ( %i=0; %i<%len; %i++ )
           {
                 %client = clientgroup.getObject(%i);
                 if ( %client != -1 && !isObject(%client.ai) )
                 {
                         if ( %client.GetPing() >= $PingMaxExcede )
                         {
                                 BottomPrint(%client, "Your Ping Level is to High For This Server. \r\n  Please Correct it within" SPC $TimeToCorrect SPC "seconds.",2,3);
                                  PringCounter(%client);
                                  echo(%client.namebase@ " has been marked with high ping.");
                          }
                 }
          }
          schedule($ServerCheckTime * 1000,false,"ServerCheckAuto");
}

So, $ServerCheckTime should be the amount of time between server scans to see clients with excessive ping.. Tell me what you think

This is something else I plan on useing (tell me if you think that this function would work):
//Fix for Mac append error
function macfix(%file_path,%msg)
{
%i = 0;
%file = new FileObject();
if(%file.openForRead(%file_path))
{
    while(!%file.isEOF())
    {
      %line = %file.readLine();
      %linenum[%i] = %line;
      %i++;
    }
}
else
{
    echo("file:" SPC %file_path SPC "not valid");
    return;
}
%file.close();

%i2 = 0;
if (%file.openForWrite(%file_path))
{
    while(%i2 != %i)
    {
      %file.writeline(%linenum[%i2]);
      %i2++;
    }
    %file.writeline(%msg);
}
%file.close();
}

That would be so I could use this:
macfix("game/data/server/PingKicker/PingLog.cs","So so has been marked with high ping.");

So that there would be a file that has history of all ping issues. Tell me what you think as well.

Thank you very much for your help. I need someone else to teach me, to point out mistakes.

Sam
#3
03/25/2006 (11:13 am)
The only thing I noticed was a spelling mistake in the ServerCHeckAuto function. You have "PringCounter(%client);" again instead of "PingCounter(%client);" :P. Other then that they look sound to me :) The only other thing I noticed was with the PingCounter function it would be more efficent this way:
function PingCounter(%client,%time)
{
        if (%time < $TimeToCorrect)
        {
              %time++;
              schedule(0,false, "BottomPrint",%client,"PingCounter:" SPC %time@ "/" @$TimeToCorrect,1,1);
              if (%client.getPing()  < $PingMaxExcede)
               {
                       CenterPrintAll(%client.nameBase SPC "Managed to Correct his/her Ping in Time",2,1);
                       %client.onTimer = 0;
                       return;
              }
             schedule(1000,0,"PingCounter",%client,%time);
        }
        if  (%time = $timeToCorrect)
        {
                      %client.delete($ClientKickDelete);
                      CenterPrintAll(%client.nameBase SPC $clientKickDeleteGlobal,3,1);
                      return;
        }
}

This is more effecient because %time is more likely to be <$timeToCorrect then equal to it. With the 2 statements the other way round it won't have to check to see if they are equal to echother each time. It won't make much difference, but I am at that stage where I am trying to notice everything and anything to make my scripts more efficient, all part of the learning process :P
Well done with the macfix function, I can't see anything wrong with that. I am not too clued up on writeing and reading from files but as far as I can see that will work ok.
Just noticed somthing in the ServerCheckAuto function. You have to make sure that when you cycle through the clients you don't include the clients that already have a timer going, otherwise you will start a new one. All you need to do is a variable check I think:
function ServerCheckAuto()
{
           %len = clientgroup.getCount();
           for ( %i=0; %i<%len; %i++ )
           {
                 %client = clientgroup.getObject(%i);
                 if ( %client != -1 && !isObject(%client.ai) )
                 {
                         if ( %client.GetPing() >= $PingMaxExcede && !%client.onTimer)
                         {
                                 BottomPrint(%client, "Your Ping Level is to High For This Server. \r\n  Please Correct it within" SPC $TimeToCorrect SPC "seconds.",2,3);
                                  %client.onTimer = 1;
                                  PingCounter(%client);
                                  echo(%client.namebase@ " has been marked with high ping.");
                          }
                 }
          }
          schedule($ServerCheckTime * 1000,false,"ServerCheckAuto");
}

The onTimer variable needs to be set back to 0 when the timer is stopped (added to the pingCounter function above).
#4
03/25/2006 (7:24 pm)
So, in the timer there should be something like:
function PingCounter(%client,%time)
{
         if ( %client == -1 )
         {
               return;
         }
         if  (%time >= $timeToCorrect)
         {

                      CenterPrintAll(%client.nameBase SPC $clientKickDeleteGlobal,2,1);
                      echo(%client.namebase SPC "has been kicked for high ping.");
                     Macfix("game/server/AutoPing/PingLog.cs",%client.namebase SPC "| Has Been Kicked For High Ping.");
                     %client.delete($ClientKickDelete);
                      return;
        }
        if (%time < $TimeToCorrect)
        {
              %time++; 
             schedule(0,false, "BottomPrint",%client,"PingCounter:\r\n" SPC %time@ "/" @$TimeToCorrect,1,2);
              if (%client.getPing()  < $PingMaxExcede) 
              {
                       CenterPrintAll(%client.nameBase SPC "Managed to Correct his/her Ping in Time",2,1);
                       [b]%client.onTimer = 0;[/b]
                       return;
              }
             schedule(1000,0,"PingCounter",%client,%time);
        }
}

Like that, very cool. Just so you know, I've currently got the script runnning, just making some improvements now, and this would be one of them. Thanks a lot, Ill post again when I feel necessary.