![]() |
AW: Query an Gameserver
Ich hoffe du hast es so gemeint. Ja... kein Papier :oops:
|
AW: Query an Gameserver
Ich bin immer noch komplett baff, was du mit diesen ganzen völlig beknackten Umwandlungen nach Hex willst. Die sind ÜBER! Hier, das folgende zusammengetippert, indem ich mir die Struktur von der Valve-Seite in meinen Editor kopiert habe, und daran den Record orientiert. Den mit Hilfe der Typinfos befüllen, und die Sache ist gelutscht. Was ein Gehampel hier.
Delphi-Quellcode:
(Komplett ungetestet und im Editor geschrieben. Mag gut sein, dass da 1-2 Dinge nicht 100%ig hin kommen. Aber NOCH mehr vorkauen geht fast nicht.)
TInfoRequest = packed record
RequestHeader: Integer; PacketHeader: AnsiChar; Payload: array[0..19] of AnsiChar; end; TInfoResponse = record ResponseHeader: Integer; PacketHeader: Byte; Protocol: Byte; Name: String; Map: String; Folder: String; Game: String; ID: SmallInt; Players: Byte; MaxPlayers: Byte; Bots: Byte; ServerType: Byte; Environment: Byte; Visibility: Byte; VAC: Byte; Version: String; end; TBufferArray = array[0..1400] of Byte; function GetString(aBuffer: TBufferArray; var aIndex: Integer): String; var b: Byte; begin result := ''; repeat Move(aBuffer[aIndex], b, SizeOf(b)); if b <> 0 then result := result + IntToStr(b); inc(aIndex); until b = 0; end; procedure GetInfo; var request: TInfoRequest; response: TInfoResponse; buffer: TBufferArray; i: Integer; begin request.RequestHeader := -1; request.PacketHeader := 'T'; request.Payload := 'Source Engine Query'; // Von mir aus auch mit einer Konstante oder einem Ressourcestring request.Payload[19] := #0; Udp1.SendBuf(request, SizeOf(TInfoRequest)); Udp1.ReceiveBuf(buffer, SizeOf(buffer)); i := 0; Move(buffer[i], response.ResponseHeader, SizeOf(response.ResponseHeader)); inc(i, SizeOf(response.ResponseHeader)); Move(buffer[i], response.PacketHeader, SizeOf(response.PacketHeader)); inc(i, SizeOf(response.PacketHeader)); Move(buffer[i], response.Protocol, SizeOf(response.Protocol)); inc(i, SizeOf(response.Protocol)); response.Name := GetString(buffer, i); response.Map := GetString(buffer, i); response.Folder := GetString(buffer, i); response.Game := GetString(buffer, i); Move(buffer[i], response.ID, SizeOf(response.ID)); inc(i, SizeOf(response.ID)); Move(buffer[i], response.Players, SizeOf(response.Players)); inc(i, SizeOf(response.Players)); Move(buffer[i], response.MaxPlayers, SizeOf(response.MaxPlayers)); inc(i, SizeOf(response.MaxPlayers)); Move(buffer[i], response.Bots, SizeOf(response.Bots)); inc(i, SizeOf(response.Bots)); Move(buffer[i], response.ServerType, SizeOf(response.ServerType)); inc(i, SizeOf(response.ServerType)); Move(buffer[i], response.Environment, SizeOf(response.Environment)); inc(i, SizeOf(response.Environment)); Move(buffer[i], response.Visibility, SizeOf(response.Visibility)); inc(i, SizeOf(response.Visibility)); Move(buffer[i], response.VAC, SizeOf(response.VAC)); inc(i, SizeOf(response.VAC)); response.Version := GetString(buffer, i); // In response steht jetzt alles richtig schön drin. Nicht als Hexkacke, sondern sauber als der Typ, den Valve vorgibt. end; Edit: War alles hübsch eingerückt, aber der "Beautifyer" der DP ist da ja anderer Meinung. Wenn man den Beitrag zitiert wird's besser. |
AW: Query an Gameserver
Und da sieht man doch schon, dass du immer noch nicht richtig in die Doku geschaut hast.
Wenn der Wert vom Typ BYTE ist, dann hat es da nur 1 (in Worten ein) Byte.
Hier Beispielhaften von der Valve Seite
Code:
Das sieht man, dass es den Wert für Extra Data Flags nicht geben muss!
FF FF FF FF 49 02 67 61 6D 65 32 78 73 2E 63 6F ÿÿÿÿI.game2xs.co
6D 20 43 6F 75 6E 74 65 72 2D 53 74 72 69 6B 65 m Counter-Strike 20 53 6F 75 72 63 65 20 23 31 00 64 65 5F 64 75 Source #1.de_du 73 74 00 63 73 74 72 69 6B 65 00 43 6F 75 6E 74 st.cstrike.Count 65 72 2D 53 74 72 69 6B 65 3A 20 53 6F 75 72 63 er-Strike: Sourc 65 00 F0 00 05 10 04 64 6C 00 00 31 2E 30 2E 30 e......dl..1.0.0 2E 32 32 00 .22. |
AW: Query an Gameserver
Zitat:
Dann sind notwendige Änderungen und Verbesserungsvorschläge leichter zu beschreiben. So ist es manchmal mehr oder weniger ein Rätselraten. |
AW: Query an Gameserver
Möchtest du dass ich das Projekt hochlade? Oder soll ich gesammten Code Posten?
|
AW: Query an Gameserver
Liste der Anhänge anzeigen (Anzahl: 1)
Ich habe jetzt mal den Beispiel-Response komplett aufgedröselt (Markdown-Format)
Code:
Im Anhang das gleiche als PDF gerendert
## A2S_INFO RESPONSE
### Example response for [Counter Strike: Source]: <pre> FF FF FF FF 49 02 67 61 6D 65 32 78 73 2E 63 6F ÿÿÿÿI.game2xs.co 6D 20 43 6F 75 6E 74 65 72 2D 53 74 72 69 6B 65 m Counter-Strike 20 53 6F 75 72 63 65 20 23 31 00 64 65 5F 64 75 Source #1.de_du 73 74 00 63 73 74 72 69 6B 65 00 43 6F 75 6E 74 st.cstrike.Count 65 72 2D 53 74 72 69 6B 65 3A 20 53 6F 75 72 63 er-Strike: Sourc 65 00 F0 00 05 10 04 64 6C 00 00 31 2E 30 2E 30 e......dl..1.0.0 2E 32 32 00 .22. </pre> #### Check for Protocol Field | Type | Bytes | Info :-- | --- | :-- | :-- Header | [long] | <pre>FF FF FF FF</pre> | -1 = Simple Response Format Payload | ∞ | <pre>49 02 67 61 6D 65 32 78 73 2E 63 6F 6D 20 43 6F<br>75 6E 74 65 72 2D 53 74 72 69 6B 65 20 53 6F 75<br>72 63 65 20 23 31 00 64 65 5F 64 75 73 74 00 63<br>73 74 72 69 6B 65 00 43 6F 75 6E 74 65 72 2D 53<br>74 72 69 6B 65 3A 20 53 6F 75 72 63 65 00 F0 00<br>05 10 04 64 6C 00 00 31 2E 30 2E 30 2E 32 32 00</pre> | #### Payload Data Field | Type | Bytes | Info :-- | --- | :-- | :-- Header | [byte] | <pre>49</pre> | I Protocol | [byte] | <pre>02</pre> | Name | [string] | <pre>67 61 6D 65 32 78 73 2E 63 6F 6D 20 43 6F 75 6E<br>74 65 72 2D 53 74 72 69 6B 65 20 53 6F 75 72 63<br>65 20 23 31 00</pre> | game2xs.com Counter-Strike Source #1 Map | [string] | <pre>64 65 5F 64 75 73 74 00</pre> | de_dust Folder | [string] |*<pre>63 73 74 72 69 6B 65 00</pre> | cstrike Game | [string] | <pre>43 6F 75 6E 74 65 72 2D 53 74 72 69 6B 65 3A 20<br>53 6F 75 72 63 65 00</pre> | Counter-Strike: Source ID | [short] | <pre>F0 00</pre> | 240 Players | [byte] | <pre>05</pre> | 5 Max. Players | [byte] | <pre>10</pre> | 16 Bots | [byte] | <pre>04</pre> | 4 Server type | [char] | <pre>64</pre> | d = dedicated Server Environment | [char] | <pre>6C</pre> | l = Linux Visibility | [byte] | <pre>00</pre> | 0 = public VAC | [byte] | <pre>00</pre> | 0 = unsecured Version | [string] | <pre>31 2E 30 2E 30 2E 32 32 00</pre> | 1.0.0.22 [byte]: https://developer.valvesoftware.com/wiki/Byte [char]: https://developer.valvesoftware.com/wiki/Byte [short]: https://developer.valvesoftware.com/wiki/Short [long]: https://developer.valvesoftware.com/wiki/Long [float]: https://developer.valvesoftware.com/wiki/Float [string]: https://developer.valvesoftware.com/wiki/String [Counter Strike: Source]: https://developer.valvesoftware.com/wiki/Counter_Strike:_Source |
AW: Query an Gameserver
Hab ich den ganzen Quatsch da oben jetzt umsonst geschrieben?
|
AW: Query an Gameserver
Zitat:
|
AW: Query an Gameserver
Zitat:
Das Konzept gefällt mir. Ich kannte die Funktion MOVE nicht und wie man merkt habe ich auch sonst wenig mit dynamischen Inhalten gearbeitet in Delphi. Ich habe ein wenig mit deinem Code rumprobiert und hab ihn halt um die IP und den Port erweitert. Das Ergebnis wenn ich zB. den Servernamen anzeigen lassen möchte ist jedoch mit mehrmaligem hin und her Probieren ernüchternd gewesen. Wahrscheinlich auf meine Dusseligkeit zurückzuführen.
Delphi-Quellcode:
Das Ergebnis sind nur viele Zahlen die ich meinen vorherigen Antworten vom Server nicht zuweisen konnte.
procedure GetInfo;
var request: TInfoRequest; response: TInfoResponse; buffer: TBufferArray; i: Integer; begin request.RequestHeader := -1; request.PacketHeader := 'T'; request.Payload := 'Source Engine Query'; // Von mir aus auch mit einer Konstante oder einem Ressourcestring request.Payload[19] := #0; form4.udp1.RemoteHost:= form4.edit1.Text; form4.udp1.RemotePort:= form4.edit2.Text; form4.udp1.Open; if (form4.udp1.Connected) then form4.Udp1.SendBuf(request, SizeOf(TInfoRequest)); form4.Udp1.ReceiveBuf(buffer, SizeOf(buffer)); i := 0; Move(buffer[i], response.ResponseHeader, SizeOf(response.ResponseHeader)); inc(i, SizeOf(response.ResponseHeader)); Move(buffer[i], response.PacketHeader, SizeOf(response.PacketHeader)); inc(i, SizeOf(response.PacketHeader)); Move(buffer[i], response.Protocol, SizeOf(response.Protocol)); inc(i, SizeOf(response.Protocol)); response.Name := GetString(buffer, i); response.Map := GetString(buffer, i); response.Folder := GetString(buffer, i); response.Game := GetString(buffer, i); Move(buffer[i], response.ID, SizeOf(response.ID)); inc(i, SizeOf(response.ID)); Move(buffer[i], response.Players, SizeOf(response.Players)); inc(i, SizeOf(response.Players)); Move(buffer[i], response.MaxPlayers, SizeOf(response.MaxPlayers)); inc(i, SizeOf(response.MaxPlayers)); Move(buffer[i], response.Bots, SizeOf(response.Bots)); inc(i, SizeOf(response.Bots)); Move(buffer[i], response.ServerType, SizeOf(response.ServerType)); inc(i, SizeOf(response.ServerType)); Move(buffer[i], response.Environment, SizeOf(response.Environment)); inc(i, SizeOf(response.Environment)); Move(buffer[i], response.Visibility, SizeOf(response.Visibility)); inc(i, SizeOf(response.Visibility)); Move(buffer[i], response.VAC, SizeOf(response.VAC)); inc(i, SizeOf(response.VAC)); response.Version := GetString(buffer, i); form4.lblServerName.Caption := response.Name; Zitat:
Ich habe jetzt verstanden was Byte, String und short für mich zu bedeuten hat. Wenn ich nach der Länge "Byte" "lesen" lasse, wird auch nur ein Byte (2 physische Zahlen im optischen Sinne) gesucht bzw. ausgegeben. wenn ich 2 Byte lesen lasse, werden 4 Zahlen gelesen. Ich hoffe ich beruhige dich etwas damit und verärgere dich nicht noch mehr falls das nicht das war was du mir mitteilen wolltest. MFG |
AW: Query an Gameserver
Liste der Anhänge anzeigen (Anzahl: 1)
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 16:26 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz