Beiträge von BlackFoX

    An deiner Stelle würde ich erst einmal gucken um was es sich dort genau handelt, also so wie ich dass sehe ist es eine Funktion die nicht gefunden wird und keine Variable. Zuerst , um welches Skript handelt es sich ? und, findest du die Funktion im Skript/in den einbezogenen Dateien überhaupt ?

    Welchen Streamer sprichst du hier an ?


    Ansonsten würde ich sagen müsste diese Funktion sofern sie für Objekte vorgesehen ist extra für den Streamer geschrieben werden so dass man weiss welches Objekt angeprochen wurde.

    soweit ich weiss so lang wie du möchtest und soviel wie dein Speicher aushält, geht halt alles auf den Ram. Viele definieren Ihre Variablen auf bis zu 1000 Zeichen was eigentlich eher unnötig ist, 256 Zeichen bis 512 Zeichen reichen schon völlig aus

    Einfach den Bügel nach oben ausklappen und in die dafür vorgesehene Metallvorrichtung einhaken, so habe ich es immer gemacht dann drückst du dir Leertaste runter und der Bügel hakt sich auch wieder in die Leertaste ein :)


    Wenn sie verbogen sind bieg sie vorsichtig wieder zurück mit einer Pinzette oder einem Schlitz-Schraubenzieher

    Hallo liebe Community,



    ich sehe hier öfters wie einige Probleme haben dynamisch veränderbare Sachen zu erstellen. Ich möchte hiermit einen Einblick schaffen wie soetwas aussehen kann ohne mich jetzt auf eine bestimmte Sache zu fokusieren, es geht lediglich um darum wie man dynamische Strukturen schafft und volle Kontrolle darüber erreicht.



    Nun, jeder kennt Pawn als Sprache und somit auch die Fähigkeit der Multidimensionalen Array sprich eine Variable die mehrere Speicherplätze hat aber immer den selben Bezeichner hat, dieser Bezeichner spricht nachher die Stelle im Speicher an welche zeigt wo sich der Anfang dieser Variable bzw. die Variable selbst befindet zudem wird dort die Größe initialisert die zeigt wie groß unsere Variable eigentlich ist z.b.


    new unsertext[] = "Hallo Welt";


    Wie man sieht ist die Variable als Array gekennzeichnet und zeigt dem Compiler beim Kompilierungsprozess dass es sich hierbei um einen Array handelt und sich mehrere Werte darin befinden,
    hier haben wir ,,Hallo Welt´´ definiert sprich 10 Zeichen mit einem weiteren Zeichen welches \0 kennzeichnet sprich hier ist Sense.
    würden wir unsere Variable nun ohne Text definieren wollen aber mit der selben Größe so müssten wir Sie wie folgt definieren


    new unsertext[11];+


    und könnten später 10 zeichen oder 10 integer Werte darin speichern, Integer steht hierbei für einen Zahlenwert sowohl im Minus als auch im Plus Bereich.
    wir können einen Array auch Multidimensional definieren sprich so


    new unsertext[][] = {{"Hallo Welt"},{"Wert2"}};


    Die Datentypen bleiben vorerst die selben sprich Zeichenketten , einzelne Zeichen oder Integer. Um dass mit den Zeichen nocheinmal zu zeigen und was ich mit Zeichenketten meine


    new unsertext[] = {'H','a','l','l','o',' ','W','e','l','t'};


    entspräche auch


    new unsertext[] = "Hallo Welt";



    Um auf einen index in der Variable zuzugreifen sprich einen Speicherplatz könnte man dies tun


    new unserzeichen = unsertext[1]; // Rückgabe hierbei wäre jetzt a


    Nie vergessen, ein Array fängt immer bei 0 , eigentlich logisch doch für viele ist es die Gewohnheit bei 1 anzufangen denn dies haben wir ja in der Schule gelernt.




    Kann ich auch andere Datentypen verwenden ?


    Ja dies ist möglich. Ihr müsste dem Compiler nur bescheid geben dass Ihr einen anderen Datentyp verwenden wollt da jeder Datentyp eine andere Größe besitzt die später erst reserviert werden muss sonst findet der Compiler weder Anfang noch Ende der Variable sprich der Registereintrag wäre falsch und wäre unauffindbar!


    z.b.


    new Float:unsereVariable[] = { 3.14 , 4.32, 5.22 };


    dies ginge auch Multidimensional wie bei allen anderen datentypen



    new Float:unsereVariable[][] = { {3.14 , 4.32, 5.22} };


    oder noch größer usw... z.b. 3 dimensional , auch 4 dimensional usw...


    new Float:unsereVariable[][] = { { {3.14 , 4.32, 5.22}, {3.14 , 4.32, 5.22} },
    { {3.14 , 4.32, 5.22}, {3.14 , 4.32, 5.22} }


    };



    nun wissen wir dass wir auch andere Datentypen verwenden können, aber was wenn wir mehrere Datentypen verwenden möchten ? Nun dann definieren wir eine Struktur die angibt welche Größen nach welcher Reihenfolge vorhanden sind damit auch hier richtige Einträge in das Register eingetragen werden können sprich wir geben dem Compiler bescheid welche Datentypen wir haben möchte und geben Ihnen einen Bezeichner , hierzu nehmen wir mal "enum" als Anweisung



    enum unsereStruktur // wir geben der Struktur mal diesen Namen
    {
    Float:eineKommaZahl,
    eineGanzeZahl,
    einearray[32] // auch in einer Struktur können weitere Strukturen die bereits da sind verwendet werden, hier nehme ich einfach ein array mit 32 Plätzen für 31 Zeichen oder Zahlen


    };



    diese kann man jetzt sozusagen jeder Variable verergeben und kann somit mehrere Datentypen in eine Variable einbinden z.b. so



    new unsereVariable[unsereStruktur]; // nun hat diese Variable ,,unsereStruktur ´´ "geerbt" und man kann sie dann dementsprechend ändern z.b.


    unsereVariable[eineGanzeZahl] = 5;


    wir greifen hier auf den Bezeichner "eineGanzeZahl" in "unsereVariable" zu sprich wir sprechen genau diese Stelle im Speicher an welche uns anzeigt es kann ein Integer/char eingetragen werden sprich dessen Größe hat , würden wir versuchen einen String zuzuweisen so gäbe es ein Problem, die größe wäre nicht für eine Kette von zeichen vorgesehen und somit würde alles was über einem Zeichen/Integer ist den Speicher dahinter überschreiben wollen, dieser Bereich ist aber schon reserviert bzw. geschützt was zu einem fatalen Fehler kommen würde denn so kämme der ganze Ablauf durcheinander und das Register wäre Fehlerhaft!


    wir können Strukturen auch Multidimensional verwenden


    new unsereVariable[20][unsereStruktur];


    so hätten wir 20 Plätze die jeweils alle die Datentypen aus "unsereStruktur" beinhalten.
    Zugriff hätten wir z.b. ganz einfach so :


    unsereVariable[2][eineGanzeZahl] = 5;
    jetzt hat "eineGanzeZahl" in Platz 2 der Variable "unsereVariable" den Wert 5. Die anderen Plätze kann man auch mit jeweils einer Zahl belegen genauso wie man die anderen Bezeichner jeweils belegen kann



    so könnte man Werte gleich festlegen was rein soll :


    new unsereVariable[][unsereStruktur] = { {5,3.14,"Hallo Welt"} , {7,4.22,"nummer 2"}};


    natürlich muss alles festgelegt werden was die Struktur "unsereStruktur" angibt und jeweils im vorgegebenen Datenytp. Würden wir eine feste Größe definieren wollen muss diese mit der Anzahl der angegebenen Daten überein stimmen
    new unsereVariable[2][unsereStruktur] = { {5,3.14,"Hallo Welt"} , {7,4.22,"nummer 2"}}; // hier müsste also eine 2 stehen, 0 für Eintrag 1, 1 für Eintrag 2, und 2 für die information wo die variable endet, nur für den Speicher wichtig




    Dynamisch arbeiten


    Als erstes definieren wir uns eine array im Kopf des Skripts und einen variable die zurückgibt wieviele id's gespeichert wurden


    new unsereIDS[20]; // 20 Speicherplätze in denen ich 20 Autos speichere
    new count = -1; // ich setze hier mal auf -1 da ich zuerst hochzähle und dann erst verwende, kann jeder machen wie er will



    Nun gehe ich in die öffentlich Funktion "OnGameModeInit" und gehe wie folgt vor


    count++; // ich zähle wie gesagt zuerst hoch um den Speicherplatz festzulegen den ich als nächstes verwende
    if(count <= 19) // damit der speicher nicht höher als 19 geht und so ein fehler auftritt da unsereIDS nur 20 slots hat und davon 19 verwendet werden können von 0 angefangen!
    {
    unsereIDS[count] = CreateVehicle(...); // Ich erstelle das Fahrzeug und speichere dessen ID in unsereIDS auf dem jeweiligen platz
    }


    würde ich jetzt abfragen wollen ob z.b. dies ein Auto aus der array ist so muss die ID des Fahrzeugs auch in der Variable vorhanden sein z.b. so


    for(new i = 0;i<count;i++)
    {
    if(GetPlayerVehicleID(playerid) != unsereIDS[i])continue; // wenn die ID des Autos in dem wir sitzen nicht unsereIDS[speicherplatz] dann schleife fortsetzen und weitersuchen
    SendClientMessage(playerid,0xFFFFFFFF,"Es ist ein Auto aus der Array!"); // wird die schleife nicht übersprungen wie oben gezeigt mit continue so muss er an diese stelle kommen und es ist ein Auto aus dem Array
    break; // schleife gleich beenden denn wir müssen nicht mehr weitersuchen, jeder wie er will, ich mache es so
    }




    Um nun etwas genauer zu werden und eine Struktur einzubinden mache ich folgendes :


    ich behalte count als zähler variable und erstelle nun eine struktur :



    enum unserFahrzeug
    {
    id,
    kostet,
    gehoert[MAX_PLAYER_NAME]
    };

    nun ändere ich meine Variable unsereIDS um in


    unsereIDS[20][unserFahrzeug];


    so vererbe ich die Struktur unsereIDS und kann detailiertere Infos eintragen und verwenden und habe so mehr Möglichkeiten
    wenn ich nun das Fahrzeug erstelle tuhe ich dies so



    count++; // wie immer erst den Platz hochzählen beim erstellen
    if(count <= 19) // ihr wisst ja was ich gesagt hab!
    {
    unsereIDS[count][id] = CreateVehicle(...); // nun speichern wir die ID in "id" und in platz den count zurückgibt


    // hier weise ich mal zum test den rest zu, diesen kann man später woanders ändern mit einer schleife oder so, hier nur als test für nachher
    unsereIDS[count][kostet] = 200; // kostet kriegt jetzt den Wert 200 also im übertragenen sinne soll mein preis 200$ für dieses Fahrzeug sein.
    format(unsereIDS[count][gehoert],MAX_PLAYER_NAME,"%s","EinName"); // ich setze gehoert auf "EinName" natürlich wieder im Platz den "count" zurückgibt
    }



    nun wenn ich später abfrage tuhe ich wieder folgendes



    new formatmsg[MAX_PLAYER_NAME + 32]; // für später um den Namen anzuzeigen
    for(new i = 0;i<count;i++)
    {
    if(GetPlayerVehicleID(playerid)
    != unsereIDS[i][id])continue; // wenn die ID des Autos in dem wir sitzen
    nicht unsereIDS[speicherplatz][id] dann schleife fortsetzen und weitersuchen
    format(formatmsg,sizeof formatmsg,"Dieses Auto gehoert %s und kostete %i",unsereIDS[i][gehoert],unsereIDS[i][kostet]); // wird die schleife nicht übersprungen
    wie oben gezeigt mit continue so muss er an diese stelle kommen und es
    ist ein Auto aus dem Array
    SendClientMessage(playerid,0xFFFFFFFF,formatmsg); // zeigt die Nachricht die ich formatiert habe an
    break; // schleife gleich beenden denn wir müssen nicht mehr weitersuchen, jeder wie er will, ich mache es so
    }



    Also, dass wars, ich hoffe ich konnte euch einen Schritt näher an die Sache bringen und es etwas verdeutlichen, es ist aus dem Prinzip heraus nicht schwer und mit etwas Zeit kriegt es jeder hin.

    Der Spaß hört aber dann auf wenn derjenige der diese Attacken ausführt erwischt wird denn dann darf er für den entstandenen Schaden aufkommen. Zum punkt "Loadbalancer", bei einer radikalen Attacke helfen nicht einmal die. Mir ist also schon klar dass es keinen 100%igen Schutz gegen DDoS gibt aber um Attacken von Skids abzuwehren reicht soetwas :D

    Jeder so wie er will. Die Programme sind nicht unnötig, ich benutze sie Beispielsweise als Hilfe wenn ich bestimmte Sachen programmiere :) sind ganz nützlich um z.b. zu schauen um Prozesse erfolgreich injeziert wurden usw. :D zudem muss man manche Prozesse auf diese Weise beenden, ich logge mich bestimmt nicht zig mal ein und aus damit ich einen Sub Prozess entladen kann.

    Och da hab ich noch andere Sachen auf Lager um solche Attacken abzuwehren. Zudem sind heute viele Hoster selbst ziemlich gut abgesichert :) da mache ich mir nicht so große Sorgen :D auch umgeleitete Attacken kann man blocken vorallem wenn die Verbindungen Suspekt sind :)

    lade dir mal Process Explorer herunter, dieses Werkzeug erkennt auch versteckte Prozesse und Dateien in jeweils anderen Prozessen ansonsten gibts auch noch "Unlocker", damit kannst du auch Dateien löschen die gerade verwendet werden bzw. einen Schreibschutz haben :) Ansonsten wie gesagt kannst du es ja Manuell machen aber so geht es schneller.

    #include <a_samp>
    #define RESET_ON_CHANGE 10 // Maximal 10x wird das Geld gezählt nach dem verändern danach setzt sich die Liste zurück und eine neue wird erstellt
    #define MAX_WARN 3 // 3 mal wird man gewarnt sobald man das Geld einfriert danach > Ban!
    forward moneyTask();
    main()
    {
    print("\n----------------------------------");
    print(" Anti Money Hack - by [BFX]Explosion");
    print("----------------------------------\n");
    }
    randomStr(len)
    {
    new rStr[32];
    if(len < 0 || len > 31)return rStr;
    for(new i = 0;i<len;i++)
    {
    new key;
    do{key = random(90);}
    while(key < 65);
    rStr[i] = key;
    }
    return rStr;
    }


    unqKey(playerid)
    {
    new rkey[16];
    do{format(rkey,sizeof rkey,"gk_%s",randomStr(8));}while(GetPVarInt(playerid,rkey) != 0);
    return rkey;
    }
    zusammen(playerid)
    {
    new nm[16],value;
    for(new j = 0;j<GetPVarsUpperIndex(playerid);j++)
    {
    GetPVarNameAtIndex(playerid,j,nm,sizeof nm);
    if(!strcmp(nm,"gk_",true,2))
    {
    value+=GetPVarInt(playerid,nm);
    if(GetPVarInt(playerid,nm) == 0)DeletePVar(playerid,nm);
    }
    }
    return value;
    }


    reset(playerid)
    {
    new nm[16],value;
    for(new j = 0;j<GetPVarsUpperIndex(playerid);j++)
    {
    GetPVarNameAtIndex(playerid,j,nm,sizeof nm);
    if(!strcmp(nm,"gk_",true,2))
    {
    value+=GetPVarInt(playerid,nm);
    DeletePVar(playerid,nm);
    }
    }
    return SetPVarInt(playerid,unqKey(playerid),value);
    }
    public moneyTask()
    {
    for(new i = 0;i<MAX_PLAYERS;i++)
    {
    if(IsPlayerNPC(i) || !IsPlayerConnected(i))continue;
    new gt = zusammen(i);
    if(!gt)continue;
    new warn = 0;
    while(GetPlayerMoney(i) != gt)
    {
    GivePlayerMoney(i,-GetPlayerMoney(i));
    GivePlayerMoney(i,gt);
    SetPVarInt(i,"_reset",GetPVarInt(i,"_reset")+1);
    if(GetPVarInt(i,"_reset") >= RESET_ON_CHANGE)reset(i);
    warn++;
    if(warn == MAX_WARN)Ban(i);
    }
    }
    }


    // Funktionen


    stock nGivePlayerMoneyEx(playerid,geld)
    {
    if(!IsPlayerConnected(playerid) || IsPlayerNPC(playerid))return 0;
    return SetPVarInt(playerid,unqKey(playerid),geld);
    }
    stock nGetPlayerMoneyEx(playerid)return zusammen(playerid);



    Hier ein Ausschnitt aus einem meiner Anti Money Cheat Systeme, dieses System ist anders und arbeitet über Zufallsschlüssel die für den Spieler generiert werde, die Beträge werden gesammelt und sobald sich das Geld verändert zusammen gezählt sprich auch Visuell aktualisert. Will der Spieler Geld einfrieren versucht das System die aktualisierung solange bis er die maximale Anzahl an Warnungen erreicht hat und verbannt den Spieler, wird die Anzeige jedoch erfolgreich auf das echte momentane Spielergeld gesetzt so bleibt alles im grünen Bereich.


    Nach 10 aktualisierungen werden die Beträge zusammen gezählt und in einen einzelnen Schlüssel transferiert danach verschwinden die anderen und es existiert ein Schlüssel für den Spieler der den echten Betrag hält, natürlich werden weitere Beträge wieder in einer Liste abgespeichert und 10x aktualisiert usw...


    Nicht vergessen den Timer moneyTask zu setzen, es reicht wenn er alle 2 Sekunden aktualisiert :)


    Mit einem Zufallsschlüssel/variablen System wird es für den noch Spieler schwerer irgendwas anzurichten, ich werde in nächster Zeit noch etwas nachbessern um es sicherer zu machen :)

    Ich habs mal so gemacht das ich einen Zufallsschlüssel für die nächste "Geldübergabe" generiert habe natürlich auch in eigene Funktionen eingebunden, alles was diesen Schlüssel nicht hatte wurde abgelehnt hinzu wurde die gesetzte Variable beim verlassen des Servers gespeichert und nicht der Betrag der Visuell zu sehen war. Bei jeder Geldübergabe habe ich einen neuen Schlüssel definiert in einer Zufalls Spielervariable, der Bezeichner dieser Variable wurde in einer weiteren Spielervariable gespeichert :)

    Also wenn du was verschlüsseln willst, ich kenne eine sehr einfache Methode :) Noch aus C/C++ Zeiten


    XOR_VALUE(input[],key[],newValue[])
    {
    new j = 0;
    for (new i = 0; i < strlen(input); i++)
    {
    if(j>i)j = 0;
    newValue[i] = (input[i] ^ key[j]);
    }
    }


    Nennt sich wie man sieht XOR, eine sehr bekannte Methode.