![]() |
AW: Query an Gameserver
Hab den Fehler gefunden.
Delphi-Quellcode:
kann ja nicht gehen... wofür hab ich denn EXTRA ne GETSTRING Funktion geschenkt bekommen?
Move(buffer[i], response.PlayerName, SizeOf(response.PlayerName)); inc(i, SizeOf(response.PlayerName));
Delphi-Quellcode:
Muss es natürlich heissen.
response.PlayerName := GetString(buffer, i);
Die Abfrage mit den Spielernamen funktioniert nun auch:
Delphi-Quellcode:
Ja mir fehlen viele Grundlagen was dieses Thema angeht. Ich hatte ehrlich gesagt auch nicht damit gerechnet vor solch Problemen (aus meiner Sicht jetzt) zu stehen als ich meinen kleinen CommunityLauncher angefangen habe zu basteln. Grundsätzlich wollte ich auch NUR die aktuelle Anzahl der Spieler anzeigen lassen, aber es taten sich mit einmal alle Möglichkeiten auf und dadurch ist es erst so eskaliert (wenn dies dann das richtige Wort ist)
procedure Get_PLAYER_INFO;
var request: TInfoRequest; response: TPlayerResponse; buffer: TBufferArray; i: Integer; y: integer; begin request.RequestHeader := -1; request.PacketHeader := 'U'; request.Payload := 'FFFFFFFF'; // Von mir aus auch mit einer Konstante oder einem Ressourcestring 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.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.Challenge, SizeOf(response.Challenge)); inc(i, SizeOf(response.Challenge)); i := 0; request.Payload[0] := chr(buffer[5]); request.Payload[1] := chr(buffer[6]); request.Payload[2] := chr(buffer[7]); request.Payload[3] := chr(buffer[8]); form4.Udp1.SendBuf(request, SizeOf(TInfoRequest)); form4.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)); Move(buffer[i], response.PlayerCount, SizeOf(response.PlayerCount)); inc(i, SizeOf(response.PlayerCount)); 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)); form4.ListBox1.Items.Add(response.PlayerName); end; form4.lblServerHeader.Caption := chr(response.PacketHeader); // D = Antwort -> Playerinfos kommen end; end; Bis jetzt habe ich immer nur kleinere Tools gebastelt die mit dann im Alltag Kleinigkeiten abnehmen oder Dateieinhalte ändern und sowas. Da brauchte ich solch Teufelszeug noch nie und dementsprechend gering sind meine Erfahrungen damit. Wobei ich sagen muss, dass ich in der Vergangenheit wohl auch eher umständlich Programmiert habe als effizient. Ich habe es auch schon vorher erwähnt. Ich bin kein Professioneller Programmierer und werds leider auch niemals werden. Aber genau dafür gibt es solche Foren, wo Menschen die Wissen haben, es auch teilen können mit denen die es nicht haben oder noch nicht genug. Trotzdem möchte ich mich hier nochmal bei jedem bedanken der an diesem Thema seinen Beitrag geleistet hat und hoffe, dass zukünftige Forumbesucher mit der selben Problematik es hierdurch leichter haben. Am Ende bleibt ein Problem übrig... Zitat:
|
AW: Query an Gameserver
Zitat:
Aber ich habe auch die Ausgabe von dem folgenden Link angeschaut: ![]() Dort wird die ID auch positiv als 33930 dargestellt. Und eine negative ID macht in meinen Augen doch auch keinen Sinn. Daher bin ich eigentlich der Meinung, dass es ein "Word" sein müsste. |
AW: Query an Gameserver
Nein, was es ist ist eindeutig von Valve festgelegt: 16 bit signed integer
Was du daraus interpretierst ist und bleibt deine Sache. Du kannst ja auch die ID als HEX-Wert ausgeben, oder ![]() Es ist einfach eine eindeutige ID und das wichtigste ist, dass beim Austausch mit dem Rest der Welt, die korrekte Bytefolge zu dieser ID wieder zurückgegeben wird. In der Schnittstelle würde ich das immer so belassen, wie es vorgegeben ist ... |
AW: Query an Gameserver
Zitat:
Ist es aber auch richtig? Ich wage daran zu zweifeln, da dort die "Steam Application ID" ausgegeben werden soll und diese beginnen bei 0. Und bei diesem Gameserver mit diesem Port, den uns Flodding genannt hat ist die AppId laut Steamdb.info nun mal 33930 und nicht -31606. |
AW: Query an Gameserver
Das ist doch lediglich eine Frage der Interpretation, 2 Byte bleiben 2 Byte.
|
AW: Query an Gameserver
Zitat:
Delphi-Quellcode:
Normalerweise sollte die Funktion WaitForData() true zurückgeben wenn der Server bereit ist. Da bei mir mit D2007 aber immer false geliefert wird, mache das wie oben gepostet.
procedure TForm4.Get_A2S_INFO;
var Request: TInfoRequest; Response: TInfoResponse; Buffer: TBufferArray; I: Integer; CheckTime: TDateTime; begin Request.RequestHeader := 'ÿÿÿÿ'; Request.PacketHeader := 'T'; Request.Payload := 'Source Engine Query'; Request.Payload[19] := #0; Udp1.RemoteHost:= Edit1.Text; Udp1.RemotePort:= Edit2.Text; Udp1.Open; if (Udp1.Connected) then begin Udp1.SendBuf(Request, SizeOf(TInfoRequest)); CheckTime := Now(); Udp1.WaitForData(5000); if (SecondsBetween(Now(),CheckTime) <= 1) then begin Udp1.ReceiveBuf(Buffer, SizeOf(Buffer)); I := 0; Move(Buffer[I], Response.ResponseHeader, SizeOf(Response.ResponseHeader)); Inc(I, SizeOf(Response.ResponseHeader)); //... end; end; end; Kann das einmal jemand prüfen, ob bei höheren Delphi-Versionen True zurückgegeben wird? Wenn ja dann könnte man das Workaround in höheren Versionen weglassen. |
AW: Query an Gameserver
EDIT: Frage nach der Antwort gepostet. :oops:
Hallo! Immernoch die "nicht erreichbar" Problematik. Mein aktueller Code um die Verbindung aufzubauen:
Delphi-Quellcode:
Wenn der Port korrekt ist, wird 1 Sekunde gewartet und dann der "buffer" gelesen.
form4.udp1.RemoteHost:= '5.45.97.44';
form4.udp1.RemotePort:= '2301'; form4.udp1.Open; if form4.udp1.Connected then begin form4.Udp1.SendBuf(request, SizeOf(TInfoRequest)); form4.Udp1.ReceiveBuf(buffer, SizeOf(buffer)); form4.udp1.WaitForData(1000); if Length(buffer)<1 then begin form4.udp1.Close; exit; end; Ist der Port aber kein QueryPort:
Delphi-Quellcode:
Das Programm hängt sich auf.
form4.udp1.RemoteHost:= '5.45.97.44';
form4.udp1.RemotePort:= '1111'; // Port geändert form4.udp1.Open; if form4.udp1.Connected then begin form4.Udp1.SendBuf(request, SizeOf(TInfoRequest)); form4.Udp1.ReceiveBuf(buffer, SizeOf(buffer)); form4.udp1.WaitForData(1000); if Length(buffer)<1 then begin form4.udp1.Close; exit; end; Ich hab schon nachgelesen und scheinbar hängt es sich nicht wirklich auf, sondern lauscht weiterhin und wartet auf Antwort. Ich bin auf diese Option gestoßen:
Delphi-Quellcode:
Damit soll das angeblich funktionieren, jedoch bekomme ich dann immer die Meldung vom "OnError"-Event, dass keine Verbindung aufgebaut werden konnte.
form4.udp1.BlockMode := bmNonBlocking
Delphi-Quellcode:
Irgendwelche Ideen?
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; |
AW: Query an Gameserver
Ich habe das OnError Event erstmal deaktiviert, weil der immer ausgelöst wurde wenn WaitForData zu lange gedauert hat.
Habs so ausprobiert jetzt:
Delphi-Quellcode:
Bleibt immernoch hängen und wartet nicht nur 1 Sekunde.
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)); CheckTime := Now(); form4.udp1.WaitForData(1000); if (SecondsBetween(Now(),CheckTime) <= 1) then begin form4.Udp1.ReceiveBuf(buffer, SizeOf(buffer)); i := 0; ... ... |
AW: Query an Gameserver
Da es mir Schmerzen verursacht, es immer wieder zu lesen: Es gibt keine UDP-Verbindung! UDP ist ein verbindungsloses Protokoll. Die Verbindung gibt es auf Anwendungsebene ... also das was du gerade programmierst.
Bezüglich des Fehlers: Guck dir mal den Errorcode an ... eventuell steht da nur so ![]() |
AW: Query an Gameserver
Zitat:
Also
Delphi-Quellcode:
Weil wenn der TimeOut nur 1 Sekunde (Wert 1000) sein soll, dann ist der Unterschied zwischen CheckTime und Now() in der If-Anweiung IMMER kleiner oder gleich 1 Sekunde.
form4.udp1.WaitForData(5000);
if (SecondsBetween(Now(),CheckTime) <= 1) then begin ... |
Alle Zeitangaben in WEZ +1. Es ist jetzt 14:26 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz