Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
92 changes: 70 additions & 22 deletions discordgsm/protocols/asa.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import time
from typing import TYPE_CHECKING

import aiohttp
import opengsq

from discordgsm.protocols.protocol import Protocol
Expand Down Expand Up @@ -36,29 +37,76 @@ async def query(self):
await self.pre_query()

host, port = str(self.kv["host"]), int(str(self.kv["port"]))
eos = opengsq.EOS(
host, port, self._deployment_id, ASA._access_token, self.timeout
)
start = time.time()
info = await eos.get_info()
ping = int((time.time() - start) * 1000)

# Try EOS first
try:
eos = opengsq.EOS(
host, port, self._deployment_id, ASA._access_token, self.timeout
)
info = await eos.get_info()
ping = int((time.time() - start) * 1000)

# Credits: @dkoz https://github.com/DiscordGSM/GameServerMonitor/pull/54/files
attributes = dict(info.get("attributes", {}))
settings = dict(info.get("settings", {}))

# Credits: @dkoz https://github.com/DiscordGSM/GameServerMonitor/pull/54/files
attributes = dict(info.get("attributes", {}))
settings = dict(info.get("settings", {}))
result: GamedigResult = {
"name": attributes.get("CUSTOMSERVERNAME_s", ""),
"map": attributes.get("MAPNAME_s", ""),
"password": attributes.get("SERVERPASSWORD_b", False),
"numplayers": info.get("totalPlayers", 0),
"numbots": 0,
"maxplayers": settings.get("maxPublicPlayers", 0),
"players": None,
"bots": None,
"connect": f"{host}:{port}",
"ping": ping,
"raw": info,
}

result: GamedigResult = {
"name": attributes.get("CUSTOMSERVERNAME_s", ""),
"map": attributes.get("MAPNAME_s", ""),
"password": attributes.get("SERVERPASSWORD_b", False),
"numplayers": info.get("totalPlayers", 0),
"numbots": 0,
"maxplayers": settings.get("maxPublicPlayers", 0),
"players": None,
"bots": None,
"connect": f"{host}:{port}",
"ping": ping,
"raw": info,
}
return result
except Exception:
# EOS failed, fallback to BattleMetrics
start = time.time() # Restart timer for BattleMetrics query

# Fallback: Query BattleMetrics API by IP:port
async with aiohttp.ClientSession() as session:
url = f"https://api.battlemetrics.com/servers?filter[game]=arksa&filter[search]={host}:{port}"
async with session.get(url, timeout=aiohttp.ClientTimeout(total=self.timeout)) as response:
if response.status != 200:
raise Exception(f"BattleMetrics API returned {response.status}")

data = await response.json()
servers = data.get("data", [])

# Find the online server matching our IP:port
server_info = None
for server in servers:
attrs = server.get("attributes", {})
if attrs.get("ip") == host and attrs.get("port") == port and attrs.get("status") == "online":
server_info = server
break

if not server_info:
raise Exception(f"No online server found on BattleMetrics for {host}:{port}")

ping = int((time.time() - start) * 1000)
attrs = server_info.get("attributes", {})
details = attrs.get("details", {})

result: GamedigResult = {
"name": attrs.get("name", ""),
"map": details.get("map", ""),
"password": details.get("password", False),
"numplayers": attrs.get("players", 0),
"numbots": 0,
"maxplayers": attrs.get("maxPlayers", 0),
"players": None,
"bots": None,
"connect": f"{host}:{port}",
"ping": ping,
"raw": attrs,
}

return result
return result