AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Netzwerke Delphi Query an Gameserver
Thema durchsuchen
Ansicht
Themen-Optionen

Query an Gameserver

Ein Thema von Flodding · begonnen am 18. Feb 2015 · letzter Beitrag vom 1. Nov 2015
Antwort Antwort
Seite 9 von 12   « Erste     789 1011     Letzte »    
Flodding

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

AW: Query an Gameserver

  Alt 25. Feb 2015, 11:57
Nachdem das OnError Event deaktiviert wurde, funktionierte dann auch "bmNonBlocking"

Der Workaround funktioniert zwar, aber die Abfragezeit ist mit 5 Sekunden etwas lang.
Delphi-Quellcode:
  form4.udp1.BlockMode := bmNonBlocking;
  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.WaitForData(250);
  form4.Udp1.ReceiveBuf(buffer, SizeOf(buffer));
  i := 0;
Dies funktioniert so ohne extra Zeitüberprüfung. Ob Queryport offen oder eben nicht.
Flo

Geändert von Flodding (25. Feb 2015 um 11:58 Uhr) Grund: Checktime entfernt
  Mit Zitat antworten Zitat
BadenPower

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

AW: Query an Gameserver

  Alt 25. Feb 2015, 12:04
Der Workaround funktioniert zwar, aber die Abfragezeit ist mit 5 Sekunden etwas lang.
Diese Zeit ist nur 5 Sekunden, wenn der Server oder Port nicht erreichbar ist. Ist er Erreichbar, dann rutscht es in Milisekunden durch.

Nachdem das OnError Event deaktiviert wurde, funktionierte dann auch "bmNonBlocking"
wenn ich den UdpSocket auf "bmNonBlocking" stelle, dann blockiert er nie. Aber ich bekomme in diesem Modus keine Daten.
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
 
#83

AW: Query an Gameserver

  Alt 25. Feb 2015, 12:09
Dies hier funktioniert bei mir:
Delphi-Quellcode:
procedure Get_A2S_INFO;
var
  request: TInfoRequest;
  response: TInfoResponse;
  buffer: TBufferArray;
  i: Integer;
  CheckTime: TDateTime;
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.BlockMode := bmNonBlocking;
  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.WaitForData(250);
    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));

    if response.ResponseHeader = -1 then
      begin
      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);
      Move(buffer[i], response.EDF, SizeOf(response.EDF)); inc(i, SizeOf(response.EDF));
      Move(buffer[i], response.EDFPort, SizeOf(response.EDFPort)); inc(i, SizeOf(response.EDFPort));
      Move(buffer[i], response.EDFSteamID, SizeOf(response.EDFSteamID)); inc(i, SizeOf(response.EDFSteamID));
      Move(buffer[i], response.EDFSpecPort, SizeOf(response.EDFSpecPort)); inc(i, SizeOf(response.EDFSpecPort));
      //response.EDFSpecName := GetString(buffer, i);
      response.EDFKeywords := GetString(buffer, i);
      Move(buffer[i], response.EDFGameID, SizeOf(response.EDFGameID)); inc(i, SizeOf(response.EDFGameID));

      form4.lblServerHeader.Caption := chr(response.PacketHeader);
      form4.lblServerProtocol.Caption := IntToStr(response.Protocol);
      form4.lblServerName.Caption := response.Name;
      form4.lblServerMap.Caption := response.Map;
      form4.lblServerFolder.Caption := response.Folder;
      form4.lblServerGame.Caption := response.Game;
      form4.lblServerID.Caption := inttostr(response.ID);
      form4.lblServerPlayers.Caption := IntToStr(response.Players);
      form4.lblServerMaxPlayers.Caption := IntToStr(response.MaxPlayers);
      form4.lblServerBots.Caption := IntToStr(response.Bots);
      form4.lblServerType.Caption := chr(response.ServerType);
      form4.lblServerEnvironment.Caption := chr(response.Environment);
      form4.lblServerVisibility.Caption := inttostr(response.Visibility);
      form4.lblServerVAC.Caption := IntToStr(response.VAC);
      form4.lblServerVersion.Caption := response.Version;
      end
      else
      form4.lblServerName.Caption := 'Server nicht erreichbar';
  end;
end;
Das Error Event:
Delphi-Quellcode:
procedure TForm4.udp1Error(Sender: TObject; SocketError: Integer);
begin
//showmessage('Could not connect. The server you are trying to query might be down');
//udp1.Active:= false;
end;
Flo
  Mit Zitat antworten Zitat
Flodding

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

AW: Query an Gameserver

  Alt 25. Feb 2015, 15:32
Die Sekundenanzeige bei Der Playerinfo will auch nicht so ganz.

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;
  PlayerList: TTreeNode;
