[SAMMELTHREAD] Kleine Scripting Fragen

In 10 Minuten startet der nächtliche Backupvorgang! Es kann währenddessen (ca. 10 Minuten) zu Einschränkungen bei der Nutzung des Forums kommen
Weitere Infos findet ihr im Thema Backup des Forums
Dein Problem konnte durch einen User gelöst werden? Bedank dich bei ihm indem du seinen Beitrag als Hilfreich markierst sowie einen Daumen oben dalässt
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
  • Beitrag von Cheevy.Shakur ()

    Dieser Beitrag wurde gelöscht, Informationen über den Löschvorgang sind nicht verfügbar.
  • Beitrag von Cheevy.Shakur ()

    Dieser Beitrag wurde gelöscht, Informationen über den Löschvorgang sind nicht verfügbar.
  • hey


    schreibe meins script gerade auf 0.3.7 RC2 um. War ein wenig faul und wollte es einfach lösen:


    Alte Schleifen habe ich folgendermaßen geändert:
    for(new i = 0; i < MAX_PLAYERS; i++)
    zu
    for(new i = 0; i < Players(); i++)


    und


    for(new i = 0; i < MAX_VEHICLES; i++)
    zu
    for(new i = 0; i < Vehicles(); i++)


    Dazu habe ich dann folfende stocks eingeüft:


    stock Players()
    {
    new MaxPlayers = GetPlayerPoolSize();
    return MaxPlayers;
    }


    und


    stock Vehicles()
    {
    new MaxVehicles = GetVehiclePoolSize();
    return MaxVehicles ;
    }


    funktioniert jedoch nicht, ich gehe davon aus das es daran liegt das ich ein stock innerhalb einer Schleife aufrufe und das anscheinend nicht klappt.
    Hat jemand ein Lösungsvorschlag, ohne dass ich vor jeder schleife erst new bla = GetPlayerPoolSize(); schreiben muss?

  • Hat jemand ein Lösungsvorschlag, ohne dass ich vor jeder schleife erst new bla = GetPlayerPoolSize(); schreiben muss?


    Das sollte man aber tun.


    Es ist recht blöde Idee immer pro Durchgang die Poolsize zu prüfen.
    Kostet nur unnötig Zeit und ist scheinbar auch recht ungenau.

    "Bevor ich mir Informationen aus der "Bild" hole,
    werde ich anfangen, Wahlergebnisse danach vorauszusagen,
    neben welchen Busch unsere Katze gepinkelt hat."

    Margarete Stokowski

  • ne das ist doch quatsch.


    Habs schon angepasst auf meine Slotanzahl.
    Aber mal angenommen ich habe 200 Slots, es sind aber nur 50 Spieler drauf, wieso sollte er dann immer bis 200 zählen, wenn er schon bei 50 aufhören kann.
    Dann mache ich mir doch lieber einmal die Arbeit und passe das dementsprechend an.

  • Du wolltest einen Lösungsvorschlag der auf GetPlayerPoolSize verzichtet. Den hast du bekommen.
    Bei jedem Schleifendurchlauf eine Funktion aufzurufen, die dir die höchste ID zurück gibt macht meiner Meinung nach keinen Sinn und ist sicherlich langsamer als einen festen Wert zu nehmen, der in etwa bei der maximalen Spieleranzahl liegt.


    Außerdem kann man das ziemlich einfach selbst machen, was wesentlich performanter ist.


    Übrigens musst du es, wenn, dann so schreiben:
    for(new i = 0; i <= Vehicles(); i++)




    Generell würde ich aber das empfehlen:
    new biggestPlayerID = -1;


    public OnPlayerConnect(playerid)
    {
    if(biggestPlayerID < playerid) biggestPlayerID = playerid;
    return 1;
    }


    public OnPlayerDisconnect(playerid, reason)
    {
    if(biggestPlayerID == playerid)
    {
    biggestPlayerID = -1;
    for(new i=playerid-1; i>=0; i--)
    {
    if(IsPlayerConnected(i))
    {
    biggestPlayerID = i;
    break;
    }
    }
    }
    return 1;
    }


    Dann sähe die Schleife so aus:
    for(new i=0; i<=biggestPlayerID; i++)


    Das ist wesentlich performanter als diese neuen (für mich höchst sinnlosen) Funktionen.


    Gleiches Prinzip kann man bei den Fahrzeugen anwenden, indem man die Funktionen hookt.

  • do.de - Domain-Offensive - Domains für alle und zu super Preisen
  • Jeffry:


    Vor einiger Zeit habe ich mit einem Filterscript von mir und deiner Hilfe einige Befehle in einem Gamemode eingebracht wovon ich aber nur die .amx besitze.


    Im Gamemode ist festgelegt das wenn's ein Befehl nicht gibt dort Uknown Command "Diesen Befehl gibt es nicht" etc kommt. Nun ist es aber so das wenn ich die Befehle vom Filterscript eingebe, das die Befehle funktionieren, doch dort der Text kommt (Vorher war das nicht so).


    Doch dieser Text kommt nur wenn ich jemand "force" den Befehl zu benutzen, wenn ich den normal eingebe passiert nix.


    So sieht es aus:


    Ein normaler Befehl hier:



    ocmd:secretstyle(playerid,params[])
    {
    SetPlayerFightingStyle (playerid, FIGHT_STYLE_KNEEHEAD);
    return 1;


    Dein ersteller Fake oder Force Befehl.


    ocmd:secretcmd(playerid,params[])
    {
    new pID, tmp[20], tmp2[20], idx;
    tmp = strtok(params, idx);
    tmp2 = strtok(params, idx);
    if(!strlen(tmp2)) return SendClientMessage(playerid,0xFF0000FF,"Fehler: /secretcmd [ID/NAME] [Befehl]");
    if(IsNumeric(tmp)) pID = strval(tmp);
    else pID = ReturnPlayerID(tmp);
    if(!IsPlayerConnected(pID)) return SendClientMessage(playerid,0xFF0000FF,"Der Spieler ist nicht online");
    new cmd[128];
    format(cmd, sizeof(cmd), params[strlen(tmp)+1]);
    CallRemoteFunction("OnPlayerCommandText", "ds", pID, cmd);
    return 1;


    Deine dazugehörige Funktion


    Spoiler anzeigen
    stock strtok(const string[], &index) //©Jeffry
    {
    new result[20], length = strlen(string), i = index;
    while ((i < length) && (string[i] == ' ')) i++;
    strmid(result,string,i,((index = strfind(string, " ", false, i)) == -1) ? (index = length) : (index) , 20);
    index++;
    return result;
    }

    Spoiler anzeigen
    stock ReturnPlayerID(l_PlayerName[]) //©Jeffry
    {
    new l_name[MAX_PLAYER_NAME];
    for(new i = 0; i < MAX_PLAYERS; i++)
    {
    if(GetPlayerName(i, l_name, MAX_PLAYER_NAME))
    {
    if(!strcmp(l_name,l_PlayerName, true)) return i;
    }
    }
    for(new i = 0; i < MAX_PLAYERS; i++)
    {
    if(GetPlayerName(i, l_name, MAX_PLAYER_NAME))
    {
    if(strfind(l_name,l_PlayerName,true)!=-1) return i;
    }
    }
    return INVALID_PLAYER_ID;
    }

    Spoiler anzeigen
    stock IsNumeric(string[])
    {
    for (new i = 0, j = strlen(string); i < j; i++)
    {
    if ((string[i] > '9' || string[i] < '0')) return 0;
    }
    return 1;
    }


    Weißt du vielleicht woran das liegt?Denn wie gesagt vorher war das ja nicht so..


    Mit freundlichen Grüßen
    JustMe.77 8)

  • Ich bin mir nicht ganz sicher seit wann ich diesen fehler habe, aufjedenfall habe ich ihn gerade bemerkt als ich mir nochmal was in der Log durchgelesen habe:


    [debug] Run time error 20: "Invalid index parameter (bad entry point)" (von Crashdetect Plugin ausgegeben)


    ich weiß das der Fehler gerne kommt wenn man kein
    main() { } hat. Ist jedoch vorhanden und bitte bitte gibt mir das auch nicht als Lösungsvorschlag!


    Der Fehler kommt immer wenn sich jemand mit dem Server verbindet.
    Das Ihr den Fehler nicht auf die Zeile bestimmten könnt ist mir bewusst, aber eventuell lässt sich die Quelle eingrenzen, so dass ich das nochmal kontrolieren kann.


    Hier nochmal ein Ausschnitt aus meiner log-Datei:

    Code
    ----------Loaded log file: "server_log.txt".----------SA-MP Dedicated Server----------------------v0.3.7-RC2, (C)2005-2015 SA-MP Team[20:59:11] [20:59:11] Server Plugins[20:59:11] --------------[20:59:11]  Loading plugin: crashdetect.so[20:59:11]   CrashDetect v4.13.1-lse is OK.[20:59:11]   Loaded.[20:59:11]  Loading plugin: mysql.so[20:59:11]  SA:MP MySQL Plugin v2.1.1 Loaded.[20:59:11]   Loaded.[20:59:11]  Loading plugin: streamer.so[20:59:11] *** Streamer Plugin v2.7.5.2 by Incognito loaded ***[20:59:11]   Loaded.[20:59:11]  Loading plugin: sscanf.so[20:59:11] [20:59:11]  ===============================[20:59:11]       sscanf plugin loaded.     [20:59:11]          Version:  2.8.1        [20:59:11]    (c) 2012 Alex "Y_Less" Cole  [20:59:11]  ===============================[20:59:11]   Loaded.[20:59:11]  Loading plugin: MapAndreas.so[20:59:11]   Loaded.[20:59:11]  Loaded 5 plugins.[20:59:11] [MySQL] Thread running. Threadsafe: Yes.[20:59:11] [20:59:11] Filterscripts[20:59:11] ---------------[20:59:11]   Loading filterscript 'gl_actions.amx'...[20:59:11]   Loaded 1 filterscripts.[20:59:11] [MySQL] Connected (0) to 'root'@'Localhost via UNIX socket'.[20:59:11] [MySQL] Server Version 5.5.40-0+wheezy1.[20:59:11] [MYSQL] Verbindung zur Datenbank wurde erfolgreich hergestellt![20:59:11] sscanf warning: String buffer overflow.[20:59:11] sscanf warning: String buffer overflow.[20:59:11] sscanf warning: String buffer overflow.[20:59:11] Number of vehicle models: 134[20:59:12] Incoming connection: 127.0.0.1:37120 id: 0[20:59:12] [debug] Run time error 20: "Invalid index parameter (bad entry point)"[20:59:12] [npc:join] Priester has joined the server (0:127.0.0.1)

  • Was heißt "vorher war es nicht so"? Was hast du geändert, zwischen der Zeit als es noch funktioniert hat (als die Nachricht nicht extra dazu kam) und als die Nachricht zum Befehl dazu gesendet wurde?


    Ich habe nur einige Befehle neu erstellt, mehr aber auch nicht..


    Habe aber gemerkt das z.B bei return 0; diese Nachicht kam und bei return 1; nicht.


    Die Sache ist ja die, das kommt nur beim fakebefehl, normal nicht..


    Mit freundlichen Grüßen
    JustMe.77 8)

  • Habe aber gemerkt das z.B bei return 0; diese Nachicht kam und bei return 1; nicht.


    Welches return meinst du? Das ganz am Ende von OnPlayerCommandText?
    Wenn du das zu return 1 änderst, dann kommt die Meldung beim faken von Befehlen nicht mehr? (Sollte sie zumindest).


    Dann die Frage:
    Wenn du einen nicht existierenden Befehl fakest, soll dann die Meldung kommen? Wenn nein, dann könnte ich dir eine Lösung anbieten.



    Nemesus Jr.:
    Die sollte weiterhin ohne Probleme funktionieren, da diese in etwa auf dem Prinzip basiert, welches ich vorhin geschildert habe, nur etwas erweitert. ;)

  • Jeffry:


    Bei OnPlayerCommandText habe ich nur ein Befehl. Meine ganzen anderen Befehle habe ich auf OCMD umgeschrieben.


    Ich möchte das die Meldung kommt wenn es den Befehl weder im Gamemode, noch im Filterscript gibt kommt.


    Zurzeit ist es aber so das diese Meldung nur kommt wenn ich einen Befehl bei einem Spieler zwinge, heißt also das er den ausführen soll. Vorher ging es ohne Probleme und die Meldung kam nicht.


    Und wenn ich den Befehl normal eingebe vom Filterscript ohne das ich einen Spieler zwinge kommt die Meldung nicht, also denke ich liegt es vielleicht am forcecmd ?


    Mit freundlichen Grüßen
    JustMe.77 8)

  • Ja, das liegt daran, dass beide OnPlayerCommandText's (im Filterscript und im Gamemode) unabhängig voneinander ausgeführt werden.
    Du kannst es mal so versuchen, ob das geht:
    ocmd:secretcmd(playerid,params[])
    {
    new pID, tmp[20], tmp2[20], idx;
    tmp = strtok(params, idx);
    tmp2 = strtok(params, idx);
    if(!strlen(tmp2)) return SendClientMessage(playerid,0xFF0000FF,"Fehler: /secretcmd [ID/NAME] [Befehl]");
    if(IsNumeric(tmp)) pID = strval(tmp);
    else pID = ReturnPlayerID(tmp);
    if(!IsPlayerConnected(pID)) return SendClientMessage(playerid,0xFF0000FF,"Der Spieler ist nicht online");
    new cmd[128];
    format(cmd, sizeof(cmd), params[strlen(tmp)+1]);
    new retVal;
    retVal = CallRemoteFunction("OnPlayerCommandTextFS_1", "ds", pID, cmd);
    if(retVal == 0) CallRemoteFunction("OnPlayerCommandTextGM", "ds", pID, cmd);
    return 1;
    }


    Und dann im Filterscript:
    forward OnPlayerCommandTextFS_1(playerid, cmdtext[]);
    public OnPlayerCommandTextFS_1(playerid, cmdtext[])
    {
    return OnPlayerCommandText(playerid, cmdtext);
    }


    Und im Gamemode:
    forward OnPlayerCommandTextGM(playerid, cmdtext[]);
    public OnPlayerCommandTextGM(playerid, cmdtext[])
    {
    return OnPlayerCommandText(playerid, cmdtext);
    }

    3HZXdYd.png

    Einmal editiert, zuletzt von Jeffry ()

  • Beitrag von NoxiZ ()

    Dieser Beitrag wurde gelöscht, Informationen über den Löschvorgang sind nicht verfügbar.