Delphi-PRAXiS
Seite 7 von 12   « Erste     567 89     Letzte »    

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)

Medium 24. Feb 2015 17:47

AW: Query an Gameserver
 
Würdest du uns Host und Port verraten? Dann würde ich meine Variante gerne mal selbst testen und ggf. debuggen. Vom Prinzip her sollte das an und für sich passen.

Flodding 24. Feb 2015 17:59

AW: Query an Gameserver
 
Zitat:

Zitat von Medium (Beitrag 1291349)
Würdest du uns Host und Port verraten? Dann würde ich meine Variante gerne mal selbst testen und ggf. debuggen. Vom Prinzip her sollte das an und für sich passen.

natürlich gerne :)

Es gibt einmal meinen privaten Server :

Host: 5.45.97.44
Port: 2301

Und dann gibt es die große Serverliste:

http://last-templers.de/a2epoch/serverlist.php

Dauert etwas bis sie geladen hat, aber dann hat man auch noch XXX andere Server zum testen mit verschiedenen Einstellungen. Die Ports in der Liste sind immer die Query Ports.

Medium 24. Feb 2015 18:27

AW: Query an Gameserver
 
Vor ca. einer Minute von deinem Server abgerufen:
Code:
Header: -1
Header2: 73
Protocol: 17
Name: [L-T-S] Epoch Origins (1.0.5.1/125548)
Map: Tavi
Folder: arma2arrowpc
Game: DayZ Epoch Origins
ID: -31606
Players: 1
MaxPlayers: 25
Bots: 0
ServerType: 100
Environment: 119
Visibility: 0
VAC: 0
Einzige Änderung: Das IntToStr() in der GetString Prozedur muss natürlich Chr() heissen. Der Rest passt.

BadenPower 24. Feb 2015 19:07

AW: Query an Gameserver
 
Zitat:

Zitat von Flodding (Beitrag 1291293)
Ändere ich den Queryport aber auf den Spielport zB, dann hängts immernoch.

In der Button2Click fehlt die Abfrage ob Connected.


und in der GetInfo

Delphi-Quellcode:
if (form4.udp1.Connected) then
form4.Udp1.SendBuf(request, SizeOf(TInfoRequest));
form4.Udp1.ReceiveBuf(buffer, SizeOf(buffer));
i := 0;
fehlt das begin-end. So wie Du es hier machst wird nur der Versuch unterbunden SendBuf auszuführen.

Aber die Zeilen danach werden immer ausgeführt, egal ob Connected oder nicht.

Flodding 24. Feb 2015 19:20

AW: Query an Gameserver
 
Also LOB an Medium der mit so wenig Aufwand doch so viel erreicht hat in diesem Thema.

Vielen Dank dafür. 8-)

Der hängt sich immernoch auf wenn ich auf einen falschen Port verbinde.
Habe die Änderungen vorgenommen wie vorgeschlagen:
Delphi-Quellcode:
form4.udp1.RemoteHost:= form4.edit1.Text;
  form4.udp1.RemotePort:= form4.edit2.Text;
  form4.udp1.Open;

  if (form4.udp1.Connected) then
  begin
  form4.Udp1.Send....
end;
Ich weiss ich werde für die folgende Frage bestimmt gesteinigt. Aber warum kommt da eine negative Zahl bei der ID raus? kommt zumindest wenn ich wie folgt aufrufe:
Delphi-Quellcode:
IntToStr(response.ID)
Liegt das wieder an der 8A84 die falschrum sind?

BadenPower 24. Feb 2015 19:28

AW: Query an Gameserver
 
Zitat:

Zitat von Flodding (Beitrag 1291355)
Der hängt sich immernoch auf wenn ich auf einen falschen Port verbinde.
Habe die Änderungen vorgenommen wie vorgeschlagen:

Delphi-Quellcode:
form4.udp1.RemoteHost:= form4.edit1.Text;
  form4.udp1.RemotePort:= form4.edit2.Text;
  form4.udp1.Open;

  if (form4.udp1.Connected) then
  begin
  form4.Udp1.Send....
end;

Nicht das END hinter SendBuf() sondern ganz ans Ende.

Delphi-Quellcode:

begin
  request.RequestHeader := 'ÿÿÿÿ';
  request.PacketHeader := 'T';
  request.Payload := 'Source Engine Query'; // Von mir aus auch mit einer Konstante oder einem Ressourcestring
  request.Payload[24] := #00;

  form4.udp1.RemoteHost:= form4.edit1.Text;
  form4.udp1.RemotePort:= form4.edit2.Text;
  form4.udp1.Open;

  if (form4.udp1.Connected) then
   begin
    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.edit1.Text := response.Name;

  end; //hier hin

end;

Flodding 24. Feb 2015 19:32

AW: Query an Gameserver
 
So habe ich es gemacht. Das kopierte Stückchen war wohl etwas unklar.
Delphi-Quellcode:
procedure Get_A2S_INFO;
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
  begin

  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);
  end;
end;

BadenPower 24. Feb 2015 20:58

AW: Query an Gameserver
 
Zitat:

Zitat von Flodding (Beitrag 1291355)
Ich weiss ich werde für die folgende Frage bestimmt gesteinigt. Aber warum kommt da eine negative Zahl bei der ID raus? kommt zumindest wenn ich wie folgt aufrufe:
Delphi-Quellcode:
IntToStr(response.ID)
Liegt das wieder an der 8A84 die falschrum sind?

Nein, dass liegt daran, dass der Typ von ID im Record TInfoResponse falsch deklariert ist.

