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 12 von 12   « Erste     2101112   
BadenPower

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

AW: Query an Gameserver

  Alt 26. Feb 2015, 18:27
Drauf gekommen bin ich durch das "unsigned" davor; bei den Anderen stand es nicht davor.
Das "unsigned" hat allerdings nichts damit zu tun, das sagt nur aus, ob der Wert auch ein Vorzeichen haben kann.

Da bei einer Port-Angabe es sinnlos wäre negative Werte zu ermöglichen ist der Wert als "unsigned" vorgegeben.


Dass die Bytes vertaucht sind, hätte Dir allerdings die Zuhilfename von Windows-Bordmitteln, wie z.B. dem Taschenrechner gezeigt. Dort hättest Du einfach einmal die Zahl, welche Du erhalten hast eingeben können und in Hex umwandeln lassen. Dann eifach die Hex-Werte vertauchen und zurück nach Dezimal umwandeln.

Wenn Du dann die erhaltene Zahl als Portadresse in Deinem Programm benutzt hättest. dann hättest Du gesehen, dass Daten empfangen werden.
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 Sir Rufo
Sir Rufo

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

AW: Query an Gameserver

  Alt 26. Feb 2015, 21:40
Das die Daten vertauscht sind steht doch lang und breit in der Dokumentation:
Zitat:
Reply format
The reply always starts with FF FF FF FF 66 0A.
The format is then a series of these server address blocks:
TypeData
ByteFirst octet of IP address
ByteSecond octet of IP address
ByteThird octet of IP address
ByteFourth octet of IP address
Unsigned ShortPort number - usually 27015 (69 87) - this is network ordered, which is unlike every other Steam protocol.
Anyway, mit viel probieren bekommt man ja auch was heraus ... ok, Lesen geht manchmal schneller. Auch wenn man nicht versteht was network ordered ist, sollte der Hinweis which is unlike every other Steam protocol auf jeden Fall hellhörig machen. Da ist was anders als sonst (genau das steht da).

Da ich mir dieses Elend mit dem Auslesen und Schreiben nicht mehr ansehen kann, hier mal eine Unit, womit man dieses Pakete sehr einfach zusammenbauen und auch wieder auseinander nehmen kann.

Kleine Demo vorweg (alles was einem unbekannt vorkommt ist in der Unit SourceQuery definiert):
Delphi-Quellcode:
program SimpleTests;

{$APPTYPE CONSOLE}
{$R *.res}

uses
  IdGlobal, IdUDPClient,
  StrUtils, SysUtils,
  SourceQuery in 'SourceQuery.pas';

procedure ParseInfoResponse( AResponse: TSourceQueryBytes );
var
  LID: SQUShort;
  LEDF: SQByte;
begin
  Writeln( 'Parse-Data:' );
  Writeln;
  Writeln( 'Protocol-Header ', AResponse.ReadLong );
  Writeln( 'Packet-Header ', AResponse.ReadChar );
  Writeln( 'Protocol ', AResponse.ReadByte );
  Writeln( 'Name ', AResponse.ReadString );
  Writeln( 'Map ', AResponse.ReadString );
  Writeln( 'Folder ', AResponse.ReadString );
  Writeln( 'Game ', AResponse.ReadString );
  LID := AResponse.ReadUShort;
  Writeln( 'ID ', LID );
  Writeln( 'Players ', AResponse.ReadByte );
  Writeln( 'Max. Players ', AResponse.ReadByte );
  Writeln( 'Bots ', AResponse.ReadByte );
  Writeln( 'Server Type ', AResponse.ReadChar );
  Writeln( 'Environment ', AResponse.ReadChar );
  Writeln( 'Visibility ', AResponse.ReadByte );
  Writeln( 'VAC ', AResponse.ReadByte );

  // Testen auf "The Ship"
  if ( LID >= 2400 ) and ( LID <= 2499 )
  then
    begin
      Writeln( 'Mode ', AResponse.ReadByte );
      Writeln( 'Witnesses ', AResponse.ReadByte );
      Writeln( 'Duration ', AResponse.ReadByte );
    end;

  Writeln( 'Version ', AResponse.ReadString );
  if not AResponse.Eof
  then
    begin
      LEDF := AResponse.ReadByte;
      Writeln( 'EDF ', LEDF );
      if LEDF and $80 = $80
      then
        begin
          Writeln( 'Port ', AResponse.ReadShort );
        end;
      if LEDF and $10 = $10
      then
        begin
          Writeln( 'SteamID ', AResponse.ReadLongLong );
        end;
      if LEDF and $40 = $40
      then
        begin
          Writeln( 'Port ', AResponse.ReadShort );
          Writeln( 'Name ', AResponse.ReadString );
        end;
      if LEDF and $20 = $20
      then
        begin
          Writeln( 'Keywords ', AResponse.ReadString );
        end;
      if LEDF and $01 = $01
      then
        begin
          Writeln( 'GameID ', AResponse.ReadLongLong );
        end;
    end;
end;

procedure TestInfoResponse;
var
  LResponse: TSourceQueryBytes;
begin
  Writeln( 'Example response for Counter Strike: Source:' );
  Writeln;
  LResponse.SetData(
    {AData} HexStrToBytes(
      {AHexStr} StringReplace(
        {} 'FF FF FF FF 49 02 67 61 6D 65 32 78 73 2E 63 6F' +
        {} '6D 20 43 6F 75 6E 74 65 72 2D 53 74 72 69 6B 65' +
        {} '20 53 6F 75 72 63 65 20 23 31 00 64 65 5F 64 75' +
        {} '73 74 00 63 73 74 72 69 6B 65 00 43 6F 75 6E 74' +
        {} '65 72 2D 53 74 72 69 6B 65 3A 20 53 6F 75 72 63' +
        {} '65 00 F0 00 05 10 04 64 6C 00 00 31 2E 30 2E 30' +
        {} '2E 32 32 00',
        {OldPattern} ' ',
        {NewPattern} '',
        {Flags} [rfReplaceAll] ) ) );

  ParseInfoResponse( LResponse );
end;

procedure RealInfoRequest;
var
  LRequest, LResponse: TSourceQueryBytes;
  LUdp: TIdUDPClient;
  LBuffer: TIdBytes;
  LResponseSize: Integer;
begin

  // Prepare Request

  LRequest.WriteLong( SQ_SIMPLEPACKET_PROTOCOL_HEADER );
  LRequest.WriteByte( SQ_INFO_REQUEST_HEADER );
  LRequest.WriteString( 'Source Engine Query' );

  Writeln( 'REQUEST-DATA:' );
  Writeln;
  Writeln( LRequest.ToString );
  Writeln;

  LBuffer := LRequest.GetData;

  LUdp := TIdUDPClient.Create( nil );
  try

    // Send Request

    Write( 'Sending ... ' );
    LUdp.SendBuffer( '5.45.97.44', 2301, LBuffer );

    // Receive Response

    SetLength( LBuffer, SQ_PACKET_MAXSIZE );
    Write( 'Receiving ... ' );
    LResponseSize := LUdp.ReceiveBuffer( LBuffer );
    Writeln( LResponseSize, ' Bytes' );
    SetLength( LBuffer, LResponseSize );
    Writeln;
  finally
    LUdp.Free;
  end;

  Writeln( 'RESPONSE-DATA:' );
  Writeln;
  Writeln( DumpBuffer( LBuffer ) );
  Writeln;

  // Parse Response

  LResponse.SetData( LBuffer );

  ParseInfoResponse( LResponse );
end;

procedure RealMasterQueryRequest;
var
  LRequest, LResponse: TSourceQueryBytes;
  LBuffer: TIdBytes;
  LBufferSize: Integer;
  LUdp: TIdUDPClient;
  LServerAddress: TSQServerAddressBlock;
  LCount, LRetries: Integer;
begin

  LServerAddress.IP1 := 0;
  LServerAddress.IP2 := 0;
  LServerAddress.IP3 := 0;
  LServerAddress.IP4 := 0;
  LServerAddress.Port := 0;

  LUdp := TIdUDPClient.Create( nil );
  try

    LCount := 0;

    repeat // Daten abrufen ...

      LRequest.Clear;
      LRequest.WriteByte( $31 ); // Message Type
      LRequest.WriteByte( SQ_REGIONCODE_RESTOFTHEWORLD ); // Region Code
      LRequest.WriteString( LServerAddress.ToString ); // IP-Address
      LRequest.WriteString( '\gamedir\arma2arrowpc' ); // Filter

      LBuffer := LRequest.GetData;

      // Send Request

      LUdp.SendBuffer( 'hl2master.steampowered.com', 27011, LBuffer );

      LRetries := 0;
      repeat
        if LRetries >= 3
        then
          raise Exception.Create( 'Too many retries' );

        SetLength( LBuffer, SQ_PACKET_MAXSIZE );
        LBufferSize := LUdp.ReceiveBuffer( LBuffer, 2000 );
        Inc( LRetries );
      until LBufferSize > 0;
      SetLength( LBuffer, LBufferSize );

      LResponse.SetData( LBuffer );

      Assert( LResponse.ReadLong = SQ_SIMPLEPACKET_PROTOCOL_HEADER );
      Assert( LResponse.ReadByte = $66 );
      Assert( LResponse.ReadByte = $0A );

      // Parse the Server-Addresses
      while not LResponse.Eof do
        begin
          Inc( LCount );
          LServerAddress.IP1 := LResponse.ReadByte;
          LServerAddress.IP2 := LResponse.ReadByte;
          LServerAddress.IP3 := LResponse.ReadByte;
          LServerAddress.IP4 := LResponse.ReadByte;
          LServerAddress.Port := swap( LResponse.ReadUShort ); // swap weil die Doku das sagt

          Writeln( LCount:7, '. ', LServerAddress.ToString );
        end;

    until ( LServerAddress.ToString = '0.0.0.0:0' ); // ... bis die leere Adresse zurückkommt

  finally
    LUdp.Free;
  end;

end;

begin
  try
    TestInfoResponse;
    RealInfoRequest;
    RealMasterQueryRequest;
  except
    on E: Exception do
      Writeln( E.ClassName, ': ', E.Message );
  end;
  ReadLn;

end.
Ausgabe von RealInfoRequest :
Code:
REQUEST-DATA:

FF FF FF FF 54 53 6F 75 72 63 65 20 45 6E 67 69   ÿÿÿÿTSource Engi
6E 65 20 51 75 65 72 79 00                        ne Query.

Sending ... Receiving ... 196 Bytes

RESPONSE-DATA:

FF FF FF FF 49 11 5B 4C 2D 54 2D 53 5D 20 45 70   ÿÿÿÿI.[L-T-S] Ep
6F 63 68 20 4F 72 69 67 69 6E 73 20 28 31 2E 30   och Origins (1.0
2E 35 2E 31 2F 31 32 35 35 34 38 29 00 54 61 76   .5.1/125548).Tav
69 00 61 72 6D 61 32 61 72 72 6F 77 70 63 00 44   i.arma2arrowpc.D
61 79 5A 20 45 70 6F 63 68 20 4F 72 69 67 69 6E   ayZ Epoch Origin
73 00 8A 84 01 19 00 64 77 00 00 31 2E 36 33 2E   s.??...dw..1.63.
31 32 35 35 34 38 00 B1 FE 08 01 CC 2C AF 75 14   125548.±þ..Ì,¯u.
40 01 62 74 2C 72 31 36 33 2C 6E 31 32 35 35 34   @.bt,r163,n12554
38 2C 73 37 2C 69 31 2C 6D 66 2C 6C 66 2C 76 66   8,s7,i1,mf,lf,vf
2C 64 74 2C 74 63 6F 6F 70 2C 67 36 35 35 34 35   ,dt,tcoop,g65545
2C 63 32 31 34 37 34 38 33 36 34 37 2D 32 31 34   ,c2147483647-214
37 34 38 33 36 34 37 2C 70 77 2C 00 8A 84 00 00   7483647,pw,.??..
00 00 00 00                                       ....

Parse-Data:

Protocol-Header -1
Packet-Header  I
Protocol       17
Name           [L-T-S] Epoch Origins (1.0.5.1/125548)
Map            Tavi
Folder         arma2arrowpc
Game           DayZ Epoch Origins
ID             33930
Players        1
Max. Players   25
Bots           0
Server Type    d
Environment    w
Visibility     0
VAC            0
Version        1.63.125548
EDF            177
Port           2302
SteamID        90094488230087681
Keywords       bt,r163,n125548,s7,i1,mf,lf,vf,dt,tcoop,g65545,c2147483647-21474
83647,pw,
GameID         33930
In der ganz kurzen Form (ohne Dump und Kommentare)) sieht ein Request dann wie folgt aus
Delphi-Quellcode:
procedure InfoRequest;
var
  LRequest, LResponse: TSourceQueryBytes;
  LUdp: TIdUDPClient;
  LBuffer: TIdBytes;
  LResponseSize: Integer;
begin
  LRequest.WriteLong( SQ_SIMPLEPACKET_PROTOCOL_HEADER );
  LRequest.WriteByte( SQ_INFO_REQUEST_HEADER );
  LRequest.WriteString( 'Source Engine Query' );

  LBuffer := LRequest.GetData;

  LUdp := TIdUDPClient.Create( nil );
  try
    LUdp.SendBuffer( '5.45.97.44', 2301, LBuffer );

    SetLength( LBuffer, SQ_PACKET_MAXSIZE );
    LResponseSize := LUdp.ReceiveBuffer( LBuffer );
    SetLength( LBuffer, LResponseSize );
  finally
    LUdp.Free;
  end;

  LResponse.SetData( LBuffer );

  ParseInfoResponse( LResponse );
end;
Der komplette Source im Anhang
Angehängte Dateien
Dateityp: zip SourceQuery.zip (4,4 KB, 18x aufgerufen)
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)

Geändert von Sir Rufo (26. Feb 2015 um 21:42 Uhr)
  Mit Zitat antworten Zitat
BadenPower

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

AW: Query an Gameserver

  Alt 28. Feb 2015, 11:55
Da ich mir dieses Elend mit dem Auslesen und Schreiben nicht mehr ansehen kann, hier mal eine Unit, womit man dieses Pakete sehr einfach zusammenbauen und auch wieder auseinander nehmen kann.
Wow, da hat ja die Unit SouceQuery.pas, welche nur die Hilfsfunktionen enhält, schon fast so viele Zeilen Code, wie mein komplett funktionsfähiges Programm mit allen Parametereinstellmöglichkeiten für die Abfragen.


Da wundert es mich nicht mehr, dass viele Programme, welche nur ein Fenster haben zum Teil und das ohne Daten geladen zu haben, bereits 50kb im Hauptspeicher belegen, statt den eigentlich erforderlichen 4kb.
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 Sir Rufo
Sir Rufo

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

AW: Query an Gameserver

  Alt 28. Feb 2015, 14:57
Jeder wie er will von Spaghetticode bis ordentlich strukturiert. Irgendwo dazwischen sortiert man sich ein. Wo siehst du dich da (rhetorische Frage, es reicht wenn du dir die selber beantwortest).
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
Flodding

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

AW: Query an Gameserver

  Alt 31. Okt 2015, 20:46
...

Ich häng immernoch an der Kompletten Serverliste...

Ich bekomme stets nur den ersten Teil, danch bekomme ich nichts brauchbares...

Noch einer Lust mir zu helfen ?

MFG

Flo
Flo
  Mit Zitat antworten Zitat
Flodding

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

AW: Query an Gameserver

  Alt 31. Okt 2015, 22:44
Irgendwie hab ich meinen aktuellen Code vergessen:

Delphi-Quellcode:
procedure Get_SERVER_LIST(a1: byte; a2: byte; a3: byte; a4: byte; a5: Word);
var
// request : TA2S_InfoRequest;
  request : TServerListRequest;
  response : TServerListResponse;
  buffer : TBufferArray;
  i : Integer;
  y : Integer;
  endoflist : Boolean;
  endofpartlist : Boolean;

  new_a1 : byte;
  new_a2 : byte;
  new_a3 : byte;
  new_a4 : byte;
  new_a5 : word;

  old_a1 : byte;
  old_a2 : byte;
  old_a3 : byte;
  old_a4 : byte;
  old_a5 : word;

  old_seed : String;
  new_seed : String;

  newport_plain: Integer;
  oldport_plain: Integer;

begin

old_a1 := $30;
old_a2 := $30;
old_a3 := $30;
old_a4 := $30;
old_a5 := $3030;

// \gamedir\arma2arrowpc
// 31 FF 30 2e 30 2e 30 2e 30 3a 30 00 5c 67 61 6d 65 64 69 72 5c 61 72 6d 61 32 61 72 72 6f 77 70 63 00

// \gamedir\arma3
// 31 ff 30 2e 30 2e 30 2e 30 3a 30 00 5c 67 61 6d 65 64 69 72 5c 61 72 6d 61 33

  request.RequestHeader := $31;
  request.PacketHeader := $FF;
  request.First := $30;
  request.First_dot := $2E;
  request.Second := $30;
  request.Second_dot := $2E;
  request.Third := $30;
  request.Third_dot := $2E;
  request.Fourth := $30;
  request.double_dot := $3A;
  request.Port := $3030;
  request.Payload[0] := $00;
  request.Payload[1] := $5C;
  request.Payload[2] := $67;
  request.Payload[3] := $61;
  request.Payload[4] := $6D;
  request.Payload[5] := $65;
  request.Payload[6] := $64;
  request.Payload[7] := $69;
  request.Payload[8] := $72;
  request.Payload[9] := $5C;
  request.Payload[10] := $61;
  request.Payload[11] := $72;
  request.Payload[12] := $6D;
  request.Payload[13] := $61;
  request.Payload[14] := $33;
  request.Payload[15] := $00;


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

  if Form1.udp1.Active = false then
  begin
  form1.udp1.Active := true;
  form1.ListBox1.Clear;
  endoflist := false;
  end;

  if (Form1.udp1.Connected) then
    begin

    y := 0;
        repeat
               i := 0;
        form1.udp1.CleanupInstance;
        Form1.Udp1.SendBuf(request, SizeOf(request));
        Form1.udp1.WaitForData(250);
        Form1.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));
// form1.Caption := chr(response.ResponseHeader) + chr(response.PacketHeader) + IntToStr(i);
        form1.Memo1.Text := bintostr((buffer));
          repeat
            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));
// Response.Port := Buffer[i] * 256 + Buffer[i+1]; Inc(i, SizeOf(Response.Port)); // Weil die Bytes vertauscht sind, müssen sie umgedreht werden für ein richtiges
            newport_plain := Buffer[i] * 256 + Buffer[i+1]; Inc(i, SizeOf(Response.Port)); // Weil die Bytes vertauscht sind, müssen sie umgedreht werden für ein richtiges

            new_a1 := response.First;
            new_a2 := response.Second;
            new_a3 := response.Third;
            new_a4 := response.Fourth;
            new_a5 := response.Port;

            new_seed := IntToStr(new_a1) + IntToStr(new_a2) + IntToStr(new_a3) + IntToStr(new_a4) + IntToStr(new_a5);

        if (response.First <> 00) AND (response.Second <> 00) AND (response.Third <> 00) AND (response.Fourth <> 00) then
              begin
                form1.duplicatcounter := 0;

               Form1.ListBox1.Items.Add ((IntToStr(new_a1)) + '.' +
                                          (IntToStr(new_a2)) + '.' +
                                          (IntToStr(new_a3)) + '.' +
                                          (IntToStr(new_a4)) + ':' +
                                           IntToStr((newport_plain)) );

                old_a1 := response.First;
                old_a2 := response.Second;
                old_a3 := response.Third;
                old_a4 := response.Fourth;
                old_a5 := newport_plain;
                old_seed := IntToStr(old_a1) + IntToStr(old_a2) + IntToStr(old_a3) + IntToStr(old_a4) + IntToStr(newport_plain);

                Application.ProcessMessages;
              end
            else
              begin
                Form1.duplicatcounter := form1.duplicatcounter + 1;
                request.First := strtoint( StringToHex(inttostr(old_a1)));
                request.Second := strtoint( StringToHex(inttostr(old_a2)));
                request.Third := strtoint( StringToHex(inttostr(old_a3)));
                request.Fourth := strtoint( StringToHex(inttostr(old_a4)));
                request.Port := strtoint( StringToHex(inttostr(old_a5)));
                Form1.Edit3.Text := StringToHex(inttostr(old_a1) + inttostr(old_a2) + inttostr(old_a3) + inttostr(old_a4) + inttostr(old_a5)) ;
              end;
              y := y + 1;
              form1.Caption := inttostr(y);
// until (IntToStr(response.First)) + '.' + (IntToStr(response.Second)) + '.' + (IntToStr(response.Third)) + '.' + (IntToStr(response.Fourth)) + ':' + IntToStr((response.Port)) = '0.0.0.0:0';
          until form1.duplicatcounter = 2;

        Form1.ListBox1.Items.Add ('---------------');
        Form1.ListBox1.Items.Add ('---------------');
        Form1.ListBox1.Items.Add ('NewSeed: ' + new_seed);
        Form1.ListBox1.Items.Add ('OldSeed: ' + old_seed);
        Form1.ListBox1.Items.Add ('---------------');
        Form1.ListBox1.Items.Add ('---------------');

        until y > 500;

      end;

Form1.udp1.Active := false;
form1.Caption := 'Servers: ' + inttostr(Form1.ListBox1.Items.Count -1);
end;
irgendwie bekomme ich 4 mal die selbe liste.
Flo
  Mit Zitat antworten Zitat
Benutzerbild von p80286
p80286

Registriert seit: 28. Apr 2008
Ort: Stolberg (Rhl)
6.659 Beiträge
 
FreePascal / Lazarus
 
#117

AW: Query an Gameserver

  Alt 1. Nov 2015, 10:38
irgendwie bekomme ich 4 mal die selbe liste.
Wenn Du 4 mal die selbe Liste Bekommst, könnte es sein, daß du 4 mal den gleichen Bufferinhalt liest.
Darum würde ich zunächst einmal den Buffer vor versenden des Request nullen fillchar wenn beim zweiten lesen nur Nullen kommen, scheint die Gegenstelle keine Daten geliefert zu haben.

request.First := strtoint( StringToHex(inttostr(old_a1))); Und wofür ist dieses seltsame Konstrukt gut?

Gruß
K-H
Programme gehorchen nicht Deinen Absichten sondern Deinen Anweisungen
R.E.D retired error detector
  Mit Zitat antworten Zitat
Flodding

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

AW: Query an Gameserver

  Alt 1. Nov 2015, 10:50
Danke für den Hinweis mit dem Leeren des Buffers. Leider hat dies noch nicht zum Erfolg geführt.

FillChar(buffer, SizeOf(buffer), 0); Nachdem ich das ganze ein wenig überarbeitet habe, komme ich nun wenigstens schonmal zu einem sicheren Ergebnis. Ich bekomme immer exakt 2 Mal die selbe Liste (geplant -> y - Vaiable) obwohl ich die IP Adresse im "response" ändere.

Hier erstmal der Code:
Delphi-Quellcode:
procedure Get_SERVER_LIST();
var
  request : TServerListRequest;
  response : TServerListResponse;
  buffer : TBufferArray;
  i : Integer;
  y : Integer;

  new_a1 : byte;
  new_a2 : byte;
  new_a3 : byte;
  new_a4 : byte;
  new_a5 : word;

  old_a1 : byte;
  old_a2 : byte;
  old_a3 : byte;
  old_a4 : byte;
  old_a5 : word;

  old_seed : String;
  new_seed : String;

begin

old_a1 := 30;
old_a2 := 30;
old_a3 := 30;
old_a4 := 30;
old_a5 := 3030;

// \gamedir\arma2arrowpc
// 31 FF 30 2e 30 2e 30 2e 30 3a 30 00 5c 67 61 6d 65 64 69 72 5c 61 72 6d 61 32 61 72 72 6f 77 70 63 00

// \gamedir\arma3
// 31 ff 30 2e 30 2e 30 2e 30 3a 30 00 5c 67 61 6d 65 64 69 72 5c 61 72 6d 61 33

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

  form1.ListBox1.Clear;

  if (Form1.udp1.Connected) then
    begin
        repeat
          request.RequestHeader := $31;
          request.PacketHeader := $FF;
          request.First := old_a1;
          request.First_dot := $2E;
          request.Second := old_a2;
          request.Second_dot := $2E;
          request.Third := old_a3;
          request.Third_dot := $2E;
          request.Fourth := old_a4;
          request.double_dot := $3A;
          request.Port := old_a5;
          request.Payload[0] := $00;
          request.Payload[1] := $5C;
          request.Payload[2] := $67;
          request.Payload[3] := $61;
          request.Payload[4] := $6D;
          request.Payload[5] := $65;
          request.Payload[6] := $64;
          request.Payload[7] := $69;
          request.Payload[8] := $72;
          request.Payload[9] := $5C;
          request.Payload[10] := $61;
          request.Payload[11] := $72;
          request.Payload[12] := $6D;
          request.Payload[13] := $61;
          request.Payload[14] := $33;
          request.Payload[15] := $00;

        Form1.Udp1.SendBuf(request, SizeOf(request));
        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));
          repeat
            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));
            Response.Port := Buffer[i] * 256 + Buffer[i+1]; Inc(i, SizeOf(Response.Port)); // Weil die Bytes vertauscht sind, müssen sie umgedreht werden für ein richtiges

            new_a1 := response.First;
            new_a2 := response.Second;
            new_a3 := response.Third;
            new_a4 := response.Fourth;
            new_a5 := response.Port;

            new_seed := IntToStr(new_a1) + IntToStr(new_a2) + IntToStr(new_a3) + IntToStr(new_a4) + IntToStr(new_a5);

            if (new_seed <> '00000') then
              begin
                 form1.duplicatcounter := 0;
                 Form1.ListBox1.Items.Add ((IntToStr(new_a1)) + '.' + (IntToStr(new_a2)) + '.' + (IntToStr(new_a3)) + '.' + (IntToStr(new_a4)) + ':' + IntToStr((new_a5)) );
                 old_a1 := new_a1;
                 old_a2 := new_a2;
                 old_a3 := new_a3;
                 old_a4 := new_a4;
                 old_a5 := new_a5;
                 old_seed := IntToStr(old_a1) + IntToStr(old_a2) + IntToStr(old_a3) + IntToStr(old_a4) + IntToStr(new_a5);
                 Application.ProcessMessages;
              end
            else
              begin
                Form1.duplicatcounter := form1.duplicatcounter + 1;
              end;
          until form1.duplicatcounter = 1;
        y := y + 1;
        Form1.ListBox1.Items.Add ('---------------');
        Form1.ListBox1.Items.Add ('---------------');
        Form1.ListBox1.Items.Add ('NewSeed: ' + new_seed);
        Form1.ListBox1.Items.Add ('OldSeed: ' + old_seed);
        Form1.ListBox1.Items.Add ('---------------');
        Form1.ListBox1.Items.Add ('---------------');
        FillChar(Buffer, SizeOf(buffer), 0); // Buffer leeren
        until y = 2;
      end;
Form1.udp1.Close;
form1.Caption := 'Servers: ' + inttostr(Form1.ListBox1.Items.Count -1);
end;
Mir scheint ich hab immernoch ein Problem damit die empfangenen Bytes für die IP und das Word für den Port richtig zu übergeben.

Flo

Geändert von Flodding ( 1. Nov 2015 um 10:54 Uhr) Grund: Fett schreibnen in Code geht nicht, "x" -Variable -> "y"
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 12 von 12   « Erste     2101112   

 

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 19:03 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