2

UdpClientを使用して、サーバー名、マップ、プレーヤー数などについてゲームサーバーにクエリを実行しています。

このページ(A2S_INFO)のガイドラインに従いました http://developer.valvesoftware.com/wiki/Server_queries#Source_servers

そして私は正しい返事を受け取っています:

代替テキストhttp://data.fuskbugg.se/skalman01/reply.JPG

情報の各チャンク(サーバー名、マップなど)をどのように取得するのかわかりません。

何か助けはありますか?リンクしたwikiで指定されている返信形式を確認する必要があると思いますが、どうすればよいかわかりません。

4

1 に答える 1

6

応答形式は、基本的に構造体のように、応答パケット内のフィールドの順序とタイプを提供します。のようなクラスを使用BinaryReaderして、パケット内のバイトのグループを読み取り、それらを適切なデータ型として解釈できます。

どのように応答を得ていますか?

  1. すでにストリームに含まれている場合は、設定されています。
  2. バイト配列の場合は、MemoryStream最初にラップします。私UdpClientはそれをこのようにすると思います。

次に、BinaryReaderストリームを使用してを作成します。ストリームとリーダーの両方がである必要があることを忘れないでくださいDisposed

BinaryReader reader = new BinaryReader(stream);

ReadByteこれで、などのリーダーのメソッドを呼び出してReadInt32、フィールドのタイプに対応するメソッドを使用して、応答から各フィールドを順番に読み取ることができます。ストリームは読み取られるときに内部オフセットを更新するため、応答バッファーの適切な場所から連続するフィールドを自動的に読み取ります。 BinaryReaderSteamパケットで使用される5つの非文字列タイプに適したメソッドがすでにあります。

  1. byte: ReadByte
  2. short: ReadInt16
  3. long: ReadInt32
  4. float: ReadSingle
  5. long long: ReadUInt64(はい、そこにUがあります。Valveページにはこれらは署名されていないと書かれています)

stringは、Valve(nullで終了するUTF-8)で指定された形式の文字列を読み取るメソッドがまだないため、少しBinaryReader注意が必要です。したがって、バイトごとに自分で行う必要があります。他のBinaryReaderメソッドとできるだけ似せるために、拡張メソッド(テストされていないコード。これがその要点です)を作成できます。

public static string ReadSteamString(this BinaryReader reader)
{
  // To hold the list of bytes making up the string
  List<byte> str = new List<byte>();
  byte nextByte = reader.ReadByte();
  // Read up to and including the null terminator...
  while (nextByte != 0)
  {
    // ...but don't include it in the string
    str.Add(nextByte);
    nextByte = reader.ReadByte();
  }

  // Interpret the result as a UTF-8 sequence      
  return Encoding.UTF8.GetString(str.ToArray());
}

あなたが与えた応答パケットでのいくつかの使用例:

// Returns -1, corresponding to FF FF FF FF
int header = reader.ReadInt32();
// Returns 0x49, for packet type
byte packetType = reader.ReadByte();
// Returns 15, for version
byte ver = reader.ReadByte();
// Returns "Lokalen TF2 #03 All maps | Vanilla"
string serverName = reader.ReadSteamString();
// Returns "cp_well"
string mapName = reader.ReadSteamString();
// etc.

BinaryWriter個々のバイト値を手動で組み立てる代わりに、同様のコードを使用してリクエストパケットを作成できます。

于 2010-06-10T20:42:14.970 に答える