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 2 von 12     12 34     Letzte »    
Flodding

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

AW: Query an Gameserver

  Alt 18. Feb 2015, 13:05
Okay also aus deinem Post verstehe ich denn jetzt, dass ich das nicht hinbekommen kann, weil ich den Kontext nicht habe oder verstehe?!

Warum kannst du denn nicht so schreiben, dass man das auch als nicht Philosoph oder professioneller Programmierer verstehen kann?

Das würde vieles leichter machen aktuell...

Und bevor du es falsch verstehst... Ich erwarte nicht von dir, dass du mir einen Codeschnipsel hinschmeisst an dem ich dann rumkauen kann...
Flo
  Mit Zitat antworten Zitat
BadenPower

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

AW: Query an Gameserver

  Alt 18. Feb 2015, 13:09
Aktuell regel ich das über ein PHP-Query-Script, da ich dies als fertige Lösung gefunden habe.

Quelle: https://github.com/xPaw/PHP-Source-Query-Class
Der Link funktioniert nicht.

Hast Du den Quellcode des Scriptes?
Wenn ja poste in einmal, denn dort müsste ja die Dekodierungsroutine für die RawDaten enthalten sein.

Hallo guten Morgen
Hier ein Link zum bereits konfigurierten Script:
http://last-templers.de/a2epoch/query/query.php
Ist das der lauffähige Link zum Script oben?
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 Neutral General
Neutral General

Registriert seit: 16. Jan 2004
Ort: Bendorf
5.219 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#13

AW: Query an Gameserver

  Alt 18. Feb 2015, 13:12
Okay also aus deinem Post verstehe ich denn jetzt, dass ich das nicht hinbekommen kann, weil ich den Kontext nicht habe oder verstehe?!
Doch du kannst es hinbekommen weil Valve ja gerade so nett war und dokumentiert hat welche Bytes wie/als was zu interpretieren sind:

https://developer.valvesoftware.com/wiki/Server_queries
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
Benutzerbild von Sir Rufo
Sir Rufo

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

AW: Query an Gameserver

  Alt 18. Feb 2015, 13:13
Da diese Daten ohne Kontext eben rein philosophisch sind, welche Antwort hast du dann erwartet? Der Begriff Kontext sollte allerdings auch Nicht-Philosophen und Nicht-Programmieren bekannt sein.

Man kann es so nicht beantworten und einen Codeschnipsel kann es dann logischerweise auch nicht geben.

Okay also aus deinem Post verstehe ich denn jetzt, dass ich das nicht hinbekommen kann, weil ich den Kontext nicht habe oder verstehe?!
Doch du kannst es hinbekommen weil Valve ja gerade so nett war und dokumentiert hat welche Bytes wie/als was zu interpretieren sind:

https://developer.valvesoftware.com/wiki/Server_queries
Aha, da ist ja das fehlende Puzzleteil
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
 
#15

AW: Query an Gameserver

  Alt 18. Feb 2015, 17:09
Aktuell regel ich das über ein PHP-Query-Script, da ich dies als fertige Lösung gefunden habe.

Quelle: https://github.com/xPaw/PHP-Source-Query-Class
Der Link funktioniert nicht.

Hast Du den Quellcode des Scriptes?
Wenn ja poste in einmal, denn dort müsste ja die Dekodierungsroutine für die RawDaten enthalten sein.

Hallo guten Morgen
Hier ein Link zum bereits konfigurierten Script:
http://last-templers.de/a2epoch/query/query.php
Ist das der lauffähige Link zum Script oben?


Bei mir funktionieren beide Links...

Der erste Link führt zum Quellcode des PHP-Scriptes, der 2te Link führt zu dem jetzt aktuell benutzten fertig konfigurierten PHP-Script welches alle Informationen anzeigt.

Zum Quellcode des PHP-Scriptes:

Code:
<?php
   /**
    * Class written by xPaw
    *
    * Website: http://xpaw.me
    * GitHub: https://github.com/xPaw/PHP-Source-Query-Class
    *
    * Special thanks to koraktor for his awesome Steam Condenser class,
    * I used it as a reference at some points.
    */
   
   if( !defined( '__DIR__' ) ) // PHP < 5.3
   {
      define( '__DIR__', dirname( __FILE__ ) );
   }
   
   require __DIR__ . '/Exceptions.class.php';
   require __DIR__ . '/Buffer.class.php';
   require __DIR__ . '/Socket.class.php';
   require __DIR__ . '/SourceRcon.class.php';
   require __DIR__ . '/GoldSourceRcon.class.php';

   use xPaw\SourceQuery\Exception\InvalidArgumentException;
   use xPaw\SourceQuery\Exception\TimeoutException;
   use xPaw\SourceQuery\Exception\InvalidPacketException;

   class SourceQuery
   {
      /**
       * Values returned by GetChallenge()
       *
       * TODO: Get rid of this? Improve? Do something else?
       */
      const GETCHALLENGE_FAILED         = 0;
      const GETCHALLENGE_ALL_CLEAR      = 1;
      const GETCHALLENGE_CONTAINS_ANSWER = 2;
      
      /**
       * Engines
       */
      const GOLDSOURCE = 0;
      const SOURCE    = 1;
      
      /**
       * Packets sent
       */
      const A2S_PING     = 0x69;
      const A2S_INFO     = 0x54;
      const A2S_PLAYER   = 0x55;
      const A2S_RULES    = 0x56;
      const A2S_SERVERQUERY_GETCHALLENGE = 0x57;
      
      /**
       * Packets received
       */
      const S2A_PING     = 0x6A;
      const S2A_CHALLENGE = 0x41;
      const S2A_INFO     = 0x49;
      const S2A_INFO_OLD = 0x6D; // Old GoldSource, HLTV uses it
      const S2A_PLAYER   = 0x44;
      const S2A_RULES    = 0x45;
      const S2A_RCON     = 0x6C;
      
      /**
       * Source rcon sent
       */
      const SERVERDATA_EXECCOMMAND   = 2;
      const SERVERDATA_AUTH          = 3;
      
      /**
       * Source rcon received
       */
      const SERVERDATA_RESPONSE_VALUE = 0;
      const SERVERDATA_AUTH_RESPONSE = 2;
      
      /**
       * Points to rcon class
       * 
       * @var SourceQueryRcon
       */
      private $Rcon;
      
      /**
       * Points to buffer class
       * 
       * @var SourceQueryBuffer
       */
      private $Buffer;
      
      /**
       * Points to socket class
       * 
       * @var SourceQuerySocket
       */
      private $Socket;
      
      /**
       * True if connection is open, false if not
       * 
       * @var bool
       */
      private $Connected;
      
      /**
       * Contains challenge
       * 
       * @var string
       */
      private $Challenge;
      
      /**
       * Use old method for getting challenge number
       * 
       * @var bool
       */
      private $UseOldGetChallengeMethod;
      
      public function __construct( )
      {
         $this->Buffer = new SourceQueryBuffer( );
         $this->Socket = new SourceQuerySocket( $this->Buffer );
      }
      
      public function __destruct( )
      {
         $this->Disconnect( );
      }

      /**
       * Opens connection to server
       *
       * @param string $Ip Server ip
       * @param int $Port Server port
       * @param int $Timeout Timeout period
       * @param int $Engine Engine the server runs on (goldsource, source)
       *
       * @throws InvalidArgumentException
       * @throws TimeoutException
       */
      public function Connect( $Ip, $Port, $Timeout = 3, $Engine = self :: SOURCE )
      {
         $this->Disconnect( );
         
         if( !is_int( $Timeout ) || $Timeout < 0 )
         {
            throw new InvalidArgumentException( 'Timeout must be an integer.', InvalidArgumentException::TIMEOUT_NOT_INTEGER );
         }
         
         if( !$this->Socket->Open( $Ip, (int)$Port, $Timeout, (int)$Engine ) )
         {
            throw new TimeoutException( 'Could not connect to server.', TimeoutException::TIMEOUT_CONNECT );
         }
         
         $this->Connected = true;
      }
      
      /**
       * Forces GetChallenge to use old method for challenge retrieval because some games use outdated protocol (e.g Starbound)
       *
       * @param bool $Value Set to true to force old method
       *
       * @returns bool Previous value
       */
      public function SetUseOldGetChallengeMethod( $Value )
      {
         $Previous = $this->UseOldGetChallengeMethod;
         
         $this->UseOldGetChallengeMethod = $Value === true;
         
         return $Previous;
      }
      
      /**
       * Closes all open connections
       */
      public function Disconnect( )
      {
         $this->Connected = false;
         $this->Challenge = 0;
         
         $this->Buffer->Reset( );
         
         $this->Socket->Close( );
         
         if( $this->Rcon )
         {
            $this->Rcon->Close( );
            
            $this->Rcon = null;
         }
      }
      
      /**
       * Sends ping packet to the server
       * NOTE: This may not work on some games (TF2 for example)
       *
       * @return bool True on success, false on failure
       */
      public function Ping( )
      {
         if( !$this->Connected )
         {
            return false;
         }
         
         $this->Socket->Write( self :: A2S_PING );
         $this->Socket->Read( );
         
         return $this->Buffer->GetByte( ) === self :: S2A_PING;
      }
      
      /**
       * Get server information
       *
       * @throws InvalidPacketException
       *
       * @return bool|array Returns array with information on success, false on failure
       */
      public function GetInfo( )
      {
         if( !$this->Connected )
         {
            return false;
         }
         
         $this->Socket->Write( self :: A2S_INFO, "Source Engine Query\0" );
         $this->Socket->Read( );
         
         $Type = $this->Buffer->GetByte( );
         
         if( $Type === 0 )
         {
            return false;
         }
         
         // Old GoldSource protocol, HLTV still uses it
         if( $Type === self :: S2A_INFO_OLD && $this->Socket->Engine === self :: GOLDSOURCE )
         {
            /**
             * If we try to read data again, and we get the result with type S2A_INFO (0x49)
             * That means this server is running dproto,
             * Because it sends answer for both protocols
             */
            
            $Server[ 'Address' ]   = $this->Buffer->GetString( );
            $Server[ 'HostName' ]  = $this->Buffer->GetString( );
            $Server[ 'Map' ]       = $this->Buffer->GetString( );
            $Server[ 'ModDir' ]    = $this->Buffer->GetString( );
            $Server[ 'ModDesc' ]   = $this->Buffer->GetString( );
            $Server[ 'Players' ]   = $this->Buffer->GetByte( );
            $Server[ 'MaxPlayers' ] = $this->Buffer->GetByte( );
            $Server[ 'Protocol' ]  = $this->Buffer->GetByte( );
            $Server[ 'Dedicated' ] = Chr( $this->Buffer->GetByte( ) );
            $Server[ 'Os' ]        = Chr( $this->Buffer->GetByte( ) );
            $Server[ 'Password' ]  = $this->Buffer->GetByte( ) === 1;
            $Server[ 'IsMod' ]     = $this->Buffer->GetByte( ) === 1;
            
            if( $Server[ 'IsMod' ] )
            {
               $Mod[ 'Url' ]       = $this->Buffer->GetString( );
               $Mod[ 'Download' ]  = $this->Buffer->GetString( );
               $this->Buffer->Get( 1 ); // NULL byte
               $Mod[ 'Version' ]   = $this->Buffer->GetLong( );
               $Mod[ 'Size' ]      = $this->Buffer->GetLong( );
               $Mod[ 'ServerSide' ] = $this->Buffer->GetByte( ) === 1;
               $Mod[ 'CustomDLL' ] = $this->Buffer->GetByte( ) === 1;
            }
            
            $Server[ 'Secure' ]  = $this->Buffer->GetByte( ) === 1;
            $Server[ 'Bots' ]    = $this->Buffer->GetByte( );
            
            if( isset( $Mod ) )
            {
               $Server[ 'Mod' ] = $Mod;
            }
            
            return $Server;
         }
         
         if( $Type !== self :: S2A_INFO )
         {
            throw new InvalidPacketException( 'GetInfo: Packet header mismatch. (0x' . DecHex( $Type ) . ')', InvalidPacketException::PACKET_HEADER_MISMATCH );
         }
         
         $Server[ 'Protocol' ]  = $this->Buffer->GetByte( );
         $Server[ 'HostName' ]  = $this->Buffer->GetString( );
         $Server[ 'Map' ]       = $this->Buffer->GetString( );
         $Server[ 'ModDir' ]    = $this->Buffer->GetString( );
         $Server[ 'ModDesc' ]   = $this->Buffer->GetString( );
         $Server[ 'AppID' ]     = $this->Buffer->GetShort( );
         $Server[ 'Players' ]   = $this->Buffer->GetByte( );
         $Server[ 'MaxPlayers' ] = $this->Buffer->GetByte( );
         $Server[ 'Bots' ]      = $this->Buffer->GetByte( );
         $Server[ 'Dedicated' ] = Chr( $this->Buffer->GetByte( ) );
         $Server[ 'Os' ]        = Chr( $this->Buffer->GetByte( ) );
         $Server[ 'Password' ]  = $this->Buffer->GetByte( ) === 1;
         $Server[ 'Secure' ]    = $this->Buffer->GetByte( ) === 1;
         
         // The Ship (they violate query protocol spec by modifying the response)
         if( $Server[ 'AppID' ] === 2400 )
         {
            $Server[ 'GameMode' ]    = $this->Buffer->GetByte( );
            $Server[ 'WitnessCount' ] = $this->Buffer->GetByte( );
            $Server[ 'WitnessTime' ] = $this->Buffer->GetByte( );
         }
         
         $Server[ 'Version' ] = $this->Buffer->GetString( );
         
         // Extra Data Flags
         if( $this->Buffer->Remaining( ) > 0 )
         {
            $Server[ 'ExtraDataFlags' ] = $Flags = $this->Buffer->GetByte( );
            
            // The server's game port
            if( $Flags & 0x80 )
            {
               $Server[ 'GamePort' ] = $this->Buffer->GetShort( );
            }
            
            // The server's SteamID - does this serve any purpose?
            if( $Flags & 0x10 )
            {
               $Server[ 'ServerID' ] = $this->Buffer->GetUnsignedLong( ) | ( $this->Buffer->GetUnsignedLong( ) << 32 ); // TODO: verify this
            }
            
            // The spectator port and then the spectator server name
            if( $Flags & 0x40 )
            {
               $Server[ 'SpecPort' ] = $this->Buffer->GetShort( );
               $Server[ 'SpecName' ] = $this->Buffer->GetString( );
            }
            
            // The game tag data string for the server
            if( $Flags & 0x20 )
            {
               $Server[ 'GameTags' ] = $this->Buffer->GetString( );
            }
            
            // GameID -- alternative to AppID?
            if( $Flags & 0x01 )
            {
               $Server[ 'GameID' ] = $this->Buffer->GetUnsignedLong( ) | ( $this->Buffer->GetUnsignedLong( ) << 32 );
            }
            
            if( $this->Buffer->Remaining( ) > 0 )
            {
               throw new InvalidPacketException( 'GetInfo: unread data? ' . $this->Buffer->Remaining( ) . ' bytes remaining in the buffer. Please report it to the library developer.',
                  InvalidPacketException::BUFFER_NOT_EMPTY );
            }
         }
         
         return $Server;
      }
      
      /**
       * Get players on the server
       *
       * @throws InvalidPacketException
       *
       * @return bool|array Returns array with players on success, false on failure
       */
      public function GetPlayers( )
      {
         if( !$this->Connected )
         {
            return false;
         }
         
         switch( $this->GetChallenge( self :: A2S_PLAYER, self :: S2A_PLAYER ) )
         {
            case self :: GETCHALLENGE_FAILED:
            {
               return false;
            }
            case self :: GETCHALLENGE_ALL_CLEAR:
            {
               $this->Socket->Write( self :: A2S_PLAYER, $this->Challenge );
               $this->Socket->Read( 14000 ); // Moronic Arma 3 developers do not split their packets, so we have to read more data
               // This violates the protocol spec, and they probably should fix it: https://developer.valvesoftware.com/wiki/Server_queries#Protocol
               
               $Type = $this->Buffer->GetByte( );
               
               if( $Type === 0 )
               {
                  return false;
               }
               else if( $Type !== self :: S2A_PLAYER )
               {
                  throw new InvalidPacketException( 'GetPlayers: Packet header mismatch. (0x' . DecHex( $Type ) . ')', InvalidPacketException::PACKET_HEADER_MISMATCH );
               }
               
               break;
            }
         }
         
         $Players = Array( );
         $Count  = $this->Buffer->GetByte( );
         
         while( $Count-- > 0 && $this->Buffer->Remaining( ) > 0 )
         {
            $Player[ 'Id' ]   = $this->Buffer->GetByte( ); // PlayerID, is it just always 0?
            $Player[ 'Name' ] = $this->Buffer->GetString( );
            $Player[ 'Frags' ] = $this->Buffer->GetLong( );
            $Player[ 'Time' ] = (int)$this->Buffer->GetFloat( );
            $Player[ 'TimeF' ] = GMDate( ( $Player[ 'Time' ] > 3600 ? "H:i:s" : "i:s" ), $Player[ 'Time' ] );
            
            $Players[ ] = $Player;
         }
         
         return $Players;
      }
      
      /**
       * Get rules (cvars) from the server
       *
       * @throws InvalidPacketException
       *
       * @return bool|array Returns array with rules on success, false on failure
       */
      public function GetRules( )
      {
         if( !$this->Connected )
         {
            return false;
         }
         
         switch( $this->GetChallenge( self :: A2S_RULES, self :: S2A_RULES ) )
         {
            case self :: GETCHALLENGE_FAILED:
            {
               return false;
            }
            case self :: GETCHALLENGE_ALL_CLEAR:
            {
               $this->Socket->Write( self :: A2S_RULES, $this->Challenge );
               $this->Socket->Read( );
               
               $Type = $this->Buffer->GetByte( );
               
               if( $Type === 0 )
               {
                  return false;
               }
               else if( $Type !== self :: S2A_RULES )
               {
                  throw new InvalidPacketException( 'GetRules: Packet header mismatch. (0x' . DecHex( $Type ) . ')', InvalidPacketException::PACKET_HEADER_MISMATCH );
               }
               
               break;
            }
         }
         
         $Rules = Array( );
         $Count = $this->Buffer->GetShort( );
         
         while( $Count-- > 0 && $this->Buffer->Remaining( ) > 0 )
         {
            $Rule = $this->Buffer->GetString( );
            $Value = $this->Buffer->GetString( );
            
            if( !Empty( $Rule ) )
            {
               $Rules[ $Rule ] = $Value;
            }
         }
         
         return $Rules;
      }

      /**
       * Get challenge (used for players/rules packets)
       *
       * @param $Header
       * @param $ExpectedResult
       * @throws InvalidPacketException
       * @return bool True if all went well, false if server uses old GoldSource protocol, and it already contains answer
       */
      private function GetChallenge( $Header, $ExpectedResult )
      {
         if( $this->Challenge )
         {
            return self :: GETCHALLENGE_ALL_CLEAR;
         }
         
         if( $this->UseOldGetChallengeMethod )
         {
            $Header = self :: A2S_SERVERQUERY_GETCHALLENGE;
         }
         
         $this->Socket->Write( $Header, 0xFFFFFFFF );
         $this->Socket->Read( );
         
         $Type = $this->Buffer->GetByte( );
         
         switch( $Type )
         {
            case self :: S2A_CHALLENGE:
            {
               $this->Challenge = $this->Buffer->Get( 4 );
               
               return self :: GETCHALLENGE_ALL_CLEAR;
            }
            case $ExpectedResult:
            {
               // Goldsource (HLTV)
               
               return self :: GETCHALLENGE_CONTAINS_ANSWER;
            }
            case 0:
            {
               return self :: GETCHALLENGE_FAILED;
            }
            default:
            {
               throw new InvalidPacketException( 'GetChallenge: Packet header mismatch. (0x' . DecHex( $Type ) . ')', InvalidPacketException::PACKET_HEADER_MISMATCH );
            }
         }
      }
      
      /**
       * Sets rcon password, for future use in Rcon()
       *
       * @param string $Password Rcon Password
       *
       * @return bool True on success, false on failure
       */
      public function SetRconPassword( $Password )
      {
         if( !$this->Connected )
         {
            return false;
         }
         
         switch( $this->Socket->Engine )
         {
            case SourceQuery :: GOLDSOURCE:
            {
               $this->Rcon = new SourceQueryGoldSourceRcon( $this->Buffer, $this->Socket );
               
               break;
            }
            case SourceQuery :: SOURCE:
            {
               $this->Rcon = new SourceQuerySourceRcon( $this->Buffer, $this->Socket );
               
               break;
            }
         }
         
         $this->Rcon->Open( );
         
         return $this->Rcon->Authorize( $Password );
      }
      
      /**
       * Sends a command to the server for execution.
       *
       * @param string $Command Command to execute
       *
       * @return string|bool Answer from server in string, false on failure
       */
      public function Rcon( $Command )
      {
         if( !$this->Connected )
         {
            return false;
         }
         
         return $this->Rcon->Command( $Command );
      }
   }
Offensichtlich werden hier die Bytes für das PHP-Script definiert und ausgewertet, entschlüsselt und oder decodiert ...
Flo

Geändert von Flodding (18. Feb 2015 um 17:11 Uhr) Grund: PHP quellcode vergessen
  Mit Zitat antworten Zitat
BadenPower

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

AW: Query an Gameserver

  Alt 18. Feb 2015, 17:25
Offensichtlich werden hier die Bytes für das PHP-Script definiert und ausgewertet, entschlüsselt und oder decodiert ...
Da hast Du doch alles, was Du benötigst.

Jetzt musst Du halt nur noch den PHP-Code in Delphi nachbilden.

Also einfacher kann man es nun wirklich nicht haben.
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
 
#17

AW: Query an Gameserver

  Alt 18. Feb 2015, 17:31
Code:
case self :: GETCHALLENGE_ALL_CLEAR:
            {
               $this->Socket->Write( self :: A2S_PLAYER, $this->Challenge );
               $this->Socket->Read( 14000 );              
               $Type = $this->Buffer->GetByte( );
               
               if( $Type === 0 )
               {
                  return false;
               }
               else if( $Type !== self :: S2A_PLAYER )
               {
                  throw new InvalidPacketException( 'GetPlayers: Packet header mismatch. (0x' . DecHex( $Type ) . ')', InvalidPacketException::PACKET_HEADER_MISMATCH );
               }
               
               break;
            }
Hier werden die Spieler auf dem Server erkannt ja?

Im oberen Teil des Codes finde ich :

Code:
const A2S_PLAYER   = 0x55;
Dies sollte bedeuten, dass der Buffer den ich senden muss so aussehen sollte:

FF FF FF FF 55

Dabei fehlt mir dann aber dieses Challenge ... das versteh ich nicht was damit gemeint ist.
Flo
  Mit Zitat antworten Zitat
BadenPower

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

AW: Query an Gameserver

  Alt 18. Feb 2015, 17:39
Hast Du Dir diese Seite schon angesehen, welche Neutral General bereits gepostet hat?

https://developer.valvesoftware.com/wiki/Server_queries
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
 
#19

AW: Query an Gameserver

  Alt 18. Feb 2015, 17:52
Ja und ich lese und lese und lese...

Ich habe das so verstanden:

Insgesammt gibt es 5 verschiedene Arten dem Server Daten abzufragen... diese wären:

A2S_INFO

A2S_PLAYER

A2S_RULES

A2A_PING

A2S_SERVERQUERY_GETCHALLENGE


Um diese Daten abzufragen benötige ich eine UDP/IP Verbindung. Über diese Verbindung muss ich jedes mal den HEADER mitsenden... dieser besteht aus FF FF FF FF (nicht gesplittetes Paket) oder FF FF FF FE (gesplittetes Paket). Da die Größe der Daten die ich abfragen will gering ist, gehe ich davon aus, dass ich nur den ersten HEADER benutzen muss. Somit haben wir den ersten teil des Buffers schon zusammen.

FF FF FF FF

um jetzt die gewünschten Daten zu bekommen muss ich das benütigte Byte hinten dranhängen.
Flo
  Mit Zitat antworten Zitat
Flodding

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

AW: Query an Gameserver

  Alt 18. Feb 2015, 18:39
Okay ... also ich habe jetzt verstanden, dass ich für die Spieler erst ein Challenge brauche...

dieses Challenge bekomme ich auch...

FF FF FF FF 55 FF FF FF FF

Damit bekomme ich dann folgende ausgabe im RAW format:

Code:
ÿÿÿÿA1º
Lðˆ' €x1€ÖvŸs '/à' øïŒ+Çvà'¤
'ð½jÇvBòðFtÆvà'Bò`ð(BÇvBò   'ü'   'à' 'T 'XðhiÇvà'xð ŒÆvSzÆv*  BòÄðeT¼vBòÄð².D$ñÿÿÿÿà'ÀðìðPñ$ñÈ pqçÈ ôðùJA°íY<Ba<BpqçÜê;&DñR&DZ&DÈñ¹r¹u»t¹u¶c…ûƒž¶cÿÿÿÿ…Îv¶c¶c*i¹uvr¹uWr¹u¶c©¶cpñ(zq¹uøÎv6q¹u(¶c¶c¶clñ¶c°ñŒj¹uðv¥…ûƒ òd q¶c…ûƒûƒ€1/}¹u/}¹u4òجqJ4p;H;wqbj¹u(ò– qûƒ4òb¹u0Àuôpò4k¹uk¹uÎvûƒ€1/}¹ulòëUÑvY Z€1â`¹uht¹uY Z; óðû)s¶cY Z€1ÿû)sò°´FY Z€x1¶cЙ!sðv¥ðv¥ ó,p¹uðv¥_¶cЙ!s&ëƒüÀ2©§0wÐ2Xîþîþ
p2/(2Й!sò°
$ôZ<+w
œ±0w$ôÎW-wÓ<+w©±Mu6/P/Í«ºÜP/¨t/¤ó
èÖvP/h2”ÎvЙ!s
$¸2Øû0pw‘m¹uxpw/Š¦0wÐ2Xîþîþ/p2
   ¶cÈ2h2Øû0h
õ/è¬0w€2¨ª8+w°Mu/x2/”/Dpw¶c…ò°P//P/h2žÂB€å¬ô5w/h2¸Š5wpw€//P/x2® h2õqeW0ôÐW3whõ4õ5w//p2ê¸*wp2//ê¸*wp2xõ°5w8/”5wõ°Mu/// g§ g
ÿÿÿÿA heisst ja nun dass es die antwort auf die Anfrage ist ein Challenge zu bekommen...

Jetzt ist mein "neues" Problem, dass ich nicht weiss wie ich die nächsten Query senden soll...

FF FF FF FF 55 CHALLENGE im RAW Format?!
Flo
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 2 von 12     12 34     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 16:06 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