Danke für die Information,
brauche ich aber nicht.
Habe damals schon das ganze GTA IV Pack also normal GTA IV + Episodes from Liberty City für 8 Euro auf Steam bekommen.
MFG
Danke für die Information,
brauche ich aber nicht.
Habe damals schon das ganze GTA IV Pack also normal GTA IV + Episodes from Liberty City für 8 Euro auf Steam bekommen.
MFG
MySQL Tutorial - Cachefunktionen & Threaded Querys
Hallo Leute,
und herzlich willkommen zu diesem Tutorial
Wie man sicher schon an der Überschrift geht es heute um die R7 des MySQL PLugins.
Wichtig: Dieses Tutorial bezieht sich auf die R7 Version des MySQL Plugins von BlueG.
(Logisch dass von Strickenkid und ältere Versionen des Plugins werden hier mit dem vorkommenden Code nicht klappen)
Entweder ihr downloadet es hier oder ihr braucht es gar nicht zu downloaden, da seit dem "Server Pack" der Version 0.3e ist sie standardmäßig bei
den Includes dabei, wenn ihr euch den SAMP Server von sa-mp.com herunterladet.
Die Include war beim 0.3e Server Packet dabei, ist aber inzwischen nicht mehr standardmäßig mit drinnen.
Hier die Google Project Seite für das MySQL Plugin von BlueG: Klick mich!
Wichtig: Hier wird nur erklärt, was sich bei der R7 Version geändert hat und wie man jetzt Daten ausließt, wie man eine MySQL Verbindung herstellt, wird
in Maddin's Tutorial ausführlich erklärt.
Aber nun fangen wir doch einfach mal an.
Inhaltsverzeichnis:
1. Wichtigsten Änderungen der R7 Version im Überblick
2. Was sind Threaded Querys überhaupt und was sind die Vorteile ?
3. Vorteile der Cachefunktionen
4. Erklärung aller wichtigen neuen Funktionen
5. Schlusswort
1. Änderungen der R7'er Version im Überblick
Mit dem Update auf R7 des MySQL Plugins von BlueG konnten sich noch nicht alle anfreunden.
Grund dafür war, dass es viele Funktionen mittlerweile nicht mehr gibt bzw. Sie einen anderen Namen bekommen haben oder ihre
Syntax sich verändert hat, die im ersten Moment für Verwirrung sorgt. Dazu kommt, dass mittlerweile nur noch threaded Querys unterstützt werden, was das zu bedeuten hat, wird in Kapitel 2 näher erläutert.
Desweiteren wurden Cache Funktionen hinzugefügt, die das Auslesen von Daten aus einer Tabelle einfacher machen sollten.
Dabei braucht man nicht mehr mit mysql_free_result oder mysql_store_result anzuwenden um das Ergebnis zu speichern oder nach der Beendigung des Querys das Ergebnis bzw. den Speicher wiederfreizugeben.
2.Was sind threaded Querys überhaupt und was sind die Vorteile ?
Kommen wir zu Beantwortung der Frage, was threaded Querys überhaupt sind.
Ich glaube zu diesem Thema gab es auch schon mal ein Tutorial, das sich jedoch auf das MySQL Plugin von Strickenkid bezog ( Das findet ihr hier ) (bei BlueG's sieht das nur ein bisschen anders aus). Wenn man mit MySQL Sachen auslesen will, bzw. einen Query ausführt, benötigt es eine gewisse Verarbeitungszeit, um diesen fertigzustellen. Wenn man jetzt z.B 3000 Autos auslesen will, bzw. man generell eine große Rate an Anfragen hat, wartet PAWN auf die Fertigstellung des Querys, da eben nicht 2 Dinge auf einmal gemacht werden können, was wiederum im schlimmsten Falle zu Laggs führen könnte.
Das kann eben passieren, wenn man beim Ausgeben eines Querys einfach im Code weiterschreibt und nicht einen 2.Thread eröffnet, wo der Code nach dem Query weitergeht. Wenn man jetzt aber einen 2.Thread eröffnet ( bzw. Callback), in dem der Code weiter geht nach dem Beendet des Querys, können in der Zwischenzeit noch andere Dinge von PAWN erledigt werden. So werden Laggs und im schlimmsten Fall sogar ein Serverabsturz vermieden.
Wie gesagt, hier nochmal der Verweiß auf das Tutorial OnQueryFinish, wo das nochmals ausführlich erklärt wird: Klick mich!
3. Vorteile der Cachefunktionen
Einzig und allein reichen threaded Querys aber dazu nicht aus, um die Geschwindigkeit um einiges zu verbessern, da man bisher immer noch
mysql_store_result() bzw. mysql_free_result() verwenden musste, um Daten richtig auslesen zu können.
Vorteile:
- Mithilfe der Cachefunktionen wird unser gesamter Code schneller. Die Geschwindigkeit verbessert sich um das 10-20 fache ( Klick mich für das Ergebnis )
- Man braucht nicht mehr mysql_store_result() bzw. mysql_free_result() zu verwenden
- Es ist mittlerweile auch leichter Daten effektiv auszulesen als mit sscanf ( und auch schneller als sscanf ! )
Hier mal ein Beispiel wie man mit sscanf Daten ausgelesen hat:
sscanf(store,"p<|>s[24]s[20]s[30]",pName,Fraktion,irgendeinstring)
Wird durch die neuen cache Funktionen zu:
cache_get_row(0,0,pName);
cache_get_row(0,1,Fraktion);
cache_get_row(0,2,irgendeinstring);
oder zu
cache_get_field_content(0,"Name",pName);
//weiteres hier
Das ganze hier ist schneller als sscanf & auch einfacher für die, die spezifischen Symbole davon nicht kennen.. Zwar ist das parsen der einen Linie von sscanf schneller als die cach_get_rows bzw.
cache_get_field_content, jedoch arbeitet die sscanf Lösung auch mit mysql_fetch_row, was einen extra Array benötigt die "Daten" zu holen und dann
daraus zu parsen. Beim Caching ist das jedoch schneller.
Die genaue Syntax der neuen Funktion bzw. Erklärung folgt in Kapitel 4.
4. Erklärung aller neuen Funktionen
In diesem Kapitel werde ich euch die Syntax,Nutzen und jeweils ein Beispiel der neuen Funktionen bringen.
mysql_function_query(connectionHandle,query[],bool:cache,callback[],format[],{Float,_}:...)
Fangen wir doch mal beim wichtigsten an, um einen Query nutzen zu können.
Die Funktion mysql_query wurde durch mysql_function_query ersetzt. Dabei wurden auch noch neue Parameter bei der letzeren Funktionen hinzugefügt.
Die Erklärung der Parameter
- connectionHandle = Logischerweiße die ConnectionHandle eurer MySQL Verbindung. Speichert den Rückgabewert von mysql_connect am besten in einer globalen Variable, und setzt diese dann hier immer ein.
-query[] = Der Query der ausgeführt werden soll. z.B "SELECT XX FROM XX Where YY = XX"
-bool:cache = Setzt ihr dies auf true, wird festgelegt, dass ihr den Cache verwenden wollt, false, deaktiviert den Cache. Empfehlenswert ist es, den Cache nur bei SELECT Abfragen zu nutzen, bei UPDATE INSERT, etc. lasst ihr das am besten auf false
-callback[] = Der Thread bzw. das Callback, in dem der Code weiterlaufen soll. Auch hier, am besten nur bei SELECT Abfragen verwenden, bei allen
anderen Abfragen einfach leerlassen also "" einfach reinschreiben
-format[] = Hier habt ihr die Möglichkeit, Parameter in den jeweiligen Callback (wenn ihr einen benutzt) mitzuliefern, wie z.B Bei SetTimerEx
-{Float }: ... = Hier kommt rein, was ihr für Parameter an das entsprechende Callback übergeben wollt.
Ein kleines Beispiel zu mysql_function_query:
mysql_function_query(handle,"SELECT ... FROM table ...'",true,"QueryFinished","si","Logan_Adams",playerid); //Führen einen SELECT Query aus, das kommt ins Callback QueryFinished, nutzen den Cache und übergeben Parameter an das Callback um eine Erstellung von anderen Variablen zu ersparen
forward QueryFinished(Name[],playerid); // Wir forwarden unseren Callback mit den entsprechenden, oben angegebenen Parametern
public QueryFinished(Name[],playerid) { //Wir erstellen unseren Callback
printf("Name: %s , ID: %d",Name,playerid); // Geben es in der Konsole aus
}
Wie gesagt, das obige ist nur ein Beispiel
Nochmal erläutere ich das richtige Einsetzen des Caches ( macht nur bei SELECT Abfragen wirklich Sinn ( die ein Ergebnis zurückliefern) )
Ein paar kleine Beispiele:
mysql_function_query(handle,"SELECT * From accounts",true,"LoadPlayers",""); //Wir führen einen SELECT Befehl aus, aktivieren den Cache, lassen es ins Callback "LoadPlayers" umleiten
Wenn ich jetzt z.B einfach ein paar Werte updaten will sieht das ca. so aus
mysql_function_query(handle,"UPDATE accounts SET level = 10 WHERE Name = 'Logan_Adams'",false,"",""); //Hier führen wir einen simplen Update Query aus, deaktivieren den Cache und lassen in kein Callback umleiten
cache_get_data(&num_rows,&num_fields,connectionHandle=1)
Diese Funktion returnt bzw. gibt die Anzahl der Zeilen und Felder zurück, die der Query returnt.
- num rows = Anzahl der Zeilen
- num fields = Anzahl der Felder
Man kann diese Funktion z.B dazu verwenden, um zu überprüfen, ob der Spieler schon auf dem Server registriert ist
Ein Beispiel:
new query[128];
format(query,sizeof query,"SELECT * FROM accounts WHERE Name = '%s'",SpielerName(playerid));
mysql_function_query(dbhandle,query,true,"OnPlayerCheck","d",playerid); //Ausgeben aller Daten vom jeweiligen Spieler
forward OnPlayerCheck(playerid); //Forwarden unseres Callbacks
public OnPlayerCheck(playerid) {
new zeilen,felder; //Erstellen zweier Variabeln für die Zeilen und Felder
cache_get_data(zeilen,felder); //Benutzen unsere Funktion um die Zeilen und Felder zu erhalten die oben im Query angefragt wurden
if(!zeilen) { //Wenn es keine Zeilen gibt , d.h. der Spieler noch nicht registriert ist
//Weiter Code ....
}
else { //Wenn es doch welche gibt, d.h. der Spieler ist schon registriert
//Weiter Code hier
}
}
cache_get_row(row,idx,dest[],connectionHandle=1)
Diese Funktion ist eine, die man eigentlich am meisten benutzt. Damit können wir viele unterschiedliche Daten auslesen.
Diese Funktion nimmt den zeilen und den Feld Index und speichert dessen Daten im angegebenen String.
- row = Zeilen Index meistens 0
- idx = Felder Index
- dest[] = Der String, in dem wir die ausgelesenen Daten zwischenspeichern wollen
Wie gesagt wir brauchen den Felder Index. Wenn unsere Tabelle, beispielsweiße so aufgebaut ist:
ID ( Auto Increment ) = Feld Index 0
Name = Feld Index 1
Passwort = Feld Index 2
Level = Feld Index 3
...
Hier bei fällt auf, dass der Feld Index immer bei 0 beginnt, was man sich merken muss (ist aber bei switch&case auch so)
Wenn ihr also so Daten auslesen wollt, immer auf den richtigen Index achten ( ein Blick in eure MySQL Tabelle genügt aber dafür, um diesen herauszufinden)
Ein kleines Beispiel:
mysql_function_query(..........) //Unser Query
forward ...... //Forwarden
public ...... { //Das entsprechende Callback
new speicher[30]; //Erstellen unserer Variable um die Daten zwischenzuspeichern
cache_get_row(0,0,speicher); //Holt uns die Daten von jetzt z.B 'ID'
printf("Seine ID: %d",strval(speicher)); //Konvertieren in eine Zahl, um es ausgeben zu können
cache_get_row(0,1,speicher); //holen uns daten aus z.B "Name"
printf("Name: %s",speicher); //Ausgeben
cache_get_row(0,2,speicher); //Holen uns Daten aus "Passwort"
printf("Passwort: %s",speicher); //Ausgeben in der Konsole
cache_get_row(0,3,speicher); //Holen uns Daten aus "Level". Da dies aber eine Zahl ist, müssen wir diese noch konvertieren
printf("Level: %d",strval(speicher)); //Ausgeben mit Konvertieren des Strings
}
Wichtig: Das was ihr erhaltet ist immer ein String. Wenn ihr jetzt z.B Level mit "speicher" ausgelesen habt müsst ihr z.B eurem Spieler Enum
SpielerInfo[playerid][Level] "speicher" zuweisen, aber nicht vergessen, speicher in eine Zahl mit strval zu konvertieren.
Bei Floats, dann natürlicht mit floatstr ...
cache_get_field(field_idx,dest[],connectionHandle=1)
Diese Funktion speichert den Namen eines Feldes.
- field_idx = Der Feld Index des Felder, der ausgelesen werden soll
- dest[] = Der String, indem der Name des Feldes zwischengespeichert werden soll
Ein kleines Beispiel dazu wäre:
//Den oberen Teil lasse ich weg ....
public QueryBeendet()
{
new fname[30]; //Erstellen einer Variablen
cache_get_field(0,fname); //Holen uns den Namen des Feldes mit dem Index 0 in die Variable "fname"
printf("Name des Feldes mit dem Index 0: %s",fname); //Ausgeben in der Konsole
return 1;
}
cache_get_field_content(row,const field_name[],dest[],connectionHandle=1)
Diese Funktion macht eigentlich genau das gleiche wie cache_get_row. Der Unterschied hierbei ist nur, dass ich keinen Feldindex angeben muss.
Für Leute, die zu faul sind, sich nach dem diesem zu erkunden, ist diese Funktion das richtige. Der
Geschwindigkeitsunterschied ist auch nur ziemlich gering.
- row = Die Zeile die ich auslesen will ( meistens 0)
- const field_name[] = Der Name des Feldes das ich auslesen will. z.B "Passwort"
- dest [] = String, in denen ich die Daten zwischenspeichern will
Ein Beispiel dazu:
//Oberer Teil ist wieder weggelassen
//Natürlich muss unten stehender Code in ein Callback
new store[24];
cache_get_field_content(0,"Name",store); //Holen uns Daten aus "Name" und speichern in "store"
printf("Name: %s",store); //Ausgeben des Wertes in der Konsole
cache_get_row_int(row,idx,connectionHandle=1)
Achtung: Diese Funktion wird nur bei den Versionen R8+ unterstützt.
Diese Funktion ist eigentlich nur eine Variation der Funktion cache_get_row, die Syntax ist auch fast die gleiche, außer,
dass es keinen destination Parameter gibt. Stattdessen wird das über die Rückgabe geregelt.
Mit dieser Funktion ist es gleich möglich Spalten in einen Integer Wert zu speichern, man muss also nicht mehr mit strval den String
von cache_get_row in eine Ganzzahl konvertieren.
Ein kleines Beispiel dazu:
public ...... { //Das entsprechende Callback
new speicher;//Variable um die Ganzzahl zu speichern
speicher = cache_get_row_int(0,0); //Holt uns die Daten von jetzt z.B 'ID' (natürlich muss der Index wieder stimmen)
printf("Seine ID: %d",speicher); //Ausgabe, aber dieses Mal ist keine Konvertierung nötig
}
Neue Tests haben ergeben, dass der neue Code hier im Beispiel ca. 1,5 mal schneller ist, als der alte Code mit Konvertierung.
cache_get_row_float(row,idx,connectionHandle=1)
Achtung: Diese Funktion wird nur bei den Versionen R8+ unterstützt.
Wieder "nur" eine Variation der Funktion cache_get_row, funktioniert wie cache_get_row_int.
Auch hier kann man einen Float Wert von einer Spalte auslesen und auch wieder in einen Float-Wert speichern, ohne Konvertierung.
Beispiel zu dieser neuen Funktion:
public ...... { //Das entsprechende Callback
new Float:speicher;//Variable um die Gleitkommazahl zu speichern
speicher = cache_get_row_float(0,5); //Holt uns die Daten von jetzt z.B 'LastX' (natürlich muss der Index wieder stimmen)
printf("LastX-Koordinate: %f",speicher); //Ausgabe, aber dieses Mal ist keine Konvertierung nötig
}
Auch hier ist der neue Code ca. 2 mal schneller als mit Konvertierung.
cache_get_field_content_int(row, const field_name[], connectionHandle = 1);
Achtung: Diese Funktion wird nur bei den Versionen R8+ unterstützt.
Diese Funktion bewirkt eigentlich genau das gleiche wie cache_get_row_int, nur dass man hier nicht den Zeilen Index angeben muss,
sondern nur den Namen des zu Inhalt holenden Feldes, konvertiert dabei dann das Ergebnis gleich in eine Ganzzahl, um nicht
selbst manuell konvertieren zu müssen.
Beispiel:
public .... { //das entsprechende Callback
new store;
store = cache_get_field_content_int(0,"ID",dbhandle); //Inhalt aus dem Feld ID holen
printf("ID: %d",store); //In der Konsole ausgeben
}
cache_get_field_content_float(row, const field_name[], connectionHandle = 1);
Achtung: Diese Funktion wird nur bei den Versionen R8+ unterstützt.
Macht genau das gleiche wie cache_get_field_content_int, konvertiert das Ergebnis jedoch jetzt gleich in eine Gleit bzw. Fließkommazahl.
Beispiel ist hier, so denke ich, nicht von Nöten.
5. Schlusswort
Ich hoffe ich konnte mit diesem Tutorial einigen Leuten helfen, die bisher mit der R7 Version noch nicht zurecht gekommen sind.
Wenn irgendwo Fehler im Tutorial sind, bitte macht mich darauf aufmerksam
Mit Freundlichen Grüßen
Wie du hast auch einen Gamemode, das auf dem R7 Plugin von G-Stylezzz basiert ?
IPrototypeI: Könntest du mir vielleicht die entsprechenden Stellen zeigen, damit ich meins ausbessern kann ?
Danke im Voraus
MFG
So habe mal dir die "heutige Sitzung" mal rauskopiert:
ZitatAlles anzeigen[22:40:05] Passing query INSERT INTO `accounts` (`Name`, `Passwort`) VALUES ('Logan_Adams', '3D085BE7A607183A92A541340AFDA5E643E2D49EEE80B3B5A952A69934B215E7C223BE6F45D4DFB0CD1E5B65B2FBE70103D6E5C90F230BCA7FD697D37501B083') |
[22:40:05] ProcessQueryThread() - Query was successful. (INSERT INTO `accounts` (`Name`, `Passwort`) VALUES ('Logan_Adams', '3D085BE7A607183A92A541340AFDA5E643E2D49EEE80B3B5A952A69934B215E7C223BE6F45D4DFB0CD1E5B65B2FBE70103D6E5C90F230BCA7FD697D37501B083'))
[22:40:05] CMySQLHandler::ProcessQueryThread() - Data is getting passed to ->ProcessTick()
[22:40:08] >> mysql_real_escape_string( Connection handle: 1 )
[22:40:08] CMySQLHandler::EscapeString(accounts); - Escaped 8 characters to accounts.
[22:40:08] >> mysql_real_escape_string( Connection handle: 1 )
[22:40:08] CMySQLHandler::EscapeString(Level); - Escaped 5 characters to Level.
[22:40:08] >> mysql_real_escape_string( Connection handle: 1 )
[22:40:08] CMySQLHandler::EscapeString(Name); - Escaped 4 characters to Name.
[22:40:08] >> mysql_real_escape_string( Connection handle: 1 )
[22:40:08] CMySQLHandler::EscapeString(Logan_Adams); - Escaped 11 characters to Logan_Adams.
[22:40:08] >> mysql_query_callback( Connection handle: 1 )
[22:40:08] >> mysql_real_escape_string( Connection handle: 1 )
[22:40:08] CMySQLHandler::EscapeString(accounts); - Escaped 8 characters to accounts.
[22:40:08] Passing query UPDATE `accounts` SET `Level` = '0' WHERE `Name` = 'Logan_Adams' |
[22:40:08] >> mysql_real_escape_string( Connection handle: 1 )
[22:40:08] ProcessQueryThread() - Query was successful. (UPDATE `accounts` SET `Level` = '0' WHERE `Name` = 'Logan_Adams')
[22:40:08] CMySQLHandler::EscapeString(Geld); - Escaped 4 characters to Geld.
[22:40:08] CMySQLHandler::ProcessQueryThread() - Data is getting passed to ->ProcessTick()
[22:40:08] >> mysql_real_escape_string( Connection handle: 1 )
[22:40:08] CMySQLHandler::EscapeString(Name); - Escaped 4 characters to Name.
[22:40:08] >> mysql_real_escape_string( Connection handle: 1 )
[22:40:08] CMySQLHandler::EscapeString(Logan_Adams); - Escaped 11 characters to Logan_Adams.
[22:40:08] >> mysql_query_callback( Connection handle: 1 )
[22:40:08] >> mysql_real_escape_string( Connection handle: 1 )
[22:40:08] CMySQLHandler::EscapeString(accounts); - Escaped 8 characters to accounts.
[22:40:08] >> mysql_real_escape_string( Connection handle: 1 )
[22:40:08] CMySQLHandler::EscapeString(Kills); - Escaped 5 characters to Kills.
[22:40:08] >> mysql_real_escape_string( Connection handle: 1 )
[22:40:08] CMySQLHandler::EscapeString(Name); - Escaped 4 characters to Name.
[22:40:08] >> mysql_real_escape_string( Connection handle: 1 )
[22:40:08] CMySQLHandler::EscapeString(Logan_Adams); - Escaped 11 characters to Logan_Adams.
[22:40:08] >> mysql_query_callback( Connection handle: 1 )
[22:40:08] >> mysql_real_escape_string( Connection handle: 1 )
[22:40:08] CMySQLHandler::EscapeString(accounts); - Escaped 8 characters to accounts.
[22:40:08] >> mysql_real_escape_string( Connection handle: 1 )
[22:40:08] CMySQLHandler::EscapeString(Tode); - Escaped 4 characters to Tode.
[22:40:08] >> mysql_real_escape_string( Connection handle: 1 )
[22:40:08] CMySQLHandler::EscapeString(Name); - Escaped 4 characters to Name.
[22:40:08] >> mysql_real_escape_string( Connection handle: 1 )
[22:40:08] CMySQLHandler::EscapeString(Logan_Adams); - Escaped 11 characters to Logan_Adams.
[22:40:08] >> mysql_query_callback( Connection handle: 1 )
[22:40:08] >> mysql_real_escape_string( Connection handle: 1 )
[22:40:08] CMySQLHandler::EscapeString(accounts); - Escaped 8 characters to accounts.
[22:40:08] >> mysql_real_escape_string( Connection handle: 1 )
[22:40:08] CMySQLHandler::EscapeString(Banned); - Escaped 6 characters to Banned.
[22:40:08] >> mysql_real_escape_string( Connection handle: 1 )
[22:40:08] CMySQLHandler::EscapeString(Name); - Escaped 4 characters to Name.
[22:40:08] >> mysql_real_escape_string( Connection handle: 1 )
[22:40:08] CMySQLHandler::EscapeString(Logan_Adams); - Escaped 11 characters to Logan_Adams.
[22:40:08] >> mysql_query_callback( Connection handle: 1 )
[22:40:08] >> mysql_real_escape_string( Connection handle: 1 )
[22:40:08] CMySQLHandler::EscapeString(accounts); - Escaped 8 characters to accounts.
[22:40:08] >> mysql_real_escape_string( Connection handle: 1 )
[22:40:08] CMySQLHandler::EscapeString(Passwort); - Escaped 8 characters to Passwort.
[22:40:08] >> mysql_real_escape_string( Connection handle: 1 )
[22:40:08] CMySQLHandler::EscapeString(Name); - Escaped 4 characters to Name.
[22:40:08] >> mysql_real_escape_string( Connection handle: 1 )
[22:40:08] CMySQLHandler::EscapeString(Logan_Adams); - Escaped 11 characters to Logan_Adams.
[22:40:08] >> mysql_query_callback( Connection handle: 1 )
[22:40:08] Passing query UPDATE `accounts` SET `Geld` = '0' WHERE `Name` = 'Logan_Adams' |
[22:40:08] ProcessQueryThread() - Query was successful. (UPDATE `accounts` SET `Geld` = '0' WHERE `Name` = 'Logan_Adams')
[22:40:08] CMySQLHandler::ProcessQueryThread() - Data is getting passed to ->ProcessTick()
[22:40:08] Passing query UPDATE `accounts` SET `Kills` = '0' WHERE `Name` = 'Logan_Adams' |
[22:40:08] ProcessQueryThread() - Query was successful. (UPDATE `accounts` SET `Kills` = '0' WHERE `Name` = 'Logan_Adams')
[22:40:08] CMySQLHandler::ProcessQueryThread() - Data is getting passed to ->ProcessTick()
[22:40:08] Passing query UPDATE `accounts` SET `Tode` = '0' WHERE `Name` = 'Logan_Adams' |
[22:40:08] ProcessQueryThread() - Query was successful. (UPDATE `accounts` SET `Tode` = '0' WHERE `Name` = 'Logan_Adams')
[22:40:08] CMySQLHandler::ProcessQueryThread() - Data is getting passed to ->ProcessTick()
[22:40:08] Passing query UPDATE `accounts` SET `Banned` = '0' WHERE `Name` = 'Logan_Adams' |
[22:40:08] ProcessQueryThread() - Query was successful. (UPDATE `accounts` SET `Banned` = '0' WHERE `Name` = 'Logan_Adams')
[22:40:08] CMySQLHandler::ProcessQueryThread() - Data is getting passed to ->ProcessTick()
[22:40:08] Passing query UPDATE `accounts` SET `Passwort` = '0' WHERE `Name` = 'Logan_Adams' |
[22:40:08] ProcessQueryThread() - Query was successful. (UPDATE `accounts` SET `Passwort` = '0' WHERE `Name` = 'Logan_Adams')
[22:40:08] CMySQLHandler::ProcessQueryThread() - Data is getting passed to ->ProcessTick()
Was auffällt, das im Query aber das richtig gehashte PW ist, jedoch nicht eingetragen wird :O
Danke im Voraus
MFG
Muss ich davor nicht iwie erst das Debug aktivieren ?
MFG
Hallo,
erst einmal vielen Dank für deine Antwort.
Und, das PW in der MySQL DB war nich auf 130 eingestellt. Habe es jetzt gemacht,
jedoch wird immernoch '0' eingetragen und der Account danach immer wieder neu eingetragen ( ich rufe nirgends das 2 mal auf )
MFG
Hallo Leute,
heute habe ich versucht mein Script, das auf MySQL Basiert, auf die R7 des G-Stylezzz Plugins umzuschreiben.
Dort werden nur noch threaded Queries unterstützt, außerdem gibt es dazu noch Cache Funktionen, die die Performanche bis zu 12 mal so gut verbessern.
Nachdem ich alles umgeschrieben habe, gibt es jetzt jedoch leider ein paar Bugs.
Es wird kein richtiges Passwort eingetragen. D.h. immer wird '0' anstatt der Eingabe eingegeben. Dann wird auch immer der Account zwei mal angelegt ...#
Hier mal ein bisschen Code:
case DIALOG_REGISTER: {
if(strlen(inputtext) < 6) {
SendClientMessage(playerid,ROT,"Fehler: Dein Passwort darf nicht kürzer als 6 Zeichen sein. Bitte wähle ein anderes Passwort!");
ShowPlayerDialog(playerid,DIALOG_REGISTER,DIALOG_STYLE_PASSWORD,"Registrierung",""WEISS_HTML"Bitte gebe hier dein Passwort ein,das du festlegen willst.\nWichtig: Merke es dir gut und beachte Groß- bzw. Kleinschreibung:","OK","");
}
else {
new buffer[129];
WP_Hash(buffer,sizeof buffer,inputtext);
CreateAccount(playerid,buffer);
SetPVarInt(playerid,"eingeloggt",1);
SpawnPlayer(playerid);
}
}
stock CreateAccount(playerid,pass[])
{
new query[256],Name[MAX_PLAYER_NAME];
GetPlayerName(playerid, Name, MAX_PLAYER_NAME);
mysql_real_escape_string(Name,Name);
mysql_real_escape_string(pass,pass);
format(query, sizeof(query), "INSERT INTO `accounts` (`Name`, `Passwort`) VALUES ('%s', '%s')", Name, pass);
mysql_function_query(mysql_connectionhandle,query,false,"","");
return true;
}
Wenn ihr mehr Code braucht, sagt es einfach.
Danke im Voraus
Hey Leute,
komischerweiße mache ich nur heute mein Skript auf, includiere was und compile.
Die Includes habe ich danach nicht mehr inkuldiert, jetzt kommen auf einmal Errors und Warnings, die vorher nie da waren.
Errors/Warnings:
ZitatAlles anzeigenGM.pwn(511) : warning 236: unknown parameter in substitution (incorrect #define pattern)
GM.pwn(511) : warning 236: unknown parameter in substitution (incorrect #define pattern)
GM.pwn(511) : warning 236: unknown parameter in substitution (incorrect #define pattern)
GM.pwn(511) : warning 236: unknown parameter in substitution (incorrect #define pattern)
GM.pwn(511) : warning 236: unknown parameter in substitution (incorrect #define pattern)
GM.pwn(511) : warning 236: unknown parameter in substitution (incorrect #define pattern)
GM.pwn(511) : warning 236: unknown parameter in substitution (incorrect #define pattern)
GM.pwn(511) : error 029: invalid expression, assumed zero
GM.pwn(511) : warning 215: expression has no effect
GM.pwn(511) : error 029: invalid expression, assumed zero
GM.pwn(511) : warning 215: expression has no effect
GM.pwn(511) : error 029: invalid expression, assumed zero
GM.pwn(511) : fatal error 107: too many error messages on one line
Wenn man sich mal die Zeile 511 anschaut, ist mir nichts aufgefallen:
stock mysql_CheckAccount(playerid)
{
new Query[128],Name[MAX_PLAYER_NAME+1];
GetPlayerName(playerid, Name, MAX_PLAYER_NAME+1);
mysql_real_escape_string(Name, Name);
format(Query, sizeof(Query), "SELECT * FROM `accounts` WHERE `Name` = '%s'", Name);
mysql_query(Query,THREAD_OnAccountChecked); //DAS HIER IST DIE ERRORZEILE
return 1;
}
Danke im Voraus!
MFG
Es kann verschiedene Ursachen haben..
SendClientMessage(playerid,"Hallo");
..wäre auch ein tag mismatch.
Nein das wäre iwie ein Argument type mismatch
MFG
Wurde jetzt ein bisschen von dem Tool enttäuscht, da bleibe ich lieber bei Notepad++.
Mir werden zwar Funktionen angezeigt, jedoch möchte ich auch die Parameter der jeweiligen Funktion einsehen können.
MFG
Wieso editierst du denn die Include ?
Ist dir eigentlich bewusst, dass die Include eigentlich gar nicht das "richtige" Junkbuster ist, sondern das Filterscript das Anti Cheat System beinhaltet ?
MFG
Danke und frage , Was passiert wenn man mit einem Befehl leben bekommt ist das dann weg ??
Bzw. wenn man duch den befehl /gmwaffen Waffen bekommt sind diese dann auch weg ?
Nein sind sie meines Wissens nicht, denn im Junkbuster wird dein Befehl also GivePlayerWeapons durch die serverseitige Funktion erstetzt, und die Waffen müssten dort bleiben, bloß bei Cheatern, b ei denen wird diese Funktion nicht aufgerufen und die Waffen werden weggenommen, usw.
MFG
genau das sagt mir einer der hier Donator gekaut hat :facepalm:
Wie kann man bitte den Donator Rank mit Zigaretten vergleichen ?
Zudem unterstütze ich damit das Forum, im Gegensatz ich mit Zigaretten mir mein eigenes Grab schaufle, und Donator mir weitaus billiger kommt, als
für Zigaretten 5 Euro / Tag auszugeben.
MFG
Ich habe mal ein paar Sachen angehängt, die ich bei mir gefunden habe.
MFG
Ne, ich verrauchs & versaufs lieber
Vielleicht solltest du dir nochmal deinen Umgang mit Geld überdenken
Der Error/Warning bedeutet , dass du die verwendete Variable bereits iwo im gleichen Sichtbereich, oder global deklariert hast.
MFG
Ich würde nicht mehr Zamaroths sondern jetzt iPlexomax's Textdraweditor benutzen, da
man das jetzt alles mit der Maus machen kann und nicht mehr mit den Pfeiltasten, etc....
Einfach mal in der SuFU eingeben im englischen SAMP Forum.
MFG
Wenn du mit DCMD einen Command machen willst, musst du noch dcmd(deinbefehl,anzahlderbuchstaben,cmdtext); unter OnPlayerCommandText jeweils
hinzufügen.
MFG
Du solltest jetzt lieber threaded Querys benutzen.
Kann dir per Skype helfen
Melde dich, wennde Hilfe brauchst.
MFG