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.
Lass es einfach so wie es ist.
Wenn du die neuen Includes mit MAX_PLAYERS 1000 hast, dann ändere das in der a_samp.inc einfach zu deiner Slot-Anzahl ab und gut ist.
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.
ok dann hattest du das falsch verstanden, ich wollte schon die Funktionen benutzen.
ok dann hattest du das falsch verstanden, ich wollte schon die Funktionen benutzen.
Ok, tut mir Leid dann.
Trotzdem empfehle ich dir von der Funktion Abstand zu nehmen und es so zu machen, wie ich es dir gezeigt habe, wenn du es wirklich performant, und ohne große Änderungen, machen willst.
ja also so wie du es vorschlägst würde ich das auch machen, war mir nur nicht sicher ob das besser ist
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
Weißt du vielleicht woran das liegt?Denn wie gesagt vorher war das ja nicht so..
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 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:
----------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)
Hast du die aktuelle crashdetect Version?
Wenn nein, oder wenn du dir nicht sicher bist, aktualisiere sie: https://github.com/Zeex/samp-plugin-crashdetect/releases
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..
Bringt nun das Include ForEachPlayer nix mehr? Oder kann man das weiterhin benutzen?
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.
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 ?
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);
}