AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Netzwerke Delphi Query an Gameserver

Query an Gameserver

Ein Thema von Flodding · begonnen am 18. Feb 2015 · letzter Beitrag vom 1. Nov 2015
Antwort Antwort
Seite 1 von 12  1 2311     Letzte » 
Flodding

Registriert seit: 26. Dez 2007
Ort: Kiel
121 Beiträge
 
Turbo Delphi für Win32
 
#1

Query an Gameserver

  Alt 18. Feb 2015, 10:17
Hallo guten Morgen

Ich bastel seit ein paar Tagen an einem Launcher/Joiner für meinen Gameserver (Arma2 - Dayz).
Dieser kann erkennen ob die richtigen Mods in der richtigern Version vorliegen und kann bei bedarf auch korrupte oder neue Dateien anfordern und Downloaden.

Jetzt möchte ich im Launcher auch noch gerne anzeigen Lassen wie viele Spieler sich aktuell auf dem Server befinden. Eventuell auch die Spielernamen; ist aber nicht so wichtig.
Aktuell regel ich das über ein PHP-Query-Script, da ich dies als fertige Lösung gefunden habe.

Quelle: https://github.com/xPaw/PHP-Source-Query-Class

Hier ein Link zum bereits konfigurierten Script:
http://last-templers.de/a2epoch/query/query.php

Jedoch möchte ich mit meinem Launcher nicht erst Text aus einer von PHP erstellten Seite auslesen und ihn dann anzeigen. Das kann ja auch direkt geschehen.

Zum Thema Delphi & Query an Source Server habe ich schon einiges gefunden, jedoch stoße ich an einem Punkt an meine Grenzen.
Es gibt ein Beispielprojekt, welches aufzeigt, wie ein Query an einen Source Server gesendet wird und empfangene Daten ausliest.

Quelle: http://www.planet-source-code.com/vb...=2022&lngWId=7

Dies Funktioniert auch ganz gut wenn man den Server und Port angibt.
In meinem Fall wäre das IP:5.45.97.44 Port:2301

Wer sich das Projekt nicht erst laden möchte ums selber auszuprobieren... hier die Ausgabe:

Code:
ÿÿÿÿI[L-T-S] Epoch Origins (1.0.5.1/125548)Taviarma2arrowpcDayZ Epoch Origins&#352;&#8222;dw1.63.125548±þ   `7'X@bt,r163,n125548,s7,i1,mf,lf,vf,dt,tcoop,g65545,c2147483647-2147483647,pw,&#352;&#8222;&#382;Pÿÿÿÿ&#8230;Nbº~PP3½Àü0óÿÿÿ¸ò#¸òf/D¸òÀü0ó&#382;ÂBÀü0ójñCz'ÀüPÄñ3½Àü&#8222;óÿÿÿó#óf/DóÀü&#8222;ó&#382;ÂBÀü&#8222;ójñCz'Àü,òجq¼!8x7P7wqbj¹u<ò&#8211;q¦'&#402;Hòb¹u0Àu&#8222;ò4k¹uk¹u²aº~¦'&#402; &#8221;&#381;/}¹u&#8364;òëUÑv³' &#8221;&#381;â`¹uht¹u³'; óðû)sP³' &#8221;&#381;ÿû)soåîYøò².DÀüz'Àüz'óùJA°Y<Ba<BÀüÜ;&DX©§0wh&#8364;îþîþ
&#338;èÀü@ó"¶A$ôZ<+w
&#339;±0w$ôÎW-wÓ<+w§È¹w6&#338;P&#338;z'|óP&#338;Ðt&#338;äóm¹uP&#338;(óº
pÿÿÿÿPØû&#732;&#376;îYäõ&#732;&#376;&#338;&#352;¦0wh&#8364;îþîþ&#338;P`(Øûõ&#338;è¬0wЪ8+w&#8220;ɹw&#338;&#338;P&#732;&#376;P3½³'P&#338;&#338;P&#338;(jñC¬ô5w&#338;(à&#352;5w&#732;&#376;&#8364;&#338;&#338;P&#338;&#8222;ö(õqeW0ôÐW3whõ4õ5w&#338;&#338;ê¸*w&#338;&#338;ê¸*wxõ°5w8&#338;&#8221;5wûɹw&#338;
Das ist auch erstmal ganz okay dass das so ausgegeben wird. Jedoch kann ich keine Ausgabe der aktuellen Anzahl der Spieler bzw. das Maximum der Spieler erkennen. Und ja, der Server war nicht Spielerlos.