Statt "SmallInt" muss der Typ von Id "Word" sein.

Dann ist nicht nur die Zahl positiv, sondern der Wert stimmt auch und ist dann 33930.

Flodding 24. Feb 2015 21:10

AW: Query an Gameserver
 
Vielen Dank , das hat auch super geklappt.

Hab jetzt mal rumgespielt und versucht die A2S_PLAYER Daten zu bekommen. Das Funktionierte vorher ja auch schon soweit, dass die aktuelle Spielerzahl ausgegeben wurde.
an dem selben Punkt bin ich jetzt mit der neuen Funktion die ich etwas umgebaut habe.
Delphi-Quellcode:
TPlayerResponse = record
  ResponseHeader: Integer;
  PacketHeader: Byte;
  Challenge: Integer;
  PlayerCount: Byte;
  PlayerIndex: Byte;
  PlayerName: String;
  PlayerScore: Integer;
  PlayerDuration: Integer;
end;
Delphi-Quellcode:
procedure Get_PLAYER_INFO;
var
  request: TInfoRequest;
  response: TPlayerResponse;
  buffer: TBufferArray;
  i: Integer;
  y: integer;
begin
  request.RequestHeader := -1;
  request.PacketHeader := 'U';
  request.Payload := 'FFFFFFFF'; // Von mir aus auch mit einer Konstante oder einem Ressourcestring

  form4.udp1.RemoteHost:= form4.edit1.Text;
  form4.udp1.RemotePort:= form4.edit2.Text;
  form4.udp1.Open;

  if (form4.udp1.Connected) then
  begin

  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.Challenge, SizeOf(response.Challenge)); inc(i, SizeOf(response.Challenge));

  i := 0;

  request.Payload[0] := chr(buffer[5]);
  request.Payload[1] := chr(buffer[6]);
  request.Payload[2] := chr(buffer[7]);
  request.Payload[3] := chr(buffer[8]);
  form4.Udp1.SendBuf(request, SizeOf(TInfoRequest));
  form4.Udp1.ReceiveBuf(buffer, SizeOf(buffer));
  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.PlayerCount, SizeOf(response.PlayerCount)); inc(i, SizeOf(response.PlayerCount));

  for y := 0 to response.PlayerCount do
    begin
    Move(buffer[i], response.PlayerIndex, SizeOf(response.PlayerIndex)); inc(i, SizeOf(response.PlayerIndex));
    Move(buffer[i], response.PlayerName, SizeOf(response.PlayerName)); inc(i, SizeOf(response.PlayerName));
    Move(buffer[i], response.PlayerScore, SizeOf(response.PlayerScore)); inc(i, SizeOf(response.PlayerScore));
    Move(buffer[i], response.PlayerDuration, SizeOf(response.PlayerDuration)); inc(i, SizeOf(response.PlayerDuration));
    end;

  form4.lblServerHeader.Caption := chr(response.PacketHeader);  // D = Antwort -> Playerinfos kommen

  end;
end;
Ich bekomme sogar das D zurückgeliefert. Hatte echt Schwierigkeiten das Challenge in den Payload zu bekommen, aber am Ende hat es dann doch geklappt und die Spielerzahl wird wieder ausgegeben.
Jetzt wollt ich natürlich weil ich einfach musste noch die Spielerdaten haben.
Das schien mir auf den ersten Blick auch ganz einfach. Nimmste einfach ne Schleife und lässt ihn durch laufen und jedes Mal die Daten weiter Lesen.
Hab mir ne Listbox vorne mit aufs Form gelegt und dann wollte ich die Listbox mit den SpielerNAMEN füllen.
Delphi-Quellcode:
form4.ListBox1.Items.Add(response.PlayerName)
Jedes Mal wenn ich auslesen möchte kommt ein Fehler.

EDIT: Das mit dem TimeOut funktioniert immernoch nicht richtig in der anderen Funktion.

Medium 24. Feb 2015 21:14

AW: Query an Gameserver
 
@BadenPower
Dann ist der auf der Valve Seite falsch deklariert. Dort ist ID als "short" gelistet, und ganz oben steht in den Typkonventionen: short = 16 bit signed integer
Ein 16 Bit ohne Vorzeichen kommt dort nichtmals vor.

@Flodding
Ich hoffe, dass abgesehen vom nacken funktionieren jetzt auch deutlich wurde, wo du deine Gedankenverknotungen hattest, und wie man prinzipiell mit solchen Dingen umgeht. Was das Ganze hier etwas gemein gemacht hat war, dass die Strings von variabler Länge sind. Wären sie mit festen Längen definiert, könnte man das ganze Geraffel mit dem Move() weg lassen, und das RecieveBuffer() direkt eine TInfoResponse Variable füllen lassen, da die Antwort dann "binär" 1:1 zu der Recordstruktur passen würde (bzw. umgekehrt). Dann wäre das nen Einzeiler.

Edit: Okay, du braucht mehr Grundlagen!!! 0xFFFFFFFF ist nicht 'FFFFFFFF'! Das erste ist eine 32 Bit Zahl in Hex-Darstellung, deins ist ein String. Dein String wäre in Hex 0x4646464646464646, also zu lang und völlig falsch. Du solltest dich bevor du mit Protokollen überhaupt anfängst dringend mit Datentypen und -darstellung befassen.


Alle Zeitangaben in WEZ +1. Es ist jetzt 21:28 Uhr.
Seite 7 von 12   « Erste     567 89     Letzte »    

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