Hey all
Mein Problem:
Ich soll in meinem Serverjoiner einbauen, dass man sich die aktuellen Infos der Gameserver anzeigen lassen kann (welche Map grad läuft und wieviele Spieler drauf sind usw.).
Und bevor ich das direkt im eigentlichen Programmcode reinpacke will ich das zuerst in nem Extrascript korrekt zum Laufen kriegen.
zunächst das Script
#include "Array.au3"
#include "GUIConstantsEx.au3"
$IP = "178.63.84.143" ; hierfür klappt es
$PORT = "28963"
;$IP = "178.254.20.92" ; hierfür klappt es nicht
;$PORT = "28960"
UDPStartup()
$hSOCKET = UDPOpen($IP, $PORT)
UDPSend($hSOCKET, "ÿÿÿÿ getinfo")
Do
$sRECV = UDPRecv($hSOCKET, 2048)
Until $sRECV <> ""
UDPCloseSocket($hSOCKET)
UDPShutdown()
$sARRAY = StringSplit(BinaryToString($sRECV), "\")
[/autoit] [autoit][/autoit] [autoit]#region String analysieren
Dim $data1, $data2, $data3, $data4, $data5, $data6
$data1 = StringRegExpReplace($sARRAY[23], "\^\d{1}", "")
Switch $sARRAY[9]
Case "ctf"
$data2 = "Capture The Flag"
Case "dd"
$data2 = "Sprengkommando"
Case "dom"
$data2 = "Herrschaft"
Case "sd"
$data2 = "Suchen Und Zerstören"
Case "war"
$data2 = "Team Deathmatch"
Case "dm"
$data2 = "Frei Für Alle"
Case "sab"
$data2 = "Sabotage"
Case "koth"
$data2 = "Hauptquartier"
Case "gtnw"
$data2 = "Thermonuklearer Krieg"
Case "oitc"
$data2 = "One In The Chamber"
Case "oneflag"
$data2 = "Eine Flagge"
Case "arena"
$data2 = "Arena"
Case "gg"
$data2 = "GunGame"
Case "ss"
$data2 = "Sharpshooter"
EndSwitch
If $sARRAY[3] = "1" Then
$data3 = "ja"
Else
$data3 = "nein"
EndIf
$data4 = $sARRAY[15] & " von " & $sARRAY[11]
Switch $sARRAY[17]
Case "mp_afghan"
$data5 = "Afghan"
Case "mp_boneyard"
$data5 = "Scrapyard"
Case "mp_brecourt"
$data5 = "Wasteland"
Case "mp_derail"
$data5 = "Derail"
Case "mp_estate"
$data5 = "Estate"
Case "mp_favela"
$data5 = "Favela"
Case "mp_invasion"
$data5 = "Invasion"
Case "mp_nightshift"
$data5 = "Skidrow"
Case "mp_quarry"
$data5 = "Quarry"
Case "mp_rundown"
$data5 = "Rundown"
Case "mp_subbase"
$data5 = "Subbase"
Case "mp_terminal"
$data5 = "Terminal"
Case "mp_underpass"
$data5 = "Underpass"
Case "mp_abandon"
$data5 = "? Abandon"
Case "mp_compact"
$data5 = "? Compact"
Case "mp_complex"
$data5 = "? Complex"
Case "mp_crash"
$data5 = "Crash"
Case "mp_fuel2"
$data5 = "Fuel"
Case "mp_overgrown"
$data5 = "Overgrown"
Case "mp_storm"
$data5 = "? Storm"
Case "mp_strike"
$data5 = "Strike"
Case "mp_trailerpark"
$data5 = "Trailer Park"
Case "mp_vacant"
$data5 = "Vacant"
Case "mp_highrise"
$data5 = "Highrise"
Case Else
$data5 = $sARRAY[17]
EndSwitch
$data6 = $sARRAY[21] & " v" & $sARRAY[5]
#endregion String analysieren
Dim $hGUI = GUICreate("Infos", 230, 160, 100, 200, -1)
Dim $listview = GUICtrlCreateListView(" |Wert", 0, 0, 230, 170)
Dim $item1a = GUICtrlCreateListViewItem("Servername" & "|" & $data1, $listview)
Dim $item2a = GUICtrlCreateListViewItem("Gametype" & "|" & $data2, $listview)
Dim $item3a = GUICtrlCreateListViewItem("Hardcore" & "|" & $data3, $listview)
Dim $item4a = GUICtrlCreateListViewItem("Spieler" & "|" & $data4, $listview)
Dim $item5a = GUICtrlCreateListViewItem("Map" & "|" & $data5, $listview)
Dim $item6a = GUICtrlCreateListViewItem("Serverversion" & "|" & $data6, $listview)
GUISetState(@SW_SHOW)
While 1
$msg = GUIGetMsg()
Select
Case $msg = $GUI_EVENT_CLOSE
Exit
EndSelect
WEnd
Was ich in Zeile 13 vom Server zurückbekomme muss ich erst in einen String umwandeln. Das sieht dann anschliessend so aus:
ÿÿÿÿinfoResponse
\hc\1\shortversion\3.0-118\pure\1\gametype\ctf\sv_maxclients\18\sv_privateClients\0\clients\0\mapname\mp_derail\protocol\61586\gamename\IW4\hostname\^0zzz____[^2IFA^0] ^3#1 ^1hardcore
Nachdem ich dann diese Antwort mit StringSplit() in ein 1D Array umgewandelt hab ist der Index des Arrays klar. Und nach diesem Index ist die GUI aufgebaut.
Bedeutet: bei Servername lass ich mir $sARRAY[23] anzeigen.
ABER: Wenn ich damit Infos eines anderen Servers hole. wo der Index anders ist, weil irgendwo im String ein zusätzlicher "Eintrag" vorhanden ist, dann stimmt ja der Index nicht mehr und $sARRAY kann
etwas vollkommen anderes sein. Darum dachte ich mir, wenn ich das 1D-Array in ein 2D umwandle, dann kann ich doch irgendwie herausfinden, in welchem Array der Text "sv_hostname" steckt und somit
weiss ich dann auch welches Array ich nehmen muss um mir in der GUI bei Servername auch das richtige anzuzeigen.
Doch soweit bin ich noch nicht, denn ich schaff es nicht, dass Array umzuschreiben.
so versuch ich das 1D-Array umzuwandeln
Mit der Rückgabe gehts nicht, weil hier der Array-Index größer ist und so die Werte nicht mehr stimmen
ÿÿÿÿinfoResponse
\hc\0\shortversion\3.0-118\fs_game\mods/isnipesnd\pure\1\gametype\sd\sv_maxclients\18\sv_privateClients\0\clients\0\mapname\mp_boneyard\protocol\61586\gamename\IW4\hostname\nGu ^0| ^7i^4S^7nipe ^4SnD^7
mit dieser Rückgabe gehts
ÿÿÿÿinfoResponse
\hc\1\shortversion\3.0-118\pure\1\gametype\ctf\sv_maxclients\18\sv_privateClients\0\clients\0\mapname\mp_derail\protocol\61586\gamename\IW4\hostname\^0zzz____[^2IFA^0] ^3#1 ^1hardcore
;UDPStartup()
;$hSOCKET = UDPOpen($IP, $PORT)
;UDPSend($hSOCKET, "ÿÿÿÿ getinfo")
;Do
; $sRECV = UDPRecv($hSOCKET, 2048)
;Until $sRECV <> ""
;UDPCloseSocket($hSOCKET)
;UDPShutdown()
$sRECV = "ÿÿÿÿinfoResponse" & @CRLF & "\hc\1\shortversion\3.0-118\pure\1\gametype\ctf\sv_maxclients\18\sv_privateClients\0\clients\0\mapname\mp_derail\protocol\61586\gamename\IW4\hostname\^0zzz____[^2IFA^0] ^3#1 ^1hardcore" ; damit gehts
;$sRECV = "ÿÿÿÿinfoResponse" & @CRLF & "\hc\0\shortversion\3.0-118\fs_game\mods/isnipesnd\pure\1\gametype\sd\sv_maxclients\18\sv_privateClients\0\clients\0\mapname\mp_boneyard\protocol\61586\gamename\IW4\hostname\nGu ^0| ^7i^4S^7nipe ^4SnD^7" ; damit gehts nicht
$sARRAY = StringSplit($sRECV, "\")
[/autoit] [autoit][/autoit] [autoit]_ArrayDisplay($sARRAY)
[/autoit] [autoit][/autoit] [autoit]Local $a2[2][$sARRAY[0]]
; Diese For Next-Schleife sieht deshalb so aus, weil ich Sie mehrfach erfolglos umschrieb...
; im Endeffekt brauch ich in der 1. Hälfte alle geraden $i´s und in der anderen alle ungeraden $i´s aus dem Array $sARRAY
; oder ihr habt vielleicht sogar bessere Umsetzungen
For $i = 0 To UBound($sARRAY[0]) - 1 Step 2
$a2[0][$i] = $sARRAY[$i] ;// 1. Dimension befüllen
Next
For $i = 1 To UBound($sARRAY[0]) -1 Step 2
$a2[1][$i] = $sARRAY[$i]
Next
_ArrayDisplay($a2); Egal wie ich es schreibe, entweder ist das ArrayDisplay leer, oder ich bekomm die "Standard-Array-Fehlermeldung
[/autoit]
Wie bekomm ich das 2D-Array also vernünftig befüllt?
MfG Lottich
PS: ich hoffe, dass ich mit dieser Überarbeitung mein Anliegen etwas deutlicher machen konnte.
Edit: Die For-Next-Schleifen überarbeitet, so wie sie für mich Sinn machen, aber trotzdem nichts anzeigen
Final-Edit: Hier die komplette Lösung, falls Interesse besteht...
Spoiler anzeigen
#Region ;**** Directives created by AutoIt3Wrapper_GUI ****
#AutoIt3Wrapper_UseUpx=n
#EndRegion ;**** Directives created by AutoIt3Wrapper_GUI ****
#include "Array.au3"
#include "GUIConstantsEx.au3"
Global $aIPs[2][2]
$aIPs[0][0] = "178.63.84.143"
$aIPs[0][1] = "28963"
$aIPs[1][0] = "178.254.20.92"
$aIPs[1][1] = "28960"
Global $hGUI = GUICreate("Infos", 650, 175, 100, 200, -1)
Global $idLV_Server = GUICtrlCreateListView("IP/Port |Servername |Gametype|Hardcore|Spieler|Map|Serverversion", 0, 0, 650, 175)
GUISetState(@SW_SHOW)
UDPStartup()
For $i = 0 To UBound($aIPs) - 1
$aInfo = _GetServerInfo($aIPs[$i][0], $aIPs[$i][1], 10000) ;TimeOut evtl. anpassen
$sItem = $aInfo[0] & "/" & $aInfo[1] & "|" & $aInfo[2] & "|" & $aInfo[5] & "|" & $aInfo[7] & "|" & $aInfo[8] & " von " & $aInfo[9] & "|" & $aInfo[6] & "|" & $aInfo[3] & " v" & $aInfo[4]
GUICtrlCreateListViewItem($sItem, $idLV_Server)
Next
UDPShutdown()
While 1
$msg = GUIGetMsg()
Select
Case $msg = $GUI_EVENT_CLOSE
Exit
EndSelect
WEnd
Func _GetServerInfo($IP, $PORT, $iTimeOut)
Local $aRaw, $iStart = TimerInit()
Local $aRet[10]
#cs
0 = IP
1 = Port
2 = Servername
3 = Gamename
4 = (Server)shortversion
5 = Gametype
6 = Map
7 = Hardcore
8 = Spieler derzeit
9 = Spieler max
#ce
$aRet[0] = $IP
$aRet[1] = $PORT
$aRet[2] = "antwortet nicht"
$hSOCKET = UDPOpen($IP, $PORT)
UDPSend($hSOCKET, "ÿÿÿÿ getinfo")
Do
$sRECV = UDPRecv($hSOCKET, 2048)
Until $sRECV <> "" Or TimerDiff($iStart) > $iTimeOut
UDPCloseSocket($hSOCKET)
If $sRECV <> "" Then
$aRaw = StringSplit(StringReplace(BinaryToString($sRECV),"|","ÿÿÿÿÿÿÿÿ"), "\")
For $i = 2 To $aRaw[0] - 1 Step 2
Switch $aRaw[$i]
Case "hostname"
$aRet[2] = StringReplace(StringReplace(StringRegExpReplace($aRaw[$i + 1], "\^\d{1}", ""),chr(0),""),"ÿÿÿÿÿÿÿÿ"," ") ;hier konnte ich die Namensdarstellung korrigieren
Case "gamename"
$aRet[3] = StringStripWS($aRaw[$i + 1], 7)
Case "shortversion"
$aRet[4] = StringStripWS($aRaw[$i + 1], 7)
Case "gametype"
$aRet[5] = _GetGameTyp(StringStripWS($aRaw[$i + 1], 7))
Case "mapname"
$aRet[6] = _GetMapName(StringStripWS($aRaw[$i + 1], 7))
Case "hc"
$aRet[7] = _GetHardCore(StringStripWS($aRaw[$i + 1], 7))
Case "clients"
$aRet[8] = StringStripWS($aRaw[$i + 1], 7)
Case "sv_maxclients"
$aRet[9] = StringStripWS($aRaw[$i + 1], 7)
EndSwitch
Next
EndIf
Return $aRet
EndFunc ;==>_GetServerInfo
Func _GetMapName($sMap)
Local $sRet = $sMap
Switch $sMap
Case "mp_afghan"
$sRet = "Afghan"
Case "mp_boneyard"
$sRet = "Scrapyard"
Case "mp_brecourt"
$sRet = "Wasteland"
Case "mp_derail"
$sRet = "Derail"
Case "mp_estate"
$sRet = "Estate"
Case "mp_favela"
$sRet = "Favela"
Case "mp_invasion"
$sRet = "Invasion"
Case "mp_nightshift"
$sRet = "Skidrow"
Case "mp_quarry"
$sRet = "Quarry"
Case "mp_rundown"
$sRet = "Rundown"
Case "mp_subbase"
$sRet = "Subbase"
Case "mp_terminal"
$sRet = "Terminal"
Case "mp_underpass"
$sRet = "Underpass"
Case "mp_abandon"
$sRet = "? Abandon"
Case "mp_compact"
$sRet = "? Compact"
Case "mp_complex"
$sRet = "? Complex"
Case "mp_crash"
$sRet = "Crash"
Case "mp_fuel2"
$sRet = "Fuel"
Case "mp_overgrown"
$sRet = "Overgrown"
Case "mp_storm"
$sRet = "? Storm"
Case "mp_strike"
$sRet = "Strike"
Case "mp_trailerpark"
$sRet = "Trailer Park"
Case "mp_vacant"
$sRet = "Vacant"
Case "mp_highrise"
$sRet = "Highrise"
;Case Else
; $sRet = $sARRAY[17]
EndSwitch
Return $sRet
EndFunc ;==>_GetMapName
Func _GetGameTyp($sGT)
Local $sRet = $sGT
Switch $sGT
Case "ctf"
$sRet = "Capture The Flag"
Case "dd"
$sRet = "Sprengkommando"
Case "dom"
$sRet = "Herrschaft"
Case "sd"
$sRet = "Suchen Und Zerstören"
Case "war"
$sRet = "Team Deathmatch"
Case "dm"
$sRet = "Frei Für Alle"
Case "sab"
$sRet = "Sabotage"
Case "koth"
$sRet = "Hauptquartier"
Case "gtnw"
$sRet = "Thermonuklearer Krieg"
Case "oitc"
$sRet = "One In The Chamber"
Case "oneflag"
$sRet = "Eine Flagge"
Case "arena"
$sRet = "Arena"
Case "gg"
$sRet = "GunGame"
Case "ss"
$sRet = "Sharpshooter"
EndSwitch
ConsoleWrite($sGT & "==> " & $sRet & @CRLF)
Return $sRet
EndFunc ;==>_GetGameTyp
Func _GetHardCore($sHC)
Local $sRet
If $sHC = "1" Then
$sRet = "ja"
Else
$sRet = "nein"
EndIf
Return $sRet
EndFunc ;==>_GetHardCore