Weiterführende Informationen sollte ich hier bekommen:

Quelle: https://developer.valvesoftware.com/wiki/Server_queries

Das einzige was ich noch verstehe ist, dass der Header & das Paket von A2S_Info im Delphi Quellcode angegeben wurde. Laut der Informationen auf der Valve Seite sollte doch auch die Anzahl der Spieler mit ausgegeben werden.

Nun gut. ich poste nochmal den Code der das Paket senden und Empfängt:

Delphi-Quellcode:
procedure TForm4.Button1Click(Sender: TObject);
var
x: array[0..25] of byte;
y: array[0..1248] of byte;
i,ctr,r,p: integer;
servername:string;
currentmap:string;
begin
memo1.Clear;
udp1.RemotePort:= edit2.Text;
udp1.RemoteHost:= edit1.Text;
udp1.Active:= true;

// The following bytes represent the query 'TSource Engine Query'
// This can be applicable to HL1 too.

x[0]:= $FF;
x[1]:= $FF;
x[2]:= $FF;
x[3]:= $FF;
x[4]:= $54;
x[5]:= $53;
x[6]:= $6F;
x[7]:= $75;
x[8]:= $72;
x[9]:= $63;
x[10]:= $65;
x[11]:= $20;
x[12]:= $45;
x[13]:= $6E;
x[14]:= $67;
x[15]:= $69;
x[16]:= $6E;
x[17]:= $65;
x[18]:= $20;
x[19]:= $51;
x[20]:= $75;
x[21]:= $65;
x[22]:= $72;
x[23]:= $79;
x[24]:= $00;

udp1.SendBuf(x,sizeof(x));

i:= 0;
ctr:= 0;
r:= 0;
udp1.ReceiveBuf(y,sizeof(y));
  repeat
    begin
      if y[i] = $00 then
        begin
          inc(ctr);
            if ctr = 1 then r:= i;
              if ctr = 2 then
                begin
                  p:= i;
                    servername:= copy(memo1.Text,r+1,(i-r)-1);
                    lblservername.Caption:= servername;
                end;
              if ctr = 3 then
                begin
                    currentmap:= copy(memo1.Text,p,(i-p)-1);
                    lblcurrentmap.Caption:= currentmap;
                end;
        end;
      memo1.Text:= memo1.Text + chr(y[i]);
      inc(i);
    end;
  until i = 1248;
end;
Beim Kompilieren kommt bei mir die Meldung:
Die Methode udp1Receive, auf die udp1.OnReceive verweist, enthält eine inkompatible Parameterliste. Soll der Verweis entfernt werden?

Dort kann NEIN geklickt werden und das Programm tut, was es soll.

Andere Quellen verwiesen auch auf die INDY9/10 Komponenten die man verwenden kann.

Ich bin verwirrt wie ich weiter machen kann und würde mich sehr freuen wenn sich ein kundiger der Materie hier melden würde um mir zu helfen.

Danke im Voraus.

Florian
Flo

Geändert von Flodding (18. Feb 2015 um 10:28 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#2

AW: Query an Gameserver

  Alt 18. Feb 2015, 10:46
Was hast du denn für eine Ausgabe erwartet?
Zitat:
Hallo, ich bins, der Tuberkel!
Du bekommst dort eine Bytefolge, die du natürlich entsprechend entschlüsseln musst. An irgendeiner Stelle werden diese Informationen stehen. Dazu muss man aber den Kontext (Struktur/Aufbau) kennen. Ohne diesen Kontext wirst du das niemals (nur sehr schwer) herausfinden.

Stell dir vor, die senden dir als Wert 42 um mit auszudrücken, dass der Server läuft und auch ansonsten alle Fragen damit zu beantworten. Diese Information - was bedeutet 42 - muss du wissen, sonst ist es Essig mit der Information.

Also hole dir die Beschreibung zu dieser Bytefolge, damit du interpretieren kannst, was dir diese Bytes sagen wollen.
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)
  Mit Zitat antworten Zitat
BadenPower

Registriert seit: 17. Jun 2009
616 Beiträge
 
#3

AW: Query an Gameserver

  Alt 18. Feb 2015, 11:11
Beim Kompilieren kommt bei mir die Meldung:
Die Methode udp1Receive, auf die udp1.OnReceive verweist, enthält eine inkompatible Parameterliste. Soll der Verweis entfernt werden?
Was ist "udp1" für eine Komponente?
Und poste noch die Deklaration der Methode udp1Receive welche dem OnReceive zugewiesen wurde.
Programmieren ist die Kunst aus Nullen und Einsen etwas sinnvollen zu gestalten.
Der bessere Künstler ist allerdings der Anwender, denn dieser findet Fehler, welche sich der Programmierer nicht vorstellen konnte.
  Mit Zitat antworten Zitat
Flodding

Registriert seit: 26. Dez 2007
Ort: Kiel
121 Beiträge
 
Turbo Delphi für Win32
 
#4

AW: Query an Gameserver

  Alt 18. Feb 2015, 11:45
Zitat:
Du bekommst dort eine Bytefolge, die du natürlich entsprechend entschlüsseln musst. An irgendeiner Stelle werden diese Informationen stehen. Dazu muss man aber den Kontext (Struktur/Aufbau) kennen. Ohne diesen Kontext wirst du das niemals (nur sehr schwer) herausfinden.
Das ist das erste Mal, dass ich mit damit arbeite.

Ich verstehe zwar was du mir sagen möchtest mit dem entschlüsseln. Soll ich jetzt diese kryptischen Zeichen umwandeln? Warum gibt er die ersten Informationen in Klartext aus, den Rest aber nicht?

Im PHP-Script wirds ja dann auch irgendwo entschlüsselt, nur finde ich nicht wo.

Was ist "udp1" für eine Komponente?
Und poste noch die Deklaration der Methode udp1Receive welche dem OnReceive zugewiesen wurde.
udp1 ist ein TUdpSocket

Delphi-Quellcode:
procedure udp1Receive(Sender: TObject; Buf: PWideChar; var DataLen: Integer);

procedure TForm4.udp1Receive(Sender: TObject; Buf: PWideChar; var DataLen: Integer);
begin
packlen:= datalen;
end;
Flo
  Mit Zitat antworten Zitat
BadenPower

Registriert seit: 17. Jun 2009
616 Beiträge
 
#5

AW: Query an Gameserver

  Alt 18. Feb 2015, 12:13
procedure udp1Receive(Sender: TObject; Buf: PWideChar; var DataLen: Integer);
Stell das mal um und Du hast eine Fehlermeldung weniger.

procedure udp1Receive(Sender: TObject; Buf: PAnsiChar; var DataLen: Integer);
Und dann schau Dir die erhaltenen Daten noch mals an.
Programmieren ist die Kunst aus Nullen und Einsen etwas sinnvollen zu gestalten.
Der bessere Künstler ist allerdings der Anwender, denn dieser findet Fehler, welche sich der Programmierer nicht vorstellen konnte.
  Mit Zitat antworten Zitat
Benutzerbild von Neutral General
Neutral General

Registriert seit: 16. Jan 2004
Ort: Bendorf
5.219 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#6

AW: Query an Gameserver

  Alt 18. Feb 2015, 12:25
procedure udp1Receive(Sender: TObject; Buf: PWideChar; var DataLen: Integer);
Stell das mal um und Du hast eine Fehlermeldung weniger.

procedure udp1Receive(Sender: TObject; Buf: PAnsiChar; var DataLen: Integer);
Und dann schau Dir die erhaltenen Daten noch mals an.
Dann wirds mit Sicherheit nicht mal compilieren. Ja probier das mal

Das einzige Problem was es hier gibt ist, dass der Server Binärdaten sendet und Flodding reinen Text erwartet.

Flodding: Da wird nirgendwo eine "8" stehen sondern eher sowas wie "◘".
Außerdem ist da nichts verschlüsselt sondern es sind halt einfach nur Binärdaten und kein String...
Michael
"Programmers talk about software development on weekends, vacations, and over meals not because they lack imagination,
but because their imagination reveals worlds that others cannot see."

Geändert von Neutral General (18. Feb 2015 um 12:33 Uhr)
  Mit Zitat antworten Zitat
BadenPower

Registriert seit: 17. Jun 2009
616 Beiträge
 
#7

AW: Query an Gameserver

  Alt 18. Feb 2015, 12:29
Dann wirds mit Sicherheit nicht mal compilieren.
Wie kommst Du auf diese schmale Brett???

Ach Du arbeitest mit Delphi2010, andere aber nicht.

Unter Delphi2007 zum Beispiel ist dort PAnsiChar und nicht PWideChar.

Wenn ich dann die Funktionsdeklaration in PWideChar änderen, dann kommt exakt die Fehlermeldung wie beim TE.


Und nun schau einmal mit was der TE arbeitet.
Programmieren ist die Kunst aus Nullen und Einsen etwas sinnvollen zu gestalten.
Der bessere Künstler ist allerdings der Anwender, denn dieser findet Fehler, welche sich der Programmierer nicht vorstellen konnte.
  Mit Zitat antworten Zitat
Benutzerbild von Neutral General
Neutral General

Registriert seit: 16. Jan 2004
Ort: Bendorf
5.219 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#8

AW: Query an Gameserver

  Alt 18. Feb 2015, 12:32
Dann wirds mit Sicherheit nicht mal compilieren.
Wie kommst Du auf diese schmale Brett???
Oh tut mir Leid. Hatte zu wenig gelesen und zu viel angenommen.
Du hast Recht.
Michael
"Programmers talk about software development on weekends, vacations, and over meals not because they lack imagination,
but because their imagination reveals worlds that others cannot see."
  Mit Zitat antworten Zitat
Flodding

Registriert seit: 26. Dez 2007
Ort: Kiel
121 Beiträge
 
Turbo Delphi für Win32
 
#9

AW: Query an Gameserver

  Alt 18. Feb 2015, 12:36
procedure udp1Receive(Sender: TObject; Buf: PWideChar; var DataLen: Integer);
Stell das mal um und Du hast eine Fehlermeldung weniger.

procedure udp1Receive(Sender: TObject; Buf: PAnsiChar; var DataLen: Integer);
Und dann schau Dir die erhaltenen Daten noch mals an.
Das Ergebnis unterscheidet sich nicht ...

Ich erwarte keinen Klartext... das hab ich vorher auch nicht erwähnt ... ich habe nur gefragt, warum der erste Teil als Klartext ankommt, der Rest aber nicht.

Ich habe hier mit der Bitte um Hilfe geschrieben.

Wie funktioniert das mit den Birnärdaten? wie wandele ich das in Klartext um ?
Flo
  Mit Zitat antworten Zitat
Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#10

AW: Query an Gameserver

  Alt 18. Feb 2015, 12:46
Zum besseren Verständnis mal ein Beispiel:

Du fragst eine API von mir ab und bekommst als Rückgabe ein Byte mit dem Dezimalwert 42.

Was bedeutet das? Erstmal gar nichts.

In einem Text-Control dargestellt siehst du ein * .
Ohne weiteres Wissen über den Kontext weisst du nur, dass ich dir ein Byte geliefert habe, was nun alles mögliche bedeuten kann.

Es kann tatsächlich bedeuten, dass es sich um ein Zeichen handelt und dann wäre es eben * .
Es kann bedeuten, dass die Motoren 1,3,5 laufen und die Motoren 0,2,4,6,7 nicht laufen 00101010 .
Es kann bedeuten dass die beiden Lampen A und B mit der Helligkeit 66% und 13% leuchten sollen
Code:
42d => 2Ah
A -> Ah => 10d / 15d = 66.66%
B -> 2h => 2d / 15d = 13.33%
Die wirkliche Bedeutung bekommt man ausschließlich über den Kontext und den erfährt man vom Erzeuger dieser Daten, denn der legt diesen Kontext fest.
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)
  Mit Zitat antworten Zitat
Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 12:54 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz