Probier es doch mal mit dem Crashdetect Plugin. Die Anleitung durchlesen und nicht vergessen wie die Compile-Parameter einzustellen.
Ich bezweifel das Jemand ( Ich übrigens auch nicht ) nur mit dem Quellcode da den Grund für den Crash entdeckt. Lass lieber das Plugin für dich den Grund finden.
Beiträge von Goldkiller
-
-
Du hast ja eigentlich alle wichtigen Dinge genannt.
- Unter OnPlayerDeath, falls in NoDMZone in Variable die killerid ablegen der den Spieler getötet hat
- Falls Spieler /punish eingibt, dessen Variable prüfen ob die dort abgelegte killerid gültig ist.
- Spieler in's Gefängnis stecken ( Achtung, die Variable jetzt ungültig setzen ). Eventuell mit SetTimerEx den Spieler nach Zeit X wieder befreien.
An welchem Punkt scheitert es denn bei dir ? -
Ich stell mir das grad vor....Goldkiller alleingelassen vorm Saturn
Ja,voll lustig .
Das war übrigens n' Scherz,dass ich daran teilnehmen würde. Wieso man das nicht ernst nehmen sollte ließt man ja schon genug im diesem Thread.Es war damals aber die Anti-NRW Haltung des selbsternannten Veranstalters, denn aus NRW würden ja zu viele "Kiddies" kommen.
-
128 ist auch zu klein.
http://jumk.de/wortanalyse/ergebnis.php
Ich bekomme dort 137. Davon 2 abziehen für %s , addiert 1 für NULL und + MAX_PLAYER_NAME.
new string[136 + MAX_PLAYER_NAME]; -
-
Man kann leider nicht auf den Timer zugreifen und auslesen wie lange dieser noch läuft bis er die Funktion aufruft.
Gibt verschiedene Wege wie man es lösen kann.
Einen Timer der eine Funktion jede Sekunden aufruft und dort eine Variable runter zählt. Ist dort für den Spieler bis auf 0 runter gezählt worden, richtige Funktion aufrufen. Anhand der Variable kannst du dann auslesen,wie lange der Timer noch läuft.
Der Andere Weg wäre über Unix Timestamps. Du würdest in einer Variable ablegen,welchen Wert der Unix Timestamp für den Spieler mindestens haben muss damit die Zeit abgelaufen ist. Zusätzlich müsstet du aber trotzdem ein Timer laufen lassen. Allerdings wird es dort zu kleineren Problemen kommen. Denn die Timer sind nie exakt ( siehst du hier ) . So kann der Timer noch laufen,obwohl der genannte Timestamp bereits lange überschritten ist und die Zeit in Wirklichkeit bereits vorbei ist.
Ein Mix aus Beidem wäre meine Wahl. -
Wie ist BLAU deklariert / definiert. Die Farbe muss auch Sichtbar sein.
Dir ist klar,dass die Koordinate irgendwo in der Luft liegt bei 1003 LE ?
Mal testweise die drawdistance extrem hoch gestellt und TestLOS aus ?
Was wird dir hier ausgegeben?
printf("3DText: %d", _:Create3DTextLabel("TEXT",BLAU,194.3783,179.4073,1003.0234,10.0,-1,0) ); -
Was machst du dort ? Durch die Änderungen machst du es nur noch schlechter.
Außerdem,entweder du zeigst den kompletten Befehl oder du lässt es. Halbe Sachen bringen hier meist nichts. -
Okay, zwei Sachen die sofort auffalen.
Es gibt auch sowas:
if() // EntwederA
else if() // Oder Entweder B
else if() // Oder aber Entweder C
else // Sonst
Die Verwendung von sscanf innerhalb der if() Abfrage bringt absolut nichts und führt nur zu Fehlern.
Ließ meinen Post nochmal. Du solltest in der ersten Nutzung von sscanf die Parameter auslesen, auch für die Anzahl. Sonst ist es teilweise doppelte Arbeit bei dir. -
Dir sollte doch wohl klar sein,dass die Anzahl 0 Quatsch ist und somit ungültig. Du kannst natürlich auch -1 verwenden oder sonst etwas. Ich würde aber 0 bzw irgendetwas negatives verwenden.
Da ich wie gesagt 0 verwenden würde, reicht eine Abfrage der Variable Anzahl kleiner/gleich 0. Ist dies dann dann der Fall,dann solltest du die Verarbeitung abbrechen und lediglich die Informationsnachricht versenden.if(sscanf(Auswahl,"si",Auswahl,Anzahl)) return SendNutzMsg(playerid, "/medis Medikamente [Anzahl]");
Diese Zeile müsstest du gegen die Abfrage von Anzahl austauschen,die ich zuvor erklärt hatte. -
Schau doch mal deinen Code genau an.
new pID, grund, string[128];
if(sscanf(params,"ui",pID,grund))return SendClientMessage(playerid,Orange,"Benutzung: /kick [SpielerID] [Grund]");
Du hast die Variable grund nicht als Array angelegt und auch nicht per sscanf nach einem Text suchen lassen ( "ui" ) .
Schau mal hier wie du einen Grund angeben kannst und verarbeitest. -
Debuggen hätte dir ganz schnell gezeigt wo der Fehler liegt.
Ich vermute mal,dass in der Variable Auswahl nicht nur das Wort "Medikamten" steckt,sondern auch die Zahl ( Also: "Medikamente 10" ). Dadurch klappt deine Abfrage nicht und du beendest den Befehl. Allerdings gibt es kein Rückgabewert,der Standardmäßig zurückgegeben wird bei dir. Dazu müsstest du zwischen Zeile 27 und 28 noch ein return 1; einfügen ( Eventuell auch 0 , nutze kein ocmd ) .printf("Auswahl: '%s'",Auswahl);
if(!strcmp(Auswahl, "medikamente", true)) {
Prüf' das mal nach und poste doch auch direkt was dir ausgegeben wird.Angenommen es liegt daran,dann würde ich direkt bei der ersten SSCANF Nutzung auch direkt die Zahl mit auslesen. Allerdings ist es keine optimale Lösung,je nachdem ob du den Befehl später auch noch umformst.
Für den Fall du nutzt SSCANF V2 ( Plugin ) , dann könntest du sscanf so anwenden:
sscanf( inputtext , "s[11]D(0)",Auswahl,Anzahl); -
-
Eure Lösungsvorschläge sind wirklich nicht gut.
Ein Array verpackt in einer extra Funktion ist da viel praktischer und auch viel einfacher zu warten.
Hier habt ihr was zum Lernen:
stock GetPlayerBonus(playerid) {
new
level = PlayerInfo[playerid][pLevel];
static aBonus[] = {
0, // level 0
3200, // level 1
3800, // ...
4400,
5200,
5800
};
if( level >= sizeof(aBonus) ) { // Falls level größer als Array, höchtes Level nehmen
return aBonus[ sizeof(aBonus) - 1 ];
}
if( level < 0 ) { // Falls level negativ, niedrigstiges Level nehmen
return aBonus[0];
}
return aBonus[ level ];
} -
Wovon sprichst du ? Du sollst die Zeile einfügen,kompilieren,testen und dann die Server_Log durchsuchen und die Ausgabe hier posten.
Da gibt es nichts zu erklären. -
Debuggen wäre da ganz nützlich.
format(Spielerdatei,sizeof(Spielerdatei),"/Accounts/%s.ini",name);
printf("Spielerdatei: '%s'\nkey: '%s'\ndini Key: '%s'",Spielerdatei, key , dini_Get(Spielerdatei,"Key") );
if(!strcmp(key,dini_Get(Spielerdatei,"Key"),false))
Was wird dir dort ausgegeben. Kannst du es selbstständig interpretieren ?
Wird jedes Passwort akzeptiert,so ist key bzw dini key wohl ein leerer String. -
Ist aber trotzdem unbedingt richtig.
new string[64],pID = killerid;
Jetzt würde es funktionieren,ist aber unsinn.Wieso sollte ich pID verwenden,wenn die Information auch in der Variable killerid steht.Wieso du auch 8x ein Array erstellst, keine Ahnung. Ein einziges mal würde auch vollkommen reichen.if(playerid != INVALID_PLAYER_ID)
{
Die Abfrage ist übrigens Quatsch.Die playerid ist immer gültig,die killerid nicht. Dort müsstest du abfragen,ob die killerid ungleich INVALID_PLAYER_ID ist. Ist killerid nämlich INVALID_PLAYER_ID,so wurde irgendwie Selbstmord begangen.Im übrigen habe ich dein Einleitungssatz auch nicht wirklich verstanden.Das ganze ist bei dir ein Satz ... ohne Satzzeichen o.Ä. .
//Edit:
Wenn du nicht weisst wofür die Parameter bei Callbacks stehen,hier findet man immer Informationen. -
Was bringt uns dein Text ?
Du hast- nicht angegeben,welche Zeile den Fehler verursacht
- nicht angegeben,wie die vollständige Fehlermeldung lautet
Merk dir für die Zukunft,solche Dinge direkt zu posten.Wahrscheinlich liegt der Fehler in dieser Zeile und lautet "Array must be indexed":
PlayerInfo[playerid][pKonto] = inputtext;
Ich nehme mal stark an,dass pKonto kein Array/String ist. Die Variable inputtext ist aber ein Array/String ( auch wenn dort vllt eine Zahl drin steckt , z.B. "435254" ) .
Du kannst nämlich nicht ein Array/String dort speichern,wo nur Platz für einen Wert ist.
Um einen String der aus Zahlen besteht in eine Zahl ( Integer ) umzuwandeln,benutzt man strval.//Edit:
new a;
new b[5] = "test";
a = b; // Geht nicht. b brauch 5 Speicherzellen, a bietet aber nur 1 an.
a = b[0]; // Funktioniert,da jetzt 1 zu 1. -
Du hast strcat mit format verwechselt.
Mit strcat kannst du Strings aneinander hängen ( verketten ). Mit format kannst du es zwar auch über Platzhalter realisieren , kannst sie in erster Linie aber dazu nutzen Variablen und andere Werte darin darzustellen.strcat(string,"{335CD6}[=========={FFFFFF}[ Dein Status ]{335CD6}==========]");
strcat(string,"{335CD6}\nName: {FFFFFF}%s",SpielerName(playerid)); // #
Ich nehme an,du möchtest die markierte Zeile mit der ersten zusammenfügen UND den Spielernamen ( markiert durch Platzhalter %s ) einfügen.
Ich mach dir mal eine Zeile vor:
strcat(string,"{335CD6}[=========={FFFFFF}[ Dein Status ]{335CD6}==========]"); // strcat nicht unbedingt notwendig. Würde auch direkt gehen.
format(string, sizeof(string),"%s{335CD6}\nName: {FFFFFF}%s",string,SpielerName(playerid)); //
Ich füge den "alten" String an den Anfang des neuen Strings und mache dann die restlichen Aktionen, wie zum Beispiel den Spielernamen auslesen und einfügen.
Das müsstest du übrigens so auch bei den Anderen Zeilen korrigieren. -
Was RedJoker schreibt ist ja auch totaler Blödsinn. Dein Query ist schon richtig so.
SQLSELECT haus.EnterX,haus.EnterY,haus.EnterZ,haus.ID,haus.SpielerID,haus.Preis,haus.Mietpreis,accounts.Name FROM haus, accounts WHERE accounts.ID = haus.ID
Dir werden jetzt auch nur Ergebnisse angezeigt,wo die haus.ID mit der accounts.ID in Beziehung gesetzt werden kann. Ob das bei allen Einträgen der Fall ist,weiss ich nicht.
Muss ich selber zugeben,hab ich erst auch nicht beachtet.Du könntest entweder eine Dummy-ID bzw User anlegen,die bedeutet,dass das Haus keinen Besitzer hat ( dann kann man es weiterhin mit nur 1 Query lösen ) oder du splittest das Erstellen der Häuser. Im ersten Fall werden die Häuser erstellt die einen Besitzer haben .Im zweiten Fall die Häuser die noch keinen Besitzer haben.