PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : MySql - extDB2 Tutorial für Einsteiger


Arconymous
04.05.2015, 14:41
Hey zusammen,

ich bastel momentan an einer Mission rum, jedoch will nurnoch das Speichern der Spieler und der Objekte nicht funktionieren.

Ich habe extDB2 installiert. Gibt es nun irgendwo Beispielmissionen oder ein Tutorial wie man die Dinge in eine Datenbank schreiben kann?
Mir würde auch reichen, wie man zunächst die Zeit, die der Server schon läuft in die Datenbank schreiben kann, um sich langsam an andere Dinge ranzutasten. Mit iniDBi hat das schon geklappt, jedoch finde ich extDB besser und vorallem angenehmer, wenn man alle seine Einträge z.B in Navicat verändern kann.

Ich hoffe ihr könnt mir helfen.

Arconymous

Nokman
04.05.2015, 18:18
Dazu kann man eigendlich das wiki von extdb2 heranziehen das ist aussagekräftig genug.

https://github.com/Torndeco/extdb2/wiki

Arconymous
04.05.2015, 18:33
Das wiki hab ich mir schon angeguckt, aber ich werde daraus irgendwie nicht schlau... Außerdem hab ich mir mal die @life_server von Altis life angeguckt. Da gibts ja auch einige mysql einträge, womit Daten in der Datenbank gespeichert werden.

Ich komme jedoch einfach nicht darauf wie man zum Beispiel die Zeit, die der Server schon läuft in die Datenbank speichert. Die abgelaufene Zeit bekommt man ja mit "time" . Hab folgendes mal in der init.sqf versucht:

