Конференция "Начинающим" » Indy + master server query protocol (VALVE)
 
  • HF-Trade © (10.01.18 17:19) [0]
    На буржуинском сайте, описан протокол для получения списка серверов:
    https://developer.valvesoftware.com/wiki/Master_Server_Query_Protocol

    В частности:
    ............
    IP:Port
    The first IP:Port you should send is "0.0.0.0:0"
    From then on, IP:Port becomes the last IP:Port received in the master servers reply. This allows steam to then grab another list of more servers.
    Terminate this with 0x00
    ............
    End of IP address list
    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.
    The end of the IP list is indicated by a received IP address of 0.0.0.0 Port:0.
    ............

    Написал c инди -

    Request := '1' + #$FF + '0.0.0.0:0' + #$00 + '\appid\33930';
    setLength(AnswerBytes, 4096);
    IdUDPClient.Send(Request, IndyTextEncoding(1251));
    I := IdUDPClient.ReceiveBuffer(AnswerBytes);
    ............
    While RequestAddr <> '0.0.0.0:0' do
    Begin
     Request := '1' + #$FF + RequestAddr + #$00 + '\appid\33930';
     setLength(AnswerBytes, 4096);
     IdUDPClient.Send(Request, IndyTextEncoding(1251));
     I := IdUDPClient.ReceiveBuffer(AnswerBytes);
     setLength(AnswerBytes, I);
     IF (Length(AnswerBytes) < 5) Then
      Break;
     RequestAddr := Get_Last_Addr(AnswerBytes);
     For I := 0 to Length(AnswerBytes) - 1 do
      AnswerString := AnswerString + AnsiChar(AnswerBytes[I]);
    End;
    ............



    Получаю ответ после первого запроса. Все правильно(проверял сервера, список рабочий).
    Далее, если я правильно понял, -
    В последнем пакете, должен прийти в конце ип 0.0.0.0 и порт 0, а до тех пор, необходимо слать запросы с указанием последнего ип+порта в пришедшем ответе.

    В Get_Last_Addr получаю последний ИП+Порт, подставляю в запрос в цикле.. И приходит тот же ответ, что и на первый запрос.

    Вот к примеру на php почти тоже самое - и все работает(вырезал именно формирование запроса).
    ............
    if ($serverIP == "0.0.0.0" AND $serverPort == "0")
    {
     echo("Sending new request to master ...\n");
     $request = "1\xFF".$seedIP.":".$seedPort."\xFF\appid\33930";
    ............



    Мож кто, что путного скажет?
  • hf-trade © (10.01.18 17:24) [1]
    И еще, меня смущает немного вот это:
    Note that whenever you open a new socket (and thus get a new random client port), the Master Server will always send you the first batch of IPs even if you pass a valid game server IP. Do not close your socket between packets.
  • Try To (11.01.18 00:52) [2]
    IdUDPClient.Connect; // <- try to establish persistent connection before sending request
    IdUDPClient.Send(Request, IndyTextEncoding(1251));
  • hf-trade © (11.01.18 09:16) [3]
    [2]
    Ессесно, так и сделано -

    IdUDPClient                  := TIdUDPClient.Create(nil);
    IdUDPClient.BroadcastEnabled := True;
    IdUDPClient.Host             := Master_Host;
    IdUDPClient.Port             := Master_Port;
    IdUDPClient.ReceiveTimeout   := 23000;
    Request                      := #$31 + #$FF + '0.0.0.0:0' + #$00 + '\appid\33930';
    IdUDPClient.Active           := True;
    IdUDPClient.Connect;
    setLength(AnswerBytes, 4096);
    IdUDPClient.Send(Request, IndyTextEncoding(1251));
    I                            := IdUDPClient.ReceiveBuffer(AnswerBytes);
  • hf-trade © (11.01.18 09:28) [4]
    В цикл тоже добавил на всякий случай)
  • NoNameUltima (11.01.18 12:12) [5]
    Добавил
    setLength(AnswerBytes, 0);
    перед
    setLength(AnswerBytes, 4096);

    но все равно результата нема..
  • KilkennyCat © (12.01.18 12:59) [6]

    > Добавил
    > setLength(AnswerBytes, 0);
    > перед
    > setLength(AnswerBytes, 4096);

    это надо в цикле делать, минимум 7 итераций
  • hf-trade © (13.01.18 00:05) [7]

    > KilkennyCat ©   (12.01.18 12:59) [6]

    сарказм?)

    т.е. при таком написаннии:

    setLength(AnswerBytes, 4096);
    Try
    IdUDPClient.Send(Request, IndyTextEncoding(1251));
    I := IdUDPClient.ReceiveBuffer(AnswerBytes);
    Except
    end;


    внутри цикла, не может быть ситуации, - когда содержимое AnswerBytes останется прежним?

    P.S. Вопрос, кстати снят - все порешал.
    P.S.P.S. Ники в браузерах разные были.
  • KilkennyCat © (13.01.18 01:09) [8]

    > hf-trade ©   (13.01.18 00:05) [7]
    > сарказм?)

    да. хотя и бывают ситуации, когда на самом деле с виду одинаковые операции дают совершенно различный результат. но не здесь.
    Здесь уместнее заполнить буфер нулями или фф, после setLength(AnswerBytes, 4096);
    Но не уверен, непомню уже, мож, очистка автоматом ща делается.
  • hf-trade © (16.01.18 16:15) [9]
    Как правильно распарсить ответ?

    Function GET_SERVER_RULES(Host: String; Port: Word): AnsiString;
    Var
    IdUDPClient : TIdUDPClient;
    Request     : AnsiString;
    Answer      : TIdBytes;
    Begin
    Result           := '';
    Try
     IdUDPClient      := TIdUDPClient.Create(nil);
     IdUDPClient.Host := Host;
     IdUDPClient.Port := Port;
     Request          := #$FF + #$FF + #$FF + #$FF + #$56 + #$FF + #$FF + #$FF + #$FF;
     setLength(Answer, 9);
     For I := 0 to 9 do
      Answer[I] := $FF;
     IdUDPClient.Active := True;
     IdUDPClient.Send(Request, IndyTextEncoding(1251));
     IdUDPClient.ReceiveBuffer(Answer);
     Request := #$FF + #$FF + #$FF + #$FF + #$56 + AnsiChar(Answer[5]) + AnsiChar(Answer[6]) + AnsiChar(Answer[7]) + AnsiChar(Answer[8]);
     setLength(Answer, 4096);
     For I := 0 to 4096 do
      Answer[I] := $FF;
     IdUDPClient.Send(Request, IndyTextEncoding(1251));
     I := IdUDPClient.ReceiveBuffer(Answer);
     setLength(Answer, I);
     IdUDPClient.Free;
     For I := 0 to HIGH(Answer) do
      Result := Result + AnsiChar(Answer[I]);
    Except
    End;
    End;

    procedure TForm_Main.Button1Click(Sender: TObject);
    Var
    Server_Rules : AnsiString;
    Begin
    Server_Rules := GET_SERVER_RULES('110.232.24.106', 2303);
    end;


    https://developer.valvesoftware.com/wiki/Server_queries

    A2S_RULES:
    Response Format
    Note:Responses to this query are usually multi-packeted.
    Data  Type  Comment
    Header  byte  Always equal to 'E' (0x45)
    Rules  short  Number of rules in the response.

    For every rule in "Rules" there is this chunk in the response:
    Data  Type  Comment
    Name  string  Name of the rule.
    Value  string  Value of the rule.
  • kilkennycat © (16.01.18 21:57) [10]

    > For I := 0 to 4096 do
    >    Answer[I] := $FF;


    FillChar, ZeroMemory...
 
Конференция "Начинающим" » Indy + master server query protocol (VALVE)
Есть новые Нет новых   [118675   +66][b:0][p:0.001]