Angepinnt [SAMMELTHREAD] Kleine Scripting Fragen

Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

Es gibt Neuigkeiten! Ab sofort könnt ihr dem Donators Club auf Lebenszeit beitreten.
Weitere Infos im Thema Donator's Club ab heute wieder verfügbar!

  • Nabend,
    Könnte mir jemand sagen wo hier der Fehler liegt?
    Er bann den gewünschten Spieler nicht bzw es passiert einfach nix... ?(

    PAWN-Quellcode

    1. CMD:ban(playerid, params[])
    2. {
    3. if(PlayerInfo[playerid][pAdmin] >= 1)
    4. {
    5. new PID;
    6. new reason[64];
    7. new str[128];
    8. new Playername[MAX_PLAYER_NAME], Adminname[MAX_PLAYER_NAME];
    9. GetPlayerName(playerid, Adminname, sizeof(Adminname));
    10. GetPlayerName(PID, Playername, sizeof(Playername));
    11. if(sscanf(params, "us[64]", PID, reason)) return SendClientMessage(playerid, -1, "[Benutze] /ban [playerid][Grund]");
    12. format(str, sizeof(str), "'%s' wurde Gebannt von [Admin] '%s'. [Grund:] %s", Playername, Adminname, reason);
    13. SendClientMessageToAll(-1, str);
    14. Ban(PID);
    15. Kick(PID);
    16. if(!IsPlayerConnected(PID))
    17. return SendClientMessage(playerid, -1, "Spieler ist nicht Online!");
    18. }
    19. else
    20. {
    21. SendClientMessage(playerid, -1,"Du bist kein Admin. Du kannst den Befehl nicht nutzen!");
    22. }
    23. return 1;
    24. }
    Alles anzeigen
  • @LordDemacia
    Auch wenn mein Code selber manchmal unordentlich ist, möchte dir diesbezüglich, mal ein paar Tipps geben.

    Verwende wie ich bereits gestern erwähnte Makros, es ist nicht sehr "gut", überall im Skript, jederzeit, den Spieler Namen erneut auszulesen, wenn es einmal auch reicht.
    Wenn du eine Variable erstellst, erstelle sie alle auf einmal, und nicht einzeln.
    Verwende doch Tab anstatt Leerzeichen um deine Zeilen einzurücken, das ist schrecklich, aber genau so, habe ich es in meiner Anfangszeit auch gemacht, ist aber so ziemlich hässlich, benutze Tab.
    Ich weiß dass es bei einer bestimmten sscanf Version der Fall war, dass man die String Länge auch bei der Nutzung angeben musst, probiere es mal ohne, ich kann es auch problemlos ohne Angabe nutzen.
    Frage am Besten gleich ab ob er Eingeloggt ist & nicht ob er nur Online ist.
    Ban & Kick hintereinander? Das macht kein Skin, bei der Ban Funktion wird man ebenfalls gekickt.
    Nutze Banfix oder einen eigenen Timer der die das mit dem Kickfix übernimmt, sprich, wenn du es so machst, wird dem Spieler selbst, die Nachricht nicht angezeigt, warum er gebannt/gekickt wurde.

    Soo
    Wie gesagt, erstell dir mal in deiner Datenbank Struktur ein Feld was sich 'ban' nennt & richte es beim Speichern & Laden ein.
    Habe dir mal den Code umgeschrieben & kleine Erklärungen unterkommentiert, hoffentlich kannst du was mit anfangen.

    PAWN-Quellcode

    1. //Makro für das Spielernamen ausgeben, kann für jeden Spieler der Online ist, genutzt werden.
    2. #define getName(%0) PlayerInfo[%0][pName]
    3. //Bei deinem Player Enum fügst du hinzu & pBan
    4. pName[MAX_PLAYER_NAME+1],
    5. pBan,
    6. //Einmalig bei OnPlayerConnect
    7. GetPlayerName(playerid, getName(playerid), MAX_PLAYER_NAME+1);
    8. CMD:ban(playerid, params[])
    9. {
    10. if(PlayerInfo[playerid][pAdmin] < 1)return SendClientMessage(playerid, -1,"Du bist kein Admin. Du kannst den Befehl nicht nutzen!");
    11. new PID, str[128];
    12. if(sscanf(params, "us", PID, str)) return SendClientMessage(playerid, -1, "[Benutze] /ban [playerid] [Grund]");
    13. if(!PlayerInfo[PID][pLoggedIn])return SendClientMessage(playerid, -1, "Spieler ist nicht eingeloggt!");
    14. format(str, sizeof str, "'%s' wurde gebannt von [Admin] '%s'. [Grund:] %s", getName(PID), getName(playerid), str),
    15. SendClientMessageToAll(-1, str),
    16. pInfo[PID][pBan] = 1,
    17. Kick(PID);
    18. return 1;
    19. }
    Alles anzeigen


    //EDIT Admin Abfrage abgeändert. || Banfix ist ein Include, lad es dir mal runter.

    Meine SSCANF Version, die ich nutze. <- Download
    BanFix - Include | Download
    Рыба лично :rolleyes:

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von Kasakow ()

  • Kasakow schrieb:

    @LordDemacia
    Auch wenn mein Code selber manchmal unordentlich ist, möchte dir diesbezüglich, mal ein paar Tipps geben.

    Verwende wie ich bereits gestern erwähnte Makros, es ist nicht sehr "gut", überall im Skript, jederzeit, den Spieler Namen erneut auszulesen, wenn es einmal auch reicht.
    Wenn du eine Variable erstellst, erstelle sie alle auf einmal, und nicht einzeln.
    Verwende doch Tab anstatt Leerzeichen um deine Zeilen einzurücken, das ist schrecklich, aber genau so, habe ich es in meiner Anfangszeit auch gemacht, ist aber so ziemlich hässlich, benutze Tab.
    Ich weiß dass es bei einer bestimmten sscanf Version der Fall war, dass man die String Länge auch bei der Nutzung angeben musst, probiere es mal ohne, ich kann es auch problemlos ohne Angabe nutzen.
    Frage am Besten gleich ab ob er Eingeloggt ist & nicht ob er nur Online ist.
    Ban & Kick hintereinander? Das macht kein Skin, bei der Ban Funktion wird man ebenfalls gekickt.
    Nutze Banfix oder einen eigenen Timer der die das mit dem Kickfix übernimmt, sprich, wenn du es so machst, wird dem Spieler selbst, die Nachricht nicht angezeigt, warum er gebannt/gekickt wurde.

    Soo
    Wie gesagt, erstell dir mal in deiner Datenbank Struktur ein Feld was sich 'ban' nennt & richte es beim Speichern & Laden ein.
    Habe dir mal den Code umgeschrieben & kleine Erklärungen unterkommentiert, hoffentlich kannst du was mit anfangen.

    PAWN-Quellcode

    1. //Makro für das Spielernamen ausgeben, kann für jeden Spieler der Online ist, genutzt werden.#define getName(%0) PlayerInfo[%0][pName]//Bei deinem Player Enum fügst du hinzu & pBanpName[MAX_PLAYER_NAME+1],pBan,//Einmalig bei OnPlayerConnectGetPlayerName(playerid, getName(playerid), MAX_PLAYER_NAME+1);CMD:ban(playerid, params[]){ if(PlayerInfo[playerid][pAdmin] < 1)return SendClientMessage(playerid, -1,"Du bist kein Admin. Du kannst den Befehl nicht nutzen!"); new PID, str[128]; if(sscanf(params, "us", PID, str)) return SendClientMessage(playerid, -1, "[Benutze] /ban [playerid] [Grund]"); if(!PlayerInfo[PID][pLoggedIn])return SendClientMessage(playerid, -1, "Spieler ist nicht eingeloggt!"); format(str, sizeof str, "'%s' wurde gebannt von [Admin] '%s'. [Grund:] %s", getName(PID), getName(playerid), str), SendClientMessageToAll(-1, str), pInfo[PID][pBan] = 1, Kick(PID); return 1;}


    //EDIT Admin Abfrage abgeändert. || Banfix ist ein Include, lad es dir mal runter.

    Meine SSCANF Version, die ich nutze. <- Download
    BanFix - Include | Download
    Danke für deinen Tipp.
    Ja das mit den Makros muss ich noch besser Umsetzen bzw mir eintrichtern :D
    Aber sehr gut erklärt. Ich werde mir mal Tutorials anschauen wegen dem kürzen Code schreiben und alles.
  • Kaliber schrieb:

    @MyU Weißt du darüber mehr? :)

    Ich weiß auch nur, dass es noch nie funktioniert hat :D
    Hat von 2007/2008 bis jetzt nicht funktioniert, vielleicht ein vergessenes feature ist im endeffekt nur noch ein überflüssige Control im SAMP Launcher, weder der Client hat ein Parameter zur übergabe noch macht der Launcher was besonderes damit - ist also nur deko.

    Das einzige was es gibt ist die rcon.exe die man damals noch über Tools -> Remote Console starten konnte, ist aber irgendwann auch verloren gegangen ¯\_(ツ)_/¯ (also der Menü Punkt die rcon.exe is noch da)

  • Schreibe es mal so:

    C-Quellcode

    1. CMD:admins(playerid, params[])
    2. {
    3. new string[256],rank[22];
    4. for(new i = GetPlayerPoolSize(),name[MAX_PLAYER_NAME+1]; i != -1; i--)
    5. {
    6. if(!IsPlayerConnected(i) || !PlayerInfo[i][pAdmin]) continue;
    7. switch(PlayerInfo[i][pAdmin])
    8. {
    9. case 1: rank = "Moderator";
    10. case 2: rank = "Anfänger Admin";
    11. case 3: rank = "Anwärter Admin";
    12. case 4: rank = "Administrator";
    13. case 5: rank = "Server-Administrator";
    14. }
    15. GetPlayerName(i, name, sizeof(name));
    16. format(string, sizeof(string), "%s{FFFFFF}%s: {1B8AE4}%s (%d)\n", string, rank, name, i);
    17. }
    18. if(!string[0]) return SendClientMessage(playerid, -1, "Keine Admins Online");
    19. ShowPlayerDialog(playerid, DIALOG_ADMINONLINE, DIALOG_STYLE_LIST, "Team Online:", string, "Close", "");
    20. return 1;
    21. }
    Alles anzeigen


    Oder hier nochmal eine Version, wo die AdminNamen etwas ausgelagert sind:

    Spoiler anzeigen


    C-Quellcode

    1. #define GetAdminRangName(%0) admin_rang_namen[(%0)-1]
    2. stock const admin_rang_namen[][] = {
    3. "Moderator",
    4. "Anfänger Admin",
    5. "Anwärter Admin",
    6. "Administrator",
    7. "Server-Administrator"
    8. };
    9. CMD:admins(playerid, params[])
    10. {
    11. new string[256];
    12. for(new i = GetPlayerPoolSize(),name[MAX_PLAYER_NAME+1]; i != -1; i--)
    13. {
    14. if(!IsPlayerConnected(i) || !PlayerInfo[i][pAdmin]) continue;
    15. GetPlayerName(i, name, sizeof(name));
    16. format(string, sizeof(string), "%s{FFFFFF}%s: {1B8AE4}%s (%d)\n", string, GetAdminRangName(PlayerInfo[i][pAdmin]), name, i);
    17. }
    18. if(!string[0]) return SendClientMessage(playerid, -1, "Keine Admins Online");
    19. ShowPlayerDialog(playerid, DIALOG_ADMINONLINE, DIALOG_STYLE_LIST, "Team Online:", string, "Close", "");
    20. return 1;
    21. }
    Alles anzeigen


    Leute, lernt scripten und versucht mal lieber etwas selber zu schreiben, als es aus einem GF zu kopieren. X/
  • @Kaliber
    Danke erstmal für den Tipp.
    Kann deinen Beitrag grade nicht als Zitat nutzen.

    Hätte grade noch eine andere Frage...
    Und zwar sitze ich grade an einem Befehl dran, der das Admin Level setzen soll.
    Funktioniert soweit auch.
    Das einzige was nicht Funktioniert ist, das es in der Datenbank gespeichert wird.

    Hier mal der Befehl:

    PAWN-Quellcode

    1. CMD:setadmin(playerid,params[])
    2. {
    3. if(PlayerInfo[playerid][pAdmin] < 1)return SendClientMessage(playerid, -1,"Du bist kein Admin. Du kannst den Befehl nicht nutzen!");
    4. new PID, str[128], rank[22];
    5. if(sscanf(params, "us", PID, str, rank))return SendClientMessage(playerid, -1 ,"[Benutze] /setadmin [playerid][rank]");
    6. if(!PlayerInfo[PID][pLoggedIn])return SendClientMessage(playerid, -1, "Spieler ist nicht eingeloggt!");
    7. {
    8. switch(PlayerInfo[PID][pAdmin])
    9. {
    10. case 1: rank = "Moderator";
    11. case 2: rank = "Anfänger Admin";
    12. case 3: rank = "Anwärter Admin";
    13. case 4: rank = "Administrator";
    14. }
    15. }
    16. format(str, sizeof(str), "'%s' wurde zu einem Admin ernannt mit dem Rank: %s",getName(PID),str, rank);
    17. SendClientMessageToAll(-1, str);
    18. PlayerInfo[PID][pAdmin] = rank;
    19. SaveUserStats(PID);
    20. return 1;
    21. }
    Alles anzeigen


    Jetzt möchte ich nur noch zusätzlich gerne, das anstatt die ID des Rang's der Name des Rangs dort steht.
    Sollte das nicht mit der Methode funktionieren die du mir oben gezeigt hast?
  • Hmmm, bei dem Befehl stimmt so einiges nicht.

    Schau dir eventuell nochmal ein paar Tutorials zu format etc an.


    LordDemacia schrieb:

    if(sscanf(params, "us", PID, str, rank))
    "us" sagt du hast 2 Variablen. Eine die was mit einer spielerid zu tun hat und einen string. Dann gibst du aber 3 an...wozu das mit dem str?

    Und wieso rank als String, wenn du es als Integer nutzen magst?

    Dann fragst du per switch & case den Rang ab, noch bevor du ihn überhaupt gesetzt hast.

    Und im Format unten, hast du wieder unnötig str stehen.

    und dann weist du einer Integer Variable...einen String mit dem Inhalt "Moderator" z.B. zu.........

    Also, dass dir da keine Errors/Warnings angezeigt werden grenzt schon nahezu an ein Wunder :D

    Besser wäre sowas (orientiert sich an der 2. Version von dem, was ich oben geschrieben hatte):

    C-Quellcode

    1. CMD:setadmin(playerid,params[])
    2. {
    3. if(PlayerInfo[playerid][pAdmin] < 1)return SendClientMessage(playerid, -1,"Du bist kein Admin. Du kannst den Befehl nicht nutzen!");
    4. new PID, str[128], rank;
    5. if(sscanf(params, "ud", PID, rank))return SendClientMessage(playerid, -1 ,"[Benutze] /setadmin [playerid][rank]");
    6. if(!PlayerInfo[PID][pLoggedIn])return SendClientMessage(playerid, -1, "Spieler ist nicht eingeloggt!");
    7. format(str, sizeof(str), "'%s' wurde zu einem Admin ernannt mit dem Rank: %s",getName(PID),GetAdminRangName(rank));
    8. SendClientMessageToAll(-1, str);
    9. PlayerInfo[PID][pAdmin] = rank;
    10. SaveUserStats(PID);
    11. return 1;
    12. }
    Alles anzeigen


    Leute, lernt scripten und versucht mal lieber etwas selber zu schreiben, als es aus einem GF zu kopieren. X/
  • Kaliber schrieb:

    Hmmm, bei dem Befehl stimmt so einiges nicht.

    Schau dir eventuell nochmal ein paar Tutorials zu format etc an.


    LordDemacia schrieb:

    if(sscanf(params, "us", PID, str, rank))
    "us" sagt du hast 2 Variablen. Eine die was mit einer spielerid zu tun hat und einen string. Dann gibst du aber 3 an...wozu das mit dem str?
    Und wieso rank als String, wenn du es als Integer nutzen magst?

    Dann fragst du per switch & case den Rang ab, noch bevor du ihn überhaupt gesetzt hast.

    Und im Format unten, hast du wieder unnötig str stehen.

    und dann weist du einer Integer Variable...einen String mit dem Inhalt "Moderator" z.B. zu.........

    Also, dass dir da keine Errors/Warnings angezeigt werden grenzt schon nahezu an ein Wunder :D

    Besser wäre sowas (orientiert sich an der 2. Version von dem, was ich oben geschrieben hatte):

    C-Quellcode

    1. CMD:setadmin(playerid,params[])
    2. {
    3. if(PlayerInfo[playerid][pAdmin] < 1)return SendClientMessage(playerid, -1,"Du bist kein Admin. Du kannst den Befehl nicht nutzen!");
    4. new PID, str[128], rank;
    5. if(sscanf(params, "ud", PID, rank))return SendClientMessage(playerid, -1 ,"[Benutze] /setadmin [playerid][rank]");
    6. if(!PlayerInfo[PID][pLoggedIn])return SendClientMessage(playerid, -1, "Spieler ist nicht eingeloggt!");
    7. format(str, sizeof(str), "'%s' wurde zu einem Admin ernannt mit dem Rank: %s",getName(PID),GetAdminRangName(rank));
    8. SendClientMessageToAll(-1, str);
    9. PlayerInfo[PID][pAdmin] = rank;
    10. SaveUserStats(PID);
    11. return 1;
    12. }
    Alles anzeigen
    Erstmal danke das du mir trotzdem Gezeigt / Erklärt hat wo meine Fehler grade in dem Shit Code waren.
    Ich werde mir nochmal genauer Anschauen wie das mit Format und alles abläuft.
  • BrightLeaN schrieb:

    Hey,
    Kann ich abfragen, ob die letzte Nachricht im Chat == einer Nachricht ist?
    Habe nichts gefunden im guten Internet
    Sowas brauch man auch eigentlich nicht.

    Gehe smarter an die Sache ran.

    Wenn es um eine Nachricht geht, die ein Spieler geschrieben hat, dann nutze einfach OnPlayerText.

    Ist es eine spezielle Info Nachricht, gesendet vom Server (dann schau, wo diese gesendet wird und dann weißt du ja, dass diese gesendet wurde...) :D

    Spoiler anzeigen
    Theoretisch kann man SCM und SCMTA hooken und dann immer die letzte Nachricht zwischenspeichern. Dann weiß man, was die letzte Nachricht war.
    Aber das muss man ja theoretisch nicht, da es smarter wäre, einfach die Aktion, die man ausführen mag, an die Gegebenheiten im Skript anzupassen.


    Leute, lernt scripten und versucht mal lieber etwas selber zu schreiben, als es aus einem GF zu kopieren. X/
  • Ja es geht halt darum, wenn ein Spieler das Interior eines Gebäudes betritt, dass er eine Nachricht erhält: "Du hast die Stadthalle betreten".

    Heißt Theoretisch.
    "Du hast die Stadthalle betreten"
    "Du hast die Stadthalle verlassen"

    hier möchte ich, wenn diese Nachricht die letzte ist, dass beim erneuten betreten diese Info Nachricht nicht raus geht.
    Sieht in meinen Augen sehr unprofessionell aus, wenn man öfters wo rein geht:

    "Du hast die Stadthalle betreten"
    "Du hast die Stadthalle verlassen"
    "Du hast die Stadthalle betreten"
    "Du hast die Stadthalle verlassen"
    "Du hast die Stadthalle betreten"
    [tt]"Du hast die Stadthalle verlassen"

    Jetzt weiß ich nicht, ob es sich lohnt einfach einen Delay zu setzten? Kann ja dann sein, dass mit Zufall der Delay im Gebäude nicht mehr aktiv ist und er dann nur die Nachricht beim rausgehen kriegt.
    Bin ja nur ein kleines bisschen Pingelig :D

    Ich weiß, dass ich weiß, dass ich nichts weiß.
  • BrightLeaN schrieb:

    hier möchte ich, wenn diese Nachricht die letzte ist, dass beim erneuten betreten diese Info Nachricht nicht raus geht
    Nutz doch bspw. Textdraws die du nur ganz kurz anzeigen lässt. Dann Spammst du den Chat damit nicht voll.
    "Bevor ich mir Informationen aus der "Bild" hole,
    werde ich anfangen, Wahlergebnisse danach vorauszusagen,
    neben welchen Busch unsere Katze gepinkelt hat."
    Margarete Stokowski