Bot-Flood Protection System

Wichtiger Hinweis: Bitte ändert nicht manuell die Schriftfarbe auf schwarz sondern belasst es bei der Standardeinstellung. Somit tragt ihr dazu bei dass euer Text auch bei Verwendung unseren dunklen Forenstils noch lesbar ist!

Tipp: Ihr wollt längere Codeausschnitte oder Logfiles bereitstellen? Benutzt unseren eigenen PasteBin-Dienst Link
  • Hallo, ich habe gerade einen Selbsttest mit einem in C# geschriebenem Programm an meinem Server gemacht, indem ich mehrere Bots als Player getarnt auf den Server verbinden lasse. Bei ~ 110 gleichzeitigen eingehenden Verbindungen crashed der Server.


    Deshalb habe ich mir kurz überlegt, wie man das verhindern bzw. unterdrücken kann.
    Das ganze funktioniert über einen IP und Client-Version Check.


    Das Tutorial


    Zuerst erstellen wird einen neuen Ordner im scriptfiles-Ordner.
    Ihr könnt diesen nennen wir ihr wollt. Ich nenne diesen mal "flood_protection".


    Als nächstes verwende ich die Include-Datei "dini". Ihr könnt natürlich auch jedes andere File-System verwenden.
    Das ganze lässt sich auch problemlos auf MySQL oder ein anderes Datenbank-System übertragen.


    Wir inkludieren also dini und prüfen bei OnPlayerConnect, ob der Spieler mit dieser IP bereits verbunden ist:



    #define SERVER_VERSION "0.3e" // die server-version


    public OnPlayerConnect(playerid)
    {
    new playerIp[16], version[10], path[33];


    GetPlayerIp(playerid, playerIp, sizeof(playerIp)); // IP adresse auslesen
    GetPlayerVersion(playerid, version, sizeof(version)); // client-version des spielers auslesen


    do // die punkte in der IP entfernen
    {
    new dotPosition = strfind(playerIp, ".");

    strdel(playerIp, dotPosition, dotPosition + 1);
    } while (strfind(playerIp, ".") != -1);


    format(path, sizeof(path), "flood_protection/%s.ip", playerIp);


    if (!strcmp(version, SERVER_VERSION))
    {
    if (dini_Exists(path))
    {
    Kick(playerid); // spieler ist bereits mit einem anderen account verbunden
    }
    else
    {
    dini_Create(path); // spieler ist noch nicht verbunden, deshalb legen wir einen eintrag an
    }
    }
    else
    {
    Kick(playerid); // der spieler verbindet nicht mit der version, mit der der server läuft
    }


    return true;
    }


    Jetzt haben wir den Hauptteil.
    Allerdings müssen wir beim Verlassen des Spielers den Datei-Eintrag auch wieder entfernen:



    public OnPlayerDisconnect(playerid, reason)
    {
    new playerIp[16], path[33];


    GetPlayerIp(playerid, playerIp, sizeof(playerIp)); // IP adresse auslesen


    do // die punkte in der IP entfernen
    {
    new dotPosition = strfind(playerIp, ".");


    strdel(playerIp, dotPosition, dotPosition + 1);


    } while (strfind(playerIp, ".") != -1);


    format(path, sizeof(path), "flood_protection/%s.ip", playerIp);


    if (dini_Exists(path))
    {
    dini_Remove(path); // eintrag entfernen
    }


    return true;
    }


    Das ganze ist frei aus dem Kopf geschrieben und ungetestet.
    Das sollte soweit aber funktionieren.


    Hackt mir für Rechtschreibfehler bitte nicht den Kopf ab.


    Lg.


    #Brotfischbaron


    In schā'a llāh

  • Was, wenn der Server crasht? Die Dateien werden nicht gelöscht und somit kommen alle, die beim Crash online waren nicht mehr auf den Server.
    Am besten sollten alle Dateien beim start des Servers gelöscht werden (Da ist ja sowieso niemand drauf). Aber woher will man die Namen aller Dateien bekommen, um diese dann löschen zu können? Da PAWN keine Funktion bietet die Scriptfiles zu durchsuchen, muss man da wohl auf eine andere Methode zurück greifen (z.b alle Dateinamen in einer extra Datei speichern, diese dann zum löschen auslesen).
    Alles in allem finde ich das aber zu umständlich, weshalb ich das ganze per SQLite lösen würde.
    Wäre schön wenn du dir das nochmal überlegen würdest und das Tutorial dem entsprechen änderst.


    Außerdem verhindert dein Tutorial, das mehrer Spieler über die gleiche IP verbinden können. Das ist relativ ungünstig wenn z.b mehrere Personen in einem Haushalt spielen möchten.

    The fact is, I am right. And if you think I'm wrong, you are wrong.

  • Wenn der Server crashed, muss dieser zu 90% per Hand wieder hochgefahren werden (wenn man kein automatisiertes System verwendet).
    Dabei können dann auch alle IP-Files per Hand gelöscht werden.
    Natürlich wäre es hier einfacher, die Dateien in einer separaten Datei zu speichern, und diese Liste dann beim Server-Start abzuarbeiten.


    Das soll lediglich die Funktionsweise eines solchen Schutzes zeigen - Wie bereits im 1. Post erwähnt, kann man das auf jedes andere Datei- und Datenbanksystem übertragen - Durch anderweitige Tutorials für das jeweilige gewünschte System, sollte das auch ohne eine Änderung dieses Tutorials möglich sein.


    Man könnte noch einbauen, dass es eine maximale Anzahl von gleichzeitig verbundenen IP-Adressen geben darf.


    #Brotfischbaron


    In schā'a llāh

  • Bei mir kickts immer die player die connecten...


    (Wie macht man das maximal 5 Spieler von derselben IP gleichzeitig connecten können?)

    Du brauchst Hilfe beim scripten? Siehe Hier:


    Klick mich!


    Derzeitiges Projekt: Youngs Deathmatch 1.0.0 [||||||||||]

    Einmal editiert, zuletzt von RedZ ()