import discord from discord.ext import commands, tasks import json import datetime # Bot setup intents = discord.Intents.default() intents.messages = True intents.message_content = True intents.guilds = True intents.members = True bot = commands.Bot(command_prefix="$", intents=intents) # Allowed IDs for $LockDown ALLOWED_IDS = [522556, 668884] # Replace with your desired IDs # Data storage file DATA_FILE = "staff_data.json" # Load data try: with open(DATA_FILE, "r") as f: staff_data = json.load(f) except FileNotFoundError: staff_data = {} # Save data function def save_data(): with open(DATA_FILE, "w") as f: json.dump(staff_data, f, indent=4) # Utility function to ensure a user has a data entry def ensure_user_data(user_id): if str(user_id) not in staff_data: staff_data[str(user_id)] = { "notes": [], "bolos": [], "warns": [], "detained": False, "roles_backup": [], } # Command: $say @bot.command() @commands.has_permissions(manage_messages=True) async def say(ctx, *, message): """ Repeats the given message. """ await ctx.message.delete() await ctx.send(message) # Command: $LockDown @bot.command() async def lockdown(ctx, state: str): """ Locks down all channels in the server. """ if ctx.author.id not in ALLOWED_IDS: await ctx.send("You do not have permission to use this command.") return if state.lower() not in ["true", "false"]: await ctx.send("Invalid state. Use `true` or `false`.") return is_lockdown = state.lower() == "true" guild = ctx.guild lockdown_role = discord.utils.get(guild.roles, name="Anti-Lockdown") for channel in guild.channels: if isinstance(channel, discord.TextChannel): overwrite = channel.overwrites_for(guild.default_role) overwrite.send_messages = not is_lockdown await channel.set_permissions(guild.default_role, overwrite=overwrite) if is_lockdown: # Lockdown mode for role in guild.roles: if role != lockdown_role: await role.edit(permissions=discord.Permissions.none()) await ctx.send("Server is now in lockdown mode.") else: # Unlock all roles and channels await ctx.send("Lockdown lifted.") # Command: $Note @bot.command() async def note(ctx, user: discord.Member, *, reason): """ Notes down an action for a user. """ ensure_user_data(user.id) staff_data[str(user.id)]["notes"].append({"reason": reason, "time": str(datetime.datetime.utcnow())}) save_data() await ctx.send(f"Noted `{user}` for: {reason}") # Command: $Note-View @bot.command() async def note_view(ctx, user: discord.Member): """ Sends a webhook with all notes for a user. """ ensure_user_data(user.id) notes = staff_data[str(user.id)]["notes"] if not notes: await ctx.send(f"No notes found for {user}.") return # Send notes as a formatted message embed = discord.Embed(title=f"Notes for {user}", color=discord.Color.blue()) for note in notes: embed.add_field(name=note["time"], value=note["reason"], inline=False) await ctx.send(embed=embed) # Command: $Bolo @bot.command() async def bolo(ctx, user: discord.Member, bolo_type: str): """ Issues a BOLO (Be on the Lookout) for a user. """ if bolo_type.lower() not in ["lookout", "watch"]: await ctx.send("Invalid BOLO type. Use `LookOut` or `Watch`.") return ensure_user_data(user.id) staff_data[str(user.id)]["bolos"].append({"type": bolo_type, "time": str(datetime.datetime.utcnow())}) save_data() await ctx.send(f"BOLO `{bolo_type}` issued for `{user}`.") # Command: $Bolo-Logs @bot.command() async def bolo_logs(ctx, channel: discord.TextChannel, bolo_type: str): """ Sends BOLO logs to the specified channel. """ logs = [] for user_id, user_data in staff_data.items(): for bolo in user_data.get("bolos", []): if bolo["type"].lower() == bolo_type.lower(): user = await bot.fetch_user(user_id) logs.append(f"{user} - {bolo['type']} at {bolo['time']}") if not logs: await ctx.send("No BOLO logs found for this type.") return await channel.send("\n".join(logs)) # Command: $Detain @bot.command() async def detain(ctx, user: discord.Member, *, reason): """ Detains a user by removing all their roles and giving a "Detained" role. """ detained_role = discord.utils.get(ctx.guild.roles, name="Detained") if not detained_role: detained_role = await ctx.guild.create_role(name="Detained", permissions=discord.Permissions.none()) ensure_user_data(user.id) staff_data[str(user.id)]["detained"] = True staff_data[str(user.id)]["roles_backup"] = [role.id for role in user.roles if role != ctx.guild.default_role] staff_data[str(user.id)]["warns"].append({"reason": reason, "time": str(datetime.datetime.utcnow())}) save_data() await user.remove_roles(*user.roles) await user.add_roles(detained_role) await ctx.send(f"{user} has been detained for: {reason}") # Command: $Temp-Detain @bot.command() async def temp_detain(ctx, user: discord.Member, time: int, *, reason): """ Temporarily detains a user and restores roles after the time expires. """ await detain(ctx, user, reason=reason) async def restore_roles(): await asyncio.sleep(time * 60) # Convert minutes to seconds detained_role = discord.utils.get(ctx.guild.roles, name="Detained") ensure_user_data(user.id) # Restore roles backup_roles = [ctx.guild.get_role(role_id) for role_id in staff_data[str(user.id)]["roles_backup"]] await user.remove_roles(detained_role) await user.add_roles(*backup_roles) staff_data[str(user.id)]["detained"] = False save_data() await ctx.send(f"{user}'s detention period has ended. Roles restored.") bot.loop.create_task(restore_roles()) # Event: On member join @bot.event async def on_member_join(member): ensure_user_data(member.id) user_data = staff_data[str(member.id)] if user_data["detained"]: detained_role = discord.utils.get(member.guild.roles, name="Detained") if not detained_role: detained_role = await member.guild.create_role(name="Detained", permissions=discord.Permissions.none()) await member.add_roles(detained_role) dm_message = f"Welcome back to {member.guild.name}. Here are your saved stats:\n" \ f"- Warns: {len(user_data['warns'])}\n" \ f"- BOLOs: {len(user_data['bolos'])}\n" \ f"- Notes: {len(user_data['notes'])}\n" \ f"- Detained: {'Yes' if user_data['detained'] else 'No'}" await member.send(dm_message) # Run the bot bot.run("YOUR_BOT_TOKEN")