diff --git a/ChaChaGameStats/GameStatsSupervisor.py b/ChaChaGameStats/GameStatsSupervisor.py
index 4f0fd57..09567d7 100644
--- a/ChaChaGameStats/GameStatsSupervisor.py
+++ b/ChaChaGameStats/GameStatsSupervisor.py
@@ -19,6 +19,7 @@ from . import RconQuakes
from . import RconUTEngineWebAdminUT2k4
from . import RconUTEngineWebAdminUT3
from . import RconUTEngineWebAdminUT99
+from . import RconUT99_ChaChaRESTStats
from . import RconMinecraft
from pickle import TRUE
from concurrent.futures import ThreadPoolExecutor
@@ -123,7 +124,7 @@ class GameStatsSupervisorFactory:
self._RconFactory = RconBase.RconFactory()
self.register_GameStatsSupervisorRconBuilder("ut2k4", RconUTEngineWebAdminUT2k4.RconUTEngineWebAdminUT2k4)
self.register_GameStatsSupervisorRconBuilder("ut3", RconUTEngineWebAdminUT3.RconUTEngineWebAdminUT3)
- self.register_GameStatsSupervisorRconBuilder("ut99", RconUTEngineWebAdminUT99.RconUTEngineWebAdminUT99)
+ self.register_GameStatsSupervisorRconBuilder("ut99", RconUTEngineWebAdminUT99.RconUT99_ChaChaRESTStats)
self.register_GameStatsSupervisorRconBuilder("q2", RconQuakes.RconSourceEngineQuake2)
self.register_GameStatsSupervisorRconBuilder("q3a", RconQuakes.RconSourceEngineQuake3A)
self.register_GameStatsSupervisorRconBuilder("codmw3", RconCODs.RconSourceEngineCODMW3)
diff --git a/ChaChaGameStats/RconUT99_ChaChaRESTStats.py b/ChaChaGameStats/RconUT99_ChaChaRESTStats.py
new file mode 100644
index 0000000..d105f2a
--- /dev/null
+++ b/ChaChaGameStats/RconUT99_ChaChaRESTStats.py
@@ -0,0 +1,93 @@
+"""
+ChaChaGameStats (c) by clement chastanier
+
+ChaChaGameStats is licensed under a
+Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International Unported License.
+
+You should have received a copy of the license along with this
+work. If not, see .
+"""
+
+import time
+from pprint import pprint
+
+import requests
+
+from . import GameStatsInterface
+from . import RconBase
+
+
+#class ExceptionRconIncorrectPadding(RconBase.ExceptionRcon):
+# pass
+
+class RconUT99_ChaChaRESTStats(RconBase.RconBase):
+ def __init__(self,GameName:str,ip:str,port:int,user:str,password:str,timeout:int):
+ print("INIT ???")
+ super().__init__(GameName,ip,port,user,password,timeout)
+ self.session = None
+ self.BaseUrl = "http://" + self.ip + ":" + str(self.port) + "/api/v1/"
+ self.GameServerStatusResult = None
+ self.timeout = timeout
+
+ def connect(self):
+ self.session = requests.session()
+ super().connect()
+
+ def disconnect(self):
+ try:
+ self.session.close()
+ except Exception as e:
+ print("WARNING: self.session.close() failed: %s" % e)
+ super().disconnect()
+
+ def GetStatus(self) -> dict():
+ PINGstarttime = time.time()
+ defaults_all=self.session.get(self.BaseUrl + "defaults_all",timeout=self.timeout)
+ PING = round( (time.time() - PINGstarttime)*1000)
+ current_all=self.session.get(self.BaseUrl + "current_all",timeout=self.timeout)
+ res=dict()
+ res["ping"]=PING
+ res["defaults_all"]=defaults_all.json()
+ res["current_all"]=current_all.json()
+ return res
+
+ ## interface implementation
+ def GetGameServerStatusResult(self) -> GameStatsInterface.GameServerStatusResult_Main:
+ self.GameServerStatusResult = super().GetGameServerStatusResult()
+ if self.GameServerStatusResult.status != "DOWN":
+ try:
+ self.GameServerStatusResult.raw = self.GetStatus()
+ self.GameServerStatusResult.status = "UP"
+ except RconBase.ExceptionRconTimeout:
+ self.GameServerStatusResult.status = "DOWN"
+ self.GameServerStatusResult.ping = 999
+ return self.GameServerStatusResult
+ except RconBase.ExceptionWrongRconPassword:
+ self.GameServerStatusResult.status = "REFUSED"
+ self.GameServerStatusResult.ping = 999
+ return self.GameServerStatusResult
+
+ self.GameServerStatusResult.name = self.GameServerStatusResult.raw["defaults_all"]["ServerName"]
+ self.GameServerStatusResult.map = self.GameServerStatusResult.raw["current_all"]["Level"]
+ self.GameServerStatusResult.gametype = self.GameServerStatusResult.raw["current_all"]["GameName"]
+ self.GameServerStatusResult.mods = ", ".join(self.GameServerStatusResult.raw["current_all"]["Mutators"])
+ self.GameServerStatusResult.maxplayers = self.GameServerStatusResult.raw["defaults_all"]["MaxPlayers"]
+ self.GameServerStatusResult.ping = self.GameServerStatusResult.raw["ping"]
+ self.GameServerStatusResult.version = None
+ self.GameServerStatusResult.players = []
+ numplayers = 0
+ for player in self.GameServerStatusResult.raw["current_all"]["player_list"]:
+ if player["bIsSpectator"] or player["bIsABot"]:
+ continue
+ newplayer = GameStatsInterface.GameServerStatusResult_Players()
+ newplayer.name = player["PlayerName"]
+ newplayer.score = player["Score"]
+ newplayer.ping = player["Ping"]
+ newplayer.ip = player["IP"]
+ newplayer.port = None
+ newplayer.uid = None
+ newplayer.num = numplayers
+ self.GameServerStatusResult.players.append(newplayer)
+ numplayers+=1
+ self.GameServerStatusResult.nplayer = numplayers
+ return self.GameServerStatusResult
\ No newline at end of file
diff --git a/ChaChaGameStats/RconUTEngineWebAdmin.py b/ChaChaGameStats/RconUTEngineWebAdmin.py
index e91f98e..5ebb629 100644
--- a/ChaChaGameStats/RconUTEngineWebAdmin.py
+++ b/ChaChaGameStats/RconUTEngineWebAdmin.py
@@ -46,7 +46,6 @@ class RconUTEngineWebAdmin(RconBase.RconBase,metaclass=abc.ABCMeta):
self.GameServerStatusResult = None
self.timeout = timeout
self.initConstant()
- self.fetchData = {};
def initConstant(self):
pass
@@ -65,8 +64,7 @@ class RconUTEngineWebAdmin(RconBase.RconBase,metaclass=abc.ABCMeta):
def _fetchPageRAW(self,page) -> str:
try:
- response = self.session.get(page,data=self.fetchData,timeout=self.timeout)
- self.fetchData = {}
+ response = self.session.get(page,timeout=self.timeout)
if response.status_code != 200:
raise RconBase.ExceptionWrongRconPassword
except requests.exceptions.RequestException as e:
@@ -150,32 +148,47 @@ class RconUTEngineWebAdminMODCENTRAL(RconUTEngineWebAdmin,metaclass=abc.ABCMeta)
tree = self._fetchPageETree(url)
try:
level1 = tree.findall(".//form[@action='"+element+"']")[0]
- level2 = level1.findall(".//table")[0]
- infoChart = level2.findall(".//tr")
- for info_record in infoChart:
- data = info_record.findall(".//td/select")
- if data :
- attributename = data[0].attrib["name"].split('.')[-1] #get last var name: BLABLA.keyname => keyname
- data_value = data[0].findall(".//option[@selected]")
+ level2 = level1.findall(".//table")
+ # table based page
+ if level2:
+ level2 = level2[0]
+ infoChart = level2.findall(".//tr")
+ for info_record in infoChart:
+ data = info_record.findall(".//td/select")
+ if data :
+ attributename = data[0].attrib["name"].split('.')[-1] #get last var name: BLABLA.keyname => keyname
+ data_value = data[0].findall(".//option[@selected]")
+ if data_value:
+ if "value" in data_value[0].attrib:
+ ar_ServerRules[attributename] = data_value[0].attrib["value"]
+ else:
+ ar_ServerRules[attributename] = data_value[0].text
+ continue
+ data = info_record.findall(".//td/input")
+ if data and data[0].attrib["name"]!="Apply":
+ attributename = data[0].attrib["name"].split('.')[-1] #get last var name: BLABLA.keyname => keyname
+ if "value" in data[0].attrib:
+ ar_ServerRules[attributename] = data[0].attrib["value"]
+ else:
+ ar_ServerRules[attributename] = data[0].text
+ if data[0].attrib["type"] == "checkbox" :
+ if "checked" in data[0].attrib:
+ ar_ServerRules[attributename] = "true"
+ else:
+ ar_ServerRules[attributename] = "false"
+ continue
+ else:
+ #new pages UT99 469c .... :-/
+ selects = level1.findall(".//select")
+ for _select in selects:
+ attributename = _select.attrib["name"].split('.')[-1] #get last var name: BLABLA.keyname => keyname
+ data_value = _select.findall(".//option[@selected]")
if data_value:
if "value" in data_value[0].attrib:
ar_ServerRules[attributename] = data_value[0].attrib["value"]
else:
ar_ServerRules[attributename] = data_value[0].text
- continue
- data = info_record.findall(".//td/input")
- if data and data[0].attrib["name"]!="Apply":
- attributename = data[0].attrib["name"].split('.')[-1] #get last var name: BLABLA.keyname => keyname
- if "value" in data[0].attrib:
- ar_ServerRules[attributename] = data[0].attrib["value"]
- else:
- ar_ServerRules[attributename] = data[0].text
- if data[0].attrib["type"] == "checkbox" :
- if "checked" in data[0].attrib:
- ar_ServerRules[attributename] = "true"
- else:
- ar_ServerRules[attributename] = "false"
- continue
+ continue
except Exception as e:
raise RconBase.ExceptionRconResultParse(e)
return ar_ServerRules
\ No newline at end of file
diff --git a/ChaChaGameStats/RconUTEngineWebAdminUT99.py b/ChaChaGameStats/RconUTEngineWebAdminUT99.py
index f0ff261..2e6939d 100644
--- a/ChaChaGameStats/RconUTEngineWebAdminUT99.py
+++ b/ChaChaGameStats/RconUTEngineWebAdminUT99.py
@@ -171,8 +171,13 @@ class RconUTEngineWebAdminUT99(RconUTEngineWebAdmin.RconUTEngineWebAdminMODCENTR
ar_PlayersStats = []
tree = self._fetchPageETree(self.currentplayersUrl)
try:
- level1 = tree.findall(".//form[@action='current_players']")[0]
- level2 = level1.findall(".//table")[1]
+ level1 = tree.findall(".//form[@action='current_players']")
+ if len(level1) == 2: #ut469c
+ level1 = level1[1]
+ level2 = level1.findall(".//table")[0]
+ else:
+ level1 = level1[0]
+ level2 = level1.findall(".//table")[1]
player_chart = level2.findall(".//tr")
del player_chart[0]
for player_record in player_chart:
diff --git a/ChaChaGameStats/_version.py b/ChaChaGameStats/_version.py
index 0d36b3b..925ed92 100644
--- a/ChaChaGameStats/_version.py
+++ b/ChaChaGameStats/_version.py
@@ -7,4 +7,4 @@ Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International Unported
You should have received a copy of the license along with this
work. If not, see .
"""
-__version__ = "0.1.4"
+__version__ = "0.1.8"
diff --git a/sample.py b/sample.py
index 76d6b6d..76b1cb9 100644
--- a/sample.py
+++ b/sample.py
@@ -39,6 +39,33 @@ if __name__ == "__main__":
"""
+ ar_games.append( _GameStatsSupervisorFactory.create( name = "ut99-dm",
+ gametype = "ut99",
+ ip = "172.16.1.41",
+
+
+ Interface_QuakeStats = { "port":5000},
+
+ Interface_RconBase = { "port":5000,
+ "username":"chacha",
+ "password":"cfographut"}
+ )
+ )
+ """
+ ar_games.append( _GameStatsSupervisorFactory.create( name = "ut99-ctf",
+ gametype = "ut99",
+ ip = "127.0.0.1",
+ #ip = "37.59.37.210",
+
+
+ #Interface_QuakeStats = { "port":5040},
+
+ Interface_RconBase = { "port":8080,
+ "username":"",
+ "password":""}
+ )
+ )
+ """
ar_games.append( _GameStatsSupervisorFactory.create( name = "ut99-niut",
gametype = "ut99",
ip = "172.16.1.40",
@@ -62,7 +89,8 @@ if __name__ == "__main__":
"username":"chacha",
"password":"cfographut"}
)
- )
+ )
+
ar_games.append( _GameStatsSupervisorFactory.create( name = "ut99-utp",
gametype = "ut99",
ip = "172.16.1.42",
@@ -76,6 +104,7 @@ if __name__ == "__main__":
)
)
+
ar_games.append( _GameStatsSupervisorFactory.create( name = "codbo2-3",
gametype = "codbo2",
ip = "GAME-CODBO2",
@@ -124,7 +153,7 @@ if __name__ == "__main__":
print("")
print("== Testing: " + game.GameName + "==")
res = game.API_GetGameServerStatusResult()
- print("res: " + str(res.__dict__))
+ pprint("res: " + str(res.__dict__))
for player in res.players:
print(player.__dict__)
if "QuakeStats" in res.raw: