[jTuT] MySQL R41-4 (Installation, XAMPP, Verwendung, Bedienung & Registrations-System)
-
-
Also %e für string, %d für Integer & für floats?
%f
Bzw wenn du es irgendwo mit z.B. zwei Nachkommastellen ausgeben willst:
%0.2f -
-
cache_get_value_name_string ?
Nur:
cache_get_value_name
http://wiki.sa-mp.com/wiki/MySQL/R40#cache_get_value_nameUnd kann mir noch jemand sagen wie man die Auto inkrementierung bei 0 beginnen lassen kann?
https://stackoverflow.com/ques…-from-0-but-starts-from-1
Allerdings solltest du eher darauf verzichten, die Zeilen mit 0 zu beginnen.
Besser wäre es, den AUTO_INCREMENT Wert trotzdem auf 1+ zu lassen, und parallel dazu eine zweite Spalte zu erstellen, die dann den AUTO_INCREMENT Wert -1 bekommt.
Somit wäre dann 1 -> 0, 2 -> 1, 3 -> 2, etc...
Oder eben von 1 beginnen zu zählen, das wäre die beste Möglichkeit. -
Code
Alles anzeigen//MySQL new query[2000]; for(new i = 1; i < sizeof(HouseInfo); i++) { mysql_format(handle, query, sizeof(query), "SELECT * FROM property WHERE id = '%d'", i); cache_get_value_name_float(0, "hEnterx", HouseInfo[i][hEnterx]); cache_get_value_name_float(0, "hEntery", HouseInfo[i][hEntery]); cache_get_value_name_float(0, "hEnterz", HouseInfo[i][hEnterz]); cache_get_value_name_float(0, "hEnterr", HouseInfo[i][hEnterr]); cache_get_value_name_float(0, "hExitx", HouseInfo[i][hExitx]); cache_get_value_name_float(0, "hExity", HouseInfo[i][hExity]); cache_get_value_name_float(0, "hExitz", HouseInfo[i][hExitz]); cache_get_value_name_float(0, "hExitr", HouseInfo[i][hExitr]); cache_get_value_name_int(0, "hHeal", HouseInfo[i][hHeal]); cache_get_value_name(0, "hOwner", HouseInfo[i][hOwner]); cache_get_value_name(0, "hDiscription", HouseInfo[i][hDiscription]); cache_get_value_name_int(0, "hPrice", HouseInfo[i][hPrice]); cache_get_value_name_int(0, "hWorld", HouseInfo[i][hWorld]); cache_get_value_name_int(0, "hInt", HouseInfo[i][hInt]); cache_get_value_name_int(0, "hLock", HouseInfo[i][hLock]); cache_get_value_name_int(0, "hOwned", HouseInfo[i][hOwned]); cache_get_value_name_int(0, "hRent", HouseInfo[i][hRent]); cache_get_value_name_int(0, "hRentabil", HouseInfo[i][hRentabil]); cache_get_value_name_int(0, "hTakings", HouseInfo[i][hTakings]); cache_get_value_name_int(0, "hDate", HouseInfo[i][hDate]); cache_get_value_name_int(0, "hLevel", HouseInfo[i][hLevel]); cache_get_value_name_int(0, "hStrom", HouseInfo[i][hStrom]); cache_get_value_name_int(0, "id", HouseInfo[i][hID]); printf("i: %d | id: %d | hEnterx: %f", i, HouseInfo[i][hID], HouseInfo[i][hEnterx]); } mysql_pquery(handle, query);
@Jeffry Weißt du warum er nichts zurück gibt? Steht unter OnGameModeInit. Das print gibt weder die [hID] , noch [hEnterx] aus.
-
Du darfst den Cache erst im Callback, welches in mysql_pquery angegeben wird, auslesen.
Gleich wie beim hier im Tutorial beschriebenen Login.
-
Habs jetzt so gelöst, kann nur schlecht einschätzen wie groß die query sein muss... schlimm wenn die bisschen überdimensional groß is?^^
Codefor(new i = 1; i < sizeof(HouseInfo); i++) { new query[2000]; mysql_format(handle, query, sizeof(query), "SELECT * FROM property WHERE id = '%d'", i); mysql_pquery(handle, query, "LoadPropertys", "d", i); }
Code
Alles anzeigenFunction LoadPropertys(i) { cache_get_value_name_float(0, "hEnterx", HouseInfo[i][hEnterx]); cache_get_value_name_float(0, "hEntery", HouseInfo[i][hEntery]); cache_get_value_name_float(0, "hEnterz", HouseInfo[i][hEnterz]); cache_get_value_name_float(0, "hEnterr", HouseInfo[i][hEnterr]); cache_get_value_name_float(0, "hExitx", HouseInfo[i][hExitx]); cache_get_value_name_float(0, "hExity", HouseInfo[i][hExity]); cache_get_value_name_float(0, "hExitz", HouseInfo[i][hExitz]); cache_get_value_name_float(0, "hExitr", HouseInfo[i][hExitr]); cache_get_value_name_int(0, "hHeal", HouseInfo[i][hHeal]); cache_get_value_name(0, "hOwner", HouseInfo[i][hOwner]); cache_get_value_name(0, "hDiscription", HouseInfo[i][hDiscription]); cache_get_value_name_int(0, "hPrice", HouseInfo[i][hPrice]); cache_get_value_name_int(0, "hWorld", HouseInfo[i][hWorld]); cache_get_value_name_int(0, "hInt", HouseInfo[i][hInt]); cache_get_value_name_int(0, "hLock", HouseInfo[i][hLock]); cache_get_value_name_int(0, "hOwned", HouseInfo[i][hOwned]); cache_get_value_name_int(0, "hRent", HouseInfo[i][hRent]); cache_get_value_name_int(0, "hRentabil", HouseInfo[i][hRentabil]); cache_get_value_name_int(0, "hTakings", HouseInfo[i][hTakings]); cache_get_value_name_int(0, "hDate", HouseInfo[i][hDate]); cache_get_value_name_int(0, "hLevel", HouseInfo[i][hLevel]); cache_get_value_name_int(0, "hStrom", HouseInfo[i][hStrom]); cache_get_value_name_int(0, "id", HouseInfo[i][hID]); printf("i: %d | id: %d | hEnterx: %f", i, HouseInfo[i][hID], HouseInfo[i][hEnterx]); }
-
Du solltest aus Performance Gründen nur ein Query absenden, ohne die WHERE Bedingung. Das Ergebnis kannst du dann im Callback mit einem Loop durchgehen. Dann wird die Datenbank nur einmal anstatt x mal angesprochen.
kann nur schlecht einschätzen wie groß die query sein muss... schlimm wenn die bisschen überdimensional groß is?^^
Das Query (SELECT...) sind bei dir keine 100 Zeichen. 2000 ist da etwas überdimensioniert.
-
Wie regel ich das dann im Callback? Weil im Moment krieg ich für jeden Schleifendurchgang nur die Werte der ersten Zeile.
Codenew query[200]; mysql_format(handle, query, sizeof(query), "SELECT * FROM property"); mysql_pquery(handle, query, "LoadPropertys");
Code
Alles anzeigenFunction LoadPropertys(i) { for(new h = 0; h < sizeof(HouseInfo); h++) { cache_get_value_name_float(0, "hEnterx", HouseInfo[i][hEnterx]); cache_get_value_name_float(0, "hEntery", HouseInfo[i][hEntery]); cache_get_value_name_float(0, "hEnterz", HouseInfo[i][hEnterz]); cache_get_value_name_float(0, "hEnterr", HouseInfo[i][hEnterr]); cache_get_value_name_float(0, "hExitx", HouseInfo[i][hExitx]); cache_get_value_name_float(0, "hExity", HouseInfo[i][hExity]); cache_get_value_name_float(0, "hExitz", HouseInfo[i][hExitz]); cache_get_value_name_float(0, "hExitr", HouseInfo[i][hExitr]); cache_get_value_name_int(0, "hHeal", HouseInfo[i][hHeal]); cache_get_value_name(0, "hOwner", HouseInfo[i][hOwner]); cache_get_value_name(0, "hDiscription", HouseInfo[i][hDiscription]); cache_get_value_name_int(0, "hPrice", HouseInfo[i][hPrice]); cache_get_value_name_int(0, "hWorld", HouseInfo[i][hWorld]); cache_get_value_name_int(0, "hInt", HouseInfo[i][hInt]); cache_get_value_name_int(0, "hLock", HouseInfo[i][hLock]); cache_get_value_name_int(0, "hOwned", HouseInfo[i][hOwned]); cache_get_value_name_int(0, "hRent", HouseInfo[i][hRent]); cache_get_value_name_int(0, "hRentabil", HouseInfo[i][hRentabil]); cache_get_value_name_int(0, "hTakings", HouseInfo[i][hTakings]); cache_get_value_name_int(0, "hDate", HouseInfo[i][hDate]); cache_get_value_name_int(0, "hLevel", HouseInfo[i][hLevel]); cache_get_value_name_int(0, "hStrom", HouseInfo[i][hStrom]); cache_get_value_name_int(0, "id", HouseInfo[i][hID]); printf("i: %d | id: %d | hEnterx: %f", i, HouseInfo[i][hID], HouseInfo[i][hEnterx]); } }
-
Du musst anstatt der 0 im ersten Parameter das h eintragen.
Für den Index i musst du den Cache Wert deiner Key Spalte (id) auslesen, vor allen anderen, und diesen Wert in i wegschreiben.
-
Und das speichern? Ist wahrscheinlich auch nicht so effizient oder? Wüsste aber nicht wie ich´s nur 1x abschicken könnte.
Das hab ich unter OnGameModeExit:Code
Alles anzeigenfor(new i = 0; i < sizeof(HouseInfo); i++) { new query[200]; mysql_format(handle, query, sizeof(query), "UPDATE property SET hEnterx = '%.1f', hEntery = '%.1f', hEnterz = '%.1f', hEnterr = '%.1f', hExitx = '%.1f', hExity = '%.1f', hExitz = '%.1f', hExitr = '%.1f',", HouseInfo[i][hEnterx], HouseInfo[i][hEntery], HouseInfo[i][hEnterz], HouseInfo[i][hEnterr], HouseInfo[i][hExitx], HouseInfo[i][hExity], HouseInfo[i][hExitz], HouseInfo[i][hExitr]); mysql_format(handle, query, sizeof(query), "%s hHeal = '%d', hOwner = '%e', hDiscription = '%e', hPrice = '%d', hWorld = '%d', hInt = '%d',", query, HouseInfo[i][hHeal], HouseInfo[i][hOwner], HouseInfo[i][hDiscription], HouseInfo[i][hPrice], HouseInfo[i][hWorld], HouseInfo[i][hInt]); mysql_format(handle, query, sizeof(query), "%s hLock = '%d', hOwned = '%d', hRent = '%d', hRentabil = '%d', hTakings = '%d', hDate = '%d',", query, HouseInfo[i][hLock], HouseInfo[i][hOwned], HouseInfo[i][hRent], HouseInfo[i][hRentabil], HouseInfo[i][hTakings], HouseInfo[i][hDate]); mysql_format(handle, query, sizeof(query), "%s hLevel = '%d', hStrom = '%d'", query, HouseInfo[i][hLevel], HouseInfo[i][hStrom]); mysql_format(handle, query, sizeof(query), "%s WHERE id = '%d'", query, HouseInfo[i][hID]); mysql_pquery(handle, query); printf("Speichern: i: %d | id: %d | hEnterx: %f | Price: %d", i, HouseInfo[i][hID], HouseInfo[i][hEnterx], HouseInfo[i][hPrice]); }
-
Und das speichern? Ist wahrscheinlich auch nicht so effizient oder? Wüsste aber nicht wie ich´s nur 1x abschicken könnte.
Grundsätzlich passt das.
Man könnte es zwar alles (für alle Häuser) in ein großes Query packen und mit INSERT INTO ... ON DUPLICATE KEY UPDATE ... absenden, das macht aber relativ wenig Sinn.Wobei es die bessere Variante wäre, ein Haus immer dann direkt zu speichern, wenn eine Änderung passiert, so oft ändert sich an den Häusern ja nichts.
Dann hättest du auch kein Problem, wenn der Server mittendrin abstürzt, ohne OnGameModeExit aufzurufen.Sprich, nicht einmal "SaveAllHouses", sondern z.B. dort wo sich der Besitzer des Hauses ändert (Kauf, Verkauf, etc...) eine Funktion "SaveHouse(id)" aufrufen.
Sowas sollte aber natürlich nicht in einem Timer stehen, der jede Sekunde aufgerufen wird, im ungünstigsten Fall noch für alle Häuser. -
Jetzt passiert was ganz komisches, er speichert die Werte für jedes Haus ein, dabei wird nur 1x in der Konsole geprintet:
-
dabei wird nur 1x in der Konsole geprintet:
Nimm das return 1; aus der Schleife (nach dem print) raus. Das beendet die Schleife sofort.
Dass die Häuser trotzdem gespeichert werden, dürfte an einem anderen Code liegen, der die Daten in die Datenbank schreibt. -
Hmm wüsste nicht woran, müsste eigentlich daran liegen
Mit dem Laden der Daten hats ja nichts zu tun oder? Unter OnGameModeInit hab ich:
Codenew query[200]; mysql_format(handle, query, sizeof(query), "SELECT * FROM property"); mysql_pquery(handle, query, "LoadPropertys");
Code
Alles anzeigenFunction LoadPropertys() { for(new i = 0; i < sizeof(HouseInfo); i++) { cache_get_value_name_float(i, "hEnterx", HouseInfo[i][hEnterx]); cache_get_value_name_float(i, "hEntery", HouseInfo[i][hEntery]); cache_get_value_name_float(i, "hEnterz", HouseInfo[i][hEnterz]); cache_get_value_name_float(i, "hEnterr", HouseInfo[i][hEnterr]); cache_get_value_name_float(i, "hExitx", HouseInfo[i][hExitx]); cache_get_value_name_float(i, "hExity", HouseInfo[i][hExity]); cache_get_value_name_float(i, "hExitz", HouseInfo[i][hExitz]); cache_get_value_name_float(i, "hExitr", HouseInfo[i][hExitr]); cache_get_value_name_int(i, "hHeal", HouseInfo[i][hHeal]); cache_get_value_name(i, "hOwner", HouseInfo[i][hOwner]); cache_get_value_name(i, "hDiscription", HouseInfo[i][hDiscription]); cache_get_value_name_int(i, "hPrice", HouseInfo[i][hPrice]); cache_get_value_name_int(i, "hWorld", HouseInfo[i][hWorld]); cache_get_value_name_int(i, "hInt", HouseInfo[i][hInt]); cache_get_value_name_int(i, "hLock", HouseInfo[i][hLock]); cache_get_value_name_int(i, "hOwned", HouseInfo[i][hOwned]); cache_get_value_name_int(i, "hRent", HouseInfo[i][hRent]); cache_get_value_name_int(i, "hRentabil", HouseInfo[i][hRentabil]); cache_get_value_name_int(i, "hTakings", HouseInfo[i][hTakings]); cache_get_value_name_int(i, "hDate", HouseInfo[i][hDate]); cache_get_value_name_int(i, "hLevel", HouseInfo[i][hLevel]); cache_get_value_name_int(i, "hStrom", HouseInfo[i][hStrom]); cache_get_value_name_int(i, "id", HouseInfo[i][hID]); printf("i: %d | id: %d | hEnterx: %f | %d | %d ", i, HouseInfo[i][hID], HouseInfo[i][hEnterx], (i+1), sizeof(HouseInfo)); if((i+1) == sizeof(HouseInfo)) { LoadPropertys2(); } } }
-
Mit dem Laden der Daten hats ja nichts zu tun oder? Unter OnGameModeInit hab ich:
Hast du das return 1 entfernt?
Wenn ja, was ist jetzt das Problem? Wenn alle Häuser gespeichert werden, ist das doch richtig, oder? -
Ich hab da stattdessen ein break; hin gemacht: https://pastebin.com/KEZtSLnp
Du meintest ja:Wobei es die bessere Variante wäre, ein Haus immer dann direkt zu speichern, wenn eine Änderung passiert, so oft ändert sich an den Häusern ja nichts.
Dann hättest du auch kein Problem, wenn der Server mittendrin abstürzt, ohne OnGameModeExit aufzurufen.Deswegen soll er bei /addhouse nur das Haus speichern das erstellt wurde, er speichert aber alle Häuser mit den Werten des neu erstellten Hauses.
-
Du meintest ja:
Achso, jetzt verstehe ich was du meinst. Ich dachte du wolltest alle Häuser ohnehin speichern.
Beim Anlegen des Hauses darfst du aber kein "UPDATE" Query nehmen, sondern musst ein INSERT nehmen (wie beim Registrieren hier im Tutorial).
Das INSERT Query gibt dir dann über das aufgerufene Callback die ID des Hauses zurück, für HouseInfo[i][hID]. -
Hab aber eigentlich die Datenbank schon mit sizeof(HouseInfo) gefüllt & die IDs haben sich ja sowieso automatisch inkrementiert.
Deswegen auch bei /addhouse die abfrage: -
@Jeffry Du sagtest wenn ich ne Dumme fragen stelle möchte, kann ich das hier gern tun hihi.
Du sagtest mir via PN, das man deine Tutorials, leicht erweitern und bearbeiten kann.
Grade stoße ich an ein Verstänissproblem.Du verwendest in deinem Tutorial ja die Funktion: ShowPlayerDialog
- #define DIALOG_REGISTER 1403
- #define DIALOG_LOGIN 2401
Ich möchte aber gerne mit Textdraw´s arbeiten, welche die Dialog Fenster ersetzen.
Nur weiß ich nicht welche Publics und was ich abändern sollte, damit der gleiche Code so weiter funktioniert.Möchte keinen fertig geschrieben Code von dir, oder sonst wem, sondern nur ein paar Hinweise, wie ich am besten Vorgehen sollte.
Natürlich bin ich nicht abgeneigt davon, dass auch andere helfen." Wie ich ein Textdraw erstelle weiß ich."
//Edit Beweis für die Dumme Frage:
Einfach mit PlayerTextDrawShow ?
Erst Wiki richtig lesen, dann fragen xD Denke hat sich erledigt. -