begin
  request.RequestHeader := -1;
  request.PacketHeader := 'U';
  request.Payload := 'FFFFFFFF';

  Form1.udp1.BlockMode := bmNonBlocking;
  Form1.udp1.RemoteHost:= Form1.edit1.Text;
  Form1.udp1.RemotePort:= Form1.edit2.Text;
  Form1.udp1.Open;

  if (Form1.udp1.Connected) then
    begin
    Form1.Udp1.SendBuf(request, SizeOf(TInfoRequest));
    Form1.udp1.WaitForData(250);
    Form1.Udp1.ReceiveBuf(buffer, SizeOf(buffer));
    //Challenge aus Buffer lesen
    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));
    if chr(response.PacketHeader) = 'Athen
      begin
      //Challende in den PayLoad schreiben
      request.Payload[0] := chr(buffer[5]);
      request.Payload[1] := chr(buffer[6]);
      request.Payload[2] := chr(buffer[7]);
      request.Payload[3] := chr(buffer[8]);
      //A2S_PLAYER request mit Challenge senden
      Form1.Udp1.SendBuf(request, SizeOf(TInfoRequest));
      Form1.udp1.WaitForData(250);
      Form1.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));
      if chr(response.PacketHeader) = 'Dthen
        begin
        Move(buffer[i], response.PlayerCount, SizeOf(response.PlayerCount)); inc(i, SizeOf(response.PlayerCount));
        Form1.TreeView1.Items.Clear;
        for y := 0 to response.PlayerCount - 1 do
          begin
          Move(buffer[i], response.PlayerIndex, SizeOf(response.PlayerIndex)); inc(i, SizeOf(response.PlayerIndex));
          response.PlayerName := GetString(buffer, i);
          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));

          PlayerList := Form1.TreeView1.Items.Add(Nil, response.PlayerName);
          Form1.TreeView1.Items.AddChild(PlayerList, 'ID: ' + IntToStr(response.PlayerIndex));
          Form1.TreeView1.Items.AddChild(PlayerList, 'Kills: ' + IntToStr(response.PlayerScore));
          Form1.TreeView1.Items.AddChild(PlayerList, 'Seconds: ' + IntToStr(response.PlayerDuration));

          Application.ProcessMessages;
          end;
        end;
      end;
    end;
form1.TreeView1.FullExpand;
Form1.udp1.Active := false;
end;
Lese ich die Zeit flasch aus?
Flo
  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
 
#85

AW: Query an Gameserver

  Alt 25. Feb 2015, 15:39
Wie immer gilt: Dokumentation lesen hilft.

Data Type Comment
Duration float Time (in seconds) player has been connected to the server.
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
 
#86

AW: Query an Gameserver

  Alt 25. Feb 2015, 17:19
LongInt wäre da richtig oder?

http://www.delphibasics.co.uk/RTL.asp?Name=LongInt
Flo
  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
 
#87

AW: Query an Gameserver

  Alt 25. Feb 2015, 17:28
Float ist eine Fließkommazahl. Single wäre der entsprechende Datentyp in Delphi.
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
 
#88

AW: Query an Gameserver

  Alt 25. Feb 2015, 21:25
Ich versuche jetzt die Master-Serverliste abzufragen.

Ich bekomme sogar Antwort.

Ich hab jetzt etliche Tests gemacht und rumprobiert, aber ich bekomme einfach keine vernünftige Liste mit servern die ich dann per Query abfragen könnte.

Delphi-Quellcode:
TServerListResponse = record
  ResponseHeader: Integer;
  PacketHeader: Word;
  First: Byte; // Byte
  Secound: Byte; // Byte
  Third: Byte; // Byte
  Fourth: Byte; // Byte
  Port: Word; // Short
end;
Delphi-Quellcode:
procedure Get_SERVER_LIST;
var
  request: TInfoRequest;
  response: TServerListResponse;
  buffer: TBufferArray;
  i: Integer;
  y: integer;
begin
// Abfrage der Arma 2 OA Server

// Example
// 31 FF 30 2E 30 2E 30 2E 30 3A 30 00 5C 6E 61 70 70 5C 35 30 30 00

// Tests
// 1ÿ0.0.0.0:0\x00\gamedir\arma2arrowpc\x00
// 31 ff 30 2e 30 2e 30 2e 30 3a 30 5c 78 30 30 5c 67 61 6d 65 64 69 72 5c 61 72 6d 61 32 61 72 72 6f 77 70 63 5c 78 30 30
// 1ÿ0.0.0.0:0\x00\gamedir\arma2arrowpc\x00
// 31 ff 30 2e 30 2e 30 2e 30 3a 30 5c 30 30 5c 67 61 6d 65 64 69 72 5c 61 72 6d 61 32 61 72 72 6f 77 70 63 5c 30 30
// 1ÿ0.0.0.0:0\00\gamedir\arma2arrowpc\00
// 31 ff 30 2e 30 2e 30 2e 30 3a 30 5c 30 5c 67 61 6d 65 64 69 72 5c 61 72 6d 61 32 61 72 72 6f 77 70 63 5c 30
// 1ÿ0.0.0.0:000\gamedir\arma2arrowpc00
// 31 ff 30 2e 30 2e 30 2e 30 3a 30 30 30 5c 67 61 6d 65 64 69 72 5c 61 72 6d 61 32 61 72 72 6f 77 70 63 30 30
// 1ÿ0.0.0.0:0ß\gamedir\arma2arrowpcß
// 31 ff 30 2e 30 2e 30 2e 30 3a 30 df 5c 67 61 6d 65 64 69 72 5c 61 72 6d 61 32 61 72 72 6f 77 70 63 df
// 1ÿ0.0.0.0:00\gamedir\arma2arrowpc0
// 31 ff 30 2e 30 2e 30 2e 30 3a 30 30 5c 67 61 6d 65 64 69 72 5c 61 72 6d 61 32 61 72 72 6f 77 70 63 30

  request.Payload[0] := $31;
  request.Payload[1] := $FF;
  request.Payload[2] := $30;
  request.Payload[3] := $2E;
  request.Payload[4] := $30;
  request.Payload[5] := $2E;
  request.Payload[6] := $30;
  request.Payload[7] := $2E;
  request.Payload[8] := $30;
  request.Payload[9] := $3A;
  request.Payload[10] := $00;

  request.Payload[11] := $30;
  request.Payload[12] := $5C;
  request.Payload[13] := $67;
  request.Payload[14] := $61;
  request.Payload[15] := $6D;
  request.Payload[16] := $65;
  request.Payload[17] := $64;
  request.Payload[18] := $69;
  request.Payload[19] := $72;
  request.Payload[20] := $5C;
  request.Payload[21] := $61;
  request.Payload[22] := $72;
  request.Payload[23] := $6D;
  request.Payload[24] := $61;
  request.Payload[25] := $32;
  request.Payload[26] := $61;
  request.Payload[27] := $72;
  request.Payload[28] := $72;
  request.Payload[29] := $6F;
  request.Payload[30] := $77;
  request.Payload[31] := $70;
  request.Payload[32] := $63;
  request.Payload[33] := $00;

  Form1.udp1.BlockMode := bmNonBlocking;
  Form1.udp1.RemoteHost:= 'hl2master.steampowered.com';
  Form1.udp1.RemotePort:= '27011';
  Form1.udp1.Open;

  if (Form1.udp1.Connected) then
    begin
    Form1.Udp1.SendBuf(request.Payload, SizeOf(request.Payload));
    Form1.udp1.WaitForData(250);
    Form1.Udp1.ReceiveBuf(buffer, SizeOf(buffer));
    i := 0;
    Move(buffer[i], response.ResponseHeader, SizeOf(response.ResponseHeader)); inc(i, SizeOf(response.ResponseHeader));
    form1.ListBox1.Clear;
    for y := 0 to 255 do
      begin
      Move(buffer[i], response.First, SizeOf(response.First)); inc(i, SizeOf(response.First));
      Move(buffer[i], response.Secound, SizeOf(response.Secound)); inc(i, SizeOf(response.Secound));
      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.Secound) + '.' + inttostr(response.Third) + '.' + inttostr(response.Fourth) + ':' + FloatToStr(response.Port));
      Application.ProcessMessages;
      end;

    end;

Form1.udp1.Active := false;
end;
Danke im Voraus diesmal
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
 
#89

AW: Query an Gameserver

  Alt 25. Feb 2015, 21:42
Was wollen einem wohl diese Worte sagen:
Zitat:
The format is then a series of these server address blocks
und dann noch (weil die Frage bestimmt auch noch kommt)
Zitat:
The full requested IP list may not fit in 1 x packet. Subsequent packets must be requested by using the last received IP address and Port as the 'seed' in the next request.
Das erste Zitat veranlasst uns zu folgendem Konstrukt
Delphi-Quellcode:
TServerAddressBlock = record
  First: Byte; // Byte
  Second: Byte; // Byte
  Third: Byte; // Byte
  Fourth: Byte; // Byte
  Port: Word; // unsigned Short
end;

TServerAddresses = array of TServerAddressBlock;

TServerListResponse = record
  ResponseHeader: Integer;
  PacketHeader: Word;
  ServerAddresses : TServerAddresses;
end;
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
 
#90

AW: Query an Gameserver

  Alt 25. Feb 2015, 21:54
Delphi-Quellcode:
  lRequest.Payload[9] := $3A;
  lRequest.Payload[10] := $00;
nach dem Doppelpunkt fehlt noch die 0 für den Port.
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
Antwort Antwort
Seite 9 von 12   « Erste     789 1011     Letzte »    

 

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 22:50 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