Das sagt der Log aber nicht, dass du dich connected hast...
Evtl, musst du warten, bis alle Bots aufm Server sind.
Das sagt der Log aber nicht, dass du dich connected hast...
Evtl, musst du warten, bis alle Bots aufm Server sind.
Musst natürlich auch noch auf den Server und den Befehl eingeben xD
Am Besten mehrere
Was sagt denn crashdetect bzw generell der Server.log?
JackReacher dieser Vorgang nennt sich hooking.
Hier ein Tutorial: Includes richtig erstellen | Hooking ganz einfach
Oder man nutzt y_hooks
Für Anregungen oder Lösungen wäre ich sehr dankbar
Es wäre cool, wenn du 2 SQL Files hochladen könntest, die die jeweiligen Tabellen mit ihren Spalten erstellen + 2 Testdatensätze und dann genau erklären, wie du dir das Ergebnis vorstellst 😅
Dann muss man sich das nicht aus dem Text theoretisch alles herleiten, dafür bin ich gerade zu faul
Und Ihr so?
Was muss ich jetzt hier verändern?
Steht doch in der Warnung, kein SHA256 verwenden.
Hatte mal bisschen hier darüber mehr erklärt: Hash Verfahren genauer erklärt
Als Fazit, nutze BCrypt: https://github.com/Sreyas-Sreelal/samp-bcrypt
PS: Verwende in MySQL Querys, niemals %s. Wurde dafür extra %q eingeführt, oder du nutzt mysql_format mit %e
ja aber dazu muss doch die 0 eine 1 sein das der timer darin auch immer wieder läuft 0 sprich false ist doch nur einmal laufen ?
Lies meinen ersten Satz, der Timer ruft sich immer wieder auf, weil er in der Funktion selbst ist 😅
Er wird einmalig aufgerufen -> Ruft sich einmalig selbst auf -> rufst sich einmalig selbst auf -> ruft sich einmalig selbst auf
Ist eine Endlosschleife
Nein, in der Funktion ruft sich der Timer immer wieder auf xD
Am Anfang wird die Funktion direkt aufgerufen, damit sich das Wetter sofort setzt
Kannst natürlich auch das auf 1 setzen und die Timer Funktion aus der Funktion löschen.
Ja, wobei du das dann noch einmal aktualisieren musst, damit die Änderung sofort gültig wird.
stock UpdateWeatherForAll()
{
for(new i; i<MAX_PLAYERS; i++)
{
if(!IsPlayerConnected(i)) continue;
if(IsPlayerInDynamicArea(i, sZoneLS)) SetPlayerWeather(i, sWeatherLS);
else if(IsPlayerInDynamicArea(i, sZoneSF)) SetPlayerWeather(i, sWeatherSF);
else if(IsPlayerInDynamicArea(i, sZoneLV)) SetPlayerWeather(i, sWeatherLV);
}
return 1;
}
Alles anzeigen
Habe hier das zu gefunden
Ja, was ich meinte war sowas:
//Ganz oben definieren
static sWeatherLS, sWeatherSF, sWeatherLV;
static sZoneLS, sZoneSF, sZoneLV;
//Unter OnGameModeInit oder OnFilterscriptInit
sZoneLS = CreateDynamicRectangle(2919.469, -782.4177, 93.423, -2837.724);
sZoneLV = CreateDynamicRectangle(2942.825, 2884.435, 794.0955, 618.9274);
sZoneSF = CreateDynamicRectangle(-1377.989, 1599.869, -2989.536, -1004.297);
ChangeWeather();
//Dann irgendwo
public OnPlayerEnterDynamicArea(playerid, STREAMER_TAG_AREA:areaid)
{
if(areaid == sZoneLS) SetPlayerWeather(playerid, sWeatherLS);
else if(areaid == sZoneSF) SetPlayerWeather(playerid, sWeatherSF);
else if(areaid == sZoneLV) SetPlayerWeather(playerid, sWeatherLV);
return 1;
}
forward ChangeWeather();
public ChangeWeather()
{
sWeatherLS = random(20);
sWeatherSF = random(20);
sWeatherLV = random(20);
SetTimer("ChangeWeather", 1000*60*10, 0); //Ändert sich alle 10min
return 1;
}
Alles anzeigen
Dann macht das das Streamer Plugin alles für dich automatisch
So hier:
//Ganz oben definieren
#define IsPlayerInLosSantos(%0) IsPlayerInArea(%0, 2919.469, 93.423, -782.4177, -2837.724)
#define IsPlayerInLasVenturas(%0) IsPlayerInArea(%0, 2942.825,794.0955,2884.435,618.9274)
#define IsPlayerInSanFierro(%0) IsPlayerInArea(%0, -1377.989,-2989.536,1599.869,-1004.297)
static sWeatherLS, sWeatherSF, sWeatherLV;
//Unter OnGameModeInit oder OnFilterscriptInit
ChangeWeather();
SetTimer("ChangeWeatherForPlayers", 1000*5, 1); // Alle 5sek
//Dann irgendwo
forward ChangeWeatherForPlayers();
public ChangeWeatherForPlayers()
{
for(new i; i<MAX_PLAYERS; i++)
{
if(!IsPlayerConnected(i)) continue;
if(IsPlayerInLosSantos(i)) SetPlayerWeather(i, sWeatherLS);
else if(IsPlayerInSanFierro(i)) SetPlayerWeather(i, sWeatherSF);
else if(IsPlayerInLasVenturas(i)) SetPlayerWeather(i, sWeatherLV);
}
return 1;
}
forward ChangeWeather();
public ChangeWeather()
{
sWeatherLS = random(20);
sWeatherSF = random(20);
sWeatherLV = random(20);
SetTimer("ChangeWeather", 1000*60*10, 0); //Ändert sich alle 10min
return 1;
}
//Unten im Skript (oder in einer utils.inc oder sowas)
stock IsPlayerInArea(playerid, Float:minx, Float:maxx, Float:miny, Float:maxy)
{
new Float:x, Float:y, Float:z;
GetPlayerPos(playerid, x, y, z);
return (x > minx && x < maxx && y > miny && y < maxy);
}
Alles anzeigen
Das Wetter muss natürlich perma gesetzt werden, falls Spieler die Zone verlassen xD
Theoretisch kannst hier auch mit dem StreamerPlugin und dynamischen Areas arbeiten, dann gibt es den Callback OnPlayerEnterDynamicArea. Dann benötigst du keine Loop die perma läuft.
Aber dafür müsst ich nochmal ins Include vom Streamer schauen, da war ich grad zu faul für xD
dass erklärt warum ich kaum noch was finde dazu.
Was suchst du denn? 😅
Eigentlich würde das doch bedeuten, dass man extrem viel zu etwas findet, je älter es ist 😄 Das Problem ist halt, dass das englische Forum gelöscht wurde...
Ich merke, Deutsche Spieler sind ein besonderes Volk.
Streich das Spieler 😂
Hey cooles Ding,
ich dachte ich bin mal so frei und geb dir ein kleines Code Review (auch wenn keiner danach gefragt hat)
Ich gehe jetzt auf nichts Pawn-Spezifisches ein, sondern ganz generell quasi ein kleines Clean Code Feedback.
Ich pack es mal in den Spoiler, damit ich hier nicht so viel Platz klaue
Zu Punkt 3, wie man das realisieren kann:
switch(listitem){
case 0:{//Kick Player
permissionChange[playerid] = 1;
return ShowCurrentAccessLevelDialog(playerid,"KICKPLAYER_USABLE");
}
Da hast du ein ewig langes switch-case.
Wie wäre es aber so, du machst ein konstantes großes Array mit den ganzen Namen, also sowas wie:
//Ganz oben ins Skript
static stock const gUserUsables[][] = {
"KICKPLAYER_USABLE",
"BANPLAYER_USABLE",
"TIMEBANPLAYER_USABLE",
"UNBANPLAYER_USABLE",
//usw..
};
//Und dann anstatt dem switch-case, einfach:
permissionChange[playerid] = listitem+1;
return ShowCurrentAccessLevelDialog(playerid, gUserUsables[listitem]);
Alles anzeigen
Dadurch würdest du dir allein dort 100 Zeilen sparen.
Dann genau das Selbe weiter unten:
switch(permissionChange[playerid]){
case 1:{// Kick Player
if(strval(inputtext) <= 0 || strval(inputtext) > MAX_ADMINLEVEL){
return ShowCurrentAccesLevelDialogE(playerid, "KICKPLAYER_USABLE");
}
permissionChange[playerid] = -1;
UpdateAccessLevel("KICKPLAYER_USABLE", strval(inputtext));
return ShowPermissionDialog(playerid);
}
case 2:{// Ban Player
if(strval(inputtext) <= 0 || strval(inputtext) > MAX_ADMINLEVEL){
return ShowCurrentAccesLevelDialogE(playerid, "BANPLAYER_USABLE");
}
permissionChange[playerid] = -1;
UpdateAccessLevel("BANPLAYER_USABLE", strval(inputtext));
return ShowPermissionDialog(playerid);
}
Alles anzeigen
Da machst du es dir viel zu kompliziert 😅
Kannst dir die 300 Zeilen sparen und einfach:
new tValue = strval(inputtext);
if(tValue <= 0 || tValue > MAX_ADMINLEVEL)
return ShowCurrentAccesLevelDialogE(playerid, gUserUsables[permissionChange[playerid]]);
UpdateAccessLevel(gUserUsables[permissionChange[playerid]], tValue);
permissionChange[playerid] = -1;
return ShowPermissionDialog(playerid);
4. Du machst es dir mit deinem Sprachensystem viel zu schwierig. Hier würde sich auch anbieten einfach ein konstantes Array anbieten und dort schreibst du alle Texte rein und greifst dann nur noch darauf zu. Da sparst du dir maaaassig Zeilen xD Zumal du oft gleich den ganzen Befehl in 2 Sprachen gemacht hast, statt nur den Code, auf den es ankommt
5. Durch die ganzen Wiederholungen ist dein Code sehr anfällig für Fehler. Also es ist fast unmöglich keine zu machen, da ständig alle Variablen manuell zurückgesetzt werden müssen etc pp. Sowas einfach in Funktionen auslagern.
6. Du nutzt sehr viele globale Variablen. Ruhig, gerade wenn es nur temporär ist paar PVars nutzen.
Für Weitere Infos, kann den YouTube Channel für CleanCode empfehlen: https://www.youtube.com/@10minuteswithcoachjoe55
Gibt da gewisse Regeln generell wie KISS und DRY (https://de.wikipedia.org/wiki/Don%E2%80%99t_repeat_yourself).
Bei deinem nächsten Projekt kannst du versuchen diese mehr zu berücksichtigen!
Es gibt einen mysql.log Entweder direkt im server Verzeichnis oder es gibt ein log Verzeichnis wo er drinnen liegt.
Falls nicht, diesen mit mysql_log(ALL); unter OnGameModeInit aktivieren.
Dort steht genau drinnen, was passiert und ob etwas fehlschlägt oder nicht
Ich finde es gut, wie du dir im Text die Titelfrage schon selbst beantwortest
Wenn die Frage ist, ob es besser geht: Es geht immer besser.