G4_Bot/methods.py

200 lines
8 KiB
Python

#methods.py
#Imports.
import os, json, discord, random, math
from dotenv import load_dotenv
#Load .env file.
load_dotenv()
PREFIX = os.getenv('BOT_PREFIX')
#######################################################################################
### COMMANDS - ALL COMMANDS MUST BE ALL LOWERCASE, NO SPACES, WITH A PREFIX OF CMD_ ###
#######################################################################################
async def cmd_hello(ctx):
await ctx.send("Hello, World!")
async def cmd_goodbye(ctx):
await ctx.send("Goodbye!")
async def cmd_whatareyou(ctx):
await ctx.send("An idiot sandwich.")
#Add points for a user.
async def cmd_addpoints(ctx, member: discord.Member = None, number = None):
points_data = loadpoints() #Load all point history into a variable.
member = member or ctx.author #Set the target equal to the user specified OR the sender of the message.
user_id = str(member.id) #Sets the user ID equal to the ID of the user specified.
pointAmount = number or 1 #Makes the amount to add either the amount specified, or just 1.
points_data[user_id] = points_data.get(user_id, 0) + int(pointAmount) #Add the desired amount of points to the user.
loadpoints(points_data) #Reload the points data.
await ctx.send(f"{member.mention} now has {points_data[user_id]} points!")
#Checks the current points of a user.
async def cmd_checkpoints(ctx, member: discord.Member = None):
points_data = loadpoints() #Load all point history into a variable.
member = member or ctx.author # Checks either the member specified, or the sender of the message.
user_id = str(member.id) #Set the user ID equal to the ID of the user specified.
points = points_data.get(user_id, 0) #Retrieve the points of the user ID.
await ctx.send(f"{member.mention} has {points} points.")
#Add a custom command to customcommands.json.
async def cmd_addcommand(ctx, command, *message):
response = (" ".join(message)) #Takes in the custom message.
commands_temp = loadcommands("commands.json") #Load the built-in commands to a temp variable.
customcommands_temp = loadcommands("customcommands.json") #Load the custom commands to a temp variable.
#Checks to see if the command already exists in commands.json.
if command in commands_temp:
await ctx.send(f"Command '{command}' already exists in base commands! Not overwriting.")
return
#Checks to see if the command already exists in customcommands.json.
if command in customcommands_temp:
await ctx.send(f"Command '{command}' already exists in custom commands! Not overwriting.")
return
#Takes the response, and adds it to the customcommands.json file.
customcommands_temp[command] = response
with open("customcommands.json", "w", encoding="utf-8") as file:
json.dump(customcommands_temp, file, indent=4)
await ctx.send(f"Command '{command}' added successfully!")
#Lists all built-in and custom commands currently set up.
async def cmd_listcommands(ctx):
try:
#Loads both custom and built-in commands to temp variables.
commands_dict = loadcommands("commands.json")
customcommands_dict = loadcommands("customcommands.json")
#Adds each set of commands into a list variable, then displays it.
commands_list = "\n".join([f"{PREFIX}**{cmd}**" for cmd, resp in commands_dict.items()])
await ctx.send(f"**Available Built-In Commands:**\n\n{commands_list}")
#Checks to see if there are any custom commands, and then lists them if there are any.
with open ("customcommands.json", 'r') as file:
data = json.load(file)
if data != {}:
customcommands_list = "\n".join([f"{PREFIX}**{cmd}**" for cmd, resp in customcommands_dict.items()])
await ctx.send(f"\n\n**Available Custom Commands:**\n\n{customcommands_list}\n\n")
#Exception for failing to load commands. Typically indicates a missing commands.json file.
except Exception as e:
await ctx.send(f"Error loading commands: {e}")
#Rolls a dice roll. Supports modifiers as well.
async def cmd_roll(ctx, inputValue, sign = None, addition = None):
#Initializing variables for the subtotal and total.
subtotal = 0
total = 0
#Rolls the dice.
try:
#Splits the input into variables separated by the letter 'd', for number of sides, and how many sides.
number, sides = map(int, inputValue.lower().split('d'))
#For however many times you roll, it passes the number of sides to a rolldie function, and adds the result to subtotal.
for _ in range(number):
subtotal += rolldie(sides)
#Checks to see if any modifiers were applied. If so, apply the logic.
if sign and addition:
total = subtotal
addition = int(addition) #Explicitly converts the modifier value to an integer.
if sign == '+': #Addition.
total = subtotal + addition
elif sign == '-': #Subtraction.
total = subtotal - addition
elif sign in ('*', 'X', 'x'): #Multiplication.
total = subtotal * addition
elif sign == '/': #Division, rounding down.
total = math.floor(subtotal / addition)
else:
await ctx.send("Invalid mathematical sign passed.")
await ctx.send(f"You rolled a total of {total} ({subtotal} {sign} {addition}).")
else:
await ctx.send(f"You rolled a total of {subtotal}.")
except ValueError as e:
await ctx.send(f"Invalid input - {e}.")
########################################################
### INTERNAL METHODS - ALL METHODS MUST BE LOWERCASE ###
########################################################
#Loads commands into variable.
def loadcommands(filename):
if not os.path.exists(filename):
with open(filename, "w", encoding="utf-8") as file:
json.dump({}, file) # Create an empty JSON file
with open(filename, "r", encoding="utf-8") as file:
return json.load(file)
#Loads points into variable.
def loadpoints():
if not os.path.exists("points.json"):
with open("points.json", "w", encoding="utf-8") as file:
json.dump({}, file) # Create an empty JSON file
with open("points.json", "r", encoding="utf-8") as file:
return json.load(file)
# Saves points to the points.json file.
def savepoints(points_data):
with open("points.json", "w", encoding="utf-8") as file:
json.dump(points_data, file, indent=4)
#Rolls die for cmd_roll
def rolldie(sides):
return random.randint(1, sides)
# Define the rotation start date (Week 1)
ROTATION_START_DATE = datetime.date(2025, 7, 14)
#@bot.command(name='rotation')
async def cmd_rotation(ctx):
# Get today's date
today = datetime.date.today() # For this example, assume July 24, 2025
# Calculate days since the start of the rotation
days_since_start = (today - ROTATION_START_DATE).days
# Calculate current week number (1, 2, or 3)
current_week = (days_since_start // 7 % 3) + 1
# Determine the status based on the week number
if current_week == 1 or current_week == 2:
status = "Work from home"
else: # current_week == 3
status = "Working at the office"
# Find the Monday of the current week
# weekday() returns 0 for Monday, 1 for Tuesday, etc.
current_monday = today - datetime.timedelta(days=today.weekday())
# Calculate weeks to add to reach the next Week 3
if current_week == 1:
weeks_to_add = 2
elif current_week == 2:
weeks_to_add = 1
else: # current_week == 3
weeks_to_add = 3
# Calculate the next Week 3 Monday
next_week3_monday = current_monday + datetime.timedelta(weeks=weeks_to_add)
# Format the response
response = (
f"You are currently in **Week {current_week}** ({status}).\n"
f"You will be back to working at the office on **{next_week3_monday.strftime('%B %d, %Y')}**."
)
# Send the response
await ctx.send(response)