diff --git a/.gitignore b/.gitignore index c49ba88..5274dfe 100644 --- a/.gitignore +++ b/.gitignore @@ -8,6 +8,7 @@ launch.json .idea test.py ActiveGames/ +GameHistory/ # Byte-compiled / optimized / DLL files diff --git a/Buttons/Turn.py b/Buttons/Turn.py index 0f46077..b8533dc 100644 --- a/Buttons/Turn.py +++ b/Buttons/Turn.py @@ -281,6 +281,7 @@ async def runUpkeep(game: GamestateHelper, interaction: discord.Interaction): asyncio.create_task(thread.edit(archived=True)) await game.upkeep(interaction) drawing = DrawHelper(game.gamestate) + game.saveEndRound() if game.gamestate["roundNum"] < 9: await interaction.channel.send(f"Tech Available At Start Of Round {game.gamestate['roundNum']}", file=await asyncio.to_thread(drawing.show_available_techs)) @@ -301,7 +302,8 @@ async def runUpkeep(game: GamestateHelper, interaction: discord.Interaction): view.add_item(Button(label="Declare Winner", style=discord.ButtonStyle.blurple, custom_id="declareWinner")) await interaction.channel.send("It seems like the game should be ended, " "hit this button to reveal the winner.", view=view) - asyncio.create_task(game.showUpdate(f"Start of round {str(game.gamestate['roundNum'])}", interaction)) + asyncio.create_task(game.showUpdate(f"Start of round {str(game.gamestate['roundNum'])}", interaction, finalSave=True)) + @staticmethod async def showReputation(game: GamestateHelper, interaction: discord.Interaction, player): diff --git a/helpers/DrawHelper.py b/helpers/DrawHelper.py index b5b5388..3f91776 100644 --- a/helpers/DrawHelper.py +++ b/helpers/DrawHelper.py @@ -1652,7 +1652,7 @@ def get_public_points(self, player, showPrivateRegardless:bool): points -= 2 return points - def show_game(self): + def show_game(self, finalSave=False): def load_tile_coordinates(): configs = Properties() with open("data/tileImageCoordinates.properties", "rb") as f: @@ -1740,6 +1740,7 @@ def create_player_area(): width = max([context2.size[0], context3.size[0] + context4.size[0] + 150, cropped_context.size[0], context5.size[0]]) height = (cropped_context.size[1] + context2.size[1] + + max(context3.size[1], context4.size[1]) + 90) final_context = Image.new("RGBA", (width, height), (0, 0, 0, 255)) centering = int((width - cropped_context.size[0])/2) @@ -1755,6 +1756,18 @@ def create_player_area(): context4.size[1]))) bytes_io = BytesIO() final_context.save(bytes_io, format="WEBP") + if finalSave == True: + if "roundNum" in self.gamestate: + rnd = self.gamestate["roundNum"] + else: + rnd = 1 + output_dir = f'gamehistory/{self.gamestate["game_id"]}' + filename = f'{self.gamestate["game_id"]}-{rnd-1}.webp' + if not os.path.exists(output_dir): + os.makedirs(output_dir) + full_path = os.path.join(output_dir, filename) + resized = final_context.resize((int(width*0.3), int(height*0.3))) + resized.save(full_path, quality=50, compress_level=8) bytes_io.seek(0) return discord.File(bytes_io, filename="map_image.webp") diff --git a/helpers/GamestateHelper.py b/helpers/GamestateHelper.py index fbe517a..65e011d 100644 --- a/helpers/GamestateHelper.py +++ b/helpers/GamestateHelper.py @@ -4,6 +4,7 @@ import portalocker import discord import config +import shutil from helpers.DrawHelper import DrawHelper from helpers.EmojiHelper import Emoji from helpers.PlayerHelper import PlayerHelper @@ -98,6 +99,15 @@ async def endGame(self, interaction: discord.Interaction): guild = interaction.guild self.gamestate["gameEnded"] = True self.update() + history_path = f'GameHistory/{self.game_id}' + if os.path.exists(history_path): + shutil.make_archive(history_path, 'zip', history_path) + stats_channel = discord.utils.get(guild.channels, name='ggranger-stats-paradise') + if stats_channel: + zf = discord.File(f'{history_path}.zip') + await stats_channel.send(file=zf) + os.remove(f'{history_path}.zip') + shutil.rmtree(f'{history_path}') category = interaction.channel.category role = discord.utils.get(guild.roles, name=self.game_id) for channel in guild.channels: @@ -189,6 +199,13 @@ def get_gamestate(self): self.file = f gamestate = json.load(f) return gamestate + + def saveEndRound(self): + output_dir = f'GameHistory/{self.game_id}' + if not os.path.exists(output_dir): + os.makedirs(output_dir) + with open(f'GameHistory/{self.game_id}/{self.game_id}-{self.gamestate["roundNum"]-1}.json', "w") as outfile: + json.dump(self.gamestate, outfile) def is_file_open(self,file_path): try: @@ -1392,9 +1409,12 @@ def get_owned_tiles(self, player): tiles.append(tile) return tiles - async def showGame(self, thread, message): + async def showGame(self, thread, message, finalSave = False): drawing = DrawHelper(self.gamestate) - map_result = await asyncio.to_thread(drawing.show_game) + if finalSave: + map_result = drawing.show_game(finalSave) + else: + map_result = await asyncio.to_thread(drawing.show_game) view = View() view.add_item(Button(label="Show Game", style=discord.ButtonStyle.blurple, custom_id="showGame")) view.add_item(Button(label="Show Reputation", style=discord.ButtonStyle.gray, custom_id="showReputation")) @@ -1406,12 +1426,12 @@ async def showGame(self, thread, message): view.add_item(button) await thread.send(view=view) - async def showUpdate(self, message: str, interaction: discord.Interaction): + async def showUpdate(self, message: str, interaction: discord.Interaction, finalSave = False): if "-" in interaction.channel.name: thread_name = interaction.channel.name.split("-")[0] + "-bot-map-updates" thread = discord.utils.get(interaction.channel.threads, name=thread_name) if thread is not None: - asyncio.create_task(self.showGame(thread, message)) + asyncio.create_task(self.showGame(thread, message, finalSave)) def getPlayerFromHSLocation(self, location): if "sector" not in self.gamestate["board"].get(location, []):