Beiträge von UncleSub

    Was ist denn daran so schlimm? Der timestamp hat nun mal einen hohen Wert?


    Evtl solltest du dir klar machen, was ein timestamp ist.


    Ein timestamp gibt dir die Zeit in Sekunden seit dem 1.1.1970 zurück. Wenn du jetzt jmd für eine bestimmte Zeit bannen willst, kann man damit wunderbar arbeiten. Du musst die Zeit, für die du ihn bannen willst, in seks umrechnen und auf den aktuellen timestamp addieren. Dadurch bekommst du heraus, bis zu welcher Sekunde nach dem 1.1.1970 der Spieler gebannt ist. Wenn er nun connected, kannst du den neuen aktuellen timestamp mit dem gespeicherten vergleichen. Wenn der aktuelle timestamp größer als der gespeicherte ist, ist der Spieler nicht mehr gebannt, ansonsten ist er es noch.


    Stimmt noch nicht ganz.
    Du musst deine Zeit in Stunden in Sekunden umrechnen und zu dem aktuellen Timestamp addieren. Dann hast du die Zeit raus, bis wann der Spieler gebannt ist.


    zeit = (gettime()+(zeit*3600));


    Das Speicherst du in deiner Spielerdatei, doch du musst, wie d0. sagte den Pfad angeben.


    Wenn der Spieler connected, fragst du folgendes ab:


    if(gettime() < varausderdateigebanntbis)


    Dann musst du den Spieler kicken, da die aktuelle Zeit noch kleiner als die Zeit, bis wann er gebannt ist, ist. varausderdateigebanntbis ist hierbei die Spielervariable, die beim Laden gesetzt wird und den Gebannt bis Wert vom timeban hat.

    Update auf Version 1.1.0:


    Seit dem neuesten Update werden die Blitzer automatisch gespeichert und geladen. Als Speicherungssystem wird dazu SQLite verwendet, da dieses System sich am Besten für diesen Zweck eignet. (Keine extra Plugin o.Ä. nötig, wie bei MySQL)
    Sobald die neueste Include installiert wurde und das Gamemode neu compiliert wurde, ist die Include voll funktionsfähig. Nach einem Restart wird die Datenbank und die Tabellenstruktur automatisch erstellt.
    Solltet ihr das Speicherungssystem nicht nutzen wollen, könnt ihr wieder durch Vorkonfigurationen dieses Feature ausschalten. Ihr müsst nur vor dem Includieren folgendes einfügen:


    #define BLITZER_NO_SAVE


    Zusätzlich dazu habe ich die Variablen im System anders benannt, so sollte es zu einer höheren Komptabilität führen! (Falls gleichnamige Variablen im Script vorhanden sind.)


    Ansonsten würde ich mich erneut über Kritik freuen!


    Mfg,
    UncleSub

    Nun gut. Weil du es bist spendier ich dir mal meine Funktion, die ich im Script dafür habe.



    stock GetVehicleInfo(vehicleid, infotype, &Float:x, &Float:y, &Float:z, &Float:angle)
    {
    if(vehicleid == INVALID_VEHICLE_ID) return 0;


    new Float:mX, Float:mY, Float:mZ;


    GetVehicleModelInfo(GetVehicleModel(vehicleid), infotype, mX, mY, mZ);


    z += mZ;


    x += (mY * floatsin(-angle, degrees));
    y += (mY * floatcos(-angle, degrees));


    angle += 270.0;
    x += (mX * floatsin(-angle, degrees));
    y += (mX * floatcos(-angle, degrees));
    angle -= 270.0;
    return 1;
    }


    Du musst der Funktion den infotype geben, sowie die Position des Autos. Die Funktion spuckt dir dann die Koordinaten des gewünschten typens aus.


    Bsp.:



    stock IsPlayerInRangeOfTankdeckel(playerid, carid)
    {
    new Float:vpos[4];
    GetVehiclePos(carid, vpos[0], vpos[1], vpos[2]);
    GetVehicleZAngle(carid, vpos[3]);
    GetVehicleInfo(carid, VEHICLE_MODEL_INFO_PETROLCAP, vpos[0], vpos[1], vpos[2], vpos[3]);
    if(IsPlayerInRangeOfPoint(playerid, 2, vpos[0], vpos[1], vpos[2]))
    {
    return 1;
    }
    return 0;
    }


    Mfg,
    UncleSub

    Wie funktioniert das ohne Timer?

    Eigentlich ganz Einfach. Der Incognito Streamer bietet Funktionen, die Areas erstellt. Außerdem bietet er ein Callback "OnPlayerEnterDynamicArea". Was man machen muss, dachte ich mir, ist, einfach eine Area um den Blitzer zu erstellen, und wenn er dort hinein fährt wird der Blitzer ausgelöst. Ich hatte das Ganze schon länger bei mir so im Script, da aber immer wieder wenn ich erwähnte, dass das Ganze ohne Timer funktiioniert, alle gefragt haben wie das möglich ist und ich denke, dass es um einiges Ressourcenfreundlicher ist, als mit Timern habe ich mich entschieden dafür eine Include zu schreiben.

    Hallo zusammen,


    mir war wirklich echt langweilig, deshalb habe ich mal diese Include gemacht.


    Was macht diese Include?


    Diese Include fügt Funktionen hinzu, die es vereinfacht Blitzer zu erstellen. Diese Blitzer sind Ressourcenfreundlicher, als manch andere Blitzer, da diese Blitzer komplett ohne Timer funktionieren. Das macht das ganze System auch noch sehr akkurat, da diese Blitzer immer dann ausgelöst werden, wenn man in der Nähe des Blitzers ist und die Geschwindigkeit übertreten hat. Sprich die gemessene Geschwindigkeit ist absolut die selbe Geschwindigkeit, die man tatsächlich fährt. Normalerweise kann es zu Verzögerungen kommen, da der Timer auf einen bestimmten Intervall eingestellt ist und der Blitzer nur in diesem Intervall die Geschwindigkeiten prüft. Es kann dann zu fehlerhaften Geschwindigkeiten kommen, sogar bis zum nicht auslösen.


    Diese Include schafft Abhilfe, denn diese Probleme können hier nicht auftreten, außer man umfährt den Blitzer.


    Welche Funktionen bietet diese Include?


    Durch diese Include werden mehrere Funktionen hinzugefügt. Hier ist mal eine Liste:



    native CreateBlitzer(Float:x, Float:y, Float:z, Float:rz, MaxSpeed); -> Erstellt einen Blitzer; Gibt die Blitzer ID des erstellten Blitzers zurück.
    native DestroyBlitzer(blitzerid); -> Zerstört Blitzer; Returns 0 bei Fehler und 1 bei Erfolg.
    native IsBlitzer(blitzerid); -> Prüft, ob angegebene Blitzer ID ein tatsächlich vorhandener Blitzer ist.
    native IsBlitzerArea(area); -> area = ID der Area, beim betreten der Area in der man geblitzt wird.
    native IsPlayerInRangeOfBlitzer(playerid); -> Prüft, ob Spieler in der Nähe eines Blitzers ist. (Return: 1: Ja | 0: Nein)
    native GetBlitzerID(playerid); -> Die Blitzer ID des nächsten Blitzers. Returns -1 wenn kein Blitzer in der Nähe ist.


    Seit dem neuesten Update werden außerdem die Blitzer automatisch gespeichert und geladen. Ihr müsst nichts weiter vornehmen. (Zum Speichern wird SQLite verwendet, die Datenbank und die Tabellenstruktur werden automatisch erstellt.)


    Außerdem wird auch ein Callback hinzugefügt:


    forward OnPlayerBlitzed(playerid, blitzerid, speed, maxspeed);


    An dieses Callback werden alle nötigen Daten geliefert, die man zur Weiterverarbeitung braucht.
    (Speed = Gemessene Geschwindigkeit | maxspeed = Maximale Geschwindigkeit des Blitzers + Toleranz)


    Zusätzlich zu diesen Funktionen kann man dieser Include aber auch noch Vorkonfigurationen mitgeben.
    Wenn man vor dem Includieren der Include folgende Defines verwendet:


    #define BLITZER_NO_SAVE


    Wenn man dies aktiviert ist, wird die Speicher- und Ladefunktion der Include ausgeschaltet. (Falls jemand das Manuell machen möchte.) [Version 1.1.0 vorausgesetzt]


    #define BLITZER_KMH_TOLERANZ


    Dem Blitzer kann eine Toleranzgrenze mitgegeben werden, ab wann er blitzen soll. (Default: 2 km/h)


    #define BLITZER_USE_GETVEHICLESPEED


    Wenn aktiviert, muss im Script eine Funktion mit Namen: "GetVehicleSpeed(vehicleid)" vorhanden sein;
    Mit diesem Define wird festgelegt, wie die km/h berechnet werden (Evtl Berechnung vom Tacho nehmen).


    Beispiele zur Konfiguration
    #define BLITZER_KMH_TOLERANZ 5 //Toleranzgrenze liegt bei 5 km/h
    #define BLITZER_USE_GETVEHICLESPEED //Funktion GetVehicleSpeed muss hinzugefügt werden.
    #include <U_Blitzer>

    Beispiele zur Konfiguration
    //Irgendwo anders im Script (Nicht in anderen public's/Funktionen)
    stock GetVehicleSpeed(vehicleid)
    {
    //Hier muss euer Speedberechnungscode rein. Bsp:
    new Float:Vx, Float:Vy, Float:Vz;
    GetVehicleVelocity(vehicleid, Vx, Vy, Vz);
    new Float:rtn;
    rtn = floatsqroot(floatpower(Vx*100,2) + floatpower(Vy*100,2));
    rtn = floatsqroot(floatpower(rtn,2) + floatpower(Vz*100,2));
    return floatround(rtn);
    }

    Beispiele zur Konfiguration
    //Beispiele zum Erstellen der Blitzer (mit ocmd)
    ocmd:createblitzer(playerid, params[])
    {
    if(IsPlayerInRangeOfBlitzer(playerid)) return SendClientMessage(playerid, 0xFFFFFFFF, "Blitzer in der Nähe!");
    new Float:pos[4],speed;
    if(sscanf(params, "i", speed)) return SendClientMessage(playerid, 0xFFFFFFFF, "Nutze: /createblitzer [MaxSpeed]");
    GetPlayerPos(playerid, pos[0], pos[1], pos[2]);
    GetPlayerFacingAngle(playerid, pos[3]);
    CreateBlitzer(pos[0], pos[1], pos[2], pos[3], speed);
    return 1;
    }
    ocmd:destroyblitz(playerid, params[])
    {
    if(!IsPlayerInRangeOfBlitzer(playerid)) return SendClientMessage(playerid, 0xFFFFFFFF, "Kein Blitzer in der Nähe!");
    DestroyBlitzer(GetBlitzerID(playerid));
    return 1;
    }


    Welche Voraussetzungen benötige ich dafür?


    Für diese Include wird der Incognito Streamer benötigt, da mit den Dynamic Areas gearbeitet wird.
    Hier könnt ihr ihn finden, falls ihr ihn nicht habt: Klick mich
    Ansonsten kann jeder diese Include ohne Einschränkungen nutzen.


    Installation


    Nach dem Download der Include muss folgende Zeile in das Gamemode eingefügt werden. (WICHTIG: Das Includieren muss nach dem Includieren des Incognito Streamers geschehen!)


    #include <U_Blitzer>


    WICHTIG: Das Includieren muss nach dem Includieren des Incognito Streamers geschehen!


    Danach muss noch folgendes ins Gamemode eingefügt werden:



    public OnPlayerBlitzed(playerid, blitzerid, speed, maxspeed)
    {
    return 1;
    }


    Danach können alle Funktionen genutzt werden.


    Download


    Version 1.1.0:
    Pastebin: Pastebin
    Direkter Download: MEGA


    Ich hoffe euch gefällt meine Include (Ist meine erste Include), ich hoffe ebenfalls auf Verbesserungsvorschläge und Ideen für kommende Versionen.


    Mfg,
    UncleSub



    Edit 1: [ pwn] [/ pwn] Tags hinzugefügt.
    Edit 2: Formulierung
    Edit 3: Update auf V 1.1.0
    Edit 4: Downloadlinks

    Okay gut. Dann lass ich das Threaded Speichern weg, evtl funktioniert es dann.


    Mit sscanf habe ich tatsächlich auch neuere Systeme laden lassen, doch das System ist schon was älter, deswegen hab ich das noch so und ich war auch zu faul um es zu ändern.


    Danke für die Tipps und die Hilfe!


    Ich editier hier glecih drunter, ob es ohne Threaded SpielerSpeichern funktioniert.


    //Edit:
    Scheint bis jetzt zu funktionieren. Danke für die Hilfe! Trotzdem finde ich es komisch, dass beim SpielerSpeichern falsche ID's übermittelt werden. Naja was solls.

    Ich benutze OnMySqlQuery, da ich ja nur die playerid übergeben muss.


    Also ich habe dann einfach



    //SpielerLaden stock
    new query[128];
    format(query, 128, "SELECT * FROM Accounts WHERE Name='%s'", SpielerName(playerid));
    mysql_query(query, MYSQL_LOADPLAYER, playerid);


    //OnMysqlQuery
    switch(resultid)
    {

    case MYSQL_LOADPLAYER:
    {
    new data[800], field[44][100];
    mysql_store_result();
    if(mysql_num_rows())
    {
    mysql_fetch_row(data);
    splitfu(data, field, '|');
    format(Spieler[spareid][pPasswort], 40, field[1]);
    Spieler[spareid][pLevel] = strval(field[2]);
    SetPlayerScore(spareid, Spieler[spareid][pLevel]);
    Spieler[spareid][pKills] = strval(field[3]);
    Spieler[spareid][pDeaths] = strval(field[4]);
    mysql_free_result();
    ......
    }
    }
    }


    Zum speichern: Hast du eigentlich recht.

    Hallo zusammen,


    ich habe mir gestern gedacht, dass ich die Datenabfrage beim Account laden und auch das Speichern in Threaded Querys umschreibe, da ich dachte, dass dadurch die Performance des Servers gesteigert wird.
    Das Problem bei der Sache ist, dass ich heute festgestellt habe, dass in die Threads falsche playerid's übergeben werden. Sprich der Account wurde überschrieben.


    Kann man das Problem irgendwie lösen, oder ist dies überhaupt bekannt?


    Mfg,
    UncleSub


    P.S.: Ich benutze das neueste MySQL Plugin von StrickenKid.

    Geht auch ohne. Dafür benötigst du die Funktion "split" oder "splitfu", wie sie auch manchmal heißt.


    Wenn du die hast, einfach falls mehrere Zeilen in der Datenbank geladen werden:



    //Deine MySQL Abfrage
    new data[256], field[/*Anzahl*/][64]; //Anzahl muss die Anzahl an Feldern in der MySQL Datenbank sein
    while(mysql_fetch_row(data)) //data ist ein String, wo alle von mysql zurückgegebenen Daten reingepackt werden
    {
    splitfu(data, field, '|') //Sagt einfach nur, dass du den String data in das Array field nach jedem '|' Zeichen "splittest"
    new datei = strval(field[0]); //als besispiel
    }
    mysql_free_result();


    Ansonsten das selbe nur statt
    while(mysql_fetch_row(data))


    nur
    mysql_fetch_row(data);


    Mfg,
    UncleSub