Skip to content

Commit 5d5d8fd

Browse files
committed
AAR added
1 parent ac0184e commit 5d5d8fd

File tree

4 files changed

+53
-16
lines changed

4 files changed

+53
-16
lines changed

plugins/competitive/listener.py

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,21 @@ def get_squadron(self, side: Side) -> Optional[Squadron]:
7070
# noinspection PyUnresolvedReferences
7171
return next((x.squadron for x in self.alive.get(side, []) if x.squadron), None)
7272

73+
def to_dict(self) -> dict:
74+
return {
75+
'match_id': self.match_id,
76+
'started': self.started.isoformat() if self.started else None,
77+
'finished': self.finished.isoformat() if self.finished else None,
78+
'winner': self.winner.name if self.winner else None,
79+
'alive': {
80+
Side.BLUE.name: [p.ucid for p in self.alive.get(Side.BLUE, [])],
81+
Side.RED.name: [p.ucid for p in self.alive.get(Side.RED, [])]
82+
},
83+
'log': {
84+
x[0].isoformat(): x[1] for x in self.log
85+
}
86+
}
87+
7388

7489
class CompetitiveListener(EventListener["Competitive"]):
7590

@@ -461,8 +476,8 @@ async def onMatchFinished(self, server: Server, data: dict) -> None:
461476
# restart the mission if configured
462477
config = self.get_config(server)
463478
if config.get('end_mission', False):
464-
if data['winner'] in ['RED', 'BLUE']:
465-
side = data['winner'].lower()
479+
if data['winner'] in ['red', 'blue']:
480+
side = data['winner']
466481
else:
467482
side = 'none' # it's a draw, needs to be different from a server shutdown
468483
await server.send_to_dcs({
@@ -509,7 +524,5 @@ async def check_matches(self):
509524

510525
asyncio.create_task(self.bot.bus.send_to_node({
511526
"command": "onMatchFinished",
512-
"match_id": match.match_id,
513-
"winner": winner.name,
514527
"server_name": server.name
515-
}))
528+
} | match.to_dict()))

plugins/competitive/reports.py

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,17 @@
22
import numpy as np
33

44
from core import report
5+
from datetime import datetime, timezone
56
from matplotlib import cm
67
from psycopg.rows import dict_row
7-
from typing import Optional
8+
from typing import Optional, TYPE_CHECKING
89

910
from ..userstats.filter import StatisticsFilter, CampaignFilter
1011
from ..userstats.highscore import compute_font_size
1112

13+
if TYPE_CHECKING:
14+
from plugins.competitive.listener import Match
15+
1216

1317
class HighscoreTrueSkill(report.GraphElement):
1418

@@ -71,3 +75,15 @@ async def render(self, interaction: discord.Interaction, limit: int, flt: Statis
7175
self.axes.set_xticks([])
7276
self.axes.set_yticks([])
7377
self.axes.text(0, 0, 'No data available.', ha='center', va='center', rotation=45, size=15)
78+
79+
80+
class MatchAAR(report.EmbedElement):
81+
82+
async def render(self, match: dict):
83+
times = []
84+
logs = []
85+
for time, log in match['log']:
86+
times.append(datetime.fromisoformat(time).replace(tzinfo=timezone.utc))
87+
logs.append(log)
88+
self.add_field(name="Time", value="\n".join([f"<t:{int(t.timestamp())}:T>" for t in times]))
89+
self.add_field(name="Log", value="\n".join(logs))

plugins/tournament/listener.py

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,7 @@
22
import discord
33
import re
44

5-
from core import EventListener, event, Server, utils, get_translation, Coalition, DataObjectFactory, PersistentReport, \
6-
Player
5+
from core import EventListener, event, Server, utils, get_translation, Coalition, DataObjectFactory, Player, Report
76
from datetime import datetime, timedelta
87
from psycopg.errors import UniqueViolation
98
from psycopg.types.json import Json
@@ -90,17 +89,20 @@ async def cleanup(self, server: Server):
9089
await server.shutdown()
9190
self.plugin.reset_serversettings(server)
9291

93-
async def render_highscore(self, server: Server):
92+
async def render_aar(self, server: Server, match: dict):
9493
config = self.get_config(server)
9594
channel = self.bot.get_channel(config.get('channels', {}).get('results', -1))
9695
if not channel:
9796
return
9897

9998
tournament = self.tournaments.get(server.name)
100-
report = PersistentReport(self.bot, self.plugin_name, 'highscore.json',
101-
embed_name=f"tournament_{tournament['tournament_id']}_highscore",
102-
channel_id=channel.id)
103-
await report.render(interaction=None, server_name=None, flt=CampaignFilter(period=tournament['name']))
99+
report = Report(self.bot, self.plugin_name, 'aar.json')
100+
env = await report.render(server_name=None, flt=CampaignFilter(period=tournament['name']), match=match)
101+
try:
102+
await channel.send(embed=env.embed, file=discord.File(env.buffer, filename='aar.png'))
103+
finally:
104+
if env.buffer:
105+
env.buffer.close()
104106

105107
async def processEvent(self, name: str, server: Server, data: dict) -> None:
106108
try:
@@ -113,6 +115,7 @@ async def processEvent(self, name: str, server: Server, data: dict) -> None:
113115
async def registerDCSServer(self, server: Server, data: dict) -> None:
114116
tournament_id = await self.get_active_tournament(server)
115117
if not tournament_id:
118+
self.log.debug(f"registerDCSServer: No active tournament for {server.name}.")
116119
self.tournaments.pop(server.name, None)
117120
return
118121

@@ -178,8 +181,10 @@ async def countdown_with_warnings(self, server: Server, delayed_start: int):
178181
async def onSimulationResume(self, server: Server, data: dict) -> None:
179182
config = self.get_config(server)
180183
if 'delayed_start' in config:
184+
self.log.debug(f"onSimulationResume: Delayed start for {server.name} is set to {config['delayed_start']} seconds.")
181185
self.tasks[server.name] = asyncio.create_task(self.countdown_with_warnings(server, config['delayed_start']))
182186
else:
187+
self.log.debug(f"onSimulationResume: Delayed start for {server.name} is not set.")
183188
self.round_started[server.name] = True
184189

185190
async def disqualify(self, server: Server, player: Player, reason: str) -> None:
@@ -403,7 +408,7 @@ async def check_tournament_finished(self, tournament_id: int) -> bool:
403408

404409
@event(name="onMatchFinished")
405410
async def onMatchFinished(self, server: Server, data: dict) -> None:
406-
winner = data['winner'].lower()
411+
winner = data['winner']
407412
match_id = await self.get_active_match(server)
408413
if self.tasks.get(server.name):
409414
self.tasks.pop(server.name).cancel()
@@ -442,8 +447,8 @@ async def onMatchFinished(self, server: Server, data: dict) -> None:
442447
# pause the server
443448
asyncio.create_task(server.current_mission.pause())
444449

445-
# update the highscore
446-
asyncio.create_task(self.render_highscore(server))
450+
# render an AAR
451+
asyncio.create_task(self.render_aar(server, data))
447452

448453
# check if the match is finished
449454
await self.check_match_finished(server, match_id)
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@
88
}
99
],
1010
"elements": [
11+
{
12+
"class": "plugins.competitive.reports.MatchAAR"
13+
},
1114
{
1215
"type": "Graph",
1316
"params": {

0 commit comments

Comments
 (0)