Desweiteren ist es zu erwähnen, dass man bei dbQuery IMMER mit einer Callback Funktion arbeiten sollte. Auf FFS Gaming gab es da schon viele Probleme was dies angeht da bei uns zich Querys gleichzeitig laufen.
- LuXorioN
Desweiteren ist es zu erwähnen, dass man bei dbQuery IMMER mit einer Callback Funktion arbeiten sollte. Auf FFS Gaming gab es da schon viele Probleme was dies angeht da bei uns zich Querys gleichzeitig laufen.
- LuXorioN
Hey, dbPoll gibt dir, falls die Abfrage erfolgreich war, eine Tabelle zurück. Daher kannst du so nicht direkt auf result zugreifen bzw es mit einer anderen Variable abgleichen.
Wie schon erwähnt, handelt es sich bei dbPoll um eine Tabelle in der es MEHRERE Einträge geben kann.
Da du aber 1 oder mehrere Einträge zurückbekommen kannst (Beispielsweise wenn mehrere Accounts mit der gleichen Serial existieren).
Zudem weiß ich nicht, was du mit deiner Variante vor hast, aber so ergibt deine Abfrage wenig bis gar keinen Sinn da du den Login über ein Befehl beziehungsweise einem GUI lösen könntest.
Desweiteren macht es keinen Sinn, die Einträge mit der Serial erneut zu vergleichen wenn du diese sowieso schon via dbQuery filterst.
Auf die Einträge in der Tabelle kannst du mit einer for-Schleife beziehungsweise mit einem direkten Index Eintrag aufrufen.
// EDIT: Du solltest aufjendefall darauf achten, deine Querys zu sichern wie beispielsweise im obigem Codebeispiel. Andernfalls kann es bei Usereingaben zu Problemen kommen - #SQL Injection
- LuXorioN
Ich markiere jz jemanden der sich richtig gut damit auskennt
Und Ihr wundert euch, dass die User hier in diesem Forum so dumm sind ? Wenn selbst die Administration nicht einmal lesen kann, was im vorherigem Beitrag geschrieben worden ist UND TROTZDEM einen unnötigen Kommentar abgeben muss ?Tolle Leistung mta-sa.org Team, tolle Leistung!
Hey, IPS (Invision Power Board) läuft über eine eigene SMTP Klasse weshalb ich dies so realisieren muss.
Der obige Code "Schnipsel" dient nur als Debug um der Sache auf dem Grund zu gehen.
Als Stream Sockets stehen folgende Protokolle zur Auswahl (falls es hilft): tcp, udp, unix, udg, ssl, tls, tlsv1.0, tlsv1.1, tlsv1.2
//EDIT: Hat sich erledigt. Anstatt via TLS bin ich direkt via TCP drauf und hab den Befehl "STARTTLS" ausgeführt.
Danke trotzdem für die Hilfe
- LuXorioN
Servus,
seit ein paar Tagen beschäftigt mich ein Problem und ich kann ihn bislang noch immer nicht lösen.
Wenn ich eine Socket-Verbindung herstellen möchte mittels TLS, haut mir PHP (7.2-fpm, 5.6-fpm, 7.0-fpm) die folgende Fehlermeldung heraus:
Wenn ich allerdings eine E-Mail über dem root versende (telnet) funktioniert alles.
Es scheint so, als würde PHP versuchen, sich via SSL zu verbinden anstatt mit TLS.
Hat dort vielleicht einer nähere Informationen, wie man dieses Problem umgehen kann ?
Google haut hier leider nichts informatives heraus.
- LuXorioN
<?php
ini_set("display_errors", true);
ini_set("display_startup_errors", true);
error_reporting(E_ALL);
$socket = fsockopen("tls://localhost", 587, $errorCode, $errorMessage);
?>
Warning: fsockopen(): SSL operation failed with code 1. OpenSSL Error messages: error:140770FC:SSL routines:SSL23_GET_SERVER_HELLO:unknown protocol in /htdocs/test.php on line 7
Warning: fsockopen(): Failed to enable crypto in /htdocs/test.php on line 7
Warning: fsockopen(): unable to connect to tls://localhost:587 (Unknown error) in /htdocs/test.php on line 7
Informationen zum Betriebssystem:
Linux version 4.15.0-10-generic (buildd@lgw01-amd64-036) (gcc version 7.3.0 (Ubuntu 7.3.0-3ubuntu1)) #11-Ubuntu SMP Tue
Feb 13 18:23:35 UTC 2018
Distributor ID: Ubuntu
Description: Ubuntu Bionic Beaver (development branch)
Release: 18.04
Codename: bionic
Servus, besitzt du den nötigen Shell Zugriff auf dem vServer / Root Server ?
Ich rate im generellemn dazu, phpseclib zu verwenden: https://github.com/phpseclib/phpseclib
Falls du heute nachmittag noch immer Hilfe benötigst, kannst du mich gerne in Skype anschreiben.
LuXorioN
Servus,
1. Zu deiner Datenbank Query
local serialcheck = dbQuery(handler, "SELECT * FROM bans WHERE bserial=?", serial )
local ipcheck = dbQuery(handler, "SELECT * FROM bans WHERE bip=?", ip)
Warum 2 Abfragen wenn eine reicht und besser ist ?
SELECT * FROM `bans` WHERE `bserial` = ? OR bip = ?;
2. Was steht in der Konsole drinne ? Es kann sein, dass die Abfrage zu lange gedauert hat und er deshalb die Verbindung nicht zulässt. Was passiert, wenn du die ganzen Abfragen weg lässt und einfach mal cancelEvent(true, "Nope"); nutzt ? Falls das funktioniert, dauert die Abfrage zu lange.
- LuXorioN
Hey, wenn du Daten Abfragen willst bzw die zuletzt eingetragene ID (Last Inserted Id - AUTO_INCREMENT (A_I)), nutz dbQuery in zusammenhang mit dbPoll, dbFree. Falls du eine große Datenbank hast, oder viele Querys aufeinmal laufen, kann es sein, dass sich der Server aufhängt (Network Trouble) bis alle Querys abgearbeitet worden sind. Hierfür würde ich dir raten um z.B Accounts zu laden, Fahrzeuge zu spawnen, ... mit einem Query-Callback zu arbeiten.
Achte aber darauf, dass du den Handler vom query (dbQuery) wieder frei gibst mit dbFree.
Solltest du vor haben, Daten zu speichern (sprich UPDATE `tabelle` SET `column1` = ?, ... WHERE `column` = ?), nutz nur dbExec.
Solltest du weitere Fragen hast, schreib mich einfach an
-- ******************************************************************************************************************************** --
g_uDatabaseConnection = dbConnect(...);
g_tblAccountInfos = {};
-- ******************************************************************************************************************************** --
-- Beispiel: Daten aus einer Datenbank laden über einem Callback
function loadAccountDataCallback(uQueryHandle, uPlayer, iAccountID)
-- Der Spieler hat den Server verlasen, bevor die Daten geladen wurden.
-- iAccountID muss nicht nochmal validiert werden da wir sie unten schon abgefragt haben.
if(not uPlayer or not isElement(uPlayer)) then
return;
end
local result = dbPoll(uQueryHandle);
-- dbPoll kann false zurückgeben bzw eine leere Tabelle falls keine Einträge gefunden wurden.
if(result and #result == 1) then
result = result[1];
-- Falls du bestimmte Operationen durchführen musst, kannst du das wie hier z.B tun
result["SpawnPosition"] = fromJSON(result["SpawnPosition"]);
-- Lade alle Account Daten
g_tblAccountInfos[uPlayer] = result;
end
end
function loadAccountData(uPlayer, iAccountID)
-- Validierung der Variablen
if(not uPlayer or not isElement(uPlayer) or type(iAccountID) ~= "number") then
outputDebugString("Invalid arguments provided @ loadAccountData");
return;
end
-- Führe die Query aus mit einem Callback
dbQuery(loadAccountDataCallback, {uPlayer, iAccountID}, g_uDatabaseConnection, "SELECT * FROM `accounts` WHERE `ID` = ? LIMIT 1;", iAccountID);
end
-- ******************************************************************************************************************************** --
-- Beispiel: Daten speichern
addEventHandler("onPlayerQuit", root, function()
if(g_tblAccountInfos[source]) then
local tblFields = g_tblAccountInfos[source];
local strQuery = "UPDATE `accounts` SET ";
local tblArguments = {};
-- Achte immer darauf, dass du die Variablen der Spieler wieder löschst, ansonsten kann es Memory Leaks geben.
g_tblAccountInfos[source] = nil;
for strField, value in pairs(tblField) do
-- Die Account ID sollte sich nie ändern dürfen.
if(strField ~= "ID") then
-- Tabellen müssen grundsätzlich konvertiert werden, hier geschieht das via JSON Strings
if(type(value) == "table") then
value = toJSON(value);
end
strQuery = strQuery .. "`" .. strField .. "` = ?, ";
table.insert(tblArguments, value);
end
end
-- Entferne ", " aus dem String
strQuery = strQuery:sub(-2);
-- Füge WHERE Statement hinzu
strQuery = strQuery " WHERE `ID` = ?;";
table.insert(tblArguments, tblField["ID"]);
-- update
dbExec(g_uDatabaseConnection, strQuery, unpack(tblArguments));
end
end);
-- ******************************************************************************************************************************** --
Alles anzeigen
WARNUNG: Bei diesem Beispiel kommt es zu SQL Fehlern, falls eine neue Tabellen Spalte hinzugefügt worden ist - Achte darauf, dass du keine Einträge hast, die nicht in der Tabellenstruktur sind.
Mit freundlichem Gruß
LuXorioN
Und der /rban Befehl ?
Du gehst auf das </> Symbol, wählst bei Syntax Highlighting Lua aus und fügst den Text / Code unten ein.
LuXorioN
Wie wäre es den, wenn du uns einmal den Timeban Befehl schicken könntest. Wir können nicht hellsehen. Das nächste mal sei bitte so lieb und denk bitte selbstständig daran anstatt danach zu Fragen. Wir können jetzt nur vermuten, was es sein könnte.
LuXorioN
Servus, ich bin auch ehr dagegen, dass es Vorlagen gibt. Zum einem würden sie (wie von Corbert erwähnt) nur gecopypasted und das würde nicht gut ausgehen. Jeder Beitrag wäre zu 70% der selbe. Projekte, die wirklich einen guten und profesionellen Scripter / Entwickler suchen, finde diese auch ohne Beiträge.
Nehmen wir jetzt einfach mal an, der Vorschlag würde akzeptiert werden und das Plugin würde installiert werden: Was denkst du würde sich verbessern ? Richtig, gar nichts. Viele Leute suchen Scripter auf VIO Basis (egal ob Ultimate, Extended, Lite, ...) und in diesen Projekten sind zu 80% nur kleine Kinder die denken, dass sie etwas mit einem VIO Server erreichen könnten. Hiermit ist natürlich die reife, sowie der Umgang mit der Community zu sehen. Oftmals kann man dies bekanntlich an der Art und Weise, wie jemand schreibt, erkennen.
Wo würde das noch hinführen ? Viele Leute würden sich kaum bis gar nicht darum kümmern, was in dem Beiträgen steht da die Thread Ersteller diese nicht ernst nehmen oder viel zu wenig Infos zum Projekt preisgeben. Selbst wenn es eine solche Vorlage gäbe denk ich nicht, dass sich viele Leute daran halten würden.
Mit freundlichem Gruß
LuXorioN
Es waren nicht nur zahlreiche Backdoors im Kernel sowie anderen Stellen. Der besagt hatte sich eine PHP Datei hochgeladen (wahrscheinlich über Plugin hooks / applications) womit er eine shell console vom www-data Benutzer aufrufen konnte. Das Problem sollte behoben sein.
Mit freundlichem Gruß
Bienen und Schildkröten GmbH
Schreib mich via CChat bzw Skype an.
LuXorioN
Hier ist eine etwas bessere Möglichkeit, die ich in meiner devtools Resource habe:
addCommandHandler("getpos", function(strCMD, ...)
local strComent = table.concat({...}, ' ');
local uVehicle = getPedOccupiedVehicle(localPlayer);
local iX, iY, iZ = getElementPosition((uVehicle or localPlayer));
local iRotX, iRotY, iRotZ = getElementRotation((uVehicle or localPlayer));
local strClipBoardText = false;
-- player inside vehicle
if(uVehicle) then
strClipBoardText = ("%.02f, %.02f, %.02f, %.02f, %.02f, %.02f"):format(iX, iY, iZ, iRotX, iRotY, iRotZ);
else
strClipBoardText = ("%.02f, %.02f, %.02f, %.02f"):format(iX, iY, iZ, iRotZ);
end
-- add comment when there was one specified
if(strComent:sub(' ', ''):len() >= 2)
strClipBoardText = strClipBoardText .. " -- " .. strComent;
end
if(setClipboard(strClipBoardText)) then
outputChatBox("Positions successfully copied into clipboard!");
end
-- den part hier kannst du wahrscheinlich löschen esseiden du willst soeine logging Funktion verwenden
if(g_bLogging) then
outputToFile("positions.txt", strClipBoardText);
end
end);
Alles anzeigen
Falls du Hilfe bei deinem Sweeper brauchst und es nicht VIO ist, kannst du dich bei mir via PM oder in Skype melden.
- LuXorioN
Kommentier mich nicht immer bei VIO Dingen. Ich gebe kein VIO Support und das weißt du auch.
Mit freundlichem Gruß
LuXorioN
Ich habe dir eine Nachricht via Konversation geschickt. Das Problem ist, dass ein Prozess den Port benutzt. Das Problem mit der Datenbank ist die, dass der Benutzer, worauf der MTA Server Prozess läuft, keine Berechitgung hat, diese Datei zu öffnen bzw zu beschreiben.
Mit freundlichem Gruß
LuXorioN
Servus, wenn du in einer XML Datei ein Funktionsname speicherst, kannst du diese auch aufrufen lassen:
function testFunction()
outputDebugString("called by string reference");
end
local strFunctionName = "testFunction";
-- überprüfe, ob die Funktion existiert
if(type(_G[strFunctionName]) == "function") then
-- rufe die Funktion auf (in den Klammern kannst du ebenfalls wie gewohnt deine Argumente übergeben).
_G[strFunctionName]();
end
Alles anzeigen
Falls weitere Fragen auftauchen sollten, kannst du mich gerne kontaktieren.
Mit freundlichem Gruß
LuXorioN
Kleine Anmerkung von mir: Warum brauchst du soetwas ? Selbst wenn jemand eine compilierte Version deines Scripts besitzt, könnte er die Abfrage ziemlich leicht umgehen. In diesem Sinne ist soeine Abfrage reiner Müll und Zeitverschwendung.
Mit freundlichem Gruß
LuXorioN