asd
This commit is contained in:
@@ -11,6 +11,9 @@ SERVICES_DIR=/root/services
|
|||||||
|
|
||||||
# Scoreboard Configuration
|
# Scoreboard Configuration
|
||||||
SCOREBOARD_WS_URL=ws://10.60.0.1:8080/api/events
|
SCOREBOARD_WS_URL=ws://10.60.0.1:8080/api/events
|
||||||
|
SCOREBOARD_API_URL=http://10.60.0.1:8080/api
|
||||||
|
USE_HTTP_POLLING=false
|
||||||
|
POLLING_INTERVAL=10
|
||||||
OUR_TEAM_ID=1
|
OUR_TEAM_ID=1
|
||||||
ALERT_THRESHOLD_POINTS=100
|
ALERT_THRESHOLD_POINTS=100
|
||||||
ALERT_THRESHOLD_TIME=300
|
ALERT_THRESHOLD_TIME=300
|
||||||
|
|||||||
@@ -189,51 +189,78 @@ async def send_telegram_alert(message: str):
|
|||||||
|
|
||||||
async def http_polling_listener():
|
async def http_polling_listener():
|
||||||
"""Poll scoreboard HTTP API for attacks as alternative to WebSocket"""
|
"""Poll scoreboard HTTP API for attacks as alternative to WebSocket"""
|
||||||
last_round = 0
|
last_check_time = datetime.utcnow()
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
try:
|
try:
|
||||||
async with aiohttp.ClientSession() as session:
|
async with aiohttp.ClientSession() as session:
|
||||||
# Try to fetch scoreboard data
|
# ForcAD API endpoints that should return JSON
|
||||||
# Common ForcAD endpoints: /api/scoreboard, /api/teams, /api/attacks
|
# Try different possible paths
|
||||||
endpoints_to_try = [
|
endpoints_to_try = [
|
||||||
f"{SCOREBOARD_API_URL}/attacks",
|
('/api/client/attack_data', 'GET'),
|
||||||
f"{SCOREBOARD_API_URL}/scoreboard",
|
('/api/client/attacks', 'GET'),
|
||||||
f"{SCOREBOARD_API_URL}/flag_stats"
|
('/api/flag/info', 'GET'),
|
||||||
|
('/api/info', 'GET'),
|
||||||
|
('/api/game_state', 'GET'),
|
||||||
]
|
]
|
||||||
|
|
||||||
for endpoint in endpoints_to_try:
|
data_found = False
|
||||||
|
|
||||||
|
for endpoint_path, method in endpoints_to_try:
|
||||||
|
endpoint = f"{SCOREBOARD_API_URL.rstrip('/api')}{endpoint_path}"
|
||||||
try:
|
try:
|
||||||
async with session.get(endpoint, timeout=aiohttp.ClientTimeout(total=5)) as resp:
|
async with session.get(endpoint, timeout=aiohttp.ClientTimeout(total=5)) as resp:
|
||||||
if resp.status == 200:
|
if resp.status == 200:
|
||||||
data = await resp.json()
|
content_type = resp.headers.get('Content-Type', '')
|
||||||
print(f"✓ Fetched data from {endpoint}")
|
|
||||||
|
|
||||||
# Process based on response structure
|
# Skip HTML responses
|
||||||
if isinstance(data, list):
|
if 'text/html' in content_type:
|
||||||
# List of attacks/events
|
continue
|
||||||
for item in data:
|
|
||||||
await process_attack_event(item)
|
try:
|
||||||
elif isinstance(data, dict):
|
data = await resp.json()
|
||||||
# Could be scoreboard with nested data
|
print(f"✓ Fetched JSON from {endpoint}")
|
||||||
# Try common keys
|
data_found = True
|
||||||
for key in ['attacks', 'flags', 'events', 'data']:
|
|
||||||
if key in data and isinstance(data[key], list):
|
# Process based on response structure
|
||||||
for item in data[key]:
|
if isinstance(data, list):
|
||||||
|
# List of attacks/events
|
||||||
|
for item in data:
|
||||||
|
if isinstance(item, dict):
|
||||||
await process_attack_event(item)
|
await process_attack_event(item)
|
||||||
break
|
elif isinstance(data, dict):
|
||||||
else:
|
# Try common keys for attack data
|
||||||
# Might be a single event
|
for key in ['attacks', 'stolen_flags', 'flags', 'events', 'data', 'rows']:
|
||||||
await process_attack_event(data)
|
if key in data:
|
||||||
|
items = data[key]
|
||||||
break # Success, no need to try other endpoints
|
if isinstance(items, list):
|
||||||
|
print(f" Found {len(items)} items in '{key}'")
|
||||||
|
for item in items:
|
||||||
|
if isinstance(item, dict):
|
||||||
|
await process_attack_event(item)
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
# Might be a single event or game state
|
||||||
|
# Check if it contains attack-like data
|
||||||
|
if any(k in data for k in ['attacker_id', 'victim_id', 'team_id', 'flag']):
|
||||||
|
await process_attack_event(data)
|
||||||
|
|
||||||
|
if data_found:
|
||||||
|
break # Found valid data, no need to try other endpoints
|
||||||
|
|
||||||
|
except (json.JSONDecodeError, aiohttp.ContentTypeError):
|
||||||
|
# Not JSON, skip
|
||||||
|
continue
|
||||||
|
|
||||||
except aiohttp.ClientError as e:
|
except aiohttp.ClientError as e:
|
||||||
print(f"Failed to fetch from {endpoint}: {e}")
|
|
||||||
continue
|
continue
|
||||||
except json.JSONDecodeError:
|
except Exception as e:
|
||||||
print(f"Invalid JSON from {endpoint}")
|
print(f"Error fetching {endpoint}: {e}")
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
if not data_found:
|
||||||
|
print(f"No valid JSON data found from scoreboard API (last check: {datetime.utcnow().strftime('%H:%M:%S')})")
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(f"HTTP polling error: {e}")
|
print(f"HTTP polling error: {e}")
|
||||||
|
|
||||||
@@ -497,27 +524,51 @@ async def debug_scoreboard():
|
|||||||
except Exception as e:
|
except Exception as e:
|
||||||
results["websocket_status"] = f"unreachable: {str(e)}"
|
results["websocket_status"] = f"unreachable: {str(e)}"
|
||||||
|
|
||||||
# Test HTTP endpoints
|
# Test HTTP endpoints - both HTML and API paths
|
||||||
results["http_api_url"] = SCOREBOARD_API_URL
|
base_url = SCOREBOARD_API_URL.rstrip('/api')
|
||||||
endpoints = [
|
endpoints = [
|
||||||
"/attacks",
|
"/api/client/attack_data",
|
||||||
"/scoreboard",
|
"/api/client/attacks",
|
||||||
"/flag_stats",
|
"/api/flag/info",
|
||||||
"/teams",
|
"/api/info",
|
||||||
"/events"
|
"/api/game_state",
|
||||||
|
"/api/attacks",
|
||||||
|
"/api/scoreboard",
|
||||||
|
"/api/teams",
|
||||||
|
"/api/events"
|
||||||
]
|
]
|
||||||
|
|
||||||
for endpoint in endpoints:
|
for endpoint in endpoints:
|
||||||
url = f"{SCOREBOARD_API_URL}{endpoint}"
|
url = f"{base_url}{endpoint}"
|
||||||
try:
|
try:
|
||||||
async with session.get(url, timeout=aiohttp.ClientTimeout(total=5)) as resp:
|
async with session.get(url, timeout=aiohttp.ClientTimeout(total=5)) as resp:
|
||||||
data = await resp.text()
|
content_type = resp.headers.get('Content-Type', '')
|
||||||
results["endpoints_tested"].append({
|
is_json = 'application/json' in content_type
|
||||||
|
is_html = 'text/html' in content_type
|
||||||
|
|
||||||
|
result = {
|
||||||
"url": url,
|
"url": url,
|
||||||
"status": resp.status,
|
"status": resp.status,
|
||||||
"reachable": resp.status == 200,
|
"reachable": resp.status == 200,
|
||||||
"data_preview": data[:500] if resp.status == 200 else None
|
"content_type": content_type,
|
||||||
})
|
"is_json": is_json,
|
||||||
|
"is_html": is_html
|
||||||
|
}
|
||||||
|
|
||||||
|
if resp.status == 200:
|
||||||
|
if is_json:
|
||||||
|
try:
|
||||||
|
data = await resp.json()
|
||||||
|
result["json_preview"] = str(data)[:500]
|
||||||
|
result["json_keys"] = list(data.keys()) if isinstance(data, dict) else "list"
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
text = await resp.text()
|
||||||
|
result["data_preview"] = text[:200]
|
||||||
|
|
||||||
|
results["endpoints_tested"].append(result)
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
results["endpoints_tested"].append({
|
results["endpoints_tested"].append({
|
||||||
"url": url,
|
"url": url,
|
||||||
|
|||||||
Reference in New Issue
Block a user