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...
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. ![]()
Wie kann ich denn nun allerdings die Farben erstellen mit Transparenz ?
Der Farbwert ist so aufgebaut: 0xAABBCCDD
AA = Rot Anteil
BB = Grün Anteil
CC = Blau Anteil
DD = Alpha, sprich Transparenz
0xAABBCC00 = unsichtbar, 0xAABBCCFF = maximal sichtbar, Farbe ist nicht durchlässig
Du musst quasi nur hinten die beiden Zahlen zwischen 00-FF etwas setzen, um die Transparenz zu ändern ![]()
Zusätzlich sollte das UPDATE Query vom Gamemode geprüft werden. Vermutlich wird nur ein INSERT gemacht, aber das Update Query schlägt fehl, deshalb werden keine Werte dort eingetragen ![]()
Ich würde dir empfehlen den Code etwas zu refactoren.
Dadurch wird er weniger Fehleranfällig, da alles separiert und getrennt von der eigentlichen Logik ist.
Hier mal als kleine Inspiration:
#include <tutorial> //Unterhalb new PlayerInfo iwo setzen ;)
public OnPlayerSpawn(playerid)
{
if(!PlayerInfo[playerid][pTutorial]) return StartPlayerTutorial(playerid);//pTutorial sollte ein Bool sein
SetCameraBehindPlayer(playerid); //Kannst du generell immer hier reinpacken, wenn du das magst :D
return 1; //Immer 1 zurückgeben, sonst werden Filterscripts ignoriert (brauchst hier kein SetPlayerSpawn, nutz einfach hier die Funktion)
}
// In tutorial.inc
static stock const CAMERA_TIME = 10_000; //in ms (_ kann als Trenner gesetzt wird, wird vom Compiler ignoriert)
stock StartPlayerTutorial(playerid)
{
SetTimerEx(!"Player_Tutorial", CAMERA_TIME, false, !"ii", playerid, 1);
SendClientMessage(playerid, COLOR_ORANGE, !"Das Tutorial startet in 10 Sekunden."); //Das ! vor Strings packt diese, macht diese kleiner und schneller. (nicht bei format anwenden)
return 1;
}
stock EndPlayerTutorial(playerid)
{
PlayerInfo[playerid][pNeuling] = 1;
PlayerInfo[playerid][pTutorial] = 1;
Player_Save(playerid);
SendClientMessage(playerid, COLOR_GREEN, !"Du hast das Tutorial erfolgreich abgeschlossen.");
TogglePlayerSpectating(playerid,0); //Spawnt den Spieler automatisch
return 1;
}
static forward Player_Tutorial(playerid, step);
public Player_Tutorial(playerid, step)
{
switch(step)
{
case 1:
{
InterpolateCameraPos(playerid, -2264.149169, -79.553237, 54.108608, -2258.836914, -133.797988, 38.133533, CAMERA_TIME);
InterpolateCameraLookAt(playerid, -2269.145263, -79.574234, 53.913345, -2263.404052, -131.805282, 37.719944, CAMERA_TIME);
SendClientMessage(playerid, COLOR_YELLOW, !"Der Neulingsspawn");
}
case 2:
{
InterpolateCameraPos(playerid, -2559.761230, 657.360534, 54.506183, -2606.139892, 570.644104, 27.216636, CAMERA_TIME);
InterpolateCameraLookAt(playerid, -2564.715087, 657.393859, 55.183780, -2609.537841, 574.257385, 26.585512, CAMERA_TIME);
SendClientMessage(playerid, COLOR_YELLOW, !"Das Krankenhaus");
}
case 3:
{
InterpolateCameraPos(playerid, -2731.381347, 52.292167, 44.589134, -2696.582275, -60.425365, 6.027071, CAMERA_TIME);
InterpolateCameraLookAt(playerid, -2727.718750, 49.573192, 42.541774, -2693.474609, -56.652973, 7.081593, CAMERA_TIME);
SendClientMessage(playerid, COLOR_YELLOW, !"Das Rathaus");
}
case 4: return EndPlayerTutorial(playerid);
}
SetTimerEx(!"Player_Tutorial", CAMERA_TIME, false, !"ii", playerid, step+1);
return 1;
}
Alles anzeigen
Dann lenkt das nicht so im eigentlichen Gamemode ab ![]()
Eventuell hat Kaliber sonst sobald er Zeit hat noch eine Idee ?
Wie ich gerade sehe, speicherst du Farben als varchar ab.
Das ist natürlich Quatsch, da Hexadezimale Zahlen, ja auch nur Zahlen sind und somit einfach nur Integer.
Ob du 0xF, 0b1111 oder 15 schreibst, ist komplett äquivalent.
Wie ist denn frak_color im enum definiert?
strval struggelt mit Hexzahlen, deshalb geht das so nicht.
Ich empfehle dir, änder den Typ in der MySQL Tabelle auf Integer und nutze natürlich cache_get_value_name_int.
Und im enum lass es eine Zahl sein.
Dann nimm meine erste Funktion und es sollte gehen ![]()
Dann hast beim Laden der Farben einen Fehler...
Wie sieht die db aus?
Wie sieht das Laden aus?
...
Der zurückgegebene Wert ist in diesem Fall 0
Dann stimmt einfach etwas mit deiner Logik nicht.
Was ist denn GfInfo[i][old_fraktion]?
Und du bekommst da keine Fehlermeldung? Du gibst einen String zurück, wo ein Integer erwartet wird...
Wie wäre es denn mit:
GetFrakColor(id)
{
for(new i; i < sizeof(FrakInfo); i++)
{
if(id == FrakInfo[i][frak_id])
{
return FrakInfo[i][frak_color];
}
}
return 0xFFFFFFFF;
}
Alles anzeigen
Interessant wäre auch, welchen Wert frak_colors hat. Evtl fehlen da Alpha Werte, diese könntest du hier auch einfach hinzufügen.
Es ist zum Fehler finden sehr hilfreich, öfter ein System.out.println einzubauen, so kannst du genau nachvollziehen, was an den gewissen geschieht und ob diese überhaupt aufgerufen werden ![]()
while(c.next()) { if(c.wasAdded()) { Lernkarte[] ak = lk.gibAlleKarten(); for(int i = 0; i < ak.length; i++) { liste.add(ak[i].toString()); } } }
Das sieht mir etwas komisch aus.
Müsste es nicht sowas irgendwie sein? 😅
Habe mit JavaFX noch nie etwas gemacht, aber die Logik wäre ja, dass es nur hinzugefügt wird, wenn es noch nicht hinzugefügt wurde. Keine Ahnung, wieso du alles noch einmal hinzufügst :o
Läuft der MySQL-Server auf dem selben Server wie der SA:MP Server?
Dann solltest du 127.0.0.1 einfach verwenden ![]()
-bash: ./samp03svr: No such file or directory
Daaa stimmt vermutlich die Berechtigung nicht. Musst evtl chmod mal nutzen ![]()
Das ist zwar der server_log und nicht der mysql.log, aber abgesehen davon läuft denn mysql überhaupt? ![]()
aber ein Problem ist noch der Server bekommt keine Verbindung zur Datenbank hergestellt.
Dann bräuchten wir einmal den mysql.log ![]()
Der wird entweder beim server_log erstellt, oder im log Verzeichnis.
Wie gesagt, bist du sicher, dass du die richtige Pawno.exe aus genau diesem Verzeichnis öffnest?
Also mal keinen Doppelklick auf das Skript, sondern zuerst die Pawno.exe öffnen und dann darüber die pwn öffnen ![]()
Im Ordner Pawno/Include/ müssen entsprechende Include Dateien liegen.
In diesem Fall streamer.inc
Vermutlich hast du vergessen diese richtig einzufügen.
Oder du öffnest die falsche Pawno.exe ![]()
Ah, sry, da kam was durcheinander, so sollte das sein:
private static String PrepareMessage(String xMessage)
{
var stringBuilder = new StringBuilder(xMessage.Normalize(NormalizationForm.FormD));
foreach (var keyValuePair in SPECIAL_DIACRITICS)
{
stringBuilder.Replace(keyValuePair.Key, keyValuePair.Value);
}
stringBuilder.Append(Convert.ToChar(0x0D));
stringBuilder.Append(Convert.ToChar(CalculateChecksum(stringBuilder.ToString())));
return stringBuilder.ToString();
}
private static byte CalculateChecksum(String xMessage)
{
byte checksum = 0x7F;
byte[] bytes = Encoding.ASCII.GetBytes(xMessage);
foreach (byte b in bytes)
{
checksum ^= b;
}
return checksum;
}
Alles anzeigen
Das kannst du entfernen, war nur ein Test.
Ist nur die Konsolen Output Kodierung nicht wichtig.