Lade mal crashdetect und zeig den server.log anschließend ![]()
Beiträge von Kaliber
-
-
In Pawn, kannst du nicht einfach unterschiedliche Typen in ein Array quetschen

Da die Sprache C-Ähnlich ist, unterliegt sie einer strengen Typisierung.
Mehr Infos dazu: https://de.wikipedia.org/wiki/Typisierung_(Informatik)
Im Gegensatz zu z.B. Javascript/Python, wo das Problemlos möglich wäre, muss hier angegeben werden, um was für einen Typ es sich handelt. Also String (Array) oder int, bool, float o.ä.
Sonst kann der Compiler das nicht verarbeiten.
Also das "enum" sorgt in diesem Fall dafür, dass der Compiler weiß, welche Typen im Array sind und es hat den netten Nebeneffekt, dass du die Variablen im Array gleich benennen kannst und es so übersichtlicher auch für dich wird

Alternativ könntest du auch mehrere Arrays erstellen:
Cnew VPNames[][] = { "Ronald", "Donald", "Gonald" }; new VPBools[sizeof(VPNames)] = {true, true, false};Das sizeof(VPNames) gibt in diesem Fall vor, dass das Array, genauso groß sein muss, wie VPNames.
Aber es ist denke ich schöner alles in einem zu haben und auch direkt mit einem Namen ansprechen zu können.
Hier hätte man mehrere Stellen, die immer zu berücksichtigen sind, das kann schnell unübersichtlich werden.
Falls es sich hier übrigens um Konstanten handelt, also ein Array, wo der Wert zur Laufzeit nicht mehr geändert wird, dann kannst du anstatt
new
stock const verwenden.
stock sagt aus (egal ob vor globalen Variablen oder Funktionen), dass wenn die Variable (oder die Funktion) nicht im Code benutzt wird, der Compiler es ignorieren kann und so wird kein Speicher reserviert in der .amx Datei.
Das const sorgt dafür, dass die Nutzung optimiert wird und du nicht (evtl. ausversehen) irgendwelche Werte mehr darin nachträglich ändern kannst.
-
Oder kann ich einfach irgendwie
Ja, fast, kannst es so machen:
C++
Alles anzeigenenum e_VPNames { v_Name[32], bool:v_Bool }; new VPNames[][e_VPNames] = //Hier kannst es [] lassen, der Compiler zählt für dich, wie viele Einträge im Array sind ;) { {"Ronald", true}, {"Donald", true}, {"Gonald", false} //<< wichtig, hier kein Komma am Ende, da der letzte Eintrag :D }; //Zum Wert ändern: VPNames[0][v_Bool] = false; //Ändert den Ronald (index 0) zu false -
Finde es gut, dass du pogressbar, statt progressbar geschrieben hast
Bash
Alles anzeigenlocal ox = exports['ox_base'] local progressBar = ox.bar progressBar:drawBar(currentArea.collectingTime * 1000, Translation[Config.Locale]['pre_collect'] .. currentArea.items[1].label .. Translation[Config.Locale]['collect']) -- 8000 if currentArea.animation ~= nil then if currentArea.animation.type == 'scenario' then TaskStartScenarioInPlace(PlayerPedId(), currentArea.animation.anim, 0, true) Citizen.Wait(currentArea.collectingTime * 1000) ClearPedTasksImmediately(PlayerPedId()) else RequestAnimDict(currentArea.animation.dict) while not HasAnimDictLoaded(currentArea.animation.dict) do Citizen.Wait(10) end TaskPlayAnim(player, currentArea.animation.dict, currentArea.animation.anim, 1.0, -1.0, 5000, 0, 1, true, true, true) Citizen.Wait(currentArea.collectingTime * 1000) end else Citizen.Wait(currentArea.collectingTime * 1000) endLaut ChatGPT könnte dir das helfen.
Da so wenig Infos zur Verfügung stehen, ist das doch schon einmal ein guter guess.
Nächstes mal doch einfach selbst ChatGPT nutzen.
-
Kann ich Informationen für Filterscript wie zB ein #define oder Variable aus dem Gamemode abrufen?!
Tatsächlich kann man das auch direkt.
PVars sind ja eher Spieler bezogen, wenn es um globale Variablen geht, könntest du folgendes tun:
C++//Im GameMode: #define GLOBAL_VAR 5 forward GetGlobalVar(); //Kannst du nennen wie du magst public GetGlobalVar() { return GLOBAL_VAR; }C++//Im Filterscript: new GLOBAL_VAR; public OnFilterScriptInit() { GLOBAL_VAR = CallRemoteFunction("GetGlobalVar", ""); return 1; }Aber am Einfachsten wäre es ein Include zu schreiben, statt einem Filterscript