_time = time;
_query = format["INSERT INTO test_1 (Zeit) VALUES('%1'), _time];

Brachte jedoch kein Ergebnis

Edit: In der examples.ini gibt es außerdem diese Einträge:
; --------------------------------------------------------------------------------
; PLAYER SAVING
; --------------------------------------------------------------------------------

[checkPlayerSave]
SQL1_1 = SELECT IF ((SELECT 1 FROM PlayerSave WHERE PlayerUID = ? AND MapID = ?), 'true', 'false');

Number of Inputs = 2
SQL1_INPUTS = 1,2

[getPlayerSave]
SQL1_1 = SELECT $CUSTOM_1$ FROM PlayerSave WHERE PlayerUID = ? AND MapID = ?;

Number of Inputs = 2
Number of Custom Inputs = 1
SQL1_INPUTS = 1,2

[getPlayerBankMoney]
SQL1_1 = SELECT BankMoney FROM PlayerInfo WHERE UID = ?;

Number of Inputs = 1
SQL1_INPUTS = 1

[insertOrUpdatePlayerInfo]
SQL1_1 = INSERT INTO PlayerInfo SET UID = ?, BattlEyeGUID = REPLACE(?, '"', ''), $CUSTOM_1$
SQL1_2 = ON DUPLICATE KEY UPDATE $CUSTOM_2$;

Number of Inputs = 1
Number of Custom Inputs = 2
SQL1_INPUTS = 1,1-STRING-BEGUID

[insertOrUpdatePlayerSave]
SQL1_1 = INSERT INTO PlayerSave SET PlayerUID = ?, MapID = ?, CreationDate = NOW(), $CUSTOM_1$
SQL1_2 = ON DUPLICATE KEY UPDATE $CUSTOM_2$;

Number of Inputs = 2
Number of Custom Inputs = 2
SQL1_INPUTS = 1,2

[deletePlayerSave]
SQL1_1 = DELETE FROM PlayerSave WHERE PlayerUID = ? AND MapID = ?;

Number of Inputs = 2
SQL1_INPUTS = 1,2

[insertOrUpdatePlayerStats]
SQL1_1 = INSERT INTO PlayerStats SET PlayerUID = ?, $CUSTOM_1$ = $CUSTOM_2$
SQL1_2 = ON DUPLICATE KEY UPDATE $CUSTOM_1$ = $CUSTOM_1$ + $CUSTOM_2$;
SQL2_1 = INSERT INTO PlayerStatsMap SET PlayerUID = ?, ServerID = ?, MapID = ?, $CUSTOM_1$ = $CUSTOM_2$
SQL2_2 = ON DUPLICATE KEY UPDATE $CUSTOM_1$ = $CUSTOM_1$ + $CUSTOM_2$;

Number of Inputs = 3
Number of Custom Inputs = 2
SQL1_INPUTS = 1
SQL2_INPUTS = 1,2,3


Das ist natürlich schön und gut, aber ich hab keine Ahnung wie ich diese Befehle auf meinem Server zum laufen bekomme... :D

Buliwyf
04.05.2015, 18:53
_query = format["INSERT INTO test_1 (Zeit) VALUES('%1'), _time];

...fehlt ja auch 'n "Gänsefüsschen"... :D

Nokman
04.05.2015, 18:54
du verwechselst mir jetzt aber nicht extdb2 mit extdb1 Altis Life sofern nicht Verändert läuft auf extdb1.

Ich habe es soweit umgeschrieben damit es ein Hc client mit der Datenbank redet in Extdb2:
Extdb2 arbeitet mit Config datein welche vordefiniert sind Macht ein schnelleres Arbeiten da er Arma extern die Befehle hat.

Zum starten und Connecten mit der Datenbank


_database = "DB";
_protocol = "SQL_CUSTOM";
_protocol_options = "hc_config";
_return = false;

if ( isNil {uiNamespace getVariable "extDB_SQL_CUSTOM_ID"}) then
{
_result = "extDB2" callExtension "9:VERSION";
diag_log format ["extDB2: Version: %1", _result];
if(_result == "") exitWith {diag_log "extDB2: Failed to Load"; false};
_result = call compile ("extDB2" callExtension format["9:ADD_DATABASE:DB", _database]);
if (_result select 0 isEqualTo 0) exitWith {diag_log format ["extDB2: Error Database: %1", _result]; false};
diag_log "extDB2: Connected to Database";
_random_number = round(random(999999));
_extDB_SQL_CUSTOM_ID = str(_random_number);
extDB_SQL_CUSTOM_ID = compileFinal _extDB_SQL_CUSTOM_ID;
_result = call compile ("extDB2" callExtension format["9:ADD_DATABASE_PROTOCOL:%1:%2:%3:%4", _database, _protocol, _extDB_SQL_CUSTOM_ID, _protocol_options]);
if ((_result select 0) isEqualTo 0) exitWith {diag_log format ["extDB2: Error Database Setup: %1", _result]; false};
diag_log format ["extDB2: Initalized %1 Protocol", _protocol];
"extDB2" callExtension "9:LOCK";
diag_log "extDB2: Locked";
uiNamespace setVariable ["extDB_SQL_CUSTOM_ID", _extDB_SQL_CUSTOM_ID];
_return = true;
}
else
{
extDB_SQL_CUSTOM_ID = compileFinal str(uiNamespace getVariable "extDB_SQL_CUSTOM_ID");
diag_log "extDB2: Already Setup";
_return = true;
};

Der Befehl zum Eintragen in die DB Wobei zu Beachten ist 1 ist der eintrag ohne Rückantwort ausleisen ist etwas schwerer da er dann erst eine nummer zurückschickt welche man callen muss.

_query = format["insertTime:%1",time];
"extDB2" callExtension format["1:%1:%2", (call extDB_SQL_CUSTOM_ID), _query];


Und dann der Entsprechende eintrag in der Config welche am anfang geladen wurde.
hc_config.ini
;;_________________________________
[insertGang]
SQL1_1 = INSERT INTO test (time)
SQL1_2 = VALUES(?);
SQL1_INPUTS = 1
Number of Inputs = 1
;;_________________________________

Arconymous
04.05.2015, 19:15
Okay ich hab jetzt folgendes gemacht:

1. In der init.sqf die Datei scripts\mysql\dbconnect.sqf ausgeführt, in der dein erster Code ist.
2. Anschließend die Datei scripts\mysql\dbsavetime.sqf erstellt und deinen zweiten Code eingetragen.
3. die Datei scripts\mysql\hc-config.ini erstellt und den letzten code eingetragen.

Wenn ich nun den Server starte, bekomme ich die Fehlermeldung:
20:10:09 "extDB2: Version: 50"
20:10:09 "extDB2: Error Database: [0,"No Config Option Found"]"

Edit: Okay ich hab herausgefunden, dass ich den Name des Abschnittes ändern muss:
[MySQL_Example] <- Das muss geändert werden
Type = MySQL
Name = arma

Username = root
Password = *********
IP = 127.0.0.1
Port = 3306

minSessions = 2
;maxSessions = 4
idleTime = 60

compress = false
; Should only use this if MySQL server is external. Also only for MySQL

Secure Auth = false
; Recommend you turn this on


Doch woher weiß ich, welchen Namen ich dort angeben muss?

Nokman
04.05.2015, 21:41
[MySQL_Example] <- Das muss geändert werden
_database = "DB";

mit dem Defninierste den namen und so muss er in der Config stehen.

[DB] <- Das muss geändert werden
_database = "DB";

Oder

[MySQL_Example] <- Das muss geändert werden
_database = "MySQL_Example";

Arconymous
29.08.2015, 04:57
Guten Morgen zusammen,

nachdem ich die Nacht damit verbracht habe, das Speichern zum Laufen zu bekommen, da ich in letzter Zeit überhaupt keine Zeit dafür hatte, bin ich wieder einmal am verzweifeln. Also stand der Dinge ist folgender:
Ich bekomme eine Verbindung zur Datenbank und die Configs können auch gelesen werden, jedoch wird das Protokoll nicht geladen. Hier meine Files und meine Ordnerstruktur:

@mymod\addons\mymod.pbo\scripts\mysql\dbconnect.sq f

private["_database","_protocol","_protocol_options","_return","_result","_random_number","_extDB_SQL_CUSTOM_ID"];

_database = "db";
_protocol = "SQL_CUSTOM_V2";
_protocol_options = "db-config.ini";
_return = false;

if ( isNil {uiNamespace getVariable "extDB_SQL_CUSTOM_ID"}) then
{
// extDB Version
_result = "extDB2" callExtension "9:VERSION";

diag_log format ["extDB2: Version: %1", _result];
if(_result == "") exitWith {diag_log "extDB2: Failed to Load"; false};
//if ((parseNumber _result) < 20) exitWith {diag_log "Error: extDB version 20 or Higher Required";};

// extDB Connect to Database
_result = call compile ("extDB2" callExtension format["9:ADD_DATABASE:%1", _database]);
if (_result select 0 isEqualTo 0) exitWith {diag_log format ["extDB2: Error Database: %1", _result]; false};
diag_log "extDB2: Connected to Database";

// Generate Randomized Protocol Name
_random_number = round(random(999999));
_extDB_SQL_CUSTOM_ID = str(_random_number);
extDB_SQL_CUSTOM_ID = compileFinal _extDB_SQL_CUSTOM_ID;

// extDB Load Protocol
_result = call compile ("extDB2" callExtension format["9:ADD_DATABASE_PROTOCOL:%1:%2:%3:%4", _database, _protocol, _extDB_SQL_CUSTOM_ID, _protocol_options]);
if ((_result select 0) isEqualTo 0) exitWith {diag_log format ["extDB2: Error Database Setup: %1", _result]; false};

diag_log format ["extDB2: Initalized %1 Protocol", _protocol];

// extDB2 Lock
"extDB2" callExtension "9:LOCK";
diag_log "extDB2: Locked";

// Save Randomized ID
uiNamespace setVariable ["extDB_SQL_CUSTOM_ID", _extDB_SQL_CUSTOM_ID];
_return = true;
}
else
{
extDB_SQL_CUSTOM_ID = compileFinal str(uiNamespace getVariable "extDB_SQL_CUSTOM_ID");
diag_log "extDB2: Already Setup";
_return = true;
};

_returnHab hier den Beispielcode von Torndeco benutzt, da der Code von Nokman genau die gleiche Fehlermeldung ausgespuckt hat.


@mymod\addons\mymod.pbo\scripts\mysql\db-config.ini
[Default]
Version = 10

Number of Inputs = 0

;;Sanitize Checks are better than Strip Characters, but only accept ASCII Characters
;;Requires abit more work to setup correctly.
Sanitize Input Value Check = false
Sanitize Output Value Check = false

;;Allows you to disable Prepared Statement Caching.
;;Mainly for people that don't want to waste memory on caching a Statement that is only once.
Prepared Statement Cache = true

;;Returns InsertID, Instead of returning [1,[]] It returns [1,[<INSERTID>,[]]]
Return InsertID = false

;;Strip Characters
Strip = true
;;Possible Actions Are "Strip" / "Strip+Log" / "Strip+Error" / "None"
Strip Chars Action = STRIP
Strip Chars = /\|;{}<>'`
;;Strip Chars Used for $CUSTOM_x$ Inputs
Strip Custom Chars = /\|;{}<>'`


; --------------------------------------------------------------------------------
; SQL Statements
; --------------------------------------------------------------------------------

[existPlayerInfo]
;; Name of call == existPlayerInfo
SQL1_1 = SELECT CASE
SQL1_2 = WHEN EXISTS(SELECT * FROM PlayerInfo WHERE UID = ?)
SQL1_3 = THEN 'true' ELSE 'false'
SQL1_4 = END
SQL1_INPUTS = 1

Number of Inputs = 1

;;SQL Statements can be split up into multiple lines to make more readable.
;; You can also run multiple SQL Statements via SQL2_1, SQL2_2, SQL3_1 etc..


[updatePlayerSaveValueString]
SQL1_1 = UPDATE PlayerSave
SQL1_2 = SET $CUSTOM_1$ = ?
SQL1_3 = WHERE PlayerUID = ? AND MapID = ?;
SQL1_INPUTS = 3, 1, 2

Number of Inputs = 3
Number of Custom Inputs = 1

;;$CUSTOM_x$ allows you to insert dynamic text into an prepared statement.
;;Downside is the statement isn't cached + possible less secure.

;;Note the order of passing inputs to extDB2 is important with custom inputs.
;; Its <inputs>:<custom_inputs>
;; So the inputs would be in this order _playerUID:_mapID:_value:_custom_1

;;Also you can re-arrange the Input Value Order


[gangInfo]
SQL1_1 = SELECT id, owner, name, maxmembers, bank, members FROM gangs WHERE active='1' AND members LIKE ?;
SQL1_INPUTS = 1

Number of Inputs = 1
OUTPUT = 1, 2-String, 3-String, 4, 5, 6

;;You can also define options for Output Value aswell if you like aswell i.e 1-STRING-BEGUID
;;Or do mixture of using INPUTS + OUTPUT Options.

Diese Datei ist auch eine Sampledatei von Torndeco.

Die Logs sagen immer, dass das Protokol nicht geladen werden kann:
extDB2: Version: 65
extDB2: https://github.com/Torndeco/extDB2
extDB2: Windows Debug Version

Message: All development for extDB2 is done on a Linux Dedicated Server
Message: If you would like to Donate to extDB2 Development
Message: https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=2SUEFTGABTAM2
Message: Also leave a message if there is any particular feature you would like to see added.
Message: Thanks for all the people that have donated.
Message: Torndeco: 20/02/15


extDB2: Found extdb-conf.ini
extDB2: Detected 8 Cores, Setting up 6 Worker Threads


[05:43:21:932451 +02:00] [Thread 5416] extDB2: Input from Server: 9:VERSION
[05:43:21:932451 +02:00] [Thread 5416] extDB2: Output to Server: 65
[05:43:21:932957 +02:00] [Thread 5416] extDB2: Input from Server: 9:ADD_DATABASE:db
[05:43:21:932957 +02:00] [Thread 5416] extDB2: Database Type: MySQL
[05:43:21:936951 +02:00] [Thread 5416] extDB2: Database Session Pool Started
[05:43:21:936951 +02:00] [Thread 5416] extDB2: Output to Server: [1]
[05:43:21:936951 +02:00] [Thread 5416] extDB2: Input from Server: 9:ADD_DATABASE_PROTOCOL:db:SQL_CUSTOM_V2:246508:db-config.ini
[05:43:21:937452 +02:00] [Thread 5416] extDB2: Failed to Load Protocol: SQL_CUSTOM_V2
[05:43:21:937452 +02:00] [Thread 5416] extDB2: Output to Server: [0,"Failed to Load Protocol"]
[05:48:20:627331 +02:00] [Thread 5416] extDB2: Stopping ...
Ich hoffe, dass es hier nette Menschen gibt, die mir bei meinem Problem, auch nach 4 monatiger Pause immernoch helfen wollen...

Viel Dank schonmal,
Arconymous

Nokman
05.09.2015, 14:41
[05:43:21:936951 +02:00] [Thread 5416] extDB2: Input from Server: 9:ADD_DATABASE_PROTOCOL:db:SQL_CUSTOM_V2:246508:db-config.ini
_protocol_options = "db-config.ini";
sollte doch
_protocol_options = "db-config";

heisen. Habe mit der sql_custom_v2 aber keine erfahrung da ich an der ersten noch bin

Gerrit vonundzu
13.11.2015, 15:41
Guten Arbend
Ich habe mir grade euche Beiträge durchgelesen habe, aber habe folgen Problem:

[16:266 +010] [Thread 2675] extDB2: Error Invalid Format: 9ATABASEatabase2

kennt jemand die Lösung??

Arconymous
13.03.2016, 01:52
Hallo zusammen,

nach langer Zeit habe ich wieder Zeit gefunden weiter zu arbeiten. Danke an @Nokman für die große Hilfe! Es hat nun endlich geklappt. :daumen: Ich kann Einträge in die Datenbank speichern und wieder abrufen.

Momentan habe ich jedoch ein weiteres Problemchen. Ich speicher die Koordinaten des Charakters in die Datenbank, update sie und will sie dann wieder verwenden. Zunächst einmal die Einstellungen der Datenbank. Es existiert die Tabelle players in der folgende Spalten gespeichert sind:

Spaltenname - Datentyp
name - TEXT
pos_x - DOUBLE
pos_y - DOUBLE
pos_z - DOUBLE

Jetzt meine .ini


[newPlayer]
SQL1_1 = INSERT INTO
SQL1_2 = players (name, pos_x, pos_y, pos_z)
SQL1_3 = VALUES
SQL1_4 = (?,?,?,?)

SQL1_INPUTS = 1,2,3,4
Number of Inputs = 4

[updatePlayer]
SQL1_1 = UPDATE
SQL1_2 = players
SQL1_3 = SET
SQL1_4 = pos_x = ?,
SQL1_5 = pos_y = ?,
SQL1_6 = pos_z = ?
SQL1_7 = WHERE
SQL1_8 = name = ?
SQL1_9 = LIMIT 1
SQL1_INPUTS = 1,2,3,4
Number of Inputs = 4


[loadPlayer]
SQL1_1 = SELECT
SQL1_2 = pos_x,
SQL1_3 = pos_y,
SQL1_4 = pos_z
SQL1_5 = FROM
SQL1_6 = players
SQL1_7 = WHERE
SQL1_8 = name = ?
SQL1_9 = LIMIT 1
SQL1_INPUTS = 1
Number of Inputs = 1


und nun nochmal die 3 Dateien die ich über AddAction ausführe:

create.sqf
//NewPlayer
_name = getPlayerUID player;
_pos_x = getPos player select 0;
_pos_y = getPos player select 1;
_pos_z = getPos player select 2;

hint str(_pos_x);
sleep 2;
hint str(_pos_y);
sleep 2;
hint str(_pos_z);
sleep 2;

hint "Save to DB!";
"extDB2" callExtension format["1:%1:newPlayer:%2:%3:%4:%5", (call extDB_SQL_CUSTOM_ID), _name, _pos_x, _pos_y, _pos_z];


save.sqf
//UpdatePlayer
_name = getPlayerUID player;
_pos_x = getPos player select 0;
_pos_y = getPos player select 1;
_pos_z = getPos player select 2;

hint str(_pos_x);
sleep 2;
hint str(_pos_y);
sleep 2;
hint str(_pos_z);
sleep 2;

hint "Save to DB!";
"extDB2" callExtension format["1:%1:updatePlayer:%2:%3:%4:%5", (call extDB_SQL_CUSTOM_ID), _pos_x, _pos_y, _pos_z, _name];


Und zu guter letzt die load.sqf
_name = getPlayerUID player;

_return = "extDB2" callExtension format["0:%1:loadPlayer:%2", (call extDB_SQL_CUSTOM_ID), _name];

hint str(_return);

/*if (typeName _return == "STRING") then {
hint "true";
};
*/

Bei der letzten Datei habe ich das Problem, dass wenn ich

callExtension format["0:%1:loadPlayer:%2"

habe, keinen Array zurückbekomme, sondern nur einen String, den ich nicht als Koordinaten für meinen Character verarbeiten kann.

"[1,[[11827.1,12736.7,0.00143433]]]"

Mit einer 1:
""

Mit einer 2:
"[2,"103"]"

Mit 4 und 5:
"[0,"Error"]"

https://github.com/Torndeco/extDB2/wiki/Calls:-General-Info

Exakt das Gleiche passierte, als ich die Koordinaten nicht in X,Y,Z aufgeteilt habe, sondern sie als ganzes gespeichert habe.

Kann mir jemand bei diesem Problem weiterhelfen?

Danke für jede Hilfe! :)

Edit:
Alles Gute nachträglich, Nokman!

Arconymous
13.03.2016, 12:19
Bin etwas weiter gekommen. Hab mittels
splitString
ein Array erstellen können, welches die Positionen beinhaltet. Nun habe ich die Koordinaten in der folgenden Form:
["1","11823.8","12729.6","0.00143433"]
Anschließend die 1 am Anfang entfernt:
["11823.8","12729.6","0.00143433"]
Danach die einzelnen Koordinaten herausgefischt:

_cx = _myarraylist select 0;
_cy = _myarraylist select 1;
_cz = _myarraylist select 2;
Und nun versucht, den Spieler zu den Koordinaten zu teleportieren:

player setpos [_cx, _cy, _cz];
Bekomme aber immer nur den Fehler "Typ Zeichenfolge, erwartet Zahl"...

Was mache ich hier falsch und wie muss man es richtig machen?

Edit:
Folgendes funktioniert:
_array = format["%1,%2,%3",_cx, _cy, _cz];

_endarray = format["[%1]", _array];

copyToClipboard _endarray;

hint _endarray;

player setpos [11823.8,12729.6,0.00143433];

Wenn ich jetzt aber player setpos [11823.8,12729.6,0.00143433];

Mit
_endarray;
austausche, klappt es nichtmehr.

Edit:
Es klappt endlich.
_name = getPlayerUID player;
_return = "extDB2" callExtension format["0:%1:loadPlayer:%2", (call extDB_SQL_CUSTOM_ID), _name];
_test = _return splitString ",[]";
_myarraylist = _test - ["1"];
_cx = _myarraylist select 0;
_cy = _myarraylist select 1;
_cz = _myarraylist select 2;
_coordx = parseNumber _cx;
_coordy = parseNumber _cy;
_coordz = parseNumber _cz;
player setpos [_coordx, _coordy, _coordz];

Nokman
13.03.2016, 18:48
auch eine möglichkeit. ansonsten kanst dud en string mit
call compile STRING
ihn ausführbar machen.

compile wandelt den String in einen Code um und mit call kanst du ihn aufrufen.