Delphi-PRAXiS
Seite 11 von 12   « Erste     91011 12      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Netzwerke (https://www.delphipraxis.net/14-netzwerke/)
-   -   Delphi Query an Gameserver (https://www.delphipraxis.net/183987-query-gameserver.html)

Flodding 26. Feb 2015 15:51

AW: Query an Gameserver
 
Im PHP-Code wird IP : PORT wie folgt per "echo" ausgegeben:
Code:
$addy = "$a1.$a2.$a3.$a4";
$key = $addy.":".$a5;
echo $key."\n";
Einige Zeilen zuvor werden $a2 - $a5 gefüllt:
Code:
$a2 = ord(fread($socket,1));
$a3 = ord(fread($socket,1));
$a4 = ord(fread($socket,1));
$a5 = ord(fread($socket,1))*256 + ord(fread($socket,1));
$a1 wird vorher schon auf die selbe Weise gefüllt und es wird überprüft ob "$a1 = 0" bzw. in diesem Fall "$a1 != 0" ist.

Wenn ich jetzt den OBEREN Code richtig deute, dann ist "$a5" der Port.
Also betrachte ich mir folgende Zeile genauer:
Code:
$a5 = ord(fread($socket,1))*256 + ord(fread($socket,1));
Ich versuche den Code jetzt einfach mal zu übersetzen:
Variable "a5" ist gleich der ASCII-Wert des Binärwertes der empfangenen Daten multipliziert mit 256. Zu diesem wird dann nochmal der ASCII-Wert des Binärwertes von eben addiert.

Quellen:
http://php.net/manual/de/function.ord.php
http://php.net/manual/de/function.fread.php

Wenn ich jetzt nachschaue, was "Ord" in Delphi bedeutet:
http://www.delphibasics.co.uk/RTL.asp?Name=Ord

Dort lese ich heraus, dass ich mit "Ord" in Delphi einen "Integer"-Wert aus folgenden Typen bekomme: " AnsiChar | Char | WideChar | Enumeration | Integer "

Dann schaue ich mir mal meine Typ-Definition für den Port an:
Delphi-Quellcode:
TServerListResponse = record
  ResponseHeader: Integer;
  PacketHeader: Word;
  First: Byte; // Byte
  Second: Byte; // Byte
  Third: Byte; // Byte
  Fourth: Byte; // Byte
  Port: Word; // unsigned Short
  ServerAdresses: TserverAddresses;
end;
Laut diesen Tabellen ist der Typ "Word" in C gleich der Typ "unsigned int".
ganz unten:
http://edn.embarcadero.com/article/10156#H15

ca. in der mitte:
http://stackoverflow.com/questions/1...void-parameter

Ein Blick in die Protokol Doku von Valve:
https://developer.valvesoftware.com/...Query_Protocol

Port ist in C Typ "unsigned short" und das Equivalent in Delphi dazu ist ein Typ "Char".

Eigener Code abgeändert:
Delphi-Quellcode:
TServerListResponse = record
  ResponseHeader: Integer;
  PacketHeader: Word;
  First: Byte; // Byte
  Second: Byte; // Byte
  Third: Byte; // Byte
  Fourth: Byte; // Byte
  Port: Char; // unsigned Short
  ServerAdresses: TserverAddresses;
end;
Wenn ich jetzt den Serverquery ausführe:
Delphi-Quellcode:
    if chr(response.PacketHeader) = 'f' then
      begin
        for y := 0 to 10 do
        begin
        Move(buffer[i], response.First, SizeOf(response.First)); inc(i, SizeOf(response.First));
        Move(buffer[i], response.Second, SizeOf(response.Second)); inc(i, SizeOf(response.Second));
        Move(buffer[i], response.Third, SizeOf(response.Third)); inc(i, SizeOf(response.Third));
        Move(buffer[i], response.Fourth, SizeOf(response.Fourth)); inc(i, SizeOf(response.Fourth));
        Move(buffer[i], response.Port, SizeOf(response.Port)); inc(i, SizeOf(response.Port));
        Form1.ListBox1.Items.Add((IntToStr(response.First)) + '.' +
                                 (IntToStr(response.Second)) + '.' +
                                 (IntToStr(response.Third)) + '.' +
                                 (IntToStr(response.Fourth)) + ':' +
                                 response.Port );
        Application.ProcessMessages;
        end;
      end;
    end;
Das Ergebnis ist weniger befriedigend:

Code:
121.21.210.134:ÿ
Oh da ist ja das "ÿ" !! Das kenne ich doch vom vorherigen Query!! "ÿ" war doch die von HEX zu Text umgewandelte "FF". Also würde mir eine Umwandlung zu HEX schonmal nichts bringen.
Ach... sind wir ma experimentierfreudig:
Delphi-Quellcode:
char(response.Port) );
Ergebnis:
Code:
111.105.136.134:ÿ
Herrje !! :twisted:

Okay warte mal wir hatten doch auch in den vorherigen Querys "Shorts", "Bytes", "Strings" und "Words". Ersetzen wir mal die anderen Typen durch die in den gerade gefundenen Listen.

Ergebnis ist, dass mit den Typ-Definitionen von den Quellen die Querys falsche Werte zurückliefern.

Sind die Quellen falsch ? Lese ich sie einfach nur falsch?
Das kann doch nicht so schwer sein die Typen aus einer Tabelle zu übertragen und dann die jeweiligen Funktionen zur Umwandlung in einen String zur Ausgabe in einer Listbox zu finden.

Neutral General 26. Feb 2015 16:00

AW: Query an Gameserver
 
Ich verstehe nicht warum du jetzt den Port von Word (RICHTIG!) in Char umgewandelt hast..
Der Port ist wie immer eine Zahl und hat nix mit einem String zu tun.

Flodding 26. Feb 2015 16:16

AW: Query an Gameserver
 
Lese bitte die Tabelle am Ende dieser Seite:

http://edn.embarcadero.com/article/10156#H15

Laut dieser Tabelle ist ein "unsigned short" in C ein "Char" in Delphi.

Neutral General 26. Feb 2015 16:22

AW: Query an Gameserver
 
Laut mir ist es ein Word.
Die Tabelle von Embarcadero ist wenn nicht falsch zumindest veraltet oder/und sehr ungenau.

Flodding 26. Feb 2015 16:33

AW: Query an Gameserver
 
nagut als Word hab ichs ja auch nicht hinbekommen.

Sir Rufo 26. Feb 2015 16:37

AW: Query an Gameserver
 
Wen interessiert es hier, was ein "unsigned short" von C übersetzt nach Delphi bedeutet?

Es interessiert doch ausschliesslich was der "unsigned short" in der Schnittstelle bedeutet. Es ist ein 16bit Wert (little endian) und den kann man einfach so in ein
Delphi-Quellcode:
Word
oder auch
Delphi-Quellcode:
UInt16
einlesen.

Neutral General 26. Feb 2015 16:40

AW: Query an Gameserver
 
Wenn mich nicht alles täuscht kommt der Port als Big Endian an.
Du musst also die Bytereihenfolge tauschen nachdem du den Port ausgelesen hast.

Das geht z.B. mit dieser Funktion:

Delphi-Quellcode:
function SwapWord(W: Word): Word;
asm
  xchg al, ah
end;

// ....

Move(buffer[i], response.Port, SizeOf(response.Port)); inc(i, SizeOf(response.Port));
response.Port := SwapWord(response.Port);
Edit: Auch wenn mir das komisch erscheint weil alle anderen Werte doch als Little Endian ankamen oder nicht?
Aber laut
Code:
$a5 = ord(fread($socket,1))*256 + ord(fread($socket,1));
ist das erste Byte ja scheinbar das MSB, daher Big Endian.
(Das irritiert mich grad selbst etwas aber schau mal obs so funktioniert :gruebel:)

Sir Rufo 26. Feb 2015 16:58

AW: Query an Gameserver
 
Den PHP-Code kann man nur dann richtig interpretieren, wenn man weiß, wie dieser Ausdruck denn abgearbeitet wird.
PHP-Quellcode:
$a5 = ord(fread($socket,1))*256 + ord(fread($socket,1));
.

Ist die Ausführungs-Reihenfolge von rechts nach links, dann wird zuerst
PHP-Quellcode:
ord(fread($socket,1))
und dann
PHP-Quellcode:
ord(fread($socket,1))*256
ausgeführt. ;)

BadenPower 26. Feb 2015 17:27

AW: Query an Gameserver
 
Zitat:

Zitat von Neutral General (Beitrag 1291645)
Wenn mich nicht alles täuscht kommt der Port als Big Endian an.
Du musst also die Bytereihenfolge tauschen nachdem du den Port ausgelesen hast.

Das geht z.B. mit dieser Funktion:

Delphi-Quellcode:
function SwapWord(W: Word): Word;
asm
  xchg al, ah
end;

Du täuschst dich nicht.


Oder als direkte Übersetzung aus dem PHP-Code so:

Delphi-Quellcode:
          Move(lBuffer[lPos], lResponseServer.Fourth, SizeOf(lResponseServer.Fourth));
          Inc(lPos, SizeOf(lResponseServer.Fourth));
          //Move(lBuffer[lPos], lResponseServer.Port, SizeOf(lResponseServer.Port));
          lResponseServer.Port := lBuffer[lPos] * 256 + lBuffer[lPos+1];
          Inc(lPos, SizeOf(lResponseServer.Port));
Einfach nur eine Zeile im Quellcode geändert und schon kommt der richtige Port-Wert heraus.

Flodding 26. Feb 2015 17:36

AW: Query an Gameserver
 
Mit der Swapword-Funktion klappt es. Danke Neutral General

Ich muss jetzt aber dazu sagen, dass ich die ganze Zeit den Verdacht hatte, dass die Bytes vertauscht sind. Drauf gekommen bin ich durch das "unsigned" davor; bei den Anderen stand es nicht davor. Aber ich war fest davon überzeugt, dass das nicht so sein wird, da die anderen "Word" ja auch nicht vertauscht waren.

Ich hätt ma früher fragen sollen. Jetzt kanns ja jeder sagen.

Ich meld mich wieder wenn ich die komplette Serverliste selbst hinbekommen habe, und ja ich weiss keiner glaubt dran, oder wenn ich es nicht geschafft habe.:?


Alle Zeitangaben in WEZ +1. Es ist jetzt 06:03 Uhr.
Seite 11 von 12   « Erste     91011 12      

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