Nützliche Codeschnipsel

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
  • oh hatte die erste Version veröffentlicht :D
    aber mit "sizeof" bekommt man es ja auch selber hin, ist halt eine Kurze form
    und wer brauch kann es ja benutzen und wer nicht, der nicht.

    Mit Freundlichen Grüßen
    Whitetiiger aka. Kaito-sensei
    P.s. Alle mit #IRONIE bestätigten Sätze von mir, sind als Ironie anzusehen.

  • Du meinst wohl eher, wenn er größer ist


    Wenn ich etwas größeres in etwas kleine "stopfe" habe ich einen sogenannten Überlauf.
    Was hier ja zu trifft.


    Nehmen wir an, der string ist 80 Zeichen groß, aber er soll ja 128 rein schreiben,
    was ja nicht möglich ist, da 128 > 80.


    Was einen Bufferoverflow erzeugt.


    wenn ich etwas kleineres in etwas größeres Stopfe, gibt es idR keine Probleme.
    Oder bekommt man mitlerweile 1 Liter Wasser in eine 500 ml Flasche? :huh:

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

    Margarete Stokowski

  • @BlackAce:
    Oh, "String" bezog sich wohl auf eine Variable des Typs String (bzw. ein Char-Array in Pawn) - habe das so verstanden, dass du einen "String", also einen Text, der kleiner als 128 Zeichen ist, in einen 128 Zeichen großen Array bringen willst und dies dann einen Overflow erzeugen soll.


    #Brotfischbaron


    In schā'a llāh

  • Da einige diese Funktion suchen poste ich sie hier mal in einer "extendet" Version:


    stock ReturnPlayerID(l_PlayerName[]) //©Jeffry
    {
    new l_name[MAX_PLAYER_NAME];
    for(new i = 0; i < MAX_PLAYERS; i++)
    {
    if(IsPlayerConnected(i))
    {
    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(IsPlayerConnected(i))
    {
    GetPlayerName(i, l_name, MAX_PLAYER_NAME);
    if(strfind(l_name,l_PlayerName,true)!=-1) return i;
    }
    }
    return INVALID_PLAYER_ID;
    }



    Benutzung:
    new meineID = ReturnPlayerID("Jeffry");
    //oder:
    new ebensomeineID = ReturnPlayerID("Jeff");


    Keywords: GetPlayerID, ReturnPlayerID, ID von Name, Name zu ID.

    3HZXdYd.png

    Einmal editiert, zuletzt von Jeffry ()

  • Jeffry:
    2 Schleifen sind da doch etwas unnötig.


    Man kann das auch viel schlner mit nur einer Schleife und einem strfind lösen.
    Ein strcmp wäre nicht unbedingt nötig.


    stock ReturnPlayerID(l_PlayerName[]) //©Jeffry
    {
    new l_name[MAX_PLAYER_NAME + 1];
    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;
    }
    Dies hätte den identischen Effekt.
    Theoretisch kann man auch IsPlayerConnected drin lassen, aber ich schätze mal das kaum das noch jemand 0.2 oder drunter nutzt.
    Daher kann man getrost über GetPlayerName gehen, denn das returnt 0 wenn der Spieler nicht connected ist.

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

    Margarete Stokowski

  • @BlackAce: Nein ist es nicht.


    Beispiel:


    ID 0 = Jeffry
    ID 1 = Jeff


    Ich suche nach "Jeff" => Mit deinem Code wird ID 0 ausgegeben. Bei meinem Code gibt es ID 1 aus, was richtig wäre, da ein Spieler genau diesen Name hat, daher wird das bevorzugt. Deshalb zwei Schleifen, ich hatte es extra als "extendet" Version beschrieben. Nur wenn kein Spieler übereinstimmt, wird gesucht, ob ein Teil übereinstimmt. Das erhöht erwiesenermaßen die Trefferrate.


    Sharpadox: Nicht wenn MAX_PLAYERS mit dem tatsächlichen maxplayers in der server.cfg übereinstimmt.

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

  • Wieso dann nicht einfach so?


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

  • Weil er erst alle auf den vollständigen (strcmp ) Namen prüfen möchte und danach alle auf den Namen teilweise ( strfind ).
    Bei dir wird jeder Spieler einzelnt erst vollständig und direkt danach teilweise geprüft.
    Das Ergebnis bei dir würde wie in diesem Beitrag nicht dem entsprechen,was Jeffry dort geschrieben hat.


    Zitat

    ID 0 = Jeffry
    ID 1 = Jeff


    Bei "Jeff" würdest du immer Jeffry erhalten ( ID 0 ) , nicht Jeff ( ID 1 ).

  • Wie auch immer, der Code funktioniert so wie er ist, und macht das was er soll. Wenn irgendjemand einen besseren hat darf er den gerne posten ansonsten lasst es. Und wenn du mir ein Beispiel bringst wie man es besser machen kann, das aber "nicht unbedingt" das Gleiche macht dann ist das für mich absoluter Bullshit um es auf den Punkt zu bringen.


    Simples Beispiel: Ich geh zum Bäcker und will ein Brot. Dann sagt mir ein anderer Kunde ich soll Brötchen nehmen, weil die auch satt machen. Schön, ist aber nicht das was ich will, denn ich will aus meinem Brot einen Brot-Fisch machen, und keinen Brötchen-Fisch.



    Ja man könnte den Code noch weiter optimieren, ja man kann ihn beliebig abändern und ja man kann ihn noch ressourcensparender machen, nur dann wird es keiner der hier eine Funktion raus-kopiert kapieren was der Code macht (und das geht schonmal an dem eigentlichen Sinn dieser Sektion des Forums voll vorbei, denn man soll ja was lernen, was bringt es einem Anfänger dann, wenn er einen Code sieht den er im Leben nicht kapieren wird. Nichts und nochmal nichts!


    Und ehrlich: Die "Optimierungen" die ich hier immer wieder sehe, die sind genau das. Was bringt es einem Anfänger denn, wenn er einen Code hat, den er nicht versteht, ABER der Code spart dem Prozessor bei 100 Durchläufen (mehr wird keiner der Server von 99.99% der Leute hier je erreichen) vielleicht 0,001 Mikrosekunden. Wo ist denn da der Sinn? Ich seh da absolut keinen.


    Was kann man an dem Code noch machen?
    Ja, ich kann noch foreach einbauen und das Plugin verlinken.
    Ja, ich kann die Spielernamen in Variablen beim Betreten des Servers noch speichern und hier durchloopen lassen.
    Ja, ich kann das Ganze in ein eigenes Plugin schreiben.
    Schön. Nur dann wird es niemand mehr verwenden.



    Selbst deswegen rechtfertigt das keine 2. schleife.
    Denn wozu gibt es sonst if else ?


    Dann würde ich jetzt gerne sehen, wie du das mit einer Schleife realisieren kannst, sodass der Code 1:1 das macht was mein Code macht. Alles andere interessiert mich hier nicht mehr.
    Und nur wenn da ein Code-Schnipsel (kein Plugin etc) kommt, der zudem noch ressourcenschonender (bzw. mindestens gleichwertig ist), dann geb ich dir gerne Recht. Ansonsten bleibe ich bei meiner Aussage oben.


    Sharpadox: Wie Goldkiller: schon sagte.



    Ich denke Goldkiller: ist wirklich einer der Einzigen hier, der wirklich kapiert um was es eigentlich geht.

  • SetTimer("Lebensystem",180000,1);//OnGameModeInit
    forward Lebensystem();//Oben im Script
    public LebenTimer() {// Irgendwo im Script
    new Float:health;
    for(new i,l=GetMaxPlayers(); i<l; i++) if(IsPlayerConnected(i)) GetPlayerHealth(i,health),SetPlayerHealth(i,health-1);
    return 1;
    }


    Ein kleiner Codeschnipsel, sollte zu verstehen sein.
    Eine Minute => 1 HP verloren

  • stock IsRPName(name[]) //©Jeffry
    {
    new found = 0;
    for(new i=2, j = strlen(name)-2; i < j; i++) if(name[i] == '_') found++;
    if(found == 1) return true;
    else return false;
    }


    Beispiel
    printf("%d", IsRPName("Jeffry_")); //nein
    printf("%d", IsRPName("_Jeffry")); //nein
    printf("%d", IsRPName("J_effry")); //nein
    printf("%d", IsRPName("Jeffr_y")); //nein
    printf("%d", IsRPName("Je_ff_ry")); //nein
    printf("%d", IsRPName("Jeffry_Thomson")); //ja



    Verwendung:
    new rpname[MAX_PLAYER_NAME];
    GetPlayerName(playerid,rpname,sizeof(rpname));
    if(!IsRPName(rpname))
    {
    //Der Spieler-Name is kein RP-entsprechender Name...weitere Aktionen hier.
    }



    Stichwörter: IsRPName, IstRPName, IstRealPlayName, IsRealPlayName, RealPlay, RP, RolePlayName, Unterstrich Name.


  • stock const WeekDays[7][11] = {
    "Sonntag",
    "Monntag",
    "Dienstag",
    "Mittwoch",
    "Donnerstag",
    "Freitag",
    "Samstag"
    };


    #define DATE_W(%0,%1,%2) WeekDays[(( %0 + _:DATE_Y(%1,%2) + _:DATE_Y(%1,%2)/4 - _:DATE_Y(%1,%2)/100 + _:DATE_Y(%1,%2)/400 + (31 * _:DATE_M(%1))/12 )% 7)]
    #define DATE_M(%0) (%0 + 12 * _:DATE_A(%0) - 2)
    #define DATE_Y(%0,%1) (%1 - _:DATE_A(%0))
    #define DATE_A(%0) ((14 - %0) / 12)


    Verwendung:

    new Date[3];
    getdate(Date[0],Date[1],Date[2]);
    printf("%s",DATE_W(Date[2],Date[1],Date[0]));



    Mit diesem Codeschnipsel ist es möglich den Wochentag zu bestimmen.

  • Hey,
    Hier mein Codesnipsel:


    Unter OnPlayerConnect:
    shotTime[playerid] = 0;
    Shot[playerid] = 0;


    dann noch ganz oben:
    new shotTime[MAX_PLAYERS];
    new Shot[MAX_PLAYERS];


    dann macht ihr ein Public:
    public OnPlayerWeaponShot(playerid, weaponid, hittype, hitid, Float:fX, Float:fY, Float:fZ)
    {
    if(weaponid != 38)
    {
    if((gettime() - shotTime[playerid]) < 1)
    {
    Shot[playerid]+=1;
    }
    else
    {
    Shot[playerid]=0;
    }
    if(Shot[playerid] > 10)
    {
    new string[128];
    format(string, sizeof(string), "AntiBot: Spieler %s wurde vom System gebannt. Grund: Rapid-Fire", SpielerName(playerid));
    SendClientMessageToAll(ROT, string);
    Ban(playerid);
    }
    shotTime[playerid] = gettime();
    }
    return 1;
    }


    Achtung! Funktioniert nur in der Version 0.3z.