oh hatte die erste Version veröffentlicht
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.
Nützliche Codeschnipsel
- breadfish
- Geschlossen
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
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
-
-
Warum denn 128?Wenn ich nen String habe der bleiner ist, hab ich nen Bufferoverflow
Sinngemäß ist das so sicherlich nicht
Du meinst wohl eher, wenn er größer ist. :b -
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? -
@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. -
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.
-
-
-
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. -
Wobei die for-Schleife so besser wäre
for(new i = 0, p = GetMaxPlayers(); i < p; i++) -
@BlackAce: Nein ist es nicht.
Beispiel:
ID 0 = Jeffry
ID 1 = JeffIch 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.
-
Nein ist es nicht.
Ich sagte auch nicht unbedingtSelbst deswegen rechtfertigt das keine 2. schleife.
Denn wozu gibt es sonst if else ? -
@BlackAce: Nein ist es nicht.
Beispiel:
ID 0 = Jeffry
ID 1 = JeffIch 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.
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.ZitatID 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 -
Also wenn Ich nach 100 Minuten nichts esse sterbe Ich nicht
Vielleicht die Zeit höher drehen, nicht damit sich hier noch einer meldet und sich wundert wieso er so schnell stirbt. -
Ich habe den Timer jetzt auf 3 Minuten gestellt, das heißt: 3 Minuten => 1 HP verloren
Das sollte nun besser sein
-
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")); //jaVerwendung:
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.