Page 1 of 3 123 LastLast
Results 1 to 10 of 28

Thread: [Q3 FIX] Q3 fake clients fix

  1. #1
    Private First Class RobsoN's Avatar
    Join Date
    Jan 2013
    Location
    /home/cod2/
    Posts
    230
    Thanks
    119
    Thanked 95 Times in 64 Posts

    [Q3 FIX] Q3 fake clients fix

    Hello, I want to share my Q3fill fix.
    Script will kick player which tries to connect to the server when other player on server has same IP address.
    The code is not diffucult but it can help to prevent annoying server haters ^^.

    NOTICE: Requires libcod!

    PHP Code:
    notifyConnecting()
    {
        
    self endon("disconnect");

        
    waittillframeend;

        if(
    isDefined(self))
        {
            
    level notify("connecting",self);
            
    setQ3Fix(); //Add this line
        
    }
        
        
    }
    setQ3Fix()
    {
        if(!
    isDefined(level.q3_fix))
            
    level.q3_fix = [];
            
        
    my_ip getIP(self);
        
        if(
    isDefined(level.q3_fix[my_ip]) && !self.data["bot"])
        {
            
    self setClientCvar("com_errorTitle""Error"); //Maybe somehow system will fail (it should'nt but we should always assume that can happens) and a real client can be kicked.
            
    self setClientCvar("com_errorMessage""IP duplicate detected"); //So let him know, what went wrong.
            
    self.kicked true;
            
    println("Warning: Kicking client with IP duplicate: "+my_ip);
            
    kick(self getEntityNumber());
            return 
    true;
        }
        
        if(!
    self.data["bot"])
            
    level.q3_fix[my_ip] = true;
            
        return 
    false;
    }
    getIP(client

        return 
    closer(430client getEntityNumber()); 
    }
    println(msg)
    {
        
    closer(200msg "\n");
    }
    Callback_PlayerDisconnect()
    {
      if(!
    isDefined(self.kicked))
          
    level.q3_fix[getIP(self)] = undefined;
      [...]

    Results:

    PHP Code:
    Going from CS_FREE to CS_CONNECTED for  (num 0 guid 0)
    Sending heartbeat to cod2master.activision.com
    Client 3 connecting with 50 challenge ping from SOMEIP
    :SOMEPORT
    Going from CS_FREE to CS_CONNECTED 
    for  (num 1 guid 0)
    WarningKicking client with IP duplicateSOMEIP
    WARNING
    Non-localized Game Message string is not allowed to have letters in itMust be changed over to a localized string"^4*^7 t0nj3WO345oa ^7Ha^9s ^7Disc^9onnected ^7Fr^9om ^4*^7eXtremE^2~^9ZOMBIES^7"
    1EXE_PLAYERKICKED 
    You can see self.data["bot"] which is boolean in my case. You should define your own variable to know if connecting entity is a bot (to prevent testclient kicking).
    Also you can add a line which adds kicked IP into a logfile. Then you can easily add it manually into firewall (or do whatever you need).

    If you got any questions or objections to my code please let me know below

    Edit#1: I forget to add array undefining when a real player disconnects
    Last edited by RobsoN; 14th January 2014 at 19:11.
    "Don't worry if your code doesn't work correctly - if everything worked, you would not work" ~Mosher's right

  2. The Following 3 Users Say Thank You to RobsoN For This Useful Post:

    kung foo man (15th January 2014),Rocky (14th January 2014),smect@ (15th January 2014)

  3. #2
    Global Mossaderator Mitch's Avatar
    Join Date
    Nov 2012
    Posts
    654
    Thanks
    204
    Thanked 450 Times in 305 Posts
    Maybe add a 10 or 15 seconde delay and add endon on 'begin'. When you receive 'begin' then it isn't a fake client.

    Edit: is self defined when it is a fake client?
    Last edited by Mitch; 14th January 2014 at 18:52. Reason: connected is a global notify, but begin isn't

  4. #3
    Private First Class RobsoN's Avatar
    Join Date
    Jan 2013
    Location
    /home/cod2/
    Posts
    230
    Thanks
    119
    Thanked 95 Times in 64 Posts
    Maybe add a 10 or 15 seconde delay and add endon on 'begin'. When you receive 'begin' then it isn't a fake client.
    I didn't tested anything with "begin" notify but I will soon.

    Edit: is self defined when it is a fake client?
    Yeah, self is defined.
    "Don't worry if your code doesn't work correctly - if everything worked, you would not work" ~Mosher's right

  5. #4
    Global Mossaderator Mitch's Avatar
    Join Date
    Nov 2012
    Posts
    654
    Thanks
    204
    Thanked 450 Times in 305 Posts
    This is my fix. It requires my libcod version with lastmsg.

    PHP Code:
    kickFakeClients()
    {
        
    self endon("begin");
        
        
    wait 15;

        
    lastmsg std\player::getLastMsg();

        if(
    lastmsg 50000)
        {
            
    ip std\player::getIP();
            
    iprintln(self.name "^7 connection timeout.");
            
    std\io::println("[CONNECTION TIMEOUT]: " self.name " (" ip ")");
            
    kick(self getEntityNumber());
        }

    std\player
    PHP Code:
    getLastMsg() { return closer(432self getEntityNumber()); } 
    libcod: http://znation.nl/libcod/
    https://github.com/M-itch/libcod/com...92938c9b93ec4e

  6. The Following 3 Users Say Thank You to Mitch For This Useful Post:

    kung foo man (12th February 2014),RobsoN (11th February 2014),Rocky (12th February 2014)

  7. #5
    Global Mossaderator Mitch's Avatar
    Join Date
    Nov 2012
    Posts
    654
    Thanks
    204
    Thanked 450 Times in 305 Posts
    I improved my code a bit
    PHP Code:
    main()
    {
        
    level.connectingip = [];

    PHP Code:
    kickFakeClients(ip)
    {
        
    self endon("begin");
        
    self endon("disconnect");

        
    delay 5;
        
    max 5000;
        
        if(!
    isDefined(level.connectingip[ip])) // less strict for first connection
        
    {
            
    level.connectingip[ip] = 1;
            
    max 50000;
            
    delay 30;
        }        

        
    wait delay;

        
    lastmsg std\player::getLastMsg();

        if(
    lastmsg max)
        {
            if(
    delay == 30 && isDefined(level.connectingip[ip]))
                
    level.connectingip[ip] = undefined// prevent strict rules for crashed clients

            
    iprintln(self.name "^7 connection timeout.");
            
    std\io::println("[CONNECTION TIMEOUT]: " self.name " (" ip ")");
            
    kick(self getEntityNumber());
        }

    PHP Code:
    ip std\player::getIP();
    self thread kickFakeClients(ip);
    self.statusicon "hud_status_connecting";
    self waittill("begin");
    self.statusicon "";

    if(
    isDefined(level.connectingip[ip]))
        
    level.connectingip[ip] = undefined
    Last edited by Mitch; 12th February 2014 at 20:23.

  8. #6
    Private
    Join Date
    Sep 2013
    Posts
    13
    Thanks
    1
    Thanked 2 Times in 2 Posts
    how to add :P

  9. #7
    Global Mossaderator Mitch's Avatar
    Join Date
    Nov 2012
    Posts
    654
    Thanks
    204
    Thanked 450 Times in 305 Posts
    Quote Originally Posted by default View Post
    how to add :P
    I have it like this:
    PHP Code:
    Callback_PlayerConnect()
    {
        
    thread dummy();

        
    ip std\player::getIP();
        
    self thread kickFakeClients(ip);
        
    self PlayerConnected(); 
    But you can also add it to CodeCallback_PlayerConnect() when you use multiple gametypes.

  10. #8
    Assadministrator IzNoGoD's Avatar
    Join Date
    Aug 2012
    Posts
    1,718
    Thanks
    17
    Thanked 1,068 Times in 674 Posts
    Dont set max on 50k if your wait is 30sec, lastmsg is number of ms that a client hasnt responded.

    Set it to 29k if you wait 30s, same goes for 5 sec and 4.9k
    "Does not work" is an error report for a bug between keyboard and chair.

    All hail Artie Effem

  11. #9
    Global Mossaderator Mitch's Avatar
    Join Date
    Nov 2012
    Posts
    654
    Thanks
    204
    Thanked 450 Times in 305 Posts
    I found a better way to detect fake clients. It also uses last msg but also the last connect time.
    The fake clients only connect to the server and nothing else. So after they connect the lastmsg time is the same as the last connect time.

    This is part of the last function they run:
    PHP Code:
    Com_DPrintf"Going from CS_FREE to CS_CONNECTED for %s\n"newcl->name );

    newcl->state CS_CONNECTED;
    newcl->nextSnapshotTime svs.time;
    newcl->lastPacketTime svs.time;
    newcl->lastConnectTime svs.time
    Proof
    PHP Code:
    Fake clients:
    [
    ipconnect1050/1050 (4GtXwfgRl3)
    [
    ipconnect1050/1050 (2S)
    [
    ipconnect1050/1050 (5II)
    [
    ipconnect6050/6050 (Z4sjLDJe4)
    [
    ipconnect6050/6050 (4GtXwfgRl3)
    [
    ipconnect6050/6050 (2S)
    [
    ipconnect6050/6050 (5II)

    Me:
    [
    ipconnect1050/1000 (Mitch||OwnZ. ^7[^456^7]) (after 1 s)
    [
    ipconnect6050/4000 (Mitch||OwnZ. ^7[^456^7]) (after 6 s
    PHP Code:
    lastconnect std\player::getLastConnectTime();
    lastmsg std\player::getLastMsg();
    std\io::println("[" ip "] connect: " lastconnect "/" lastmsg " (" self.name ")"); 
    PHP Code:
    getLastConnectTime() { return closer(433self getEntityNumber()); } 
    https://github.com/M-itch/libcod/com...8d28c88ac75c45
    http://znation.nl/libcod

    PHP Code:
    kickFakeClients(ip)
    {
        
    self endon("begin");
        
    self endon("disconnect");

        if(
    self getGuid() != 0)
            return; 
    // cd key can only be used once

        
    wait 5;

        
    lastconnect std\player::getLastConnectTime();
        
    lastmsg std\player::getLastMsg();
        
        if(
    lastmsg == lastconnect)
        {
            
    ip std\player::getIP();
            
    std\io::println("[" ip "] connect: " lastconnect "/" lastmsg " (" self.name ")");
            
    iprintln(self.name "^7 connection timeout.");
            
    kick(self getEntityNumber());
        }

    Last edited by Mitch; 26th February 2014 at 14:48.

  12. The Following 2 Users Say Thank You to Mitch For This Useful Post:

    RobsoN (26th February 2014),smect@ (26th February 2014)

  13. #10
    Private First Class RobsoN's Avatar
    Join Date
    Jan 2013
    Location
    /home/cod2/
    Posts
    230
    Thanks
    119
    Thanked 95 Times in 64 Posts
    Well done, thanks for sharing this Mitch!
    "Don't worry if your code doesn't work correctly - if everything worked, you would not work" ~Mosher's right

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •