HL2 Server abfragen
Übersicht

gambleBetreff: HL2 Server abfragen |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Hi,
ich habe mir vorgenommen mal ein kleines Programm zu schreiben, mit welchem man Infos von einem HL2 Server angezeigt bekommt. Dazu muss ich zuerst folgendes an den Server schicken: UINT32 0xFFFFFFFF BYTE 0x54 Ich habe es im Moment wie folgt gelöst: BlitzBasic:
Bekomme jedoch keine Antwort. Ich ahne schon, dass der Server mich einfach nicht versteht. Sobald ich aber ein 0x vor beide Werte anhänge, bekomme ich was von "Unknow identifier: x ...". Wie kann ich das jetzt lösen? |
||
gamble |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Weiß zwar nicht was da los ist, auf jedenfall funktioniert das Beispiel da oben jetzt. Dafür habe ich jetzt ein anderes Problem:
Ich habe den Integer, das Kontrollbyte, die Protokollversion und den Servernamen ohne Probleme ausgelesen. Wenn ich ReadString dann aber nochmal anwenden, wird mir NICHTS ausgegeben, obwohl da noch genug im Stream drin liegt (das nächste wäre der Mapname, ebenfalls ein String). Warum klappt das nicht? Ist das vielleicht ein Bug in Bnet? |
||
![]() |
Vertex |
![]() Antworten mit Zitat ![]() |
---|---|---|
Sorry, ich verstehe nicht, was das Problem ist.
Strings jedenfalls haben ihr eigenes Format in BMax. Damit wird der Server sicher nix anfangen können. Versuchs höchstens mal mit WriteLine statts WriteString. mfg olli |
||
vertex.dreamfall.at | GitHub |
gamble |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Es geht ums lesen, nicht ums schreiben.
Das Problem ist folgendes: Ich lese aus dem Stream, und obwohl im Stream noch etwas drin ist (sein müsste), bekomme ich nichts ausgegeben. Wenn ich ReadByte, Readint ... verwende dann bekomme ich wirre Zahlenkombinationen. Nur bei ReadString bekomme ich nichts zurück, obwohl da eigentlich ein String auf mich wartet. Das die Strings ein anderes Format haben dürfte auch nicht wirklich der Grund sein, immerhin konnte ich den Server-Namen ja auch auslesen. |
||
![]() |
Jolinah |
![]() Antworten mit Zitat ![]() |
---|---|---|
Jo, das liegt bestimmt am Stringformat. Hatte dafür extra mal ne Funktion geschrieben, habs leider beim Upgrade auf die neue BMax Version verloren ![]() Also vor dem eigentlichen String steht ja immer die Länge des Strings. Wenn der String 255 Zeichen lang ist hätte das ja genau in einem Byte Platz. Wenn der String aber länger ist brauchts 2 Bytes. Um nicht einfach fix 4 Bytes zu übertragen wenn diese gar nicht nötig wären hat man das mit diesem 7-Bit encoding gemacht. Damit kann man jedoch nur noch 128 in 1 Byte bringen, weil ein Teil des Bytes für diesen kleinen Algorythmus (oder wie man es nennen soll) verwendet wird. Da man aber meistens nicht ellenlange Texte übers Netzwerk überträgt in Spielen (meistens < 128 Zeichen) lohnt sich das ganze schon, da man jedesmal 3 Bytes einspart pro String. Wenn der String dann grösser ist werden einfach mehrere Bytes vorab geschickt. Diese dynamische Anzahl an Vorab-Bytes macht dann BMax Probleme. Vielleicht finde ich die Funktion irgendwo noch oder mache sie neu. Wenn nicht kannst du ja mal nach 7-Bit encoded Integers oder so suchen ![]() Edit: Soviel ich weiss muss man bei ReadString in BMax ja die Länge des Strings angeben. Das heisst man muss die Länge vorher manuell auslesen. Beim Servernamen war da vielleicht auch nur 1 Byte am Anfang, aber bei anderen Texten könnten es halt auch 2 oder 4 sein wegen der dynamischen Länge. |
||
gamble |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Urgh, das ist ägerlich ... Aber warum einfach, wenns auch kompliziert geht ![]() Edit: Ah, Lösung! Ich habe vor das zweite ReadString einfach ein ReadByte gepackt. Jetzt wird mir der String auch angezeigt ![]() Edit 2: Soweit so gut. Jetzt muss ich nur noch die Länge der Strings herausfinden den ich lesen will. Das Byte was ich vorher ausgelesen hab, hat allerdings den Wert 0, obwohl der String selber 8 Zeichen hat. Wie komm ich denn jetzt an die Stringlänge ran? |
||
- Zuletzt bearbeitet von gamble am So, Mai 22, 2005 19:50, insgesamt 2-mal bearbeitet
![]() |
Jolinah |
![]() Antworten mit Zitat ![]() |
---|---|---|
Weil man damit Traffic einsparen kann, und somit auch Kosten ![]() Edit: Hab C Code gefunden, hier der BMax Code, sollte funktionieren (nicht getestet) Code: Function Read7BitInt(stream:TStream) Local _count:Int = 0 Local _shift:Int = 0 Local _counter:Int = 0 Local _b:Byte = 0 Repeat Try _b = ReadByte(stream) Catch Ex:Object Throw "Error reading 7 Bit encoded Integer" End Try _counter :+ 1 If _counter > 4 Throw "Overflow 7 Bit encoded Integer" EndIf _count = _count | (_b & $7F) Shl _shift _shift :+ 7 Until (_b & $80) = 0 Return _count End Function Anwendung: Code: Local length:Int = Read7BitInt(stream) Local mystring:String = ReadString(stream, length) |
||
gamble |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Bekomme gleich die Exception um die Ohren gehauen:
Overflow 7 Bit encoded Integer ![]() |
||
![]() |
Jolinah |
![]() Antworten mit Zitat ![]() |
---|---|---|
Ich hatte nen Fehler bei Repeat Until. Original wars do while. Das heisst du musst das Not einfach entfernen, siehe oben.
Edit: Hier noch das schreiben Code: Function Write7BitInt(stream:TStream, value:Int) While value >= $80 WriteByte(stream, Byte((value | $80)) ) value = value Shr 7 Wend WriteByte(stream, Byte(value)) End Function Code: Local name:String = "Bla" Write7BitInt(stream, Len(name)) WriteString(stream, name) |
||
gamble |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Jo, danke. Nur das Ergebnis ist leider 0 - wie beim "normalen" ReadByte auch. Merkwürdig. | ||
![]() |
Jolinah |
![]() Antworten mit Zitat ![]() |
---|---|---|
Dann wirds wohl sonst ein Problem sein. Bist du sicher dass du alles entsprechend dem Protokoll von HL2 richtig gemacht hast? | ||
gamble |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Eigentlich schon. Ich poste einfach mal den Code:
Code: While True If RecvUDPMsg(STREAM) Then Local server:TS2A_INFO_SRC = New TS2A_INFO_SRC Readint(STREAM) server.Kontrollbyte = ReadByte(STREAM) server.Protokollversion = ReadByte(STREAM) server.Name = ReadString(STREAM,32) Local length = Read7BitInt(STREAM) Print ReadString(STREAM,length) End End If Wend Das erste Readint beinhaltet einfach nur -1, die nächsten beiden Bytes beinhalten das Kontrollbyte und die Protokollversion. Dann folgt schon der Servername. Da ich im Moment nur teste, kenne ich die Länge aus dem Kopf (32 Zeichen). Ermitteln kann ich sie auch nich, da ich dann irgendwas von 100 erhalte. Danach halt der Mapname - da length aber 0 ist wird der nicht angezeigt. Hier der Aufbau der Antwort vom Server. Vielleicht bekommt das ja wer zum laufen? http://wiki.hlsw.de/wiki/index...eprotokoll |
||
![]() |
Jolinah |
![]() Antworten mit Zitat ![]() |
---|---|---|
Hm Interessant ![]() Kennst du grad eine Server-IP? Dann kann ich ja auch mal bisschen rumprobieren. |
||
gamble |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Klar.
62.4.74.236:30900 |
||
![]() |
Vertex |
![]() Antworten mit Zitat ![]() |
---|---|---|
Hi!
Zitat: SzString: Null-Terminierte Zeichenkette
Code: Local UDP:TUDPStream
Local Temp:String Local Char:Byte UDP = CreateUDPStream() WriteInt UDP, $FFFFFFFF WriteByte UDP, $54 SendUDPMsg UDP, IntIP("62.4.74.236"), 30900 Repeat If RecvUDPMsg(UDP) Then Print "OK: "+Hex(Readint(UDP)) Print "Kontrollbyte: "+Chr(ReadByte(UDP)) Print "Protokollversion: "+ReadByte(UDP) Repeat Char = ReadByte(UDP) If Char = 0 Then Exit Temp :+ Chr(Char) Forever Print "Servername: "+Temp Temp = "" Repeat Char = ReadByte(UDP) If Char = 0 Then Exit Temp :+ Chr(Char) Forever Print "Map Name: "+Temp Temp = "" Repeat Char = ReadByte(UDP) If Char = 0 Then Exit Temp :+ Chr(Char) Forever Print "Spielverzeichnis: "+Temp Temp = "" Repeat Char = ReadByte(UDP) If Char = 0 Then Exit Temp :+ Chr(Char) Forever Print "Spielname: "+Temp Print "ApplicationID: "+ReadShort(UDP) Print "Spielerzahl: "+ReadByte(UDP) Print "Maximale Spieleranzahl : "+ReadByte(UDP) Print "Anzahl der Bots : "+ReadByte(UDP) Print "Dedicated: "+Chr(ReadByte(UDP)) Print "Betriebssystem: "+Chr(ReadByte(UDP)) Print "Passwort: "+ReadByte(UDP) Print "Secure Valve Anti Cheat aktiviert?: "+ReadByte(UDP) Exit EndIf Forever CloseUDPStream(UDP) End Zitat: OK: FFFFFFFF
Kontrollbyte: I Protokollversion: 7 Servername: tRaSh ! http://trash.clan-4u.net Map Name: de_dust Spielverzeichnis: cstrike Spielname: Counter-Strike: Source ApplicationID: 240 Spielerzahl: 10 Maximale Spieleranzahl : 10 Anzahl der Bots : 0 Dedicated: d Betriebssystem: l Passwort: 0 Secure Valve Anti Cheat aktiviert?: 0 mfg olli |
||
vertex.dreamfall.at | GitHub |
gamble |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Wahnsinn, ich danke Dir ! ![]() |
||
![]() |
Jolinah |
![]() Antworten mit Zitat ![]() |
---|---|---|
Achso ![]() Ich glaub ich muss mal meine C Kentnisse aufstocken.. kenn die ganzen Abkürzungen nicht alle auswendig ![]() PS: Hoffe das mit dem 7Bit encoded kann trotzdem wer brauchen ![]() Edit: Aber was ich nicht ganz verstehe ist wieso ich beim erforschen des Streams nicht alles empfangen habe... Code: Strict Local server = IntIP("62.4.74.236") Local port = 30900 Local udp = CreateUDPStream() WriteInt(udp, $FFFFFFFF) WriteByte(udp, $54) SendUDPMsg(udp, server, port) Local quit:Byte = False Repeat If RecvUDPMsg(udp) <> 0 While Not Eof(udp) Print Chr(ReadByte(udp)) Wend EndIf Until KeyHit(KEY_ESCAPE) Or quit = True CloseUDPStream(udp) End Ausgabe: Code: ÿ ÿ ÿ ÿ I t R a S h ! h t t p : / / t r a s h . c l a n - 4 u . n e t Müsste aber doch noch weiter gehen, das heisst Eof kann man hier wohl vergessen.. wegen den Nullterminierten Strings ![]() |
||
![]() |
Vertex |
![]() Antworten mit Zitat ![]() |
---|---|---|
Print bei BMax hat ein bug. Bei bestimmten Zeichen (ich glaube sogar Null-terminated selber), ist eine folgende Ausgabe via Print nichtmehr möglich.
mfg olli |
||
vertex.dreamfall.at | GitHub |
![]() |
Jolinah |
![]() Antworten mit Zitat ![]() |
---|---|---|
Naja funktioniert ja jetzt, auch wieder was dazu gelernt danke ![]() |
||
gamble |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Bin gerade dabei die Spieler vom Server auszulesen - musste dabei aber einen anderen Server abfragen, da der oben genannte im Moment leer ist. Dabei ist mir aufgefallen dass nicht alle Server auf den Request überhaupt antworten.
Bei manchen Servern bekomme ich nicht einmal den Servernamen (etc) zurück, bei einem anderen klappt dann zum Beispiel alles. |
||
Übersicht


Powered by phpBB © 2001 - 2006, phpBB Group