Skip to content

Commit

Permalink
Improved bot commands
Browse files Browse the repository at this point in the history
  • Loading branch information
vikvanderlinden committed Sep 17, 2023
1 parent e9a2f1a commit 2301ed6
Show file tree
Hide file tree
Showing 8 changed files with 25 additions and 34 deletions.
7 changes: 3 additions & 4 deletions command_handlers/add_player.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,18 +15,17 @@
bot.config.get("CTF_OPERATOR_ROLE")
)
async def add_player(interaction, player: discord.Member):
await interaction.response.defer()
message_id = interaction.channel.last_message_id
await interaction.response.defer(thinking=True)

role_name = interaction.channel.category.name
ctf_role = discord.utils.get(interaction.guild.roles, name=role_name)

if not ctf_role:
await interaction.followup.edit_message(message_id, content=f"Please execute this command in a CTF category.")
await interaction.edit_original_response(content=f"Please execute this command in a CTF category.")
return

await player.add_roles(ctf_role)
await interaction.followup.edit_message(message_id, content=f"{player.mention} was added as player in `{role_name}`")
await interaction.edit_original_response(content=f"{player.mention} was added as player in `{role_name}`")

@add_player.error
async def add_player_error(interaction, error):
Expand Down
8 changes: 3 additions & 5 deletions command_handlers/create_challenge.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,20 +13,18 @@
@app_commands.describe(name="The challenge name")
@app_commands.describe(category="The category (web,crypto,pwn,rev,...)")
async def create_challenge(interaction: discord.Interaction, name: str, category: str):
await interaction.response.defer()
message_id = interaction.channel.last_message_id
await interaction.response.defer(thinking=True, ephemeral=True)

ctf_category = interaction.channel.category
ctf_role = discord.utils.get(interaction.guild.roles, name=ctf_category.name)

if not ctf_role or interaction.user.get_role(ctf_role.id) is None:
await interaction.followup.edit_message(message_id, content="You are not playing this CTF so you can't add a challenge.\nIf you are playing please ask an admin.")
await interaction.edit_original_response(content="You are not playing this CTF so you can't add a challenge.\nIf you are playing please ask an admin.")
return

channel = await create_challenge_channel(interaction, f"{category}-{name}", ctf_category)

await interaction.followup.edit_message(message_id,
content=f"Done; {channel.mention} created!\nGo solve that thing :muscle:")
await interaction.edit_original_response(content=f"Done; {channel.mention} created!\nGo solve that thing :muscle:")

async def create_challenge_channel(interaction, name, ctf_category):
new_position = get_new_channel_position(ctf_category,name)
Expand Down
5 changes: 2 additions & 3 deletions command_handlers/create_ctf.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,7 @@
)
@app_commands.describe(name="The CTF name")
async def create_ctf(interaction: discord.Interaction, name: str):
await interaction.response.defer()
message_id = interaction.channel.last_message_id
await interaction.response.defer(thinking=True)

admin_role: discord.Role = discord.utils.get(interaction.guild.roles, name=bot.config.get("ADMIN_ROLE"))
member_role: discord.Role = discord.utils.get(interaction.guild.roles, name=bot.config.get("MEMBER_ROLE"))
Expand All @@ -25,7 +24,7 @@ async def create_ctf(interaction: discord.Interaction, name: str):
ctf_category = await create_ctf_category(interaction, "⚡ " + name, member_role, ctf_role, admin_role)
ctf_main_channel = await create_ctf_main_channel(interaction, name, ctf_category)

await interaction.followup.edit_message(message_id, content=f"Done: CTF boilerplate is set up :raised_hands:\nGo to the {ctf_main_channel.mention} channel to start adding challenges.")
await interaction.edit_original_response(content=f"Done: CTF boilerplate is set up :raised_hands:\nGo to the {ctf_main_channel.mention} channel to start adding challenges.")

async def create_ctf_role(interaction, name, member_role):
role_color = discord.Color(int(bot.config.get("CTF_ROLE_COLOR_HEX"),16))
Expand Down
2 changes: 1 addition & 1 deletion command_handlers/help.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,6 @@ async def create_challenge(interaction: discord.Interaction):
* You really want to join in playing this CTF, but have not been added yet.
* You would like to play a specific CTF that is not in our planning.
* You mistakenly marked a challenge as solved and would like to revert it.
* You played in a CTF and would like to review the discussion from a Discord challenge channel."""
* You played in a CTF and would like to review the discussion from a Discord challenge channel that is not visible anymore."""

await interaction.response.send_message(help_message, ephemeral=True)
7 changes: 3 additions & 4 deletions command_handlers/remove_player.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,18 +15,17 @@
bot.config.get("CTF_OPERATOR_ROLE")
)
async def add_player(interaction, player: discord.Member):
await interaction.response.defer()
message_id = interaction.channel.last_message_id
await interaction.response.defer(thinking=True, ephemeral=True)

role_name = interaction.channel.category.name
ctf_role = discord.utils.get(interaction.guild.roles, name=role_name)

if not ctf_role:
await interaction.followup.edit_message(message_id, content=f"Please execute this command in a CTF category.")
await interaction.edit_original_response(content=f"Please execute this command in a CTF category.")
return

await player.remove_roles(ctf_role)
await interaction.followup.edit_message(message_id, content=f"{player.mention} was removed as player from `{role_name}`")
await interaction.edit_original_response(content=f"{player.mention} was removed as player from `{role_name}`")

@add_player.error
async def add_player_error(interaction, error):
Expand Down
14 changes: 7 additions & 7 deletions command_handlers/solved.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,35 +4,35 @@
from discord import app_commands
import discord
from utils.ctf import get_new_channel_position
from error_handlers.permissions import check_role_error
from error_handlers.default import default as default_error_handler


@bot.client.tree.command(description="Use in a challenge to indicate you have solved the challenge.", guild=bot.guild)
@app_commands.describe(flag="The correct flag for this challenge")
async def solved(interaction, flag: str):
await interaction.response.defer()
message_id = interaction.channel.last_message_id
await interaction.response.defer(thinking=True)

ctf_category = interaction.channel.category
ctf_role = discord.utils.get(interaction.guild.roles, name=ctf_category.name)

if not ctf_role:
# TODO: Can still be run from the main channel for each ctf
await interaction.followup.edit_message(message_id, content="This is not a ctf challenge channel, this command can only be run from a challenge channel.", ephemeral=True)
await interaction.edit_original_response(content="This is not a ctf challenge channel, this command can only be run from a challenge channel.")
return

if interaction.user.get_role(ctf_role.id) is None:
await interaction.followup.edit_message(message_id, content="You are not playing this CTF so you can't add a challenge.\nIf you are playing please ask an admin.", ephemeral=True)
await interaction.edit_original_response(content="You are not playing this CTF so you can't mark a challenge solved.\nIf you are playing please ask an admin.")
return

if "solved" in interaction.channel.name:
await interaction.followup.edit_message(message_id, content="This challenge is already solved.\nIf this was a mistake please contact an admin.", ephemeral=True)
await interaction.edit_original_response(content="This challenge is already solved.\nIf this was a mistake please contact an admin.")
return

new_name = f"solved_{interaction.channel.name}"
new_position = get_new_channel_position(interaction.channel.category, new_name)

await interaction.channel.edit(name=new_name,position=new_position)
await interaction.followup.edit_message(message_id, content=f"Nice, great work! :partying_face:\nSolved by {interaction.user.mention} with `{flag}`.")
await interaction.edit_original_response(content=f"Nice, great work! :partying_face:\nSolved by {interaction.user.mention} with `{flag}`.")

@solved.error
async def error_on_create_challenge_command(interaction, error):
Expand Down
11 changes: 6 additions & 5 deletions command_handlers/unsolve.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
import discord
from discord import app_commands
from utils.ctf import get_new_channel_position
from error_handlers.permissions import check_role_error
from error_handlers.default import default as default_error_handler


@bot.client.tree.command(description="Use in a challenge to revert the solving of the challenge.", guild=bot.guild)
Expand All @@ -12,26 +14,25 @@
bot.config.get("CTF_OPERATOR_ROLE")
)
async def unsolve(interaction):
await interaction.response.defer()
await interaction.response.defer(thinking=True)
message_id = interaction.channel.last_message_id

ctf_category = interaction.channel.category
ctf_role = discord.utils.get(interaction.guild.roles, name=ctf_category.name)

if not ctf_role:
# TODO: Can still be run from the main channel for each ctf
await interaction.followup.edit_message(message_id, content="This is not a ctf challenge channel, this command can only be run from a challenge channel.", ephemeral=True)
await interaction.edit_original_response(content="This is not a ctf challenge channel, this command can only be run from a challenge channel.")
return

if "solved" not in interaction.channel.name:
await interaction.followup.edit_message(message_id, content="This challenge is not solved.\nIn order to mark a challenge as unsolved it should have been marked as solved.", ephemeral=True)
await interaction.edit_original_response(content="This challenge is not solved.\nIn order to mark a challenge as unsolved it should have been marked as solved.")
return

new_name = interaction.channel.name.replace("solved_", "")
new_position = get_new_channel_position(interaction.channel.category, new_name)

await interaction.channel.edit(name=new_name, position=new_position)
await interaction.response.send_message(f"Awww, it turned out this wasn't a solve after all :pensive:")
await interaction.edit_original_response(content=f"Turns out this wasn't a solve after all :pensive:")

@unsolve.error
async def error_on_create_challenge_command(interaction, error):
Expand Down
5 changes: 0 additions & 5 deletions utils/ctf.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,7 @@
import discord
import asyncio

def get_new_channel_position(category, new_channel_name):
channels = category.channels
channel_map = sorted(map(lambda c: (c.name.replace("solved_", "zzzzzz_"), c.position), channels[1:]), key=channel_sort_key)
print(channel_map)
print(new_channel_name)

return calculate_position(new_channel_name.replace("solved_", "zzzzzz_"), channel_map)

Expand All @@ -26,7 +22,6 @@ def calculate_position(name, channel_map):
if new_position is None:
new_position = last_position + 100

print(last_position, new_position)
return new_position

def channel_sort_key(channel_map_entry):
Expand Down

0 comments on commit 2301ed6

Please sign in to comment.