mafflife

Wowee

Jul 28th, 2025 (edited)
188
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 11.13 KB | Gaming | 0 0
  1. import discord
  2. from discord.ext import commands
  3. from discord import app_commands
  4. import json
  5. import os
  6. from datetime import datetime
  7.  
  8. # Bot setup
  9. intents = discord.Intents.default()
  10. bot = commands.Bot(command_prefix="!", intents=intents)
  11. LOG_LIMIT = 50
  12. STORAGE_FILE = "ships_data.json"
  13.  
  14. # Ship class
  15. class Ship:
  16.     def __init__(self, ship_type, name, location, home_port, status, damage, regiment, keys,
  17.                  message_id=None, channel_id=None):
  18.         self.ship_type = ship_type
  19.         self.name = name
  20.         self.location = location
  21.         self.home_port = home_port
  22.         self.status = status
  23.         self.damage = int(damage)
  24.         self.regiment = regiment
  25.         self.keys = keys
  26.         self.message_id = message_id
  27.         self.channel_id = channel_id
  28.  
  29.     def to_embed(self):
  30.         embed = discord.Embed(title=self.name, color=discord.Color.blue())
  31.         embed.add_field(name="Type", value=self.ship_type, inline=True)
  32.         embed.add_field(name="Status", value=self.status, inline=True)
  33.         embed.add_field(name="Damage", value=f"{'💨' * self.damage}", inline=True)
  34.         embed.add_field(name="Location", value=self.location, inline=True)
  35.         embed.add_field(name="Home Port", value=self.home_port, inline=True)
  36.         embed.add_field(name="Regiment", value=self.regiment, inline=True)
  37.         embed.add_field(name="Keys", value=self.keys, inline=True)
  38.         return embed
  39.  
  40. # Persistent storage
  41. class ShipDataStore:
  42.     def __init__(self, storage_path=STORAGE_FILE):
  43.         self.storage_path = storage_path
  44.         self.ships = {}
  45.         self.logs = {}
  46.         self.load()
  47.  
  48.     def add_ship(self, ship):
  49.         self.ships[ship.name] = ship
  50.         self.logs.setdefault(ship.name, [])
  51.  
  52.     def remove_ship(self, name):
  53.         if name in self.ships:
  54.             del self.ships[name]
  55.         if name in self.logs:
  56.             del self.logs[name]
  57.         self.save()
  58.  
  59.     def log_action(self, ship_name, user, action):
  60.         if ship_name not in self.logs:
  61.             self.logs[ship_name] = []
  62.         timestamp = datetime.utcnow().strftime('%Y-%m-%d %H:%M:%S UTC')
  63.         self.logs[ship_name].append(f"[{timestamp}] {user}: {action}")
  64.         self.logs[ship_name] = self.logs[ship_name][-LOG_LIMIT:]
  65.         self.save()
  66.  
  67.     def get_logs(self, ship_name):
  68.         return self.logs.get(ship_name, [])
  69.  
  70.     def save(self):
  71.         data = {
  72.             "ships": {name: vars(ship) for name, ship in self.ships.items()},
  73.             "logs": self.logs
  74.         }
  75.         with open(self.storage_path, "w") as f:
  76.             json.dump(data, f, indent=4)
  77.  
  78.     def load(self):
  79.         if not os.path.exists(self.storage_path):
  80.             return
  81.         with open(self.storage_path, "r") as f:
  82.             data = json.load(f)
  83.             for name, values in data.get("ships", {}).items():
  84.                 ship = Ship(**values)
  85.                 self.ships[name] = ship
  86.             self.logs = data.get("logs", {})
  87.  
  88. data_store = ShipDataStore()
  89.  
  90. # Interactive button view
  91. class ShipView(discord.ui.View):
  92.     def __init__(self, ship: Ship):
  93.         super().__init__(timeout=None)
  94.         self.ship = ship
  95.  
  96.     @discord.ui.button(label="Departing", style=discord.ButtonStyle.success)
  97.     async def departing(self, interaction: discord.Interaction, button: discord.ui.Button):
  98.         self.ship.status = "Deployed" if button.label == "Departing" else "Parked"
  99.         button.label = "Returned" if button.label == "Departing" else "Departing"
  100.         await self.update(interaction, f"Status changed to {self.ship.status}")
  101.  
  102.     @discord.ui.button(label="Repair", style=discord.ButtonStyle.primary)
  103.     async def repair(self, interaction: discord.Interaction, button: discord.ui.Button):
  104.         self.ship.status = "Repairing" if button.label == "Repair" else "Parked"
  105.         button.label = "Finish Repairs" if button.label == "Repair" else "Repair"
  106.         await self.update(interaction, f"Status changed to {self.ship.status}")
  107.  
  108.     @discord.ui.button(label="Dead", style=discord.ButtonStyle.danger)
  109.     async def dead(self, interaction: discord.Interaction, button: discord.ui.Button):
  110.         self.ship.status = "Dead"
  111.         await self.update(interaction, f"Marked as Dead")
  112.  
  113.     async def update(self, interaction, action_desc):
  114.         data_store.log_action(self.ship.name, interaction.user.name, action_desc)
  115.         channel = interaction.client.get_channel(self.ship.channel_id)
  116.         message = await channel.fetch_message(self.ship.message_id)
  117.         await message.edit(embed=self.ship.to_embed(), view=self)
  118.         await interaction.response.defer()
  119.         data_store.save()
  120.  
  121. # Continuing from previous code...
  122.  
  123. @bot.event
  124. async def on_ready():
  125.     print(f"Logged in as {bot.user}")
  126.     try:
  127.         synced = await bot.tree.sync()
  128.         print(f"Synced {len(synced)} commands")
  129.     except Exception as e:
  130.         print(f"Failed to sync commands: {e}")
  131.  
  132. # Helper function to get ship by name or respond with error
  133. async def get_ship_or_error(interaction, ship_name):
  134.     ship = data_store.ships.get(ship_name)
  135.     if not ship:
  136.         await interaction.response.send_message(f"Ship `{ship_name}` not found.", ephemeral=True)
  137.         return None
  138.     return ship
  139.  
  140. # /create_ship command
  141. @bot.tree.command(name="create_ship", description="Create a new ship record")
  142. @app_commands.describe(
  143.     ship_type="Type of ship (destroyer, submarine, battleship, bluefin)",
  144.     name="Name of the ship",
  145.     location="Current location of the ship",
  146.     home_port="Ship's home port",
  147.     status="Current status (Deployed, Parked, Repairing, Dead)",
  148.     damage="Damage count (0-5)",
  149.     regiment="Regiment the ship belongs to",
  150.     keys="Squad keys"
  151. )
  152. @app_commands.checks.has_permissions(administrator=True)
  153. async def create_ship(interaction: discord.Interaction, ship_type: str, name: str, location: str,
  154.                       home_port: str, status: str, damage: int, regiment: str, keys: str):
  155.     if name in data_store.ships:
  156.         await interaction.response.send_message(f"A ship named `{name}` already exists.", ephemeral=True)
  157.         return
  158.  
  159.     # Validate damage
  160.     if not 0 <= damage <= 5:
  161.         await interaction.response.send_message("Damage must be between 0 and 5.", ephemeral=True)
  162.         return
  163.  
  164.     ship = Ship(ship_type, name, location, home_port, status, damage, regiment, keys)
  165.     view = ShipView(ship)
  166.  
  167.     # Send message with embed and buttons
  168.     message = await interaction.channel.send(embed=ship.to_embed(), view=view)
  169.     ship.message_id = message.id
  170.     ship.channel_id = message.channel.id
  171.  
  172.     data_store.add_ship(ship)
  173.     data_store.save()
  174.     data_store.log_action(name, interaction.user.name, "Created ship")
  175.  
  176.     await interaction.response.send_message(f"Ship `{name}` created successfully.", ephemeral=True)
  177.  
  178. # /update_ship command
  179. @bot.tree.command(name="update_ship", description="Update a ship's field")
  180. @app_commands.describe(
  181.     name="Name of the ship",
  182.     field="Field to update (Location, Home Port, Status, Damage, Keys)",
  183.     data="New value for the field"
  184. )
  185. @app_commands.checks.has_permissions(administrator=True)
  186. async def update_ship(interaction: discord.Interaction, name: str, field: str, data: str):
  187.     ship = await get_ship_or_error(interaction, name)
  188.     if not ship:
  189.         return
  190.  
  191.     field = field.lower()
  192.     valid_fields = ['location', 'home port', 'status', 'damage', 'keys']
  193.     if field not in [f.lower() for f in valid_fields]:
  194.         await interaction.response.send_message(f"Invalid field `{field}`. Valid fields: {', '.join(valid_fields)}", ephemeral=True)
  195.         return
  196.  
  197.     if field == "damage":
  198.         try:
  199.             damage_val = int(data)
  200.             if not 0 <= damage_val <= 5:
  201.                 raise ValueError()
  202.             ship.damage = damage_val
  203.         except ValueError:
  204.             await interaction.response.send_message("Damage must be an integer between 0 and 5.", ephemeral=True)
  205.             return
  206.     elif field == "home port":
  207.         ship.home_port = data
  208.     elif field == "location":
  209.         ship.location = data
  210.     elif field == "status":
  211.         ship.status = data
  212.     elif field == "keys":
  213.         ship.keys = data
  214.  
  215.     data_store.log_action(name, interaction.user.name, f"Updated {field} to {data}")
  216.  
  217.     # Update embed in message
  218.     channel = bot.get_channel(ship.channel_id)
  219.     if channel:
  220.         try:
  221.             message = await channel.fetch_message(ship.message_id)
  222.             await message.edit(embed=ship.to_embed(), view=ShipView(ship))
  223.         except:
  224.             pass
  225.  
  226.     data_store.save()
  227.     await interaction.response.send_message(f"Updated `{field}` of ship `{name}`.", ephemeral=True)
  228.  
  229. # /remove_ship command
  230. @bot.tree.command(name="remove_ship", description="Remove a ship from tracking")
  231. @app_commands.describe(name="Name of the ship to remove")
  232. @app_commands.checks.has_permissions(administrator=True)
  233. async def remove_ship(interaction: discord.Interaction, name: str):
  234.     if name not in data_store.ships:
  235.         await interaction.response.send_message(f"No ship named `{name}` found.", ephemeral=True)
  236.         return
  237.     data_store.remove_ship(name)
  238.     await interaction.response.send_message(f"Ship `{name}` removed.", ephemeral=True)
  239.  
  240. # /list_ships command
  241. @bot.tree.command(name="list_ships", description="List all tracked ships")
  242. async def list_ships(interaction: discord.Interaction):
  243.     if not data_store.ships:
  244.         await interaction.response.send_message("No ships are currently being tracked.", ephemeral=True)
  245.         return
  246.     ships_list = "\n".join(f"- {name} ({ship.ship_type}) - Status: {ship.status}" for name, ship in data_store.ships.items())
  247.     await interaction.response.send_message(f"Tracked ships:\n{ships_list}", ephemeral=True)
  248.  
  249. # /view_logs command
  250. @bot.tree.command(name="view_logs", description="View last 50 logs of a ship")
  251. @app_commands.describe(name="Name of the ship")
  252. @app_commands.checks.has_permissions(administrator=True)
  253. async def view_logs(interaction: discord.Interaction, name: str):
  254.     if name not in data_store.ships:
  255.         await interaction.response.send_message(f"No ship named `{name}` found.", ephemeral=True)
  256.         return
  257.     logs = data_store.get_logs(name)
  258.     if not logs:
  259.         await interaction.response.send_message(f"No logs found for ship `{name}`.", ephemeral=True)
  260.         return
  261.  
  262.     # Format logs, splitting into multiple messages if too long
  263.     MAX_CHARS = 1900
  264.     log_text = "\n".join(logs)
  265.     messages = []
  266.     while log_text:
  267.         if len(log_text) <= MAX_CHARS:
  268.             messages.append(log_text)
  269.             break
  270.         else:
  271.             split_index = log_text.rfind("\n", 0, MAX_CHARS)
  272.             if split_index == -1:
  273.                 split_index = MAX_CHARS
  274.             messages.append(log_text[:split_index])
  275.             log_text = log_text[split_index:].lstrip("\n")
  276.  
  277.     await interaction.response.send_message(f"Logs for ship `{name}`:", ephemeral=True)
  278.     for part in messages:
  279.         await interaction.followup.send(f"```\n{part}\n```", ephemeral=True)
  280.  
  281.  
  282. bot.run("MTM1OTAyOTM1OTY1ODI3MDg2MQ.G8uvpN.BrzUjaS2DPFhKlm5X4HejxrVcMpPI3u-ukJRko")
  283.  
Advertisement
Add Comment
Please, Sign In to add comment