Beiträge von Templer

    Zitat


    Der Vertrag sieht unseriös aus. Er gibt an ab dem 03.10.2014 keine Rechte mehr an dem Script zu haben. Sollte er es trotzdem weiter geben/verkaufen begeht er Klicke Hier.


    Es wurde aber nicht von meiner Seite aus weiter gegeben / verkauft. Diese Person die den Verkauf getätigt hat, steht überhaupt nicht in Kontakt mit mir.

    Zitat


    Zitat von »[F]aisal«


    letztens hat mir wer das script angeboten ob ich es kaufen möchte ich habe drauf verzichtet und skillex + Robin haben es gekauft das war irgendein Österreicher weiß nicht mehr seinen Namen

    Das Script wurde nur an Skrillex und Robin verkauft. Der User hier ist der Programmierer von dem Projekt. Ich kann bestätigen, dass es sonst kein anderer hat und es auch nicht weitergegeben wird.


    Bei Bedarf gebe ich auch Unterstützung, wie das Script funktioniert. Einfach per Privat Nachricht melden und einen Terminvorschlag machen.


    Sofern Käufer besteht, werde ich auch die Installation betreuen bzw. mithelfen. Es ist auch möglich das Script unter Linux laufen zu lassen, jedoch ist dies ein kleiner Mehraufwand und wäre nur auf einem eigenen Linux Server möglich, worauf "wine" installiert ist (da der Linux Compiler bisher bei mir selbst Probleme von normalen Bot-Dateien Probleme hatte).


    Lg


    p.S. Der Grund warum es grundsätzlich nur auf Windows funktioniert ist der Bedarf für das RaubSystem und BusSystem, da die Bot-Dateien InGame automatisch kompiliert werden. Damals gab es eben kein RNPC, aber natürlich könnte dies einer mit Erfahrung umschreiben.

    Füg mal den Query manuell in deine SQL-Tabelle ein, ob ein Fehler kommt:


    UPDATE pRP_gutscheine SET gutscheincode='1810',gutscheinname='Test',gutscheindesc='Test',gutscheintyp='1',gutscheinmenge='1',gutscheinanzahl='1' WHERE id='1'


    wenn möglich den Query beheben und im Script aktualisieren.


    Leider muss ich nur jetzt schon gehen. Hoffe jemand anders kann dir jetzt helfen, sonst kann ich erst morgen Abend wieder.


    Lg


    //EDIT: ich sagte schon vorher, dass bei GUTSCHEIN_CREATE_CODE das INSERT INTO fehl ist. Das DELETE FROM war schon richtig.

    Oh entschuldige, ein dummer Fehler von mir.


    es liegt an der Zeile im Dialog, wo der Gutschein aktualisiert wird mit UPDATE:
    mysql_function_query(MySqlConnection,mainquery,false,"","");


    umändern zu


    mysql_function_query(MySqlConnection,query,false,"","");


    Sry, bitte nochmals testen.


    //EDIT: Mir fällt auch zu spät auf, dass dein Spaltenname in der MySQL Tabelle falsch is mit gutscheindesc (In der Datenbankspalte steht nur gutscheindes, oder ist die Anzeige verkürzt?)

    Sieht gut aus. Also würd ich sagen, dass du damit zufrieden bist, oder? ^^ Stehen die Werte auch so in der Datenbank?


    Wenn ja: Kannst du den Gutschein nach einem Neustart auch nützen? Wenn nicht, dann bitte den Code, wo du die Gutscheine einliest. Aber ich denke das wird schon schief gehen.

    In OnDialogResponse bei GUTSCHEIN_CREATE_CODE ist bei response == 0 ein INSERT INTO. Hier sollte doch der erstellte Gutschein in der Datenbank doch wieder gelöscht werden. (Bei /gutschein wird ja bereits einer erstellt)


    mysql_free_result(); ist unnötig nach Queries die kein SELECT beinhalten.



    Wieso möchtest du alle Gutscheine aktualisieren? Es reicht doch nur den zu aktualisieren, den man erstellt oder bearbeitet hat.


    Ich würde also empfehlen, dein while Code-Ausschnitt zu löschen und den Dialog GUTSCHEIN_DIALOG_ANZAHL folgendermaßen umzuändern:



    case GUTSCHEIN_DIALOG_ANZAHL:
    {
    new anzahl = strval(inputtext);
    if(response == 0)
    {
    switch(Gutschein[MakeGutschein[playerid]][gutscheintyp])
    {
    case 1:
    {//Level
    ShowPlayerDialog(playerid,GUTSCHEIN_DIALOG_MENGE,DIALOG_STYLE_INPUT,"Gutscheinerstellung Schritt 5","Wie viel Level soll man bei diesem Gutschein erhalten:","Weiter","Zurück");
    return 1;
    }
    case 2:
    {//DonatorZeit
    ShowPlayerDialog(playerid,GUTSCHEIN_DIALOG_MENGE,DIALOG_STYLE_INPUT,"Gutscheinerstellung Schritt 5","Wie viel PremiumZeit soll man bei diesem Gutschein erhalten:","Weiter","Zurück");
    return 1;
    }
    case 3:
    {//Fahrzeuge
    ShowPlayerDialog(playerid,GUTSCHEIN_DIALOG_MENGE,DIALOG_STYLE_INPUT,"Gutscheinerstellung Schritt 5","Welches Fahrzeug soll man erhalten:","Weiter","Zurück");
    return 1;
    }
    case 4:
    {//Respektpunkte
    ShowPlayerDialog(playerid,GUTSCHEIN_DIALOG_MENGE,DIALOG_STYLE_INPUT,"Gutscheinerstellung Schritt 5","Wie viele Respektpunkte soll man erhalten:","Weiter","Zurück");
    return 1;
    }
    case 5:
    {//Geld
    ShowPlayerDialog(playerid,GUTSCHEIN_DIALOG_MENGE,DIALOG_STYLE_INPUT,"Gutscheinerstellung Schritt 5","Wie viel Geld soll man erhalten:","Weiter","Zurück");
    return 1;
    }
    }
    return 1;
    }
    if(response == 1)
    {
    new query[256], gutscheinn = MakeGutschein[playerid];
    if(!strlen(inputtext))
    {
    ShowPlayerDialog(playerid,GUTSCHEIN_DIALOG_ANZAHL,DIALOG_STYLE_INPUT,"Gutscheinerstellung Schritt 6","Wie oft kann dieser Gutschein verwendet werden:","Weiter","Zurück");
    return 1;
    }
    if(!IsNumeric(inputtext))
    {
    ShowPlayerDialog(playerid,GUTSCHEIN_DIALOG_ANZAHL,DIALOG_STYLE_INPUT,"Gutscheinerstellung Schritt 6","Wie oft kann dieser Gutschein verwendet werden:","Weiter","Zurück");
    return SendClientMessage(playerid,GRAU,"Gebe nur Zahlen ein!");
    }
    else if(anzahl <= 0)
    {
    ShowPlayerDialog(playerid,GUTSCHEIN_DIALOG_ANZAHL,DIALOG_STYLE_INPUT,"Gutscheinerstellung Schritt 6","Wie oft kann dieser Gutschein verwendet werden:","Weiter","Zurück");
    return SendClientMessage(playerid,GRAU,"Anzahl muss > 0 sein!");
    }
    else
    {
    SendClientMessage(playerid,GELB,"Gutschein erfolgreich erstellt!");
    MakeGutschein[playerid] = 0;
    // Nebenbei war hier auch vorhin ein Fehler, dass du die Variable MakeGutschein auf 0 zurückgesetzt hast und erst
    // danach die Anzahl gesetzt hast.
    Gutschein[gutscheinn][gutscheinanzahl] = anzahl;
    format(query,sizeof(query),"UPDATE "#DATENBANKTAG"_gutscheine SET gutscheincode='%s',gutscheinname='%s',gutscheindesc='%s',gutscheintyp='%d',gutscheinmenge='%d',gutscheinanzahl='%d' WHERE id='%d'", Gutschein[gutscheinn][gutscheincode],Gutschein[gutscheinn][gutscheinname],Gutschein[gutscheinn][gutscheindesc],Gutschein[gutscheinn][gutscheintyp],Gutschein[gutscheinn][gutscheinmenge],Gutschein[gutscheinn][gutscheinanzahl],gutscheinn);
    printf("GUTSCHEIN-DEBUG | %s", query); // Zu Debugzwecken
    mysql_function_query(MySqlConnection,query,false,"","");
    }
    return 1;
    }
    }


    Wenn das Abspeichern funktioniert, können wir uns zum Laden vorarbeiten :P Aber bitte nach deinen Aktualisierungen einen Gutschein InGame erstellen und dann aus den Server-Logs die Zeile mit GUTSCHEIN-DEBUG aussuchen, Danke

    Ok, hab von der Entfernung deine Klammern nicht gesehen, Sry :P Ich hasse diese Schreibweise, um unnötig einen Doppelbruch zu schreiben. Da liebe ich die normale Schreibweise mit nur einem Bruch.


    Ja stimmt, meine benötigt unnötig viele Berechnungen.


    Lg

    Ach gott. Jefrry schreib mir mal bitte, wann bei einer Rechnung von (inhalt / gesamt) es jemals mehr als 1 wird? Lassen wir doch einfach den Tank überfüllen und irgendwie im "void" den Tank aufbewahren, oder? Das du danach noch um weitere 10 dividierst, frag ich gar nicht nach.


    @Topic:
    Am lustigsten wäre es, wenn man eine Schleife nützt :P



    #define MAX_TANK_INFO_STEPS 10
    #define MAX_TANK_INFO_INPUT_LENGTH 2 // Weil "I" und " "
    new tankInfo[6*MAX_TANK_INFO_STEPS*MAX_TANK_INFO_INPUT_LENGTH+1], // 6 Plätze für ~g~ und ~r~. (+1 für NULL)
    Float:derzeitiger_tank = 10.0, // Hier bitte die Funktion/Variable für den derzeitigen Tank
    Float:maximaler_tank = 50.0, // Hier bitte die Funktion/Variable für den maximalen Tank
    // Die Berechnung unterbei bitte lassen.
    calculated = floatround(floatmul(floatdiv(derzeitiger_tank, maximaler_tank), MAX_TANK_INFO_STEPS), floatround_floor),
    bool:limitReached = false; // Ab wann die Anzeige rot wird.
    format(tankInfo,sizeof(tankInfo),"~g~"); // Fange mit den Grünen Punkten an
    for(new step = 0; step != MAX_TANK_INFO_STEPS; step++) { // Zähle bis zu den maximalen Schritten
    if(!limitReached && step >= calculated) { strcat(tankInfo,"~r~"); limitReached = true; } // Ab der Grenze auf Rot umstellen
    strcat(tankInfo,"I "); // Zeichne die "I" Punkte mit Abstand danach " "
    }


    //EDIT: MAX_TANK_INFO_INPUT_LENGTH hinzugegfügt, weil ein Abstand danach kommt. Sry

    Sofern du aber eine Variablen Definition mit MAX_VEHICLES vermeiden möchtest (2000), dann würde ich dir eine PVar-Variante gerne zeigen:



    public OnPlayerCommandText(playerid, cmdtext[])
    {
    if(strcmp(cmdtext, "/sirene",true) == 0)
    {
    if(!IsPlayerInAnyVehicle(playerid)) return SendClientMessage(playerid,COLOR_GREY," Sie sitzen in keinem Fahrzeug...");

    new old_object = GetPVarInt(playerid,"PlayerSirene") - 1,
    vehicle_id = GetPlayerVehicleID(playerid),
    vehicle_model = GetVehicleModel(vehicle_id),
    siren_object;

    if(old_object > -1) {
    DestroyObject(old_object);
    DeletePVar(playerid,"PlayerSirene");
    }

    siren_object = CreateObject(19419,0.0,0.0,0.0,0.0,0.0,0.0);
    SetPVarInt(playerid,"PlayerSirene",(siren_object+1));
    switch(vehicle_model)
    {
    // Hier weitere Fahrzeuge hinzufügen (zuerst aber richtige Position herausfinden).

    // Sultan
    case 560: return AttachObjectToVehicle(siren_object,vehicle_id,-0.5,0.0,0.85,0,0,0);

    // Aus Faulheit kann man jedoch auch eine statische Position für alle nicht definierte Fahrzeuge definieren
    // Einfach folgende Zeile entkommentieren (Ist aber nicht zum empfehlen, weil es unordentlich aussieht).
    // default: return AttachObjectToVehicle(siren_object,vehicle_id,0.0,0.0,0.0,0,0,0);
    }
    DeletePVar(playerid,"PlayerSirene");
    DestroyObject(siren_object);
    return SendClientMessage(playerid,COLOR_GREY," Sie sitzen in keinem gültigen Fahrzeug, worauf die Sirene passt...");
    }
    return 0;
    }


    public OnPlayerDisconnect(playerid, reason)
    {
    if(GetPVarInt(playerid,"PlayerSirene") > 0) DestroyObject(GetPVarInt(playerid,"PlayerSirene")-1);
    return 1;
    }


    public OnPlayerStateChange(playerid, newstate, oldstate)
    {
    if((oldstate == PLAYER_STATE_PASSENGER || oldstate == PLAYER_STATE_DRIVER) && GetPVarInt(playerid,"PlayerSirene") > 0) {
    DestroyObject(GetPVarInt(playerid,"PlayerSirene")-1);
    DeletePVar(playerid,"PlayerSirene");
    }
    return 1;
    }

    Ich versteh nicht, warum ihr ein Array mit MAX_PLAYERS erstellen wollt. Ressourcenschonender wäre es, wenn man pro WantedLevel die Zahl erstellt.


    Es sind ja nur 6 WantedLevel, also würden 6 TextDraw´s reichen. Alles was unter 100 ist, kann man schön ohne MAX_PLAYERS lösen (100 als fiktive Grenze :P).


    Ein Ausschnitt wie es aussehen könnte (eine eigene Funktion):



    public SetPlayerOwnWantedLevel(playerid, level)
    {
    new current_level = GetPVarInt(playerid,"PlayerWantedLevel") - 1;
    if(current_level > -1) {
    TextDrawHideForPlayer(playerid, WantedStar[current_level]);
    TextDrawHideForPlayer(playerid, WantedNumber[current_level]);
    }

    if(level < 1 || level >= MAX_WANTED_LEVEL) {
    DeletePVar(playerid,"PlayerWantedLevel");
    return true;
    }
    TextDrawShowForPlayer(playerid, WantedStar[(level-1)]);
    TextDrawShowForPlayer(playerid, WantedNumber[(level-1)]);
    SetPVarInt(playerid, "PlayerWantedLevel", level);
    return true;
    }


    Kommentar: Normalerweise würde für den Stern auch ein Textdraw reichen, aber hinter dieser Funktion steckt eine automatische Farbabstufung drinnen. Bedeutet je höher das WantedLevel, desto rötlicher wird es vom Gelb.


    Also es würde auch so reichen:



    public SetPlayerOwnWantedLevel(playerid, level)
    {
    new current_level = GetPVarInt(playerid,"PlayerWantedLevel") - 1;
    if(current_level > -1) {
    TextDrawHideForPlayer(playerid, WantedStar);
    TextDrawHideForPlayer(playerid, WantedNumber[current_level]);
    }

    if(level < 1 || level >= MAX_WANTED_LEVEL) {
    DeletePVar(playerid,"PlayerWantedLevel");
    return true;
    }
    TextDrawShowForPlayer(playerid, WantedStar);
    TextDrawShowForPlayer(playerid, WantedNumber[(level-1)]);
    SetPVarInt(playerid, "PlayerWantedLevel", level);
    return true;
    }


    Die volle Lösung hab ich dem Author per PN zukommen lassen, weil es mir langweilig war und sonst jeder diese Lösung kopieren würde ^^


    Lg

    Ich möchte gerne diesen Post "Pushen", da wir noch immer dringlich Personal bräuchten. Personen die bei uns bereits waren können auch gerne einen Beitrag schreiben, warum Sie nichtmehr ein 2tes Male erschienen (Interessiert mich persönlich).


    In den letzten Tagen gab es auch einige Aktualisierungen zum Script und ist nun ziemlich "sicher".


    Unterstützung wäre auch nett, wenn jemand sich um das UCP kümmern könnte. Es ist bereits eine Version fertiggestellt worden, jedoch bin ich zeitlich überfordert mich um SAMP und UCP zu kümmern.


    Ich entschuldige mich auch für den Forum-Fehler der anscheinend paar Tage anhielt für Besucher. Dieser wurde behoben! (Lag an der vollen wcf1_session Tabelle, weil der Cronjob "Hourly Update" nichtmehr automatisch ausgeführt worden war).


    EDIT: Mit dem Wort "sicher" meine ich, dass unser Script zu dem Zeitpunkt kein wirkliches Anticheat hatte. Dies wurde sofort nachgeholt.

    Zur Vollständigkeit zitiere ich noch Y_Less, warum SAMP nicht auf die neue PAWN Version umgeschrieben wird: Die neue Version würde Sicherheitslücken schließen, welche von anderen Autoren ausgenutzt werden. (besonders weil Systeme von Y_Less nutzlos wären, weil er selbst diese Bug´s ausnutzt :P)


    Ich finde es nur schade, weil in der neuen Version eine Mac Version bereitgestellt worden ist und ein User bei Google Code bereits einen patch schrieb, der das kompilieren einer Mac Version vervollständigte.


    Leider steht aber auch der Source-Code von der PAWN Version 3.2.3664 nichtmehr zur Verfügung.


    Die Änderungen zur Version Version 3.2, build 3664 hier:
    http://pastebin.com/Qn4xmwCf
    (Ein bisschen reinstöbern zeigt auch bereits die volle Änderung der Sprache und wahrscheinlich ist da drinnen auch irgendwo der Bugfix für unser Problem)


    Quelle: http://forum.sa-mp.com/showthread.php?t=274061&page=6


    p.S. Ich entschuldige wenn das Forum bereits ein solches Thema angeschnitten hat. Sollte jemand einen Link zu einem Post betreffend (Neue PAWN Version) finden, so schreibe er ihn bitte unterbei.


    Hier wollte ich nur das endgültige Fazit zum derzeit unbeschreiblichen Fehler bringen, damit auch interessierte Leser in Zukunft damit klar kommen. (Daher auch Zitate beigefügt vom sa-mp.com Forum, wenn dieses vorher offline geschaltet werden sollte, als sa-mp.de :P)


    Der Link zu Pastebin wird wahrscheinlich noch lange halten.


    //EDIT: Tippfehler behoben

    Hier meine Testläufe (Man bemerke jedoch, dass der Fehler zur Laufzeit nur mit "crashdetect" erkannt werden kann. Ohne dem Plugin sieht man den Fehler überhaupt nicht und er überspringt den Code):



    public OnGameModeInit()
    {
    // Don't use these lines if it's a filterscript
    SetGameModeText("Blank Script");
    AddPlayerClass(0, 1958.3783, 1343.1572, 15.3746, 269.1425, 0, 0, 0, 0, 0, 0);

    new test = 5;
    if(test == 5) {
    if(test == 5) {
    if(test == 5) {
    if(test == 5) {
    // Wenn Diese Zeile auskommentiert wird, komm kein Compilterfehler,
    // kann er w‰hrend der Laufzeit nicht darauf zugreifen.
    // new Waffen[10][2];
    }
    }
    }
    new Waffen[10][2];
    Waffen[0][1] = 999;
    printf("DEBUG %d", Waffen[0][1]);

    // Wenn die folgende Initialisierung oberhalb vom 2-dimensionalem Array
    // geschieht, dann erkennt der Compiler dies auch als Fehler.
    new Waffe;
    Waffe = 5;
    printf("DEBUG %d", Waffe);
    }


    if(test == 5) {

    new Waffe;
    Waffe = 6;


    printf("DEBUG %d", Waffe);

    // Ergibt auch keinen Compilerfehler aber einen Fehler zur Laufzeit,
    // wenn auskommentiert.
    // new Waffen[10][2];
    Waffen[0][1] = 888;
    printf("DEBUG %d", Waffen[0][1]);
    }

    return 1;
    }


    Finde die Tatsache mit der Variable "Waffe" lustig, weil wenn man die Deklaration "Waffen" und die Verwendung weglöscht, erkennt der PAWN Compiler es nicht als "already defined" für Waffe.


    Nebenbei das "already defined" für die Variable "Waffe" erscheint nur, wenn sie oberhalb vom Array initialisiert wird.


    Hier ein Test der fehlerfrei ist:



    public OnGameModeInit()
    {
    // Don't use these lines if it's a filterscript
    SetGameModeText("Blank Script");
    AddPlayerClass(0, 1958.3783, 1343.1572, 15.3746, 269.1425, 0, 0, 0, 0, 0, 0);

    new test = 5;
    if(test == 5) {
    new Waffe;
    Waffe = 5;
    printf("DEBUG %d", Waffe);
    }


    if(test == 5) {

    new Waffe;
    Waffe = 6;


    printf("DEBUG %d", Waffe);
    }

    return 1;
    }


    Hab aus der Dokumentation folgendes herausgelesen:


    Zitat


    Multi-dimensional arrays are arrays that contain references to the sub-arrays.
    That is, a two-dimensional array is an “array of single-dimensional arrays”.∗
    Below are a few examples of declarations of two-dimensional arrays


    Bedeutet er erstellt in dem Fall zwei 1-dimensionale-Array´s womöglich, die wie folgt aussehen könnten:
    ACHTUNG: Das folgende ist nur Bauernverstand, weil ich mich mit Compiler nie ausgesetzt habe.
    LOGIK: Da PAWN 32-byte Felder erstellt (256 Bit) soll er die Adresse zu Waffen[0] um eben 256-bit verschieben, sodass die Adresse von Waffen[1] mit dem ODER-Parameter eingeordnet wird.

    new Waffen{2], WaffenLink[10] = {&Waffen[1] << 256 | &Waffen[0], ...};


    Letzten Endes vermischt der Compiler den VariablenNamen mit dem Funktionsnamen und den inneren if´s (Ich geh davon aus, dass jedes if eine eigene ID in einer Funktion hat).


    Also es muss ein Compilerfehler selbst sein, da er wahrscheinlich vergisst die 2. Variable (Anschaulich an "WaffenLink") nicht umwandelt und an die if-Strukturen (oder andere wie "switch") anpasst. (An der Funktion schon, sonst würde man nicht in einer anderen Funktion es erneut definieren können)


    Wobei das mit den 32-byte (256 Bit Verschiebung) muss nicht stimmen, da es letztendlich nur auf einem Bauernverstand beruht.


    Lg

    Jap, im gesamten (inklusive Includes).


    // EDIT: Also die beste Lösung statt zwei zu definieren, dass du vor dem großen if die Variable deklarierst. Herumschieben tut PAWN in dem Falle nicht. Aber es wäre wirklich interessant zu wissen ^^ Hier sollte mal ein Profi uns aufklären.

    So wie du den Code geschrieben hast ist irgendwie komisch. Mich wundert es überhaupt, dass er alle Fahrzeuge ladet (gehe ich davon aus, weil du schreibst, dass es lange dauert).


    Lösche bitte die Zeile mit mysql_num_rows. Damit schränkst du dich nur ein, dass wenn ein Fahrzeug existiert, soll er alles laden, aber sonst nicht :P


    Kann an vielen Faktoren liegen. Aber es ist logisch, dass dein Script sich aufhängen wird, weil du womöglich keine "Threaded" MySQL verwendest. Alternative wäre, wenn du mithilfe von SetTimerEx und einem internen Pointer Stück für Stück einen Query abfragst.


    Aber probier vielleicht auch mal statt "localhost" die IP "127.0.0.1" zum Verbinden des MySQL-Server´s.


    Ansonsten hat wer anderer auch eine tolle Idee vielleicht ^^