Ich habe noch ein anderes Problem, vielleicht kannst du mir da auch helfen
Wenn ich sccanf2 einbinde (aktuelle version) zerschießt das so halb meinen script. Die Spieler Auswahl ist nicht mehr sichtbar bzw code in OnPlayerRequestClass ist tot (spawnen funktioniert aber noch) undmanche commands (OnPlayerCOmmandText -> /gmx) gehen nicht mehr.
(Der Compiler sagt es ist alles tutti. (sscanf plugin im Ordner und .cfg, ocmd.inc (2013 neuste?) und sscanf2.inc in pawno)Lade mal das crashdetect Plugin und prüf den Server.log)

-
-
-
Hört sich zumindest sinnvoll an xD?
Ja, das klingt gut

Kannst du eventuell eine MariaDB-Bibliothek empfehlen?

Der MariaDB Connector soll - soweit ich das zumindest lesen konnte - ziemlich schlecht sein.
Habe bisher mit C++ nur mit PostgreSQL gearbeitet und damit mit libpqxx
Aber der MariaDB Connector, ist wohl auch eine Alternative: https://github.com/mariadb-corporation/mariadb-connector-cpp
Viel Erfolg 👍🏼
-
Heyho 👋🏼
Hoffe es ist okay, wenn ich ein paar doofe Fragen stelle.
Wozu wartest du auf die Threads? Gäbe es keine Möglichkeit, dass die Threads einfach direkt das irgendwo rein schreiben ihr Ergebnis? Direkt in eine Datenbank o.ä.?
Wieso nutzt du jsons? 😅 Und nicht direkt z.B. eine (Postgre)SQL Datenbank?
So könntest du aus den Threads heraus direkt das Ergebnis irgendwohin speichern und müsstest auf nichts warten im Mainthread.
Die Überprüfung der Objekte dauert so lange, dass in dieser Zeit keine Status-Updates in der Konsole folgen können.
Um nur das Problem konkret zu lösen, würde denke ich auch ein einfaches sleep reichen, was du in die Loop packst

-
%s ist für einen String was auch immer das ist
Ein String ist ein Text.
Also alles was du in den Anführungszeichen schreibst. "Hallo" oder "Test1234" das sind Strings.
Und dein Kennzeichen ist auch ein String.
PS: Bitte verwende kein MD5, um Passwörter zu hashen. Das bringt nämlich nichts. (Siehe: Hash Verfahren genauer erklärt)
-
Einige dieser Zahlen sind VehicleID's von Flugzeugen diese sollen natürlich nicht erstellt werden
Nur Flugzeuge oder auch Helikopter?
Was ist mit Booten?
Was ist mit Zügen?
Was ist mit Anhängern? 😅
Es gibt Utils-Funktionen, da hatte jemand Langeweile und hat das mal alles rausgeschrieben: https://github.com/WoutProvost/samp-util/tree/master
samp-util/vehicle.inc at master · WoutProvost/samp-utilA set of useful utility functions for SA-MP. Contribute to WoutProvost/samp-util development by creating an account on GitHub.github.comCnew model, type; for(;;) { //Dirty model = randomEx(400, 609); type = GetVehicleModelType(model); if(type != VEHICLE_TYPE_PLANE) break; } //Hier kannst dann model nutzenEndlosschleifen sind immer bisschen dirty.
Besser wäre es, einfach ein konstantes Array zu haben, wo du alle modelids, welche gültig sind speicherst und daraus dann eine zufällige ID wählst.
Zum Beispiel:
-
random(609) + 400
Das gibt dir eine Zahl zwischen:
(0-608)+400...also wird dein Wert zwischen: 400-1008 sein.
400-609
Dann musst du:
400+random(210) verwenden.
Oder du definierst dir eine einfacherer Funktion (tust du ganz oben ins Skript):
#define randomEx(%0,%1) (random((%1) - (%0) + 1) + (%0))
Da kannst du einfach:
randomEx(400, 609)
verwenden

-
Und das mehrere Male.

Excuse me, what

Wie zur Hölle bekommt man das denn hin. Das bedeutet du hast Funktionen, die sehen wie folgt aus:
stock test(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, a, b, c, d, e, f, g)
oder
public test(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, a, b, c, d, e, f, g)
Also dass die mehr als 32 Parameter haben.
Keine Ahnung, wie man das schafft xD Musst du das Design etwas anpassen.
Kannst ja mal eine Posten, dann können wir mal draufschauen

-
Ioannis20x gibt hier ein Wiki dazu: https://team.sa-mp.com/wiki/MySQL_R40.html
Die neuen Funktionen heißen ähnlich, musst du quasi nur umbenennen und die Parameter neu anordnen

#Handy
-
Ein Lock reicht ungünstigerweise nicht aus, da das Sichern eines kritischen Abschnittes selbst kritisch ist.
Yes mb, es war nicht atomar. Sry, es ist 10 Jahre her, dass ich manuell so sections sichern musste...
Genau aus dem Grund macht das auch keiner manuell xD
nicht die Korrektheit ändert
Hat ja nichts mit Clean Code zu tun. Was eine Troll Ergänzung.
-
Also der Code von dir funktioniert nicht, dort fahren mehrere Autos über die Brücke, da der kritische Abschnitt nicht richtig ist gesichert ist
Naja, ich sag mal, eigentlich sollte der genauso funktionieren wie dein Code.
Wieso meinst du, dass er nicht funktioniert?
Das heißt in beiden Fällen kann es zu einer Race-Condition kommen, da die Variablen nicht richtig synchronisiert werden zwischen den Threads.
Dafür sollte man z.B. stdatomic.h oder Mutexes nutzen.
Beides wird hier nicht getan, somit ist das so oder so kritisch...
-
Mogly1 dann versuch ich mal etwas Licht ins Dunkel zu bringen.
Wieso ist das bad code?
- Alle Abfragen in eine Zeile gestopft. Wozu gibt es Funktionen? Ruhig auslagern und alles schön benennen. (Also kapseln)
- Unübersichtlich du hast viele if-Blöcke, der Status erhöht sich da random, dann dort mal. Sowas solltest du sequenziell abarbeiten. Versuche keine if-Trees zu bauen: Externer Inhalt www.youtube.comInhalte von externen Seiten werden ohne Ihre Zustimmung nicht automatisch geladen und angezeigt.Durch die Aktivierung der externen Inhalte erklären Sie sich damit einverstanden, dass personenbezogene Daten an Drittplattformen übermittelt werden. Mehr Informationen dazu haben wir in unserer Datenschutzerklärung zur Verfügung gestellt.
- Der Grund von 1 & 2 sorgen dann für das Deadlock. Weil du selbst nicht mehr überblickst, wo jetzt welcher Status gesetzt wird und er wann wohin wandert...
Anfangs ist man noch sehr darauf bedacht jedes Byte und jeden CPU Zyklus zu sichern.
Aber die Clean-Code Regeln sind deutlich wichtiger: https://de.wikipedia.org/wiki/Clean_Code
Und darauf aufbauend, Software-Engineering.
Okay, nun zum Rest.
Ich verstehe nicht, wofür du die status Variable benötigst. Ich verstehe weiterhin nicht, wofür du die enter Variable brauchst.
Weiterhin verstehe ich nicht, wofür du die "Kollision Variable" brauchst. Der Plan ist doch, dass sowas nicht stattfinden kann, oder etwa nicht?
Wieso dann nicht z.B. einfach so lösen?
//Edit: Funktioniert nicht, außer als wenn ticket eine atomare Variable ist.
C
Alles anzeigen#define _DEFAULT_SOURCE #include <unistd.h> #include <stdlib.h> #include <stdio.h> #include <pthread.h> #include <time.h> #define NUM_THREADS 5 #define sle 0.01 #define crosses 100 clock_t start_t, end_t; volatile long ticket; int bridge_crosses; void lock (long tid) { while(ticket != -1) { printf("Thread [%ld] waiting...\n",tid); sleep(sle); } ticket = tid; } void unlock (long tid) { printf("Thread [%ld] unlocked!\n", tid); ticket=-1; } void *bridge_scenario (void *threadid) { long tid = (long) threadid; printf ("Hello World! It's me, thread #%ld !\n", tid); while (bridge_crosses < crosses) { lock(tid); printf("Car [%ld] crossing the road...\n", tid); sleep(sle); unlock(tid); bridge_crosses += 1; sleep(sle); } pthread_exit (NULL); } int main() { start_t = clock(); pthread_t threads[NUM_THREADS]; long t; // init data bridge_crosses = 0; ticket = -1; for (t = 0; t < NUM_THREADS; t++) { printf ("In main: creating thread %ld\n", t); int rc = pthread_create(&threads[t], NULL, bridge_scenario, (void *)t); if (rc) { printf ("ERROR; return code from pthread_create () is %d\n", rc); exit (-1); } } // joining threads for (t = 0; t < NUM_THREADS; t++) { pthread_join(threads[t], NULL); } // output end_t = clock(); double total_t = (double)(end_t - start_t) / CLOCKS_PER_SEC; printf ("bridge crosses: %d\n time: %f \n", bridge_crosses, total_t); /* Last thing that main() should do */ pthread_exit (NULL); return 0; }So könntest z.B. auch ganz einfach zählen, wie oft welches Auto gerade drübergefahren ist.
Und es kann so zu keinen Kollisionen kommen.
Der Grund btw, wieso das ohne das printf bei dir nicht funktioniert ist der, dass der Compiler die Variablen und Abfragen wegoptimiert 😄 Auf -O2 denkt der sich, ach, das brauch der nicht, weg damit xD
Damit das nicht passiert, musst du sie volatile setzen, dann lässt der Compiler die Finger davon

Hoffe es hilft etwas.
-
Mogly1 Noch schlechter hätte man die Frage glaube wirklich nicht formulieren können.
Was genau möchtest du erreichen.
Erkläre doch mal mehr zu deinem Code. Was genau geht denn nicht? Die printf sind ja ausgeklammert, da wird also nichts ausgegeben. Wieso geht denn das nicht?
Was soll das random Semikolon da? Soll das eine Endlosschleife sein? Dieser Code ist maximal dirty.
Eventuell mehr auf Clean-Code achten...
-
Achso.
Ja, das sind nur Warnings, die kannst du eig ignorieren.
Beheben tust du sie entweder, indem du deine MySQL Version updatest (empfohlen).
Oder du bearbeitest das a_mysql.inc, denn da kommen die Warnings her, das hat nichts mit deinem Code zu tun.
Dort werden Strings in den Funktionen übergeben, als Beispiel:
C++native MySQL:mysql_connect(host[], user[], password[], database[], MySQLOpt:option_id = MySQLOpt:0);//So steht es da native MySQL:mysql_connect(const host[], const user[], const password[], const database[], MySQLOpt:option_id = MySQLOpt:0); //So müsste es aussehenAlso immer wenn Strings (bzw Arrays) übergeben werden, also wenn diese eckigen Klammern bei den Parametern verwendet werden, sollte man ein const verwenden, wenn diese in der Funktion nicht verändert werden

-
weiß jemand woran das liegt und kann mir evtl helfen?
Wieso in aller Wellt sollte das query const sein?
const bedeutet, der Wert ist konstant und ändert sich nicht. Aber da du das hier bei der Deklaration verwendest und der "Variable" keinen Wert zuweist, wäre das immer leer...
Also mach aus dem const ein new
