✨
This commit is contained in:
@@ -1,7 +1,7 @@
|
|||||||
from interactions import Extension, slash_command, SlashContext
|
from interactions import Extension, slash_command, SlashContext
|
||||||
from gwendolyn.utils import PARAMS as params
|
from gwendolyn.utils import PARAMS as params
|
||||||
|
|
||||||
class BetterNeflixExtension(Extension):
|
class BetterNetflixExtension(Extension):
|
||||||
"""Contains the Better Netflix commands."""
|
"""Contains the Better Netflix commands."""
|
||||||
@slash_command(**params["better_netflix"]["movie"])
|
@slash_command(**params["better_netflix"]["movie"])
|
||||||
async def movie(self, ctx: SlashContext):
|
async def movie(self, ctx: SlashContext):
|
||||||
@@ -9,4 +9,8 @@ class BetterNeflixExtension(Extension):
|
|||||||
|
|
||||||
@slash_command(**params["better_netflix"]["show"])
|
@slash_command(**params["better_netflix"]["show"])
|
||||||
async def show(self, ctx: SlashContext):
|
async def show(self, ctx: SlashContext):
|
||||||
await self.bot.better_netflix.show(ctx)
|
await self.bot.better_netflix.show(ctx)
|
||||||
|
|
||||||
|
@slash_command(**params["better_netflix"]["downloading"])
|
||||||
|
async def downloading(self, ctx: SlashContext):
|
||||||
|
await self.bot.better_netflix.downloading(ctx)
|
||||||
12
gwendolyn/ext/games.py
Normal file
12
gwendolyn/ext/games.py
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
from interactions import Extension, slash_command, SlashContext
|
||||||
|
from gwendolyn.utils import PARAMS as params
|
||||||
|
|
||||||
|
class GamesExtension(Extension):
|
||||||
|
"""Contains the game commands."""
|
||||||
|
@slash_command(**params["games"]["money"]["balance"])
|
||||||
|
async def balance(self, ctx: SlashContext):
|
||||||
|
await self.bot.money.sendBalance(ctx)
|
||||||
|
|
||||||
|
@slash_command(**params["games"]["money"]["give"])
|
||||||
|
async def give(self, ctx: SlashContext):
|
||||||
|
await self.bot.money.giveMoney(ctx)
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
"""A collection of all Gwendolyn functions."""
|
"""A collection of all Gwendolyn functions."""
|
||||||
|
|
||||||
__all__ = ["Other","BetterNetflix", "Sonarr", "Radarr", "TMDb", "QBittorrent"]
|
__all__ = ["Other","BetterNetflix", "Sonarr", "Radarr", "TMDb", "QBittorrent", "Money"]
|
||||||
|
|
||||||
from .other import Other
|
from .other import Other
|
||||||
from .better_netflix import Radarr, Sonarr, BetterNetflix, TMDb, QBittorrent
|
from .better_netflix import Radarr, Sonarr, BetterNetflix, TMDb, QBittorrent
|
||||||
|
from .games import Money, Games
|
||||||
@@ -117,7 +117,7 @@ class BetterNetflix():
|
|||||||
|
|
||||||
if "imdb" in picked_movie['ratings']:
|
if "imdb" in picked_movie['ratings']:
|
||||||
description += f"<:imdb:1301506320603676782> {picked_movie['ratings']['imdb']['value']}"
|
description += f"<:imdb:1301506320603676782> {picked_movie['ratings']['imdb']['value']}"
|
||||||
description += "/10"
|
description += "/10 "
|
||||||
|
|
||||||
if "rottenTomatoes" in picked_movie['ratings']:
|
if "rottenTomatoes" in picked_movie['ratings']:
|
||||||
rt_value = picked_movie['ratings']['rottenTomatoes']['value']
|
rt_value = picked_movie['ratings']['rottenTomatoes']['value']
|
||||||
@@ -195,7 +195,7 @@ class BetterNetflix():
|
|||||||
|
|
||||||
return progress_bar
|
return progress_bar
|
||||||
|
|
||||||
message = [""]
|
message = []
|
||||||
all_downloaded = True
|
all_downloaded = True
|
||||||
|
|
||||||
dm_section_title = "*Torrent Downloads*"
|
dm_section_title = "*Torrent Downloads*"
|
||||||
@@ -260,222 +260,45 @@ class BetterNetflix():
|
|||||||
torrent["last_activity"] < time()-7200):
|
torrent["last_activity"] < time()-7200):
|
||||||
message.append(torrent_info)
|
message.append(torrent_info)
|
||||||
|
|
||||||
if download_ratio < 1 and torrent["state"] != "stalledDL":
|
return message
|
||||||
all_downloaded = False
|
|
||||||
|
|
||||||
return message, all_downloaded
|
async def _generate_download_list(self):
|
||||||
|
|
||||||
async def _generate_download_list(self, show_dm, show_movies, show_shows,
|
|
||||||
episodes):
|
|
||||||
"""Generate a list of all torrents.
|
"""Generate a list of all torrents.
|
||||||
|
|
||||||
*Returns*
|
*Returns*
|
||||||
message_text: str
|
message_text: str
|
||||||
A formatted list of all torrents
|
A formatted list of all torrents
|
||||||
|
|
||||||
all_downloaded: bool
|
|
||||||
Whether all torrents are downloaded
|
|
||||||
"""
|
"""
|
||||||
self.bot.log("Generating torrent list")
|
self.bot.log("Generating torrent list")
|
||||||
title_width = 100
|
title_width = 90
|
||||||
message = []
|
message = self._draw_torrent_list(title_width)
|
||||||
|
|
||||||
if show_dm:
|
message_text = "```"+"\n".join(message)+"```"
|
||||||
m, all_downloaded = self._draw_torrent_list(title_width)
|
|
||||||
message += m
|
|
||||||
|
|
||||||
# if show_movies:
|
|
||||||
# message.append("")
|
|
||||||
# movies_section_title = "*Missing movies not downloading*"
|
|
||||||
# movies_section_line = (
|
|
||||||
# "-"*((title_width-len(movies_section_title))//2)
|
|
||||||
# )
|
|
||||||
# message.append(
|
|
||||||
# movies_section_line+movies_section_title+movies_section_line
|
|
||||||
# )
|
|
||||||
# movie_list = requests.get(
|
|
||||||
# self.radarr_url+"movie?apiKey="+self.credentials["radarr_key"]
|
|
||||||
# ).json()
|
|
||||||
# print(
|
|
||||||
# self.radarr_url+"movie?apiKey="+self.credentials["radarr_key"]
|
|
||||||
# )
|
|
||||||
# movie_queue = requests.get(
|
|
||||||
# self.radarr_url+"queue?apiKey="+self.credentials["radarr_key"]
|
|
||||||
# ).json()
|
|
||||||
# movie_queue_ids = []
|
|
||||||
|
|
||||||
# for queue_item in movie_queue["records"]:
|
|
||||||
# movie_queue_ids.append(queue_item["movieId"])
|
|
||||||
|
|
||||||
# for movie in movie_list:
|
|
||||||
# if (not movie["hasFile"] and
|
|
||||||
# movie["id"] not in movie_queue_ids):
|
|
||||||
# movie_name = movie["title"]
|
|
||||||
# if len(movie_name) > 40:
|
|
||||||
# if movie_name[36] == " ":
|
|
||||||
# movie_name = movie_name[:36]+"...."
|
|
||||||
# else:
|
|
||||||
# movie_name = movie_name[:37]+"..."
|
|
||||||
|
|
||||||
# while len(movie_name) < 41:
|
|
||||||
# movie_name += " "
|
|
||||||
|
|
||||||
# if movie["monitored"]:
|
|
||||||
# movie_info = movie_name+"Could not find a torrent"
|
|
||||||
# else:
|
|
||||||
# movie_info = self.long_strings["No torrent"].format(
|
|
||||||
# movie_name
|
|
||||||
# )
|
|
||||||
|
|
||||||
# message.append(movie_info)
|
|
||||||
|
|
||||||
# if show_shows:
|
|
||||||
# message.append("")
|
|
||||||
# show_section_title = "*Missing shows not downloading*"
|
|
||||||
# show_section_line = "-"*((title_width-len(show_section_title))//2)
|
|
||||||
# message.append(
|
|
||||||
# show_section_line+show_section_title+show_section_line
|
|
||||||
# )
|
|
||||||
|
|
||||||
# show_list = requests.get(
|
|
||||||
# self.sonarr_url+"series?apiKey="+self.credentials["sonarr_key"]
|
|
||||||
# ).json()
|
|
||||||
|
|
||||||
# for show in show_list:
|
|
||||||
# if show["seasons"][0]["seasonNumber"] == 0:
|
|
||||||
# seasons = show["seasons"][1:]
|
|
||||||
# else:
|
|
||||||
# seasons = show["seasons"]
|
|
||||||
# if any(
|
|
||||||
# (
|
|
||||||
# i["statistics"]["episodeCount"] !=
|
|
||||||
# i["statistics"]["totalEpisodeCount"]
|
|
||||||
# ) for i in seasons):
|
|
||||||
# if all(
|
|
||||||
# i["statistics"]["episodeCount"] == 0 for i in seasons
|
|
||||||
# ):
|
|
||||||
# message.append(show["title"] + " (all episodes)")
|
|
||||||
# else:
|
|
||||||
# if episodes:
|
|
||||||
# missing_episodes = sum(
|
|
||||||
# (i["statistics"]["totalEpisodeCount"] -
|
|
||||||
# i["statistics"]["episodeCount"])
|
|
||||||
# for i in seasons)
|
|
||||||
# message.append(
|
|
||||||
# f"{show['title']} ({missing_episodes} episodes)"
|
|
||||||
# )
|
|
||||||
|
|
||||||
message.append("-"*title_width)
|
|
||||||
|
|
||||||
message_text = "```"+"\n".join(message[1:])+"```"
|
|
||||||
if message_text == "``````":
|
if message_text == "``````":
|
||||||
message_text = self.long_strings["No torrents downloading"]
|
message_text = self.long_strings["No torrents downloading"]
|
||||||
|
|
||||||
return message_text, all_downloaded
|
return message_text
|
||||||
|
|
||||||
# async def downloading(self, ctx, content):
|
async def downloading(self, ctx: SlashContext):
|
||||||
# """Send message with list of all downloading torrents."""
|
"""Send message with list of all downloading torrents."""
|
||||||
# async def send_long_message(ctx,message_text):
|
async def send_long_message(ctx,message_text):
|
||||||
# if len(message_text) <= 1994:
|
if len(message_text) <= 1994:
|
||||||
# await ctx.send("```"+message_text+"```")
|
await ctx.send("```"+message_text+"```")
|
||||||
# else:
|
else:
|
||||||
# cut_off_index = message_text[:1994].rfind("\n")
|
cut_off_index = message_text[:1994].rfind("\n")
|
||||||
# await ctx.send("```"+message_text[:cut_off_index]+"```")
|
await ctx.send("```"+message_text[:cut_off_index]+"```")
|
||||||
# await send_long_message(ctx,message_text[cut_off_index+1:])
|
await send_long_message(ctx,message_text[cut_off_index+1:])
|
||||||
|
|
||||||
# await self.bot.defer(ctx)
|
ctx.defer()
|
||||||
|
|
||||||
# # showDM, showMovies, showShows, episodes
|
message_text = await self._generate_download_list()
|
||||||
# parameters = [False, False, False, False]
|
if not message_text.startswith("```"):
|
||||||
# show_dm_args = ["d", "dm", "downloading", "downloadmanager"]
|
await ctx.send(message_text)
|
||||||
# show_movies_args = ["m", "movies"]
|
|
||||||
# show_shows_args = ["s", "shows", "series"]
|
|
||||||
# show_episode_args = ["e", "episodes"]
|
|
||||||
# arg_list = [
|
|
||||||
# show_dm_args, show_movies_args, show_shows_args, show_episode_args
|
|
||||||
# ]
|
|
||||||
# input_args = []
|
|
||||||
# valid_arguments = True
|
|
||||||
|
|
||||||
# while content != "" and valid_arguments:
|
elif len(message_text) > 2000:
|
||||||
# if content[0] == " ":
|
message_text = message_text[3:-3]
|
||||||
# content = content[1:]
|
await send_long_message(ctx,message_text)
|
||||||
# elif content[0] == "-":
|
|
||||||
# if content[1] == "-":
|
|
||||||
# arg_start = 2
|
|
||||||
# if " " in content:
|
|
||||||
# arg_stop = content.find(" ")
|
|
||||||
# else:
|
|
||||||
# arg_stop = None
|
|
||||||
# else:
|
|
||||||
# arg_start = 1
|
|
||||||
# arg_stop = 2
|
|
||||||
|
|
||||||
# input_args.append(content[arg_start:arg_stop])
|
else:
|
||||||
# if arg_stop is None:
|
await ctx.send(message_text)
|
||||||
# content = ""
|
|
||||||
# else:
|
|
||||||
# content = content[arg_stop:]
|
|
||||||
# else:
|
|
||||||
# valid_arguments = False
|
|
||||||
|
|
||||||
# if valid_arguments:
|
|
||||||
# for arg_index, arg_aliases in enumerate(arg_list):
|
|
||||||
# arg_in_input = [i in input_args for i in arg_aliases]
|
|
||||||
# if any(arg_in_input):
|
|
||||||
# input_args.remove(arg_aliases[arg_in_input.index(True)])
|
|
||||||
# parameters[arg_index] = True
|
|
||||||
|
|
||||||
# if len(input_args) != 0 or (not parameters[2] and parameters[3]):
|
|
||||||
# valid_arguments = False
|
|
||||||
|
|
||||||
# show_anything = any(i for i in parameters)
|
|
||||||
# if not (valid_arguments and show_anything):
|
|
||||||
# await ctx.send(self.long_strings["Invalid parameters"])
|
|
||||||
# else:
|
|
||||||
# message_text, all_downloaded = await self.__generate_download_list(
|
|
||||||
# *parameters
|
|
||||||
# )
|
|
||||||
# if not message_text.startswith("```"):
|
|
||||||
# await ctx.send(message_text)
|
|
||||||
|
|
||||||
# elif len(message_text) > 2000:
|
|
||||||
# message_text = message_text[3:-3]
|
|
||||||
# await send_long_message(ctx,message_text)
|
|
||||||
|
|
||||||
# elif all_downloaded:
|
|
||||||
# await ctx.send(message_text)
|
|
||||||
|
|
||||||
# else:
|
|
||||||
# updates_left = 60
|
|
||||||
# message_text = self.long_strings["Update"].format(
|
|
||||||
# message_text[:-3], ceil(updates_left/6)
|
|
||||||
# )
|
|
||||||
# old_message = await ctx.send(message_text)
|
|
||||||
|
|
||||||
# while ((not all_downloaded) and updates_left > 0):
|
|
||||||
# await asyncio.sleep(10)
|
|
||||||
# updates_left -= 1
|
|
||||||
# message_text, all_downloaded = await (
|
|
||||||
# self.__generate_download_list(*parameters)
|
|
||||||
# )
|
|
||||||
# message_text = self.long_strings["Update"].format(
|
|
||||||
# message_text[:-3],
|
|
||||||
# ceil(updates_left/6)
|
|
||||||
# )
|
|
||||||
# await old_message.edit(content = message_text)
|
|
||||||
|
|
||||||
# message_text, all_downloaded = await (
|
|
||||||
# self.__generate_download_list(*parameters)
|
|
||||||
# )
|
|
||||||
|
|
||||||
# if message_text.startswith("```"):
|
|
||||||
# if all_downloaded:
|
|
||||||
# self.bot.log("All torrents are downloaded")
|
|
||||||
# else:
|
|
||||||
# message_text = self.long_strings["No updates"].format(
|
|
||||||
# message_text[:-3]
|
|
||||||
# )
|
|
||||||
# self.bot.log("The message updated 20 times")
|
|
||||||
|
|
||||||
# await old_message.edit(content = message_text)
|
|
||||||
|
|||||||
11
gwendolyn/funcs/games/__init__.py
Normal file
11
gwendolyn/funcs/games/__init__.py
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
"""Game functions for Gwendolyn."""
|
||||||
|
|
||||||
|
__all__ = ["Money", "Games"]
|
||||||
|
|
||||||
|
from .money import Money
|
||||||
|
|
||||||
|
class Games():
|
||||||
|
def __init__(self, bot):
|
||||||
|
"""Initialize the class."""
|
||||||
|
self.bot = bot
|
||||||
|
self.database = bot.database
|
||||||
150
gwendolyn/funcs/games/money.py
Normal file
150
gwendolyn/funcs/games/money.py
Normal file
@@ -0,0 +1,150 @@
|
|||||||
|
"""
|
||||||
|
Contains the code that deals with money.
|
||||||
|
|
||||||
|
*Classes*
|
||||||
|
---------
|
||||||
|
Money
|
||||||
|
Deals with money.
|
||||||
|
"""
|
||||||
|
import interactions # Used for typehints
|
||||||
|
|
||||||
|
|
||||||
|
class Money():
|
||||||
|
"""
|
||||||
|
Deals with money.
|
||||||
|
|
||||||
|
*Methods*
|
||||||
|
---------
|
||||||
|
checkBalance(user: str)
|
||||||
|
sendBalance(ctx: interactions.SlashContext)
|
||||||
|
addMoney(user: str, amount: int)
|
||||||
|
giveMoney(ctx: interactions.SlashContext, user: discord.User,
|
||||||
|
amount: int)
|
||||||
|
|
||||||
|
*Attributes*
|
||||||
|
------------
|
||||||
|
bot: Gwendolyn
|
||||||
|
The instance of Gwendolyn
|
||||||
|
database: pymongo.Client
|
||||||
|
The mongo database
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, bot):
|
||||||
|
"""Initialize the class."""
|
||||||
|
self.bot = bot
|
||||||
|
self.database = bot.database
|
||||||
|
|
||||||
|
def checkBalance(self, user: str):
|
||||||
|
"""
|
||||||
|
Get the account balance of a user.
|
||||||
|
|
||||||
|
*Parameters*
|
||||||
|
------------
|
||||||
|
user: str
|
||||||
|
The user to get the balance of.
|
||||||
|
|
||||||
|
*Returns*
|
||||||
|
---------
|
||||||
|
balance: int
|
||||||
|
The balance of the user's account.
|
||||||
|
"""
|
||||||
|
self.bot.log("checking "+user+"'s account balance")
|
||||||
|
|
||||||
|
user_data = self.database["users"].find_one({"_id": user})
|
||||||
|
|
||||||
|
if user_data is not None:
|
||||||
|
return user_data["money"]
|
||||||
|
else:
|
||||||
|
return 0
|
||||||
|
|
||||||
|
async def sendBalance(self, ctx: interactions.SlashContext):
|
||||||
|
"""
|
||||||
|
Get your own account balance.
|
||||||
|
|
||||||
|
*Parameters*
|
||||||
|
------------
|
||||||
|
ctx: interactions.SlashContext
|
||||||
|
The context of the command.
|
||||||
|
"""
|
||||||
|
await ctx.defer()
|
||||||
|
response = self.checkBalance("#"+str(ctx.author.id))
|
||||||
|
user_name = ctx.author.display_name
|
||||||
|
if response == 1:
|
||||||
|
new_message = f"{user_name} has {response} GwendoBuck"
|
||||||
|
else:
|
||||||
|
new_message = f"{user_name} has {response} GwendoBucks"
|
||||||
|
await ctx.send(new_message)
|
||||||
|
|
||||||
|
# Adds money to the account of a user
|
||||||
|
def addMoney(self, user: str, amount: int):
|
||||||
|
"""
|
||||||
|
Add money to a user account.
|
||||||
|
|
||||||
|
*Parameters*
|
||||||
|
------------
|
||||||
|
user: str
|
||||||
|
The id of the user to give money.
|
||||||
|
amount: int
|
||||||
|
The amount to add to the user's account.
|
||||||
|
"""
|
||||||
|
self.bot.log("adding "+str(amount)+" to "+user+"'s account")
|
||||||
|
|
||||||
|
user_data = self.database["users"].find_one({"_id": user})
|
||||||
|
|
||||||
|
if user_data is not None:
|
||||||
|
updater = {"$inc": {"money": amount}}
|
||||||
|
self.database["users"].update_one({"_id": user}, updater)
|
||||||
|
else:
|
||||||
|
new_user = {
|
||||||
|
"_id": user,
|
||||||
|
"user name": self.bot.database_funcs.get_name(user),
|
||||||
|
"money": amount
|
||||||
|
}
|
||||||
|
self.database["users"].insert_one(new_user)
|
||||||
|
|
||||||
|
# Transfers money from one user to another
|
||||||
|
async def giveMoney(self, ctx: interactions.SlashContext,
|
||||||
|
user: interactions.User, amount: int):
|
||||||
|
"""
|
||||||
|
Give someone else money from your account.
|
||||||
|
|
||||||
|
*Parameters*
|
||||||
|
------------
|
||||||
|
ctx: interactions.SlashContext
|
||||||
|
The context of the command.
|
||||||
|
user: interactions.User
|
||||||
|
The user to give money.
|
||||||
|
amount: int
|
||||||
|
The amount to transfer.
|
||||||
|
"""
|
||||||
|
await ctx.defer()
|
||||||
|
username = user.display_name
|
||||||
|
if self.bot.database_funcs.get_id(username) is None:
|
||||||
|
async for member in ctx.guild.fetch_members(limit=None):
|
||||||
|
if member.display_name.lower() == username.lower():
|
||||||
|
username = member.display_name
|
||||||
|
user_id = f"#{member.id}"
|
||||||
|
new_user = {
|
||||||
|
"_id": user_id,
|
||||||
|
"user name": username,
|
||||||
|
"money": 0
|
||||||
|
}
|
||||||
|
self.bot.database["users"].insert_one(new_user)
|
||||||
|
|
||||||
|
userid = f"#{ctx.author.id}"
|
||||||
|
user_data = self.database["users"].find_one({"_id": userid})
|
||||||
|
targetUser = self.bot.database_funcs.get_id(username)
|
||||||
|
|
||||||
|
if amount <= 0:
|
||||||
|
self.bot.log("They tried to steal")
|
||||||
|
await ctx.send("Yeah, no. You can't do that")
|
||||||
|
elif targetUser is None:
|
||||||
|
self.bot.log("They weren't in the system")
|
||||||
|
await ctx.send("The target doesn't exist")
|
||||||
|
elif user_data is None or user_data["money"] < amount:
|
||||||
|
self.bot.log("They didn't have enough GwendoBucks")
|
||||||
|
await ctx.send("You don't have that many GwendoBuck")
|
||||||
|
else:
|
||||||
|
self.addMoney(f"#{ctx.author.id}", -1 * amount)
|
||||||
|
self.addMoney(targetUser, amount)
|
||||||
|
await ctx.send(f"Transferred {amount} GwendoBucks to {username}")
|
||||||
@@ -7,59 +7,59 @@ from .name_generator import NameGenerator
|
|||||||
from .roll import DieRoller
|
from .roll import DieRoller
|
||||||
|
|
||||||
def gen_help_text(commands: list[SlashCommand]):
|
def gen_help_text(commands: list[SlashCommand]):
|
||||||
return '\n'.join([f"`/{i.name}`\t— {i.description}" for i in commands])
|
return '\n'.join(sorted([f"`/{i.name}`\t— {i.description}" for i in commands]))
|
||||||
|
|
||||||
class Other():
|
class Other():
|
||||||
def __init__(self, bot):
|
def __init__(self, bot):
|
||||||
self.bot = bot
|
self.bot = bot
|
||||||
self._name_generator = NameGenerator()
|
self._name_generator = NameGenerator()
|
||||||
self._roller = DieRoller()
|
self._roller = DieRoller()
|
||||||
|
|
||||||
# Responds with a greeting of a time-appropriate maner
|
# Responds with a greeting of a time-appropriate maner
|
||||||
async def hello_func(self, ctx: SlashContext):
|
async def hello_func(self, ctx: SlashContext):
|
||||||
def time_in_range(start, end, i):
|
def time_in_range(start, end, i):
|
||||||
# Return true if i is in the range [start, end]
|
# Return true if i is in the range [start, end]
|
||||||
if start <= end:
|
if start <= end:
|
||||||
return start <= i <= end
|
return start <= i <= end
|
||||||
else:
|
else:
|
||||||
return start <= i or i <= end
|
return start <= i or i <= end
|
||||||
|
|
||||||
author = ctx.author.display_name
|
author = ctx.author.display_name
|
||||||
now = datetime.datetime.now()
|
now = datetime.datetime.now()
|
||||||
if time_in_range(now.replace(hour=5, minute=0, second=0, microsecond=0),now.replace(hour=10, minute=0, second=0, microsecond=0), now):
|
if time_in_range(now.replace(hour=5, minute=0, second=0, microsecond=0),now.replace(hour=10, minute=0, second=0, microsecond=0), now):
|
||||||
send_message = "Good morning, "+str(author)
|
send_message = "Good morning, "+str(author)
|
||||||
elif time_in_range(now.replace(hour=13, minute=0, second=0, microsecond=0),now.replace(hour=18, minute=0, second=0, microsecond=0), now):
|
elif time_in_range(now.replace(hour=13, minute=0, second=0, microsecond=0),now.replace(hour=18, minute=0, second=0, microsecond=0), now):
|
||||||
send_message = "Good afternoon, "+str(author)
|
send_message = "Good afternoon, "+str(author)
|
||||||
elif time_in_range(now.replace(hour=18, minute=0, second=0, microsecond=0),now.replace(hour=22, minute=0, second=0, microsecond=0), now):
|
elif time_in_range(now.replace(hour=18, minute=0, second=0, microsecond=0),now.replace(hour=22, minute=0, second=0, microsecond=0), now):
|
||||||
send_message = "Good evening, "+str(author)
|
send_message = "Good evening, "+str(author)
|
||||||
elif time_in_range(now.replace(hour=22, minute=0, second=0, microsecond=0),now.replace(hour=23, minute=59, second=59, microsecond=0), now):
|
elif time_in_range(now.replace(hour=22, minute=0, second=0, microsecond=0),now.replace(hour=23, minute=59, second=59, microsecond=0), now):
|
||||||
send_message = "Good night, "+str(author)
|
send_message = "Good night, "+str(author)
|
||||||
else:
|
else:
|
||||||
send_message = "Hello, "+str(author)
|
send_message = "Hello, "+str(author)
|
||||||
|
|
||||||
await ctx.send(send_message)
|
await ctx.send(send_message)
|
||||||
|
|
||||||
async def help_func(self, ctx: SlashContext, command: str):
|
async def help_func(self, ctx: SlashContext, command: str):
|
||||||
if command == "":
|
if command == "":
|
||||||
text = gen_help_text([i for i in self.bot.application_commands if isinstance(i,SlashCommand)])
|
text = gen_help_text([i for i in self.bot.application_commands if isinstance(i,SlashCommand)])
|
||||||
embed = Embed(title = "Help", description = text,color = 0x59f442)
|
embed = Embed(title = "Help", description = text,color = 0x59f442)
|
||||||
await ctx.send(embed = embed)
|
await ctx.send(embed = embed)
|
||||||
else:
|
else:
|
||||||
self.bot.log(f"Looking for help-{command}.txt",str(ctx.channel_id))
|
self.bot.log(f"Looking for help-{command}.txt",str(ctx.channel_id))
|
||||||
try:
|
try:
|
||||||
with open(f"gwendolyn/resources/help/help-{command}.txt",encoding="utf-8") as file_pointer:
|
with open(f"gwendolyn/resources/help/help-{command}.txt",encoding="utf-8") as file_pointer:
|
||||||
text = file_pointer.read()
|
text = file_pointer.read()
|
||||||
embed = Embed(title = command.capitalize(), description = text,color = 0x59f442)
|
embed = Embed(title = command.capitalize(), description = text,color = 0x59f442)
|
||||||
await ctx.send(embed = embed)
|
await ctx.send(embed = embed)
|
||||||
except:
|
except:
|
||||||
await ctx.send(f"Could not find a help file for the command '/{command}'")
|
await ctx.send(f"Could not find a help file for the command '/{command}'")
|
||||||
|
|
||||||
async def generate_name(self, ctx: SlashContext):
|
async def generate_name(self, ctx: SlashContext):
|
||||||
await ctx.send(self._name_generator.generate())
|
await ctx.send(self._name_generator.generate())
|
||||||
|
|
||||||
async def roll_dice(self, ctx: SlashContext, dice: str):
|
async def roll_dice(self, ctx: SlashContext, dice: str):
|
||||||
try:
|
try:
|
||||||
roll = self._roller.roll(dice)
|
roll = self._roller.roll(dice)
|
||||||
await ctx.send(f":game_die:Rolling dice `{dice}`\n{roll}")
|
await ctx.send(f":game_die:Rolling dice `{dice}`\n{roll}")
|
||||||
except:
|
except:
|
||||||
await ctx.send("There was an error in the rolling")
|
await ctx.send("There was an error in the rolling")
|
||||||
|
|||||||
@@ -6,71 +6,71 @@ from pymongo import MongoClient # Used for database management
|
|||||||
|
|
||||||
from gwendolyn.utils import log
|
from gwendolyn.utils import log
|
||||||
from gwendolyn.exceptions import NoToken, CannotConnectToService
|
from gwendolyn.exceptions import NoToken, CannotConnectToService
|
||||||
from gwendolyn.funcs import Other, BetterNetflix, Sonarr, Radarr, TMDb, QBittorrent
|
from gwendolyn.funcs import Other, BetterNetflix, Sonarr, Radarr, TMDb, QBittorrent, Money, Games
|
||||||
|
|
||||||
class Gwendolyn(Client):
|
class Gwendolyn(Client):
|
||||||
def __init__(self, testing: bool = True):
|
def __init__(self, testing: bool = True):
|
||||||
"""Initialize the bot."""
|
"""Initialize the bot."""
|
||||||
initiation_parameters = {
|
initiation_parameters = {
|
||||||
"status": Status.DND,
|
"status": Status.DND,
|
||||||
"delete_unused_application_cmds": True
|
"delete_unused_application_cmds": True
|
||||||
}
|
}
|
||||||
super().__init__(**initiation_parameters)
|
super().__init__(**initiation_parameters)
|
||||||
|
|
||||||
self.testing = testing
|
self.testing = testing
|
||||||
|
|
||||||
self._add_clients_and_options()
|
self._add_clients_and_options()
|
||||||
self._add_functions()
|
self._add_functions()
|
||||||
self._add_extensions()
|
self._add_extensions()
|
||||||
|
|
||||||
def _add_clients_and_options(self):
|
def _add_clients_and_options(self):
|
||||||
"""Add all the client, option and credentials objects."""
|
"""Add all the client, option and credentials objects."""
|
||||||
load_dotenv()
|
load_dotenv()
|
||||||
self.bot_token = getenv("DISCORD_TOKEN")
|
self.bot_token = getenv("DISCORD_TOKEN")
|
||||||
|
|
||||||
if self.bot_token == "TOKEN":
|
if self.bot_token == "TOKEN":
|
||||||
raise NoToken()
|
raise NoToken()
|
||||||
|
|
||||||
self.admins = getenv("ADMINS").split(",")
|
self.admins = getenv("ADMINS").split(",")
|
||||||
|
|
||||||
mongo_user = getenv("MONGODB_USER")
|
mongo_user = getenv("MONGODB_USER")
|
||||||
mongo_password = getenv("MONGODB_PASSWORD")
|
mongo_password = getenv("MONGODB_PASSWORD")
|
||||||
mongo_url = f"mongodb+srv://{mongo_user}:{mongo_password}@gwendolyn"
|
mongo_url = f"mongodb+srv://{mongo_user}:{mongo_password}@gwendolyn"
|
||||||
mongo_url += ".qkwfy.mongodb.net/Gwendolyn?retryWrites=true&w=majority"
|
mongo_url += ".qkwfy.mongodb.net/Gwendolyn?retryWrites=true&w=majority"
|
||||||
database_client = MongoClient(mongo_url)
|
database_client = MongoClient(mongo_url)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
database_client.admin.command("ping")
|
database_client.admin.command("ping")
|
||||||
self.log("Connected to Mango Client")
|
self.log("Connected to Mango Client")
|
||||||
except:
|
except:
|
||||||
raise CannotConnectToService("Mango Client")
|
raise CannotConnectToService("Mango Client")
|
||||||
|
|
||||||
if self.testing:
|
if self.testing:
|
||||||
self.log("Testing mode")
|
self.log("Testing mode")
|
||||||
self.database = database_client["Gwendolyn-Test"]
|
self.database = database_client["Gwendolyn-Test"]
|
||||||
self.load_extension("interactions.ext.jurigged")
|
else:
|
||||||
else:
|
self.database = database_client["Gwendolyn"]
|
||||||
self.database = database_client["Gwendolyn"]
|
|
||||||
|
|
||||||
def _add_functions(self):
|
def _add_functions(self):
|
||||||
self.other = Other(self)
|
self.other = Other(self)
|
||||||
self.better_netflix = BetterNetflix(
|
self.money = Money(self)
|
||||||
self,
|
self.better_netflix = BetterNetflix(
|
||||||
radarr=Radarr(getenv("RADARR_IP"),getenv("RADARR_PORT"),getenv("RADARR_API_KEY")),
|
self,
|
||||||
sonarr=Sonarr(getenv("SONARR_IP"),getenv("SONARR_PORT"),getenv("SONARR_API_KEY")),
|
radarr=Radarr(getenv("RADARR_IP"),getenv("RADARR_PORT"),getenv("RADARR_API_KEY")),
|
||||||
tmdb=TMDb(getenv("TMDB_API_ACCESS_TOKEN")),
|
sonarr=Sonarr(getenv("SONARR_IP"),getenv("SONARR_PORT"),getenv("SONARR_API_KEY")),
|
||||||
qbittorrent=QBittorrent(getenv("QBITTORRENT_IP"),getenv("QBITTORRENT_PORT"),getenv("QBITTORRENT_USERNAME"),getenv("QBITTORRENT_PASSWORD"))
|
tmdb=TMDb(getenv("TMDB_API_ACCESS_TOKEN")),
|
||||||
)
|
qbittorrent=QBittorrent(getenv("QBITTORRENT_IP"),getenv("QBITTORRENT_PORT"),getenv("QBITTORRENT_USERNAME"),getenv("QBITTORRENT_PASSWORD"))
|
||||||
|
)
|
||||||
|
|
||||||
def _add_extensions(self):
|
def _add_extensions(self):
|
||||||
"""Load cogs."""
|
"""Load cogs."""
|
||||||
for filename in listdir("./gwendolyn/ext"):
|
for filename in listdir("./gwendolyn/ext"):
|
||||||
if filename.endswith(".py"):
|
if filename.endswith(".py"):
|
||||||
self.load_extension(f"gwendolyn.ext.{filename[:-3]}")
|
self.load_extension(f"gwendolyn.ext.{filename[:-3]}")
|
||||||
|
|
||||||
def log(self, messages, channel: str = "", level: int = 20): # pylint:disable=no-self-use
|
def log(self, messages, channel: str = "", level: int = 20): # pylint:disable=no-self-use
|
||||||
"""Log a message. Described in utils/util_functions.py."""
|
"""Log a message. Described in utils/util_functions.py."""
|
||||||
log(messages, channel, level)
|
log(messages, channel, level)
|
||||||
|
|
||||||
def start(self):
|
def start(self):
|
||||||
super().start(self.bot_token)
|
super().start(self.bot_token)
|
||||||
@@ -34,7 +34,7 @@
|
|||||||
},
|
},
|
||||||
"ping" : {
|
"ping" : {
|
||||||
"name" : "ping",
|
"name" : "ping",
|
||||||
"description" : "Get the Gwendolyn's latency to the server"
|
"description" : "Get Gwendolyn's latency to the server"
|
||||||
},
|
},
|
||||||
"roll" : {
|
"roll" : {
|
||||||
"name": "roll",
|
"name": "roll",
|
||||||
@@ -65,6 +65,36 @@
|
|||||||
"show": {
|
"show": {
|
||||||
"name": "show",
|
"name": "show",
|
||||||
"description": "Get a random show from Better Netflix"
|
"description": "Get a random show from Better Netflix"
|
||||||
|
},
|
||||||
|
"downloading": {
|
||||||
|
"name": "downloading",
|
||||||
|
"description": "Get a list of everything being downloaded"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"games": {
|
||||||
|
"money": {
|
||||||
|
"balance" : {
|
||||||
|
"name" : "balance",
|
||||||
|
"description" : "See your balance of GwendoBucks"
|
||||||
|
},
|
||||||
|
"give" : {
|
||||||
|
"name" : "give",
|
||||||
|
"description" : "Give GwendoBucks to another user",
|
||||||
|
"options" : [
|
||||||
|
{
|
||||||
|
"name" : "user",
|
||||||
|
"description" : "The user you're sending GwendoBucks to",
|
||||||
|
"type" : 6,
|
||||||
|
"required" : "true"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name" : "amount",
|
||||||
|
"description" : "The number of GwendoBucks you're sending",
|
||||||
|
"type" : 4,
|
||||||
|
"required" : "true"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Binary file not shown.
|
Before Width: | Height: | Size: 3.0 KiB After Width: | Height: | Size: 3.0 KiB |
@@ -3,38 +3,38 @@ from discord.ext import commands # Has the cog class
|
|||||||
|
|
||||||
|
|
||||||
class EventCog(commands.Cog):
|
class EventCog(commands.Cog):
|
||||||
"""Handles bot events."""
|
"""Handles bot events."""
|
||||||
|
|
||||||
def __init__(self, bot):
|
def __init__(self, bot):
|
||||||
"""Initialize the bot."""
|
"""Initialize the bot."""
|
||||||
self.bot = bot
|
self.bot = bot
|
||||||
self.bot.on_error = self.on_error
|
self.bot.on_error = self.on_error
|
||||||
|
|
||||||
@commands.Cog.listener()
|
@commands.Cog.listener()
|
||||||
async def on_ready(self):
|
async def on_ready(self):
|
||||||
"""Log and set bot status when bot logs in."""
|
"""Log and set bot status when bot logs in."""
|
||||||
await self.bot.event_handler.on_ready()
|
await self.bot.event_handler.on_ready()
|
||||||
|
|
||||||
@commands.Cog.listener()
|
@commands.Cog.listener()
|
||||||
async def on_slash_command(self, ctx):
|
async def on_slash_command(self, ctx):
|
||||||
"""Log when a slash command is run."""
|
"""Log when a slash command is run."""
|
||||||
await self.bot.event_handler.on_slash_command(ctx)
|
await self.bot.event_handler.on_slash_command(ctx)
|
||||||
|
|
||||||
@commands.Cog.listener()
|
@commands.Cog.listener()
|
||||||
async def on_slash_command_error(self, ctx, error):
|
async def on_slash_command_error(self, ctx, error):
|
||||||
"""Log when a slash error occurs."""
|
"""Log when a slash error occurs."""
|
||||||
await self.bot.error_handler.on_slash_command_error(ctx, error)
|
await self.bot.error_handler.on_slash_command_error(ctx, error)
|
||||||
|
|
||||||
async def on_error(self, method, *args, **kwargs): # pylint: disable=unused-argument
|
async def on_error(self, method, *args, **kwargs): # pylint: disable=unused-argument
|
||||||
"""Log when an error occurs."""
|
"""Log when an error occurs."""
|
||||||
await self.bot.error_handler.on_error(method)
|
await self.bot.error_handler.on_error(method)
|
||||||
|
|
||||||
@commands.Cog.listener()
|
@commands.Cog.listener()
|
||||||
async def on_component(self, ctx):
|
async def on_component(self, ctx):
|
||||||
"""Handle when someone reacts to a message."""
|
"""Handle when someone reacts to a message."""
|
||||||
await self.bot.event_handler.on_component(ctx)
|
await self.bot.event_handler.on_component(ctx)
|
||||||
|
|
||||||
|
|
||||||
def setup(bot):
|
def setup(bot):
|
||||||
"""Add the eventcog to the bot."""
|
"""Add the eventcog to the bot."""
|
||||||
bot.add_cog(EventCog(bot))
|
bot.add_cog(EventCog(bot))
|
||||||
|
|||||||
@@ -8,153 +8,153 @@ params = get_params()
|
|||||||
|
|
||||||
|
|
||||||
class GamesCog(commands.Cog):
|
class GamesCog(commands.Cog):
|
||||||
"""Contains miscellaneous game commands."""
|
"""Contains miscellaneous game commands."""
|
||||||
|
|
||||||
def __init__(self, bot):
|
def __init__(self, bot):
|
||||||
"""Initialize the cog."""
|
"""Initialize the cog."""
|
||||||
self.bot = bot
|
self.bot = bot
|
||||||
|
|
||||||
@cog_ext.cog_slash(**params["balance"])
|
@cog_ext.cog_slash(**params["balance"])
|
||||||
async def balance(self, ctx):
|
async def balance(self, ctx):
|
||||||
"""Check user balance."""
|
"""Check user balance."""
|
||||||
await self.bot.money.sendBalance(ctx)
|
await self.bot.money.sendBalance(ctx)
|
||||||
|
|
||||||
@cog_ext.cog_slash(**params["give"])
|
@cog_ext.cog_slash(**params["give"])
|
||||||
async def give(self, ctx, user, amount):
|
async def give(self, ctx, user, amount):
|
||||||
"""Give another user an amount of GwendoBucks."""
|
"""Give another user an amount of GwendoBucks."""
|
||||||
await self.bot.money.giveMoney(ctx, user, amount)
|
await self.bot.money.giveMoney(ctx, user, amount)
|
||||||
|
|
||||||
@cog_ext.cog_slash(**params["trivia"])
|
@cog_ext.cog_slash(**params["trivia"])
|
||||||
async def trivia(self, ctx, answer=""):
|
async def trivia(self, ctx, answer=""):
|
||||||
"""Run a game of trivia."""
|
"""Run a game of trivia."""
|
||||||
await self.bot.games.trivia.triviaParse(ctx, answer)
|
await self.bot.games.trivia.triviaParse(ctx, answer)
|
||||||
|
|
||||||
|
|
||||||
class BlackjackCog(commands.Cog):
|
class BlackjackCog(commands.Cog):
|
||||||
"""Contains the blackjack commands."""
|
"""Contains the blackjack commands."""
|
||||||
|
|
||||||
def __init__(self, bot):
|
def __init__(self, bot):
|
||||||
"""Initialize the cog."""
|
"""Initialize the cog."""
|
||||||
self.bot = bot
|
self.bot = bot
|
||||||
|
|
||||||
@cog_ext.cog_subcommand(**params["blackjack_start"])
|
@cog_ext.cog_subcommand(**params["blackjack_start"])
|
||||||
async def blackjack_start(self, ctx):
|
async def blackjack_start(self, ctx):
|
||||||
"""Start a game of blackjack."""
|
"""Start a game of blackjack."""
|
||||||
await self.bot.games.blackjack.start(ctx)
|
await self.bot.games.blackjack.start(ctx)
|
||||||
|
|
||||||
@cog_ext.cog_subcommand(**params["blackjack_bet"])
|
@cog_ext.cog_subcommand(**params["blackjack_bet"])
|
||||||
async def blackjack_bet(self, ctx, bet):
|
async def blackjack_bet(self, ctx, bet):
|
||||||
"""Enter the game of blackjack with a bet."""
|
"""Enter the game of blackjack with a bet."""
|
||||||
await self.bot.games.blackjack.enter_game(ctx, bet)
|
await self.bot.games.blackjack.enter_game(ctx, bet)
|
||||||
|
|
||||||
@cog_ext.cog_subcommand(**params["blackjack_hilo"])
|
@cog_ext.cog_subcommand(**params["blackjack_hilo"])
|
||||||
async def blackjack_hilo(self, ctx):
|
async def blackjack_hilo(self, ctx):
|
||||||
"""Get the hilo value for the deck in blackjack."""
|
"""Get the hilo value for the deck in blackjack."""
|
||||||
await self.bot.games.blackjack.hilo(ctx)
|
await self.bot.games.blackjack.hilo(ctx)
|
||||||
|
|
||||||
@cog_ext.cog_subcommand(**params["blackjack_shuffle"])
|
@cog_ext.cog_subcommand(**params["blackjack_shuffle"])
|
||||||
async def blackjack_shuffle(self, ctx):
|
async def blackjack_shuffle(self, ctx):
|
||||||
"""Shuffle the blackjack game."""
|
"""Shuffle the blackjack game."""
|
||||||
await self.bot.games.blackjack.shuffle(ctx)
|
await self.bot.games.blackjack.shuffle(ctx)
|
||||||
|
|
||||||
@cog_ext.cog_subcommand(**params["blackjack_cards"])
|
@cog_ext.cog_subcommand(**params["blackjack_cards"])
|
||||||
async def blackjack_cards(self, ctx):
|
async def blackjack_cards(self, ctx):
|
||||||
"""Get the amount of cards left in the blackjack deck."""
|
"""Get the amount of cards left in the blackjack deck."""
|
||||||
await self.bot.games.blackjack.cards(ctx)
|
await self.bot.games.blackjack.cards(ctx)
|
||||||
|
|
||||||
|
|
||||||
class ConnectFourCog(commands.Cog):
|
class ConnectFourCog(commands.Cog):
|
||||||
"""Contains all the connect four commands."""
|
"""Contains all the connect four commands."""
|
||||||
|
|
||||||
def __init__(self, bot):
|
def __init__(self, bot):
|
||||||
"""Initialize the cog."""
|
"""Initialize the cog."""
|
||||||
self.bot = bot
|
self.bot = bot
|
||||||
|
|
||||||
@cog_ext.cog_subcommand(**params["connect_four_start_user"])
|
@cog_ext.cog_subcommand(**params["connect_four_start_user"])
|
||||||
async def connect_four_start_user(self, ctx, user):
|
async def connect_four_start_user(self, ctx, user):
|
||||||
"""Start a game of connect four against another user."""
|
"""Start a game of connect four against another user."""
|
||||||
await self.bot.games.connect_four.start(ctx, user)
|
await self.bot.games.connect_four.start(ctx, user)
|
||||||
|
|
||||||
@cog_ext.cog_subcommand(**params["connect_four_start_gwendolyn"])
|
@cog_ext.cog_subcommand(**params["connect_four_start_gwendolyn"])
|
||||||
async def connect_four_start_gwendolyn(self, ctx, difficulty=3):
|
async def connect_four_start_gwendolyn(self, ctx, difficulty=3):
|
||||||
"""Start a game of connect four against Gwendolyn."""
|
"""Start a game of connect four against Gwendolyn."""
|
||||||
await self.bot.games.connect_four.start(ctx, difficulty)
|
await self.bot.games.connect_four.start(ctx, difficulty)
|
||||||
|
|
||||||
|
|
||||||
class HangmanCog(commands.Cog):
|
class HangmanCog(commands.Cog):
|
||||||
"""Contains all the hangman commands."""
|
"""Contains all the hangman commands."""
|
||||||
|
|
||||||
def __init__(self, bot):
|
def __init__(self, bot):
|
||||||
"""Initialize the cog."""
|
"""Initialize the cog."""
|
||||||
self.bot = bot
|
self.bot = bot
|
||||||
|
|
||||||
@cog_ext.cog_slash(**params["hangman"])
|
@cog_ext.cog_slash(**params["hangman"])
|
||||||
async def hangman(self, ctx):
|
async def hangman(self, ctx):
|
||||||
"""Start a game of hangman."""
|
"""Start a game of hangman."""
|
||||||
await self.bot.games.hangman.start(ctx)
|
await self.bot.games.hangman.start(ctx)
|
||||||
|
|
||||||
class WordleCog(commands.Cog):
|
class WordleCog(commands.Cog):
|
||||||
"""Contains all the wordle commands."""
|
"""Contains all the wordle commands."""
|
||||||
|
|
||||||
def __init__(self, bot):
|
def __init__(self, bot):
|
||||||
"""Initialize the cog."""
|
"""Initialize the cog."""
|
||||||
self.bot = bot
|
self.bot = bot
|
||||||
|
|
||||||
@cog_ext.cog_subcommand(**params["wordle_start"])
|
@cog_ext.cog_subcommand(**params["wordle_start"])
|
||||||
async def wordle_start(self, ctx, letters = 5):
|
async def wordle_start(self, ctx, letters = 5):
|
||||||
"""Start a game of wordle."""
|
"""Start a game of wordle."""
|
||||||
await self.bot.games.wordle.start(ctx, letters)
|
await self.bot.games.wordle.start(ctx, letters)
|
||||||
|
|
||||||
@cog_ext.cog_subcommand(**params["wordle_guess"])
|
@cog_ext.cog_subcommand(**params["wordle_guess"])
|
||||||
async def wordle_guess(self, ctx, guess):
|
async def wordle_guess(self, ctx, guess):
|
||||||
"""Start a game of wordle."""
|
"""Start a game of wordle."""
|
||||||
await self.bot.games.wordle.guess(ctx, guess)
|
await self.bot.games.wordle.guess(ctx, guess)
|
||||||
|
|
||||||
|
|
||||||
class HexCog(commands.Cog):
|
class HexCog(commands.Cog):
|
||||||
"""Contains all the hex commands."""
|
"""Contains all the hex commands."""
|
||||||
|
|
||||||
def __init__(self, bot):
|
def __init__(self, bot):
|
||||||
"""Initialize the cog."""
|
"""Initialize the cog."""
|
||||||
self.bot = bot
|
self.bot = bot
|
||||||
self.hex = self.bot.games.hex
|
self.hex = self.bot.games.hex
|
||||||
|
|
||||||
@cog_ext.cog_subcommand(**params["hex_start_user"])
|
@cog_ext.cog_subcommand(**params["hex_start_user"])
|
||||||
async def hex_start_user(self, ctx, user):
|
async def hex_start_user(self, ctx, user):
|
||||||
"""Start a game of hex against another player."""
|
"""Start a game of hex against another player."""
|
||||||
await self.hex.start(ctx, user)
|
await self.hex.start(ctx, user)
|
||||||
|
|
||||||
@cog_ext.cog_subcommand(**params["hex_start_gwendolyn"])
|
@cog_ext.cog_subcommand(**params["hex_start_gwendolyn"])
|
||||||
async def hex_start_gwendolyn(self, ctx, difficulty=2):
|
async def hex_start_gwendolyn(self, ctx, difficulty=2):
|
||||||
"""Start a game of hex against Gwendolyn."""
|
"""Start a game of hex against Gwendolyn."""
|
||||||
await self.hex.start(ctx, difficulty)
|
await self.hex.start(ctx, difficulty)
|
||||||
|
|
||||||
@cog_ext.cog_subcommand(**params["hex_place"])
|
@cog_ext.cog_subcommand(**params["hex_place"])
|
||||||
async def hex_place(self, ctx, coordinates):
|
async def hex_place(self, ctx, coordinates):
|
||||||
"""Place a piece in the hex game."""
|
"""Place a piece in the hex game."""
|
||||||
await self.hex.placeHex(ctx, coordinates, f"#{ctx.author.id}")
|
await self.hex.placeHex(ctx, coordinates, f"#{ctx.author.id}")
|
||||||
|
|
||||||
@cog_ext.cog_subcommand(**params["hex_undo"])
|
@cog_ext.cog_subcommand(**params["hex_undo"])
|
||||||
async def hex_undo(self, ctx):
|
async def hex_undo(self, ctx):
|
||||||
"""Undo your last hex move."""
|
"""Undo your last hex move."""
|
||||||
await self.hex.undo(ctx)
|
await self.hex.undo(ctx)
|
||||||
|
|
||||||
@cog_ext.cog_subcommand(**params["hex_swap"])
|
@cog_ext.cog_subcommand(**params["hex_swap"])
|
||||||
async def hex_swap(self, ctx):
|
async def hex_swap(self, ctx):
|
||||||
"""Perform a hex swap."""
|
"""Perform a hex swap."""
|
||||||
await self.hex.swap(ctx)
|
await self.hex.swap(ctx)
|
||||||
|
|
||||||
@cog_ext.cog_subcommand(**params["hex_surrender"])
|
@cog_ext.cog_subcommand(**params["hex_surrender"])
|
||||||
async def hex_surrender(self, ctx):
|
async def hex_surrender(self, ctx):
|
||||||
"""Surrender the hex game."""
|
"""Surrender the hex game."""
|
||||||
await self.hex.surrender(ctx)
|
await self.hex.surrender(ctx)
|
||||||
|
|
||||||
|
|
||||||
def setup(bot):
|
def setup(bot):
|
||||||
"""Add all the cogs to the bot."""
|
"""Add all the cogs to the bot."""
|
||||||
bot.add_cog(GamesCog(bot))
|
bot.add_cog(GamesCog(bot))
|
||||||
bot.add_cog(BlackjackCog(bot))
|
bot.add_cog(BlackjackCog(bot))
|
||||||
bot.add_cog(ConnectFourCog(bot))
|
bot.add_cog(ConnectFourCog(bot))
|
||||||
bot.add_cog(HangmanCog(bot))
|
bot.add_cog(HangmanCog(bot))
|
||||||
bot.add_cog(HexCog(bot))
|
bot.add_cog(HexCog(bot))
|
||||||
bot.add_cog(WordleCog(bot))
|
bot.add_cog(WordleCog(bot))
|
||||||
|
|||||||
@@ -8,25 +8,25 @@ params = get_params()
|
|||||||
|
|
||||||
|
|
||||||
class LookupCog(commands.Cog):
|
class LookupCog(commands.Cog):
|
||||||
"""Contains the lookup commands."""
|
"""Contains the lookup commands."""
|
||||||
|
|
||||||
def __init__(self, bot):
|
def __init__(self, bot):
|
||||||
"""Initialize the cog."""
|
"""Initialize the cog."""
|
||||||
self.bot = bot
|
self.bot = bot
|
||||||
|
|
||||||
# Looks up a spell
|
# Looks up a spell
|
||||||
@cog_ext.cog_slash(**params["spell"])
|
@cog_ext.cog_slash(**params["spell"])
|
||||||
async def spell(self, ctx, query):
|
async def spell(self, ctx, query):
|
||||||
"""Look up a spell."""
|
"""Look up a spell."""
|
||||||
await self.bot.lookup_funcs.spell_func(ctx, query)
|
await self.bot.lookup_funcs.spell_func(ctx, query)
|
||||||
|
|
||||||
# Looks up a monster
|
# Looks up a monster
|
||||||
@cog_ext.cog_slash(**params["monster"])
|
@cog_ext.cog_slash(**params["monster"])
|
||||||
async def monster(self, ctx, query):
|
async def monster(self, ctx, query):
|
||||||
"""Look up a monster."""
|
"""Look up a monster."""
|
||||||
await self.bot.lookup_funcs.monster_func(ctx, query)
|
await self.bot.lookup_funcs.monster_func(ctx, query)
|
||||||
|
|
||||||
|
|
||||||
def setup(bot):
|
def setup(bot):
|
||||||
"""Add the cog to the bot."""
|
"""Add the cog to the bot."""
|
||||||
bot.add_cog(LookupCog(bot))
|
bot.add_cog(LookupCog(bot))
|
||||||
|
|||||||
@@ -9,92 +9,92 @@ params = get_params()
|
|||||||
|
|
||||||
|
|
||||||
class MiscCog(commands.Cog):
|
class MiscCog(commands.Cog):
|
||||||
"""Contains the miscellaneous commands."""
|
"""Contains the miscellaneous commands."""
|
||||||
|
|
||||||
def __init__(self, bot):
|
def __init__(self, bot):
|
||||||
"""Initialize the cog."""
|
"""Initialize the cog."""
|
||||||
self.bot = bot
|
self.bot = bot
|
||||||
self.bot.remove_command("help")
|
self.bot.remove_command("help")
|
||||||
self.generators = bot.other.generators
|
self.generators = bot.other.generators
|
||||||
self.plex = bot.other.plex
|
self.plex = bot.other.plex
|
||||||
self.nerd_shit = bot.other.nerd_shit
|
self.nerd_shit = bot.other.nerd_shit
|
||||||
|
|
||||||
@cog_ext.cog_slash(**params["ping"])
|
@cog_ext.cog_slash(**params["ping"])
|
||||||
async def ping(self, ctx: SlashContext):
|
async def ping(self, ctx: SlashContext):
|
||||||
"""Send the bot's latency."""
|
"""Send the bot's latency."""
|
||||||
await ctx.send(f"Pong!\nLatency is {round(self.bot.latency * 1000)}ms")
|
await ctx.send(f"Pong!\nLatency is {round(self.bot.latency * 1000)}ms")
|
||||||
|
|
||||||
@cog_ext.cog_slash(**params["stop"])
|
@cog_ext.cog_slash(**params["stop"])
|
||||||
async def stop(self, ctx: SlashContext):
|
async def stop(self, ctx: SlashContext):
|
||||||
"""Stop the bot."""
|
"""Stop the bot."""
|
||||||
await self.bot.stop(ctx)
|
await self.bot.stop(ctx)
|
||||||
|
|
||||||
@cog_ext.cog_slash(**params["help"])
|
@cog_ext.cog_slash(**params["help"])
|
||||||
async def help_command(self, ctx: SlashContext, command=""):
|
async def help_command(self, ctx: SlashContext, command=""):
|
||||||
"""Get help for commands."""
|
"""Get help for commands."""
|
||||||
await self.bot.other.help_func(ctx, command)
|
await self.bot.other.help_func(ctx, command)
|
||||||
|
|
||||||
@cog_ext.cog_slash(**params["thank"])
|
@cog_ext.cog_slash(**params["thank"])
|
||||||
async def thank(self, ctx: SlashContext):
|
async def thank(self, ctx: SlashContext):
|
||||||
"""Thank the bot."""
|
"""Thank the bot."""
|
||||||
await ctx.send("You're welcome :blush:")
|
await ctx.send("You're welcome :blush:")
|
||||||
|
|
||||||
@cog_ext.cog_slash(**params["hello"])
|
@cog_ext.cog_slash(**params["hello"])
|
||||||
async def hello(self, ctx: SlashContext):
|
async def hello(self, ctx: SlashContext):
|
||||||
"""Greet the bot."""
|
"""Greet the bot."""
|
||||||
await self.bot.other.hello_func(ctx)
|
await self.bot.other.hello_func(ctx)
|
||||||
|
|
||||||
@cog_ext.cog_slash(**params["roll"])
|
@cog_ext.cog_slash(**params["roll"])
|
||||||
async def roll(self, ctx: SlashContext, dice="1d20"):
|
async def roll(self, ctx: SlashContext, dice="1d20"):
|
||||||
"""Roll dice."""
|
"""Roll dice."""
|
||||||
await self.bot.other.roll_dice(ctx, dice)
|
await self.bot.other.roll_dice(ctx, dice)
|
||||||
|
|
||||||
@cog_ext.cog_slash(**params["image"])
|
@cog_ext.cog_slash(**params["image"])
|
||||||
async def image(self, ctx: SlashContext):
|
async def image(self, ctx: SlashContext):
|
||||||
"""Get a random image from Bing."""
|
"""Get a random image from Bing."""
|
||||||
await self.bot.other.image_func(ctx)
|
await self.bot.other.image_func(ctx)
|
||||||
|
|
||||||
@cog_ext.cog_slash(**params["movie"])
|
@cog_ext.cog_slash(**params["movie"])
|
||||||
async def movie(self, ctx: SlashContext):
|
async def movie(self, ctx: SlashContext):
|
||||||
"""Get a random movie from the Plex server."""
|
"""Get a random movie from the Plex server."""
|
||||||
await self.bot.other.movie_func(ctx)
|
await self.bot.other.movie_func(ctx)
|
||||||
|
|
||||||
@cog_ext.cog_slash(**params["name"])
|
@cog_ext.cog_slash(**params["name"])
|
||||||
async def name(self, ctx: SlashContext):
|
async def name(self, ctx: SlashContext):
|
||||||
"""Generate a random name."""
|
"""Generate a random name."""
|
||||||
await self.generators.name_gen(ctx)
|
await self.generators.name_gen(ctx)
|
||||||
|
|
||||||
@cog_ext.cog_slash(**params["tavern"])
|
@cog_ext.cog_slash(**params["tavern"])
|
||||||
async def tavern(self, ctx: SlashContext):
|
async def tavern(self, ctx: SlashContext):
|
||||||
"""Generate a random tavern name."""
|
"""Generate a random tavern name."""
|
||||||
await self.generators.tavern_gen(ctx)
|
await self.generators.tavern_gen(ctx)
|
||||||
|
|
||||||
@cog_ext.cog_slash(**params["wiki"])
|
@cog_ext.cog_slash(**params["wiki"])
|
||||||
async def wiki(self, ctx: SlashContext, wiki_page=""):
|
async def wiki(self, ctx: SlashContext, wiki_page=""):
|
||||||
"""Get a page on a fandom wiki."""
|
"""Get a page on a fandom wiki."""
|
||||||
await self.bot.other.find_wiki_page(ctx, wiki_page)
|
await self.bot.other.find_wiki_page(ctx, wiki_page)
|
||||||
|
|
||||||
@cog_ext.cog_slash(**params["add_movie"])
|
@cog_ext.cog_slash(**params["add_movie"])
|
||||||
async def add_movie(self, ctx: SlashContext, movie):
|
async def add_movie(self, ctx: SlashContext, movie):
|
||||||
"""Search for a movie and add it to the Plex server."""
|
"""Search for a movie and add it to the Plex server."""
|
||||||
await self.plex.request_movie(ctx, movie)
|
await self.plex.request_movie(ctx, movie)
|
||||||
|
|
||||||
@cog_ext.cog_slash(**params["add_show"])
|
@cog_ext.cog_slash(**params["add_show"])
|
||||||
async def add_show(self, ctx: SlashContext, show):
|
async def add_show(self, ctx: SlashContext, show):
|
||||||
"""Search for a show and add it to the Plex server."""
|
"""Search for a show and add it to the Plex server."""
|
||||||
await self.plex.request_show(ctx, show)
|
await self.plex.request_show(ctx, show)
|
||||||
|
|
||||||
@cog_ext.cog_slash(**params["downloading"])
|
@cog_ext.cog_slash(**params["downloading"])
|
||||||
async def downloading(self, ctx: SlashContext, parameters="-d"):
|
async def downloading(self, ctx: SlashContext, parameters="-d"):
|
||||||
"""Get the current downloading torrents."""
|
"""Get the current downloading torrents."""
|
||||||
await self.plex.downloading(ctx, parameters)
|
await self.plex.downloading(ctx, parameters)
|
||||||
|
|
||||||
@cog_ext.cog_slash(**params["wolf"])
|
@cog_ext.cog_slash(**params["wolf"])
|
||||||
async def wolf(self, ctx: SlashContext, query):
|
async def wolf(self, ctx: SlashContext, query):
|
||||||
"""Perform a search on Wolfram Alpha."""
|
"""Perform a search on Wolfram Alpha."""
|
||||||
await self.nerd_shit.wolf_search(ctx, query)
|
await self.nerd_shit.wolf_search(ctx, query)
|
||||||
|
|
||||||
|
|
||||||
def setup(bot):
|
def setup(bot):
|
||||||
"""Add the cog to the bot."""
|
"""Add the cog to the bot."""
|
||||||
bot.add_cog(MiscCog(bot))
|
bot.add_cog(MiscCog(bot))
|
||||||
|
|||||||
@@ -8,33 +8,33 @@ params = get_params()
|
|||||||
|
|
||||||
|
|
||||||
class StarWarsCog(commands.Cog):
|
class StarWarsCog(commands.Cog):
|
||||||
"""Contains the Star Wars commands."""
|
"""Contains the Star Wars commands."""
|
||||||
|
|
||||||
def __init__(self, bot):
|
def __init__(self, bot):
|
||||||
"""Initialize the cog."""
|
"""Initialize the cog."""
|
||||||
self.bot = bot
|
self.bot = bot
|
||||||
|
|
||||||
@cog_ext.cog_slash(**params["star_wars_roll"])
|
@cog_ext.cog_slash(**params["star_wars_roll"])
|
||||||
async def star_wars_roll(self, ctx, dice=""):
|
async def star_wars_roll(self, ctx, dice=""):
|
||||||
"""Roll Star Wars dice."""
|
"""Roll Star Wars dice."""
|
||||||
await self.bot.star_wars.roll.parseRoll(ctx, dice)
|
await self.bot.star_wars.roll.parseRoll(ctx, dice)
|
||||||
|
|
||||||
@cog_ext.cog_slash(**params["star_wars_destiny"])
|
@cog_ext.cog_slash(**params["star_wars_destiny"])
|
||||||
async def star_wars_destiny(self, ctx, parameters=""):
|
async def star_wars_destiny(self, ctx, parameters=""):
|
||||||
"""Control Star Wars destiny points."""
|
"""Control Star Wars destiny points."""
|
||||||
await self.bot.star_wars.destiny.parseDestiny(ctx, parameters)
|
await self.bot.star_wars.destiny.parseDestiny(ctx, parameters)
|
||||||
|
|
||||||
@cog_ext.cog_slash(**params["star_wars_crit"])
|
@cog_ext.cog_slash(**params["star_wars_crit"])
|
||||||
async def star_wars_crit(self, ctx, severity: int = 0):
|
async def star_wars_crit(self, ctx, severity: int = 0):
|
||||||
"""Roll for critical injuries."""
|
"""Roll for critical injuries."""
|
||||||
await self.bot.star_wars.roll.critRoll(ctx, severity)
|
await self.bot.star_wars.roll.critRoll(ctx, severity)
|
||||||
|
|
||||||
@cog_ext.cog_slash(**params["star_wars_character"])
|
@cog_ext.cog_slash(**params["star_wars_character"])
|
||||||
async def star_wars_character(self, ctx, parameters=""):
|
async def star_wars_character(self, ctx, parameters=""):
|
||||||
"""Access and change Star Wars character sheet data."""
|
"""Access and change Star Wars character sheet data."""
|
||||||
await self.bot.star_wars.character.parseChar(ctx, parameters)
|
await self.bot.star_wars.character.parseChar(ctx, parameters)
|
||||||
|
|
||||||
|
|
||||||
def setup(bot):
|
def setup(bot):
|
||||||
"""Add the cog to the bot."""
|
"""Add the cog to the bot."""
|
||||||
bot.add_cog(StarWarsCog(bot))
|
bot.add_cog(StarWarsCog(bot))
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
"""Exceptions for Gwendolyn"""
|
"""Exceptions for Gwendolyn"""
|
||||||
|
|
||||||
class GameNotInDatabase(Exception):
|
class GameNotInDatabase(Exception):
|
||||||
def __init__(self, game: str, channel: str):
|
def __init__(self, game: str, channel: str):
|
||||||
self.message = f"There is no {game} game in channel {channel}"
|
self.message = f"There is no {game} game in channel {channel}"
|
||||||
super().__init__(self.message)
|
super().__init__(self.message)
|
||||||
|
|
||||||
class InvalidInteraction(Exception):
|
class InvalidInteraction(Exception):
|
||||||
def __init__(self, custom_id: str, decoded: str):
|
def __init__(self, custom_id: str, decoded: str):
|
||||||
self.message = f"{custom_id = }, {decoded = }"
|
self.message = f"{custom_id = }, {decoded = }"
|
||||||
super().__init__(self.message)
|
super().__init__(self.message)
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -13,306 +13,306 @@ from gwendolyn_old.exceptions import GameNotInDatabase
|
|||||||
from gwendolyn_old.utils import encode_id
|
from gwendolyn_old.utils import encode_id
|
||||||
|
|
||||||
class GameBase():
|
class GameBase():
|
||||||
"""The base class for the games."""
|
"""The base class for the games."""
|
||||||
|
|
||||||
def __init__(self, bot, game_name: int, drawer):
|
def __init__(self, bot, game_name: int, drawer):
|
||||||
"""Initialize the class."""
|
"""Initialize the class."""
|
||||||
self.bot = bot
|
self.bot = bot
|
||||||
self.long_strings = self.bot.long_strings
|
self.long_strings = self.bot.long_strings
|
||||||
self.resources = "gwendolyn/resources/games/"
|
self.resources = "gwendolyn/resources/games/"
|
||||||
self.game_name = game_name
|
self.game_name = game_name
|
||||||
self.draw = drawer(bot, self)
|
self.draw = drawer(bot, self)
|
||||||
|
|
||||||
def _get_action_rows(self, buttons: list[tuple[str, list]]):
|
def _get_action_rows(self, buttons: list[tuple[str, list]]):
|
||||||
self.bot.log("Generation action rows")
|
self.bot.log("Generation action rows")
|
||||||
button_objects = []
|
button_objects = []
|
||||||
for label, data, style in buttons:
|
for label, data, style in buttons:
|
||||||
custom_id = encode_id([self.game_name] + data)
|
custom_id = encode_id([self.game_name] + data)
|
||||||
button_objects.append(Button(
|
button_objects.append(Button(
|
||||||
style=style,
|
style=style,
|
||||||
label=label,
|
label=label,
|
||||||
custom_id=custom_id
|
custom_id=custom_id
|
||||||
))
|
))
|
||||||
|
|
||||||
action_rows = []
|
action_rows = []
|
||||||
for i in range(((len(button_objects)-1)//5)+1):
|
for i in range(((len(button_objects)-1)//5)+1):
|
||||||
action_rows.append(ActionRow(*button_objects[i*5:i*5+5]))
|
action_rows.append(ActionRow(*button_objects[i*5:i*5+5]))
|
||||||
|
|
||||||
return action_rows
|
return action_rows
|
||||||
|
|
||||||
async def _send_image(self, channel: Messageable,
|
async def _send_image(self, channel: Messageable,
|
||||||
buttons: list[tuple[str, list]] = None, delete=True):
|
buttons: list[tuple[str, list]] = None, delete=True):
|
||||||
self.draw.draw(str(channel.id))
|
self.draw.draw(str(channel.id))
|
||||||
file_path = f"{self.resources}images/{self.game_name}{channel.id}.png"
|
file_path = f"{self.resources}images/{self.game_name}{channel.id}.png"
|
||||||
old_image = await channel.send(
|
old_image = await channel.send(
|
||||||
file=File(file_path), delete_after=120 if delete else None)
|
file=File(file_path), delete_after=120 if delete else None)
|
||||||
|
|
||||||
if buttons is not None and len(buttons) < 25:
|
if buttons is not None and len(buttons) < 25:
|
||||||
await old_image.edit(components = self._get_action_rows(buttons))
|
await old_image.edit(components = self._get_action_rows(buttons))
|
||||||
|
|
||||||
return old_image
|
return old_image
|
||||||
|
|
||||||
class DatabaseGame(GameBase):
|
class DatabaseGame(GameBase):
|
||||||
"""The base class for the games."""
|
"""The base class for the games."""
|
||||||
|
|
||||||
def __init__(self, bot, game_name, drawer):
|
def __init__(self, bot, game_name, drawer):
|
||||||
"""Initialize the class."""
|
"""Initialize the class."""
|
||||||
super().__init__(bot, game_name, drawer)
|
super().__init__(bot, game_name, drawer)
|
||||||
self.database = self.bot.database
|
self.database = self.bot.database
|
||||||
self.old_images_path = f"{self.resources}old_images/{self.game_name}"
|
self.old_images_path = f"{self.resources}old_images/{self.game_name}"
|
||||||
|
|
||||||
def access_document(self, channel: str, collection_name: str="games",
|
def access_document(self, channel: str, collection_name: str="games",
|
||||||
raise_missing_error: bool=True):
|
raise_missing_error: bool=True):
|
||||||
collection = self.bot.database[f"{self.game_name} {collection_name}"]
|
collection = self.bot.database[f"{self.game_name} {collection_name}"]
|
||||||
game = collection.find_one({"_id": channel})
|
game = collection.find_one({"_id": channel})
|
||||||
if game is None and raise_missing_error:
|
if game is None and raise_missing_error:
|
||||||
raise GameNotInDatabase(self.game_name, channel)
|
raise GameNotInDatabase(self.game_name, channel)
|
||||||
|
|
||||||
return game
|
return game
|
||||||
|
|
||||||
def _test_document(self, channel: str, collection_name: str="games"):
|
def _test_document(self, channel: str, collection_name: str="games"):
|
||||||
collection = self.bot.database[f"{self.game_name} {collection_name}"]
|
collection = self.bot.database[f"{self.game_name} {collection_name}"]
|
||||||
game = collection.find_one({"_id": channel})
|
game = collection.find_one({"_id": channel})
|
||||||
return game is not None
|
return game is not None
|
||||||
|
|
||||||
def _update_document(self, channel: str, updater: dict,
|
def _update_document(self, channel: str, updater: dict,
|
||||||
collection_name: str="games"):
|
collection_name: str="games"):
|
||||||
self.database[f"{self.game_name} {collection_name}"].update_one(
|
self.database[f"{self.game_name} {collection_name}"].update_one(
|
||||||
{"_id": channel},
|
{"_id": channel},
|
||||||
updater,
|
updater,
|
||||||
upsert=True
|
upsert=True
|
||||||
)
|
)
|
||||||
|
|
||||||
def _delete_document(self, channel: str, collection_name: str="games"):
|
def _delete_document(self, channel: str, collection_name: str="games"):
|
||||||
self.database[f"{self.game_name} {collection_name}"].delete_one(
|
self.database[f"{self.game_name} {collection_name}"].delete_one(
|
||||||
{"_id": channel}
|
{"_id": channel}
|
||||||
)
|
)
|
||||||
|
|
||||||
def _insert_document(self, data: dict, collection_name: str="games"):
|
def _insert_document(self, data: dict, collection_name: str="games"):
|
||||||
self.database[f"{self.game_name} {collection_name}"].insert_one(data)
|
self.database[f"{self.game_name} {collection_name}"].insert_one(data)
|
||||||
|
|
||||||
async def _delete_old_image(self, channel: Messageable):
|
async def _delete_old_image(self, channel: Messageable):
|
||||||
with open(self.old_images_path + str(channel.id), "r") as file_pointer:
|
with open(self.old_images_path + str(channel.id), "r") as file_pointer:
|
||||||
old_image = await channel.fetch_message(int(file_pointer.read()))
|
old_image = await channel.fetch_message(int(file_pointer.read()))
|
||||||
|
|
||||||
await old_image.delete()
|
await old_image.delete()
|
||||||
|
|
||||||
async def _send_image(self, channel: Messageable,
|
async def _send_image(self, channel: Messageable,
|
||||||
buttons: list[tuple[str, list]] = None, delete=True):
|
buttons: list[tuple[str, list]] = None, delete=True):
|
||||||
old_image = await super()._send_image(channel, buttons, delete)
|
old_image = await super()._send_image(channel, buttons, delete)
|
||||||
with open(self.old_images_path + str(channel.id), "w") as file_pointer:
|
with open(self.old_images_path + str(channel.id), "w") as file_pointer:
|
||||||
file_pointer.write(str(old_image.id))
|
file_pointer.write(str(old_image.id))
|
||||||
|
|
||||||
async def _start_new(self, channel: Messageable, new_game: dict,
|
async def _start_new(self, channel: Messageable, new_game: dict,
|
||||||
buttons: list[tuple[str, list]] = None,
|
buttons: list[tuple[str, list]] = None,
|
||||||
delete = True):
|
delete = True):
|
||||||
new_game['_id'] = str(channel.id)
|
new_game['_id'] = str(channel.id)
|
||||||
self._insert_document(new_game)
|
self._insert_document(new_game)
|
||||||
await self._send_image(channel, buttons, delete)
|
await self._send_image(channel, buttons, delete)
|
||||||
|
|
||||||
async def _end_game(self, channel: Messageable):
|
async def _end_game(self, channel: Messageable):
|
||||||
await self._delete_old_image(channel)
|
await self._delete_old_image(channel)
|
||||||
await self._send_image(channel, delete=False)
|
await self._send_image(channel, delete=False)
|
||||||
self._delete_document(str(channel.id))
|
self._delete_document(str(channel.id))
|
||||||
|
|
||||||
|
|
||||||
class CardGame(DatabaseGame):
|
class CardGame(DatabaseGame):
|
||||||
"""The class for card games."""
|
"""The class for card games."""
|
||||||
def __init__(self, bot, game_name, drawer, deck_used):
|
def __init__(self, bot, game_name, drawer, deck_used):
|
||||||
"""Initialize the class."""
|
"""Initialize the class."""
|
||||||
super().__init__(bot, game_name, drawer)
|
super().__init__(bot, game_name, drawer)
|
||||||
self.decks_used = deck_used
|
self.decks_used = deck_used
|
||||||
|
|
||||||
def _shuffle_cards(self, channel: str):
|
def _shuffle_cards(self, channel: str):
|
||||||
self.bot.log(f"Shuffling cards for {self.game_name}")
|
self.bot.log(f"Shuffling cards for {self.game_name}")
|
||||||
with open(f"{self.resources}deck_of_cards.txt", "r") as file_pointer:
|
with open(f"{self.resources}deck_of_cards.txt", "r") as file_pointer:
|
||||||
deck = file_pointer.read()
|
deck = file_pointer.read()
|
||||||
|
|
||||||
all_decks = deck.split("\n") * self.decks_used
|
all_decks = deck.split("\n") * self.decks_used
|
||||||
random.shuffle(all_decks)
|
random.shuffle(all_decks)
|
||||||
|
|
||||||
self._update_document(
|
self._update_document(
|
||||||
channel,
|
channel,
|
||||||
{"$set": {"_id": channel, "cards": all_decks}},
|
{"$set": {"_id": channel, "cards": all_decks}},
|
||||||
"cards"
|
"cards"
|
||||||
)
|
)
|
||||||
|
|
||||||
def _draw_card(self, channel: str):
|
def _draw_card(self, channel: str):
|
||||||
"""
|
"""
|
||||||
Draw a card from the stack.
|
Draw a card from the stack.
|
||||||
|
|
||||||
*Parameters*
|
*Parameters*
|
||||||
------------
|
------------
|
||||||
channel: str
|
channel: str
|
||||||
The id of the channel the card is drawn in.
|
The id of the channel the card is drawn in.
|
||||||
"""
|
"""
|
||||||
self.bot.log("drawing a card")
|
self.bot.log("drawing a card")
|
||||||
|
|
||||||
drawn_card = self.access_document(channel, "cards")["cards"][0]
|
drawn_card = self.access_document(channel, "cards")["cards"][0]
|
||||||
self._update_document(channel, {"$pop": {"cards": -1}}, "cards")
|
self._update_document(channel, {"$pop": {"cards": -1}}, "cards")
|
||||||
|
|
||||||
return drawn_card
|
return drawn_card
|
||||||
|
|
||||||
class BoardGame(GameBase):
|
class BoardGame(GameBase):
|
||||||
async def _test_opponent(self, ctx: IntCont, opponent: Union[int, User]):
|
async def _test_opponent(self, ctx: IntCont, opponent: Union[int, User]):
|
||||||
if isinstance(opponent, int):
|
if isinstance(opponent, int):
|
||||||
# Opponent is Gwendolyn
|
# Opponent is Gwendolyn
|
||||||
if opponent in range(1, 6):
|
if opponent in range(1, 6):
|
||||||
difficulty = int(opponent)
|
difficulty = int(opponent)
|
||||||
difficulty_text = f" with difficulty {difficulty}"
|
difficulty_text = f" with difficulty {difficulty}"
|
||||||
opponent = self.bot.user.id
|
opponent = self.bot.user.id
|
||||||
else:
|
else:
|
||||||
await ctx.send("Difficulty doesn't exist")
|
await ctx.send("Difficulty doesn't exist")
|
||||||
self.bot.log("They challenged a difficulty that doesn't exist")
|
self.bot.log("They challenged a difficulty that doesn't exist")
|
||||||
return False
|
return False
|
||||||
elif isinstance(opponent, User):
|
elif isinstance(opponent, User):
|
||||||
if opponent.bot:
|
if opponent.bot:
|
||||||
# User has challenged a bot
|
# User has challenged a bot
|
||||||
if opponent == self.bot.user:
|
if opponent == self.bot.user:
|
||||||
# It was Gwendolyn
|
# It was Gwendolyn
|
||||||
difficulty = 3
|
difficulty = 3
|
||||||
difficulty_text = f" with difficulty {difficulty}"
|
difficulty_text = f" with difficulty {difficulty}"
|
||||||
opponent = self.bot.user.id
|
opponent = self.bot.user.id
|
||||||
else:
|
else:
|
||||||
await ctx.send("You can't challenge a bot!")
|
await ctx.send("You can't challenge a bot!")
|
||||||
self.bot.log("They tried to challenge a bot")
|
self.bot.log("They tried to challenge a bot")
|
||||||
return False
|
return False
|
||||||
else:
|
else:
|
||||||
# Opponent is another player
|
# Opponent is another player
|
||||||
if ctx.author != opponent:
|
if ctx.author != opponent:
|
||||||
opponent = opponent.id
|
opponent = opponent.id
|
||||||
difficulty = 5
|
difficulty = 5
|
||||||
difficulty_text = ""
|
difficulty_text = ""
|
||||||
else:
|
else:
|
||||||
await ctx.send("You can't play against yourself")
|
await ctx.send("You can't play against yourself")
|
||||||
self.bot.log("They tried to play against themself")
|
self.bot.log("They tried to play against themself")
|
||||||
return False
|
return False
|
||||||
|
|
||||||
return opponent, (difficulty, difficulty_text)
|
return opponent, (difficulty, difficulty_text)
|
||||||
|
|
||||||
class BaseDrawer():
|
class BaseDrawer():
|
||||||
"""Class for drawing games."""
|
"""Class for drawing games."""
|
||||||
def __init__(self, bot, game: GameBase):
|
def __init__(self, bot, game: GameBase):
|
||||||
self.bot = bot
|
self.bot = bot
|
||||||
self.game = game
|
self.game = game
|
||||||
self.fonts_path = "gwendolyn/resources/fonts/"
|
self.fonts_path = "gwendolyn/resources/fonts/"
|
||||||
self.font_name = "futura-bold"
|
self.font_name = "futura-bold"
|
||||||
|
|
||||||
self.resources = game.resources
|
self.resources = game.resources
|
||||||
game_name = game.game_name
|
game_name = game.game_name
|
||||||
self.default_image = f"{self.resources}default_images/{game_name}.png"
|
self.default_image = f"{self.resources}default_images/{game_name}.png"
|
||||||
self.default_size = None
|
self.default_size = None
|
||||||
self.default_color = None
|
self.default_color = None
|
||||||
self.images_path = f"{self.resources}images/{game_name}"
|
self.images_path = f"{self.resources}images/{game_name}"
|
||||||
|
|
||||||
def _get_size(self, game: dict):
|
def _get_size(self, game: dict):
|
||||||
return self.default_size
|
return self.default_size
|
||||||
|
|
||||||
def _draw_image(self, game: dict, image: Image.Image):
|
def _draw_image(self, game: dict, image: Image.Image):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def draw(self, channel: str):
|
def draw(self, channel: str):
|
||||||
game = self.game.access_document(channel)
|
game = self.game.access_document(channel)
|
||||||
if self.default_image is not None:
|
if self.default_image is not None:
|
||||||
image = Image.open(self.default_image)
|
image = Image.open(self.default_image)
|
||||||
else:
|
else:
|
||||||
image = Image.new("RGB", self._get_size(game), self.default_color)
|
image = Image.new("RGB", self._get_size(game), self.default_color)
|
||||||
self._draw_image(game, image)
|
self._draw_image(game, image)
|
||||||
self._save_image(image, channel)
|
self._save_image(image, channel)
|
||||||
|
|
||||||
def _get_font(self, size: int, font_name: str = None):
|
def _get_font(self, size: int, font_name: str = None):
|
||||||
if font_name is None:
|
if font_name is None:
|
||||||
font_name = self.font_name
|
font_name = self.font_name
|
||||||
return ImageFont.truetype(f"{self.fonts_path}{font_name}.ttf", size)
|
return ImageFont.truetype(f"{self.fonts_path}{font_name}.ttf", size)
|
||||||
|
|
||||||
def _adjust_font(self, max_font_size: int, text: str, max_text_size: int,
|
def _adjust_font(self, max_font_size: int, text: str, max_text_size: int,
|
||||||
font_name: str = None):
|
font_name: str = None):
|
||||||
font_size = max_font_size
|
font_size = max_font_size
|
||||||
font = self._get_font(font_size, font_name)
|
font = self._get_font(font_size, font_name)
|
||||||
text_width = font.getsize(text)[0]
|
text_width = font.getsize(text)[0]
|
||||||
|
|
||||||
while text_width > max_text_size:
|
while text_width > max_text_size:
|
||||||
font_size -= 1
|
font_size -= 1
|
||||||
font = self._get_font(font_size, font_name)
|
font = self._get_font(font_size, font_name)
|
||||||
text_width = font.getsize(text)[0]
|
text_width = font.getsize(text)[0]
|
||||||
|
|
||||||
return font, font_size
|
return font, font_size
|
||||||
|
|
||||||
def _save_image(self, image: Image.Image, channel: str):
|
def _save_image(self, image: Image.Image, channel: str):
|
||||||
self.bot.log("Saving image")
|
self.bot.log("Saving image")
|
||||||
image.save(f"{self.images_path}{channel}.png")
|
image.save(f"{self.images_path}{channel}.png")
|
||||||
|
|
||||||
def _draw_shadow_text(self, text: str, colors: list[tuple[int, int, int]],
|
def _draw_shadow_text(self, text: str, colors: list[tuple[int, int, int]],
|
||||||
font_size: int):
|
font_size: int):
|
||||||
font = self._get_font(font_size)
|
font = self._get_font(font_size)
|
||||||
offset = font_size//20
|
offset = font_size//20
|
||||||
shadow_offset = font_size//10
|
shadow_offset = font_size//10
|
||||||
|
|
||||||
text_size = list(font.getsize(text))
|
text_size = list(font.getsize(text))
|
||||||
text_size[0] += 1 + (offset * 2)
|
text_size[0] += 1 + (offset * 2)
|
||||||
text_size[1] += 1 + (offset * 2) + shadow_offset
|
text_size[1] += 1 + (offset * 2) + shadow_offset
|
||||||
|
|
||||||
image = Image.new("RGBA", tuple(text_size), (0, 0, 0, 0))
|
image = Image.new("RGBA", tuple(text_size), (0, 0, 0, 0))
|
||||||
text_image = ImageDraw.Draw(image)
|
text_image = ImageDraw.Draw(image)
|
||||||
|
|
||||||
for color_index, color in enumerate(colors[:-1]):
|
for color_index, color in enumerate(colors[:-1]):
|
||||||
color_offset = offset//(color_index+1)
|
color_offset = offset//(color_index+1)
|
||||||
if color_index == 0:
|
if color_index == 0:
|
||||||
color_shadow_offset = shadow_offset
|
color_shadow_offset = shadow_offset
|
||||||
else:
|
else:
|
||||||
color_shadow_offset = 0
|
color_shadow_offset = 0
|
||||||
|
|
||||||
for i in range(4):
|
for i in range(4):
|
||||||
x_pos = [-1,1][i % 2] * color_offset
|
x_pos = [-1,1][i % 2] * color_offset
|
||||||
y_pos = [-1,1][(i//2) % 2] * color_offset + color_shadow_offset
|
y_pos = [-1,1][(i//2) % 2] * color_offset + color_shadow_offset
|
||||||
position = (offset + x_pos, offset + y_pos)
|
position = (offset + x_pos, offset + y_pos)
|
||||||
text_image.text(position, text, fill=color, font=font)
|
text_image.text(position, text, fill=color, font=font)
|
||||||
|
|
||||||
text_image.text((offset, offset), text, fill=colors[-1], font=font)
|
text_image.text((offset, offset), text, fill=colors[-1], font=font)
|
||||||
|
|
||||||
return image
|
return image
|
||||||
|
|
||||||
class CardDrawer(BaseDrawer):
|
class CardDrawer(BaseDrawer):
|
||||||
def __init__(self, bot, game: GameBase):
|
def __init__(self, bot, game: GameBase):
|
||||||
super().__init__(bot, game)
|
super().__init__(bot, game)
|
||||||
self.cards_path = f"{self.resources}cards/"
|
self.cards_path = f"{self.resources}cards/"
|
||||||
|
|
||||||
# pylint: disable=invalid-name
|
# pylint: disable=invalid-name
|
||||||
self.CARD_WIDTH = 691
|
self.CARD_WIDTH = 691
|
||||||
self.CARD_HEIGHT = 1065
|
self.CARD_HEIGHT = 1065
|
||||||
|
|
||||||
self.CARD_BORDER = 100
|
self.CARD_BORDER = 100
|
||||||
self.CARD_OFFSET = 125
|
self.CARD_OFFSET = 125
|
||||||
# pylint: enable=invalid-name
|
# pylint: enable=invalid-name
|
||||||
|
|
||||||
def _set_card_size(self, wanted_card_width: int):
|
def _set_card_size(self, wanted_card_width: int):
|
||||||
ratio = wanted_card_width / self.CARD_WIDTH
|
ratio = wanted_card_width / self.CARD_WIDTH
|
||||||
self.CARD_WIDTH = wanted_card_width
|
self.CARD_WIDTH = wanted_card_width
|
||||||
self.CARD_HEIGHT = int(self.CARD_HEIGHT * ratio)
|
self.CARD_HEIGHT = int(self.CARD_HEIGHT * ratio)
|
||||||
self.CARD_BORDER = int(self.CARD_BORDER * ratio)
|
self.CARD_BORDER = int(self.CARD_BORDER * ratio)
|
||||||
self.CARD_OFFSET = int(self.CARD_OFFSET * ratio)
|
self.CARD_OFFSET = int(self.CARD_OFFSET * ratio)
|
||||||
|
|
||||||
def _draw_cards(self, hand: list[str], hidden_cards: int = 0):
|
def _draw_cards(self, hand: list[str], hidden_cards: int = 0):
|
||||||
image_width = (self.CARD_BORDER * 2) + self.CARD_WIDTH
|
image_width = (self.CARD_BORDER * 2) + self.CARD_WIDTH
|
||||||
image_width += (self.CARD_OFFSET * (len(hand)-1))
|
image_width += (self.CARD_OFFSET * (len(hand)-1))
|
||||||
image_size = (image_width, (self.CARD_BORDER * 2) + self.CARD_HEIGHT)
|
image_size = (image_width, (self.CARD_BORDER * 2) + self.CARD_HEIGHT)
|
||||||
background = Image.new("RGBA", image_size, (0, 0, 0, 0))
|
background = Image.new("RGBA", image_size, (0, 0, 0, 0))
|
||||||
|
|
||||||
for i, card in enumerate(hand):
|
for i, card in enumerate(hand):
|
||||||
position = (
|
position = (
|
||||||
self.CARD_BORDER + (self.CARD_OFFSET*i),
|
self.CARD_BORDER + (self.CARD_OFFSET*i),
|
||||||
self.CARD_BORDER
|
self.CARD_BORDER
|
||||||
)
|
)
|
||||||
|
|
||||||
if i + hidden_cards < len(hand):
|
if i + hidden_cards < len(hand):
|
||||||
card_image = Image.open(f"{self.cards_path}{card.upper()}.png")
|
card_image = Image.open(f"{self.cards_path}{card.upper()}.png")
|
||||||
else:
|
else:
|
||||||
card_image = Image.open(f"{self.cards_path}red_back.png")
|
card_image = Image.open(f"{self.cards_path}red_back.png")
|
||||||
|
|
||||||
card_image = card_image.resize(
|
card_image = card_image.resize(
|
||||||
(self.CARD_WIDTH, self.CARD_HEIGHT),
|
(self.CARD_WIDTH, self.CARD_HEIGHT),
|
||||||
resample=Image.BILINEAR
|
resample=Image.BILINEAR
|
||||||
)
|
)
|
||||||
background.paste(card_image, position, card_image)
|
background.paste(card_image, position, card_image)
|
||||||
|
|
||||||
return background
|
return background
|
||||||
|
|||||||
@@ -3,8 +3,8 @@ Has a container for game functions.
|
|||||||
|
|
||||||
*Classes*
|
*Classes*
|
||||||
---------
|
---------
|
||||||
Games
|
Games
|
||||||
Container for game functions.
|
Container for game functions.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
@@ -17,30 +17,30 @@ from .wordle import WordleGame
|
|||||||
|
|
||||||
|
|
||||||
class Games():
|
class Games():
|
||||||
"""
|
"""
|
||||||
Contains game classes.
|
Contains game classes.
|
||||||
|
|
||||||
*Attributes*
|
*Attributes*
|
||||||
------------
|
------------
|
||||||
bot: Gwendolyn
|
bot: Gwendolyn
|
||||||
The instance of Gwendolyn.
|
The instance of Gwendolyn.
|
||||||
blackjack
|
blackjack
|
||||||
Contains blackjack functions.
|
Contains blackjack functions.
|
||||||
connect_four
|
connect_four
|
||||||
Contains connect four functions.
|
Contains connect four functions.
|
||||||
hangman
|
hangman
|
||||||
Contains hangman functions.
|
Contains hangman functions.
|
||||||
hex
|
hex
|
||||||
Contains hex functions
|
Contains hex functions
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, bot):
|
def __init__(self, bot):
|
||||||
"""Initialize the container."""
|
"""Initialize the container."""
|
||||||
self.bot = bot
|
self.bot = bot
|
||||||
|
|
||||||
self.trivia = Trivia(bot)
|
self.trivia = Trivia(bot)
|
||||||
self.blackjack = Blackjack(bot)
|
self.blackjack = Blackjack(bot)
|
||||||
self.connect_four = ConnectFour(bot)
|
self.connect_four = ConnectFour(bot)
|
||||||
self.hangman = Hangman(bot)
|
self.hangman = Hangman(bot)
|
||||||
self.hex = HexGame(bot)
|
self.hex = HexGame(bot)
|
||||||
self.wordle = WordleGame(bot)
|
self.wordle = WordleGame(bot)
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -3,149 +3,149 @@ Contains the code that deals with money.
|
|||||||
|
|
||||||
*Classes*
|
*Classes*
|
||||||
---------
|
---------
|
||||||
Money
|
Money
|
||||||
Deals with money.
|
Deals with money.
|
||||||
"""
|
"""
|
||||||
import interactions # Used for typehints
|
import interactions # Used for typehints
|
||||||
import discord # Used for typehints
|
import discord # Used for typehints
|
||||||
|
|
||||||
|
|
||||||
class Money():
|
class Money():
|
||||||
|
"""
|
||||||
|
Deals with money.
|
||||||
|
|
||||||
|
*Methods*
|
||||||
|
---------
|
||||||
|
checkBalance(user: str)
|
||||||
|
sendBalance(ctx: interactions.SlashContext)
|
||||||
|
addMoney(user: str, amount: int)
|
||||||
|
giveMoney(ctx: interactions.SlashContext, user: discord.User,
|
||||||
|
amount: int)
|
||||||
|
|
||||||
|
*Attributes*
|
||||||
|
------------
|
||||||
|
bot: Gwendolyn
|
||||||
|
The instance of Gwendolyn
|
||||||
|
database: pymongo.Client
|
||||||
|
The mongo database
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, bot):
|
||||||
|
"""Initialize the class."""
|
||||||
|
self.bot = bot
|
||||||
|
self.database = bot.database
|
||||||
|
|
||||||
|
def checkBalance(self, user: str):
|
||||||
"""
|
"""
|
||||||
Deals with money.
|
Get the account balance of a user.
|
||||||
|
|
||||||
*Methods*
|
*Parameters*
|
||||||
---------
|
|
||||||
checkBalance(user: str)
|
|
||||||
sendBalance(ctx: interactions.SlashContext)
|
|
||||||
addMoney(user: str, amount: int)
|
|
||||||
giveMoney(ctx: interactions.SlashContext, user: discord.User,
|
|
||||||
amount: int)
|
|
||||||
|
|
||||||
*Attributes*
|
|
||||||
------------
|
------------
|
||||||
bot: Gwendolyn
|
user: str
|
||||||
The instance of Gwendolyn
|
The user to get the balance of.
|
||||||
database: pymongo.Client
|
|
||||||
The mongo database
|
*Returns*
|
||||||
|
---------
|
||||||
|
balance: int
|
||||||
|
The balance of the user's account.
|
||||||
"""
|
"""
|
||||||
|
self.bot.log("checking "+user+"'s account balance")
|
||||||
|
|
||||||
def __init__(self, bot):
|
user_data = self.database["users"].find_one({"_id": user})
|
||||||
"""Initialize the class."""
|
|
||||||
self.bot = bot
|
|
||||||
self.database = bot.database
|
|
||||||
|
|
||||||
def checkBalance(self, user: str):
|
if user_data is not None:
|
||||||
"""
|
return user_data["money"]
|
||||||
Get the account balance of a user.
|
else:
|
||||||
|
return 0
|
||||||
|
|
||||||
*Parameters*
|
async def sendBalance(self, ctx: interactions.SlashContext):
|
||||||
------------
|
"""
|
||||||
user: str
|
Get your own account balance.
|
||||||
The user to get the balance of.
|
|
||||||
|
|
||||||
*Returns*
|
*Parameters*
|
||||||
---------
|
------------
|
||||||
balance: int
|
ctx: interactions.SlashContext
|
||||||
The balance of the user's account.
|
The context of the command.
|
||||||
"""
|
"""
|
||||||
self.bot.log("checking "+user+"'s account balance")
|
await self.bot.defer(ctx)
|
||||||
|
response = self.checkBalance("#"+str(ctx.author.id))
|
||||||
|
user_name = ctx.author.display_name
|
||||||
|
if response == 1:
|
||||||
|
new_message = f"{user_name} has {response} GwendoBuck"
|
||||||
|
else:
|
||||||
|
new_message = f"{user_name} has {response} GwendoBucks"
|
||||||
|
await ctx.send(new_message)
|
||||||
|
|
||||||
user_data = self.database["users"].find_one({"_id": user})
|
# Adds money to the account of a user
|
||||||
|
def addMoney(self, user: str, amount: int):
|
||||||
|
"""
|
||||||
|
Add money to a user account.
|
||||||
|
|
||||||
if user_data is not None:
|
*Parameters*
|
||||||
return user_data["money"]
|
------------
|
||||||
else:
|
user: str
|
||||||
return 0
|
The id of the user to give money.
|
||||||
|
amount: int
|
||||||
|
The amount to add to the user's account.
|
||||||
|
"""
|
||||||
|
self.bot.log("adding "+str(amount)+" to "+user+"'s account")
|
||||||
|
|
||||||
async def sendBalance(self, ctx: interactions.SlashContext):
|
user_data = self.database["users"].find_one({"_id": user})
|
||||||
"""
|
|
||||||
Get your own account balance.
|
|
||||||
|
|
||||||
*Parameters*
|
if user_data is not None:
|
||||||
------------
|
updater = {"$inc": {"money": amount}}
|
||||||
ctx: interactions.SlashContext
|
self.database["users"].update_one({"_id": user}, updater)
|
||||||
The context of the command.
|
else:
|
||||||
"""
|
new_user = {
|
||||||
await self.bot.defer(ctx)
|
"_id": user,
|
||||||
response = self.checkBalance("#"+str(ctx.author.id))
|
"user name": self.bot.database_funcs.get_name(user),
|
||||||
user_name = ctx.author.display_name
|
"money": amount
|
||||||
if response == 1:
|
}
|
||||||
new_message = f"{user_name} has {response} GwendoBuck"
|
self.database["users"].insert_one(new_user)
|
||||||
else:
|
|
||||||
new_message = f"{user_name} has {response} GwendoBucks"
|
|
||||||
await ctx.send(new_message)
|
|
||||||
|
|
||||||
# Adds money to the account of a user
|
# Transfers money from one user to another
|
||||||
def addMoney(self, user: str, amount: int):
|
async def giveMoney(self, ctx: interactions.SlashContext,
|
||||||
"""
|
user: discord.User, amount: int):
|
||||||
Add money to a user account.
|
"""
|
||||||
|
Give someone else money from your account.
|
||||||
|
|
||||||
*Parameters*
|
*Parameters*
|
||||||
------------
|
------------
|
||||||
user: str
|
ctx: interactions.SlashContext
|
||||||
The id of the user to give money.
|
The context of the command.
|
||||||
amount: int
|
user: discord.User
|
||||||
The amount to add to the user's account.
|
The user to give money.
|
||||||
"""
|
amount: int
|
||||||
self.bot.log("adding "+str(amount)+" to "+user+"'s account")
|
The amount to transfer.
|
||||||
|
"""
|
||||||
|
await self.bot.defer(ctx)
|
||||||
|
username = user.display_name
|
||||||
|
if self.bot.database_funcs.get_id(username) is None:
|
||||||
|
async for member in ctx.guild.fetch_members(limit=None):
|
||||||
|
if member.display_name.lower() == username.lower():
|
||||||
|
username = member.display_name
|
||||||
|
user_id = f"#{member.id}"
|
||||||
|
new_user = {
|
||||||
|
"_id": user_id,
|
||||||
|
"user name": username,
|
||||||
|
"money": 0
|
||||||
|
}
|
||||||
|
self.bot.database["users"].insert_one(new_user)
|
||||||
|
|
||||||
user_data = self.database["users"].find_one({"_id": user})
|
userid = f"#{ctx.author.id}"
|
||||||
|
user_data = self.database["users"].find_one({"_id": userid})
|
||||||
|
targetUser = self.bot.database_funcs.get_id(username)
|
||||||
|
|
||||||
if user_data is not None:
|
if amount <= 0:
|
||||||
updater = {"$inc": {"money": amount}}
|
self.bot.log("They tried to steal")
|
||||||
self.database["users"].update_one({"_id": user}, updater)
|
await ctx.send("Yeah, no. You can't do that")
|
||||||
else:
|
elif targetUser is None:
|
||||||
new_user = {
|
self.bot.log("They weren't in the system")
|
||||||
"_id": user,
|
await ctx.send("The target doesn't exist")
|
||||||
"user name": self.bot.database_funcs.get_name(user),
|
elif user_data is None or user_data["money"] < amount:
|
||||||
"money": amount
|
self.bot.log("They didn't have enough GwendoBucks")
|
||||||
}
|
await ctx.send("You don't have that many GwendoBuck")
|
||||||
self.database["users"].insert_one(new_user)
|
else:
|
||||||
|
self.addMoney(f"#{ctx.author.id}", -1 * amount)
|
||||||
# Transfers money from one user to another
|
self.addMoney(targetUser, amount)
|
||||||
async def giveMoney(self, ctx: interactions.SlashContext,
|
await ctx.send(f"Transferred {amount} GwendoBucks to {username}")
|
||||||
user: discord.User, amount: int):
|
|
||||||
"""
|
|
||||||
Give someone else money from your account.
|
|
||||||
|
|
||||||
*Parameters*
|
|
||||||
------------
|
|
||||||
ctx: interactions.SlashContext
|
|
||||||
The context of the command.
|
|
||||||
user: discord.User
|
|
||||||
The user to give money.
|
|
||||||
amount: int
|
|
||||||
The amount to transfer.
|
|
||||||
"""
|
|
||||||
await self.bot.defer(ctx)
|
|
||||||
username = user.display_name
|
|
||||||
if self.bot.database_funcs.get_id(username) is None:
|
|
||||||
async for member in ctx.guild.fetch_members(limit=None):
|
|
||||||
if member.display_name.lower() == username.lower():
|
|
||||||
username = member.display_name
|
|
||||||
user_id = f"#{member.id}"
|
|
||||||
new_user = {
|
|
||||||
"_id": user_id,
|
|
||||||
"user name": username,
|
|
||||||
"money": 0
|
|
||||||
}
|
|
||||||
self.bot.database["users"].insert_one(new_user)
|
|
||||||
|
|
||||||
userid = f"#{ctx.author.id}"
|
|
||||||
user_data = self.database["users"].find_one({"_id": userid})
|
|
||||||
targetUser = self.bot.database_funcs.get_id(username)
|
|
||||||
|
|
||||||
if amount <= 0:
|
|
||||||
self.bot.log("They tried to steal")
|
|
||||||
await ctx.send("Yeah, no. You can't do that")
|
|
||||||
elif targetUser is None:
|
|
||||||
self.bot.log("They weren't in the system")
|
|
||||||
await ctx.send("The target doesn't exist")
|
|
||||||
elif user_data is None or user_data["money"] < amount:
|
|
||||||
self.bot.log("They didn't have enough GwendoBucks")
|
|
||||||
await ctx.send("You don't have that many GwendoBuck")
|
|
||||||
else:
|
|
||||||
self.addMoney(f"#{ctx.author.id}", -1 * amount)
|
|
||||||
self.addMoney(targetUser, amount)
|
|
||||||
await ctx.send(f"Transferred {amount} GwendoBucks to {username}")
|
|
||||||
|
|||||||
@@ -3,8 +3,8 @@ Contains code for trivia games.
|
|||||||
|
|
||||||
*Classes*
|
*Classes*
|
||||||
---------
|
---------
|
||||||
Trivia
|
Trivia
|
||||||
Contains all the code for the trivia commands.
|
Contains all the code for the trivia commands.
|
||||||
"""
|
"""
|
||||||
import urllib # Used to get data from api
|
import urllib # Used to get data from api
|
||||||
import json # Used to read data from api
|
import json # Used to read data from api
|
||||||
@@ -15,191 +15,191 @@ from interactions import SlashContext # Used for type hints
|
|||||||
|
|
||||||
|
|
||||||
class Trivia():
|
class Trivia():
|
||||||
"""
|
"""
|
||||||
Contains the code for trivia games.
|
Contains the code for trivia games.
|
||||||
|
|
||||||
*Methods*
|
*Methods*
|
||||||
|
---------
|
||||||
|
triviaStart(channel: str) -> str, str, str
|
||||||
|
triviaAnswer(user: str, channel: str, command: str) -> str
|
||||||
|
triviaCountPoints(channel: str)
|
||||||
|
triviaParse(ctx: SlashContext, answer: str)
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, bot):
|
||||||
|
"""Initialize the class."""
|
||||||
|
self.bot = bot
|
||||||
|
|
||||||
|
def triviaStart(self, channel: str):
|
||||||
|
"""
|
||||||
|
Start a game of trivia.
|
||||||
|
|
||||||
|
Downloads a question with answers, shuffles the wrong answers
|
||||||
|
with the correct answer and returns the questions and answers.
|
||||||
|
Also saves the question in the database.
|
||||||
|
|
||||||
|
*Parameters*
|
||||||
|
------------
|
||||||
|
channel: str
|
||||||
|
The id of the channel to start the game in
|
||||||
|
|
||||||
|
*Returns*
|
||||||
---------
|
---------
|
||||||
triviaStart(channel: str) -> str, str, str
|
send_message: str
|
||||||
triviaAnswer(user: str, channel: str, command: str) -> str
|
The message to return to the user.
|
||||||
triviaCountPoints(channel: str)
|
|
||||||
triviaParse(ctx: SlashContext, answer: str)
|
|
||||||
"""
|
"""
|
||||||
|
triviaQuestions = self.bot.database["trivia questions"]
|
||||||
|
question = triviaQuestions.find_one({"_id": channel})
|
||||||
|
|
||||||
def __init__(self, bot):
|
self.bot.log(f"Trying to find a trivia question for {channel}")
|
||||||
"""Initialize the class."""
|
|
||||||
self.bot = bot
|
|
||||||
|
|
||||||
def triviaStart(self, channel: str):
|
if question is None:
|
||||||
"""
|
apiUrl = "https://opentdb.com/api.php?amount=10&type=multiple"
|
||||||
Start a game of trivia.
|
with urllib.request.urlopen(apiUrl) as response:
|
||||||
|
data = json.loads(response.read())
|
||||||
|
|
||||||
Downloads a question with answers, shuffles the wrong answers
|
question = data["results"][0]["question"]
|
||||||
with the correct answer and returns the questions and answers.
|
self.bot.log(f"Found the question \"{question}\"")
|
||||||
Also saves the question in the database.
|
answers = data["results"][0]["incorrect_answers"]
|
||||||
|
answers.append(data["results"][0]["correct_answer"])
|
||||||
|
random.shuffle(answers)
|
||||||
|
correctAnswer = data["results"][0]["correct_answer"]
|
||||||
|
correctAnswer = answers.index(correctAnswer) + 97
|
||||||
|
|
||||||
*Parameters*
|
newQuestion = {
|
||||||
------------
|
"_id": channel,
|
||||||
channel: str
|
"answer": str(chr(correctAnswer)),
|
||||||
The id of the channel to start the game in
|
"players": {}
|
||||||
|
}
|
||||||
|
triviaQuestions.insert_one(newQuestion)
|
||||||
|
|
||||||
*Returns*
|
replacements = {
|
||||||
---------
|
"'": "\'",
|
||||||
send_message: str
|
""": "\"",
|
||||||
The message to return to the user.
|
"“": "\"",
|
||||||
"""
|
"”": "\"",
|
||||||
triviaQuestions = self.bot.database["trivia questions"]
|
"é": "é"
|
||||||
question = triviaQuestions.find_one({"_id": channel})
|
}
|
||||||
|
question = data["results"][0]["question"]
|
||||||
|
|
||||||
self.bot.log(f"Trying to find a trivia question for {channel}")
|
for key, value in replacements.items():
|
||||||
|
question = question.replace(key, value)
|
||||||
|
|
||||||
if question is None:
|
for answer in answers:
|
||||||
apiUrl = "https://opentdb.com/api.php?amount=10&type=multiple"
|
for key, value in replacements.items():
|
||||||
with urllib.request.urlopen(apiUrl) as response:
|
answer = answer.replace(key, value)
|
||||||
data = json.loads(response.read())
|
|
||||||
|
|
||||||
question = data["results"][0]["question"]
|
return question, answers, correctAnswer
|
||||||
self.bot.log(f"Found the question \"{question}\"")
|
else:
|
||||||
answers = data["results"][0]["incorrect_answers"]
|
log_message = "There was already a trivia question for that channel"
|
||||||
answers.append(data["results"][0]["correct_answer"])
|
self.bot.log(log_message)
|
||||||
random.shuffle(answers)
|
return self.bot.long_strings["Trivia going on"], "", ""
|
||||||
correctAnswer = data["results"][0]["correct_answer"]
|
|
||||||
correctAnswer = answers.index(correctAnswer) + 97
|
|
||||||
|
|
||||||
newQuestion = {
|
def triviaAnswer(self, user: str, channel: str, command: str):
|
||||||
"_id": channel,
|
"""
|
||||||
"answer": str(chr(correctAnswer)),
|
Answer the current trivia question.
|
||||||
"players": {}
|
|
||||||
}
|
|
||||||
triviaQuestions.insert_one(newQuestion)
|
|
||||||
|
|
||||||
replacements = {
|
*Parameters*
|
||||||
"'": "\'",
|
------------
|
||||||
""": "\"",
|
user: str
|
||||||
"“": "\"",
|
The id of the user who answered.
|
||||||
"”": "\"",
|
channel: str
|
||||||
"é": "é"
|
The id of the channel the game is in.
|
||||||
}
|
command: str
|
||||||
question = data["results"][0]["question"]
|
The user's answer.
|
||||||
|
|
||||||
for key, value in replacements.items():
|
*Returns*
|
||||||
question = question.replace(key, value)
|
---------
|
||||||
|
send_message: str
|
||||||
|
The message to send if the function failed.
|
||||||
|
"""
|
||||||
|
triviaQuestions = self.bot.database["trivia questions"]
|
||||||
|
question = triviaQuestions.find_one({"_id": channel})
|
||||||
|
|
||||||
for answer in answers:
|
if command not in ["a", "b", "c", "d"]:
|
||||||
for key, value in replacements.items():
|
self.bot.log("I didn't quite understand that")
|
||||||
answer = answer.replace(key, value)
|
return "I didn't quite understand that"
|
||||||
|
elif question is None:
|
||||||
|
self.bot.log("There's no question right now")
|
||||||
|
return "There's no question right now"
|
||||||
|
elif user in question["players"]:
|
||||||
|
self.bot.log(f"{user} has already answered this question")
|
||||||
|
return f"{user} has already answered this question"
|
||||||
|
else:
|
||||||
|
self.bot.log(f"{user} answered the question in {channel}")
|
||||||
|
|
||||||
return question, answers, correctAnswer
|
updater = {"$set": {f"players.{user}": command}}
|
||||||
else:
|
triviaQuestions.update_one({"_id": channel}, updater)
|
||||||
log_message = "There was already a trivia question for that channel"
|
return None
|
||||||
self.bot.log(log_message)
|
|
||||||
return self.bot.long_strings["Trivia going on"], "", ""
|
|
||||||
|
|
||||||
def triviaAnswer(self, user: str, channel: str, command: str):
|
def triviaCountPoints(self, channel: str):
|
||||||
"""
|
"""
|
||||||
Answer the current trivia question.
|
Add money to every winner's account.
|
||||||
|
|
||||||
*Parameters*
|
*Parameters*
|
||||||
------------
|
------------
|
||||||
user: str
|
channel: str
|
||||||
The id of the user who answered.
|
The id of the channel the game is in.
|
||||||
channel: str
|
"""
|
||||||
The id of the channel the game is in.
|
triviaQuestions = self.bot.database["trivia questions"]
|
||||||
command: str
|
question = triviaQuestions.find_one({"_id": channel})
|
||||||
The user's answer.
|
|
||||||
|
|
||||||
*Returns*
|
self.bot.log("Counting points for question in "+channel)
|
||||||
---------
|
|
||||||
send_message: str
|
|
||||||
The message to send if the function failed.
|
|
||||||
"""
|
|
||||||
triviaQuestions = self.bot.database["trivia questions"]
|
|
||||||
question = triviaQuestions.find_one({"_id": channel})
|
|
||||||
|
|
||||||
if command not in ["a", "b", "c", "d"]:
|
if question is not None:
|
||||||
self.bot.log("I didn't quite understand that")
|
for player, answer in question["players"].items():
|
||||||
return "I didn't quite understand that"
|
if answer == question["answer"]:
|
||||||
elif question is None:
|
self.bot.money.addMoney(player, 1)
|
||||||
self.bot.log("There's no question right now")
|
else:
|
||||||
return "There's no question right now"
|
self.bot.log("Couldn't find the questio")
|
||||||
elif user in question["players"]:
|
|
||||||
self.bot.log(f"{user} has already answered this question")
|
|
||||||
return f"{user} has already answered this question"
|
|
||||||
else:
|
|
||||||
self.bot.log(f"{user} answered the question in {channel}")
|
|
||||||
|
|
||||||
updater = {"$set": {f"players.{user}": command}}
|
return None
|
||||||
triviaQuestions.update_one({"_id": channel}, updater)
|
|
||||||
return None
|
|
||||||
|
|
||||||
def triviaCountPoints(self, channel: str):
|
async def triviaParse(self, ctx: SlashContext, answer: str):
|
||||||
"""
|
"""
|
||||||
Add money to every winner's account.
|
Parse a trivia command.
|
||||||
|
|
||||||
*Parameters*
|
*Parameters*
|
||||||
------------
|
------------
|
||||||
channel: str
|
ctx: SlashContext
|
||||||
The id of the channel the game is in.
|
The context of the command.
|
||||||
"""
|
answer: str
|
||||||
triviaQuestions = self.bot.database["trivia questions"]
|
The answer, if any.
|
||||||
question = triviaQuestions.find_one({"_id": channel})
|
"""
|
||||||
|
await self.bot.defer(ctx)
|
||||||
|
channelId = str(ctx.channel_id)
|
||||||
|
if answer == "":
|
||||||
|
question, options, correctAnswer = self.triviaStart(channelId)
|
||||||
|
if options != "":
|
||||||
|
results = "**"+question+"**\n"
|
||||||
|
for x, option in enumerate(options):
|
||||||
|
results += chr(x+97) + ") "+option+"\n"
|
||||||
|
|
||||||
self.bot.log("Counting points for question in "+channel)
|
await ctx.send(results)
|
||||||
|
|
||||||
if question is not None:
|
await asyncio.sleep(60)
|
||||||
for player, answer in question["players"].items():
|
|
||||||
if answer == question["answer"]:
|
|
||||||
self.bot.money.addMoney(player, 1)
|
|
||||||
else:
|
|
||||||
self.bot.log("Couldn't find the questio")
|
|
||||||
|
|
||||||
return None
|
self.triviaCountPoints(channelId)
|
||||||
|
|
||||||
async def triviaParse(self, ctx: SlashContext, answer: str):
|
delete_gameParams = ["trivia questions", channelId]
|
||||||
"""
|
self.bot.database_funcs.delete_game(*delete_gameParams)
|
||||||
Parse a trivia command.
|
|
||||||
|
|
||||||
*Parameters*
|
self.bot.log("Time's up for the trivia question", channelId)
|
||||||
------------
|
send_message = self.bot.long_strings["Trivia time up"]
|
||||||
ctx: SlashContext
|
format_parameters = [chr(correctAnswer), options[correctAnswer-97]]
|
||||||
The context of the command.
|
send_message = send_message.format(*format_parameters)
|
||||||
answer: str
|
await ctx.send(send_message)
|
||||||
The answer, if any.
|
else:
|
||||||
"""
|
await ctx.send(question, hidden=True)
|
||||||
await self.bot.defer(ctx)
|
|
||||||
channelId = str(ctx.channel_id)
|
|
||||||
if answer == "":
|
|
||||||
question, options, correctAnswer = self.triviaStart(channelId)
|
|
||||||
if options != "":
|
|
||||||
results = "**"+question+"**\n"
|
|
||||||
for x, option in enumerate(options):
|
|
||||||
results += chr(x+97) + ") "+option+"\n"
|
|
||||||
|
|
||||||
await ctx.send(results)
|
elif answer in ["a", "b", "c", "d"]:
|
||||||
|
userId = f"#{ctx.author.id}"
|
||||||
await asyncio.sleep(60)
|
response = self.triviaAnswer(userId, channelId, answer)
|
||||||
|
if response is None:
|
||||||
self.triviaCountPoints(channelId)
|
user_name = ctx.author.display_name
|
||||||
|
await ctx.send(f"{user_name} answered **{answer}**")
|
||||||
delete_gameParams = ["trivia questions", channelId]
|
else:
|
||||||
self.bot.database_funcs.delete_game(*delete_gameParams)
|
await ctx.send(response)
|
||||||
|
else:
|
||||||
self.bot.log("Time's up for the trivia question", channelId)
|
self.bot.log("I didn't understand that", channelId)
|
||||||
send_message = self.bot.long_strings["Trivia time up"]
|
await ctx.send("I didn't understand that")
|
||||||
format_parameters = [chr(correctAnswer), options[correctAnswer-97]]
|
|
||||||
send_message = send_message.format(*format_parameters)
|
|
||||||
await ctx.send(send_message)
|
|
||||||
else:
|
|
||||||
await ctx.send(question, hidden=True)
|
|
||||||
|
|
||||||
elif answer in ["a", "b", "c", "d"]:
|
|
||||||
userId = f"#{ctx.author.id}"
|
|
||||||
response = self.triviaAnswer(userId, channelId, answer)
|
|
||||||
if response is None:
|
|
||||||
user_name = ctx.author.display_name
|
|
||||||
await ctx.send(f"{user_name} answered **{answer}**")
|
|
||||||
else:
|
|
||||||
await ctx.send(response)
|
|
||||||
else:
|
|
||||||
self.bot.log("I didn't understand that", channelId)
|
|
||||||
await ctx.send("I didn't understand that")
|
|
||||||
|
|||||||
@@ -25,177 +25,177 @@ PRESENT_COLOR = "#0f7aa8"
|
|||||||
COLORS = [INCORRECT_COLOR, PRESENT_COLOR, CORRECT_COLOR]
|
COLORS = [INCORRECT_COLOR, PRESENT_COLOR, CORRECT_COLOR]
|
||||||
|
|
||||||
class WordleGame(DatabaseGame):
|
class WordleGame(DatabaseGame):
|
||||||
"""Implementation of wordle game."""
|
"""Implementation of wordle game."""
|
||||||
def __init__(self, bot):
|
def __init__(self, bot):
|
||||||
super().__init__(bot, "wordle", WordleDrawer)
|
super().__init__(bot, "wordle", WordleDrawer)
|
||||||
self._API_url = "https://api.wordnik.com/v4/words.json/randomWords?" # pylint: disable=invalid-name
|
self._API_url = "https://api.wordnik.com/v4/words.json/randomWords?" # pylint: disable=invalid-name
|
||||||
api_key = self.bot.credentials["wordnik_key"]
|
api_key = self.bot.credentials["wordnik_key"]
|
||||||
self._APIPARAMS = { # pylint: disable=invalid-name
|
self._APIPARAMS = { # pylint: disable=invalid-name
|
||||||
"hasDictionaryDef": True,
|
"hasDictionaryDef": True,
|
||||||
"minCorpusCount": 5000,
|
"minCorpusCount": 5000,
|
||||||
"maxCorpusCount": -1,
|
"maxCorpusCount": -1,
|
||||||
"minDictionaryCount": 1,
|
"minDictionaryCount": 1,
|
||||||
"maxDictionaryCount": -1,
|
"maxDictionaryCount": -1,
|
||||||
"limit": 1,
|
"limit": 1,
|
||||||
"api_key": api_key
|
"api_key": api_key
|
||||||
}
|
}
|
||||||
|
|
||||||
async def start(self, ctx, letters: int):
|
async def start(self, ctx, letters: int):
|
||||||
if self._test_document(str(ctx.channel_id)):
|
if self._test_document(str(ctx.channel_id)):
|
||||||
await ctx.send("There is already a wordle game in this channel.")
|
await ctx.send("There is already a wordle game in this channel.")
|
||||||
self.bot.log("There was already a game going on")
|
self.bot.log("There was already a game going on")
|
||||||
return
|
return
|
||||||
|
|
||||||
params = self._APIPARAMS
|
params = self._APIPARAMS
|
||||||
params["minLength"] = letters
|
params["minLength"] = letters
|
||||||
params["maxLength"] = letters
|
params["maxLength"] = letters
|
||||||
word = "-"
|
word = "-"
|
||||||
while "-" in word or "." in word:
|
while "-" in word or "." in word:
|
||||||
response = requests.get(self._API_url, params=params)
|
response = requests.get(self._API_url, params=params)
|
||||||
if response.json() == []:
|
if response.json() == []:
|
||||||
ctx.send("Could not find a word. Try again")
|
ctx.send("Could not find a word. Try again")
|
||||||
return
|
return
|
||||||
word = list(response.json()[0]["word"].upper())
|
word = list(response.json()[0]["word"].upper())
|
||||||
|
|
||||||
self.bot.log(f"Found the word \"{''.join(word)}\"")
|
self.bot.log(f"Found the word \"{''.join(word)}\"")
|
||||||
game = {"word": word, "guesses": [], "results": []}
|
game = {"word": word, "guesses": [], "results": []}
|
||||||
await ctx.send("Starting a wordle game.")
|
await ctx.send("Starting a wordle game.")
|
||||||
await self._start_new(ctx.channel, game, delete=False)
|
await self._start_new(ctx.channel, game, delete=False)
|
||||||
|
|
||||||
def _get_result(self, guess: list[str], word: list[str]):
|
def _get_result(self, guess: list[str], word: list[str]):
|
||||||
result = ["_" for _ in guess]
|
result = ["_" for _ in guess]
|
||||||
for i, letter in enumerate(guess):
|
for i, letter in enumerate(guess):
|
||||||
if letter == word[i]:
|
if letter == word[i]:
|
||||||
result[i] = "*"
|
result[i] = "*"
|
||||||
|
|
||||||
for i, letter in enumerate(guess):
|
for i, letter in enumerate(guess):
|
||||||
if letter in word and result[i] != "*":
|
if letter in word and result[i] != "*":
|
||||||
same_letter = guess[:i].count(letter)
|
same_letter = guess[:i].count(letter)
|
||||||
same_letter += len(
|
same_letter += len(
|
||||||
[
|
[
|
||||||
l for j,l in
|
l for j,l in
|
||||||
enumerate(guess[i:])
|
enumerate(guess[i:])
|
||||||
if guess[i:][j] == letter and result[i:][j] == "*"
|
if guess[i:][j] == letter and result[i:][j] == "*"
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
if same_letter < word.count(letter):
|
if same_letter < word.count(letter):
|
||||||
result[i] = "-"
|
result[i] = "-"
|
||||||
|
|
||||||
return result
|
return result
|
||||||
|
|
||||||
async def guess(self, ctx, guess: str):
|
async def guess(self, ctx, guess: str):
|
||||||
if not guess.isalpha():
|
if not guess.isalpha():
|
||||||
await ctx.send("You can only use letters in your guess")
|
await ctx.send("You can only use letters in your guess")
|
||||||
return
|
return
|
||||||
|
|
||||||
guess = list(guess.upper())
|
guess = list(guess.upper())
|
||||||
try:
|
try:
|
||||||
game = self.access_document(str(ctx.channel_id))
|
game = self.access_document(str(ctx.channel_id))
|
||||||
except GameNotInDatabase:
|
except GameNotInDatabase:
|
||||||
await ctx.send("No game in channel")
|
await ctx.send("No game in channel")
|
||||||
return
|
return
|
||||||
|
|
||||||
if len(guess) != len(game['word']):
|
if len(guess) != len(game['word']):
|
||||||
await ctx.send(
|
await ctx.send(
|
||||||
f"Your guess must be {len(game['word'])} letters long")
|
f"Your guess must be {len(game['word'])} letters long")
|
||||||
return
|
return
|
||||||
|
|
||||||
await ctx.send(f"Guessed {''.join(guess)}")
|
await ctx.send(f"Guessed {''.join(guess)}")
|
||||||
result = self._get_result(guess, game['word'])
|
result = self._get_result(guess, game['word'])
|
||||||
|
|
||||||
updater = {
|
updater = {
|
||||||
"$set": {
|
"$set": {
|
||||||
f"guesses.{len(game['guesses'])}": guess,
|
f"guesses.{len(game['guesses'])}": guess,
|
||||||
f"results.{len(game['guesses'])}": result
|
f"results.{len(game['guesses'])}": result
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
self._update_document(str(ctx.channel_id), updater)
|
self._update_document(str(ctx.channel_id), updater)
|
||||||
|
|
||||||
if result == ["*" for _ in game['word']]:
|
if result == ["*" for _ in game['word']]:
|
||||||
await ctx.send("You guessed the word! Adding 15 GwendoBucks to your account")
|
await ctx.send("You guessed the word! Adding 15 GwendoBucks to your account")
|
||||||
self.bot.money.addMoney(f"#{ctx.author_id}", 15)
|
self.bot.money.addMoney(f"#{ctx.author_id}", 15)
|
||||||
await self._end_game(ctx.channel)
|
await self._end_game(ctx.channel)
|
||||||
elif len(game['guesses']) == 5:
|
elif len(game['guesses']) == 5:
|
||||||
await ctx.send(f"You used up all available guesses. The word was '{''.join(game['word'])}'")
|
await ctx.send(f"You used up all available guesses. The word was '{''.join(game['word'])}'")
|
||||||
await self._end_game(ctx.channel)
|
await self._end_game(ctx.channel)
|
||||||
else:
|
else:
|
||||||
print(len(game['guesses']))
|
print(len(game['guesses']))
|
||||||
await self._delete_old_image(ctx.channel)
|
await self._delete_old_image(ctx.channel)
|
||||||
await self._send_image(ctx.channel, delete=False)
|
await self._send_image(ctx.channel, delete=False)
|
||||||
|
|
||||||
class WordleDrawer(BaseDrawer):
|
class WordleDrawer(BaseDrawer):
|
||||||
def __init__(self, bot, game: WordleGame):
|
def __init__(self, bot, game: WordleGame):
|
||||||
super().__init__(bot, game)
|
super().__init__(bot, game)
|
||||||
self.default_image = None
|
self.default_image = None
|
||||||
self.default_color = BACKGROUND_COLOR
|
self.default_color = BACKGROUND_COLOR
|
||||||
self.default_size = (0, 0)
|
self.default_size = (0, 0)
|
||||||
|
|
||||||
def _get_size(self, game: dict):
|
def _get_size(self, game: dict):
|
||||||
width = (
|
width = (
|
||||||
(len(game['word']) * SQUARE_SIZE) +
|
(len(game['word']) * SQUARE_SIZE) +
|
||||||
((len(game['word']) - 1) * SQUARE_PADDING) +
|
((len(game['word']) - 1) * SQUARE_PADDING) +
|
||||||
(2 * IMAGE_MARGIN)
|
(2 * IMAGE_MARGIN)
|
||||||
)
|
)
|
||||||
height = (
|
height = (
|
||||||
(6 * SQUARE_SIZE) +
|
(6 * SQUARE_SIZE) +
|
||||||
(5 * ROW_PADDING) +
|
(5 * ROW_PADDING) +
|
||||||
(2 * IMAGE_MARGIN)
|
(2 * IMAGE_MARGIN)
|
||||||
)
|
)
|
||||||
size = (width, height)
|
size = (width, height)
|
||||||
|
|
||||||
return size
|
return size
|
||||||
|
|
||||||
def _draw_row(self, row, drawer, font, word: str, colors: list[str] = None,
|
def _draw_row(self, row, drawer, font, word: str, colors: list[str] = None,
|
||||||
border_color: str = None):
|
border_color: str = None):
|
||||||
if colors is None:
|
if colors is None:
|
||||||
colors = [BACKGROUND_COLOR for _ in range(len(word))]
|
colors = [BACKGROUND_COLOR for _ in range(len(word))]
|
||||||
|
|
||||||
for i, letter in enumerate(word):
|
for i, letter in enumerate(word):
|
||||||
y_pos = IMAGE_MARGIN + (row * (SQUARE_SIZE + ROW_PADDING))
|
y_pos = IMAGE_MARGIN + (row * (SQUARE_SIZE + ROW_PADDING))
|
||||||
x_pos = IMAGE_MARGIN + (i * (SQUARE_SIZE + SQUARE_PADDING))
|
x_pos = IMAGE_MARGIN + (i * (SQUARE_SIZE + SQUARE_PADDING))
|
||||||
top_left = (x_pos, y_pos)
|
top_left = (x_pos, y_pos)
|
||||||
bottom_right = (x_pos + SQUARE_SIZE, y_pos + SQUARE_SIZE)
|
bottom_right = (x_pos + SQUARE_SIZE, y_pos + SQUARE_SIZE)
|
||||||
|
|
||||||
drawer.rounded_rectangle(
|
drawer.rounded_rectangle(
|
||||||
(top_left,bottom_right),
|
(top_left,bottom_right),
|
||||||
10,
|
10,
|
||||||
colors[i],
|
colors[i],
|
||||||
border_color,
|
border_color,
|
||||||
3
|
3
|
||||||
)
|
)
|
||||||
|
|
||||||
text_pos = (
|
text_pos = (
|
||||||
x_pos + (SQUARE_SIZE//2),
|
x_pos + (SQUARE_SIZE//2),
|
||||||
y_pos + int(SQUARE_SIZE * 0.6)
|
y_pos + int(SQUARE_SIZE * 0.6)
|
||||||
)
|
)
|
||||||
|
|
||||||
drawer.text(text_pos, letter, TEXT_COLOR, font=font, anchor="mm")
|
drawer.text(text_pos, letter, TEXT_COLOR, font=font, anchor="mm")
|
||||||
|
|
||||||
def _determine_colors(self, results):
|
def _determine_colors(self, results):
|
||||||
return [COLORS[["_","-","*"].index(symbol)] for symbol in results]
|
return [COLORS[["_","-","*"].index(symbol)] for symbol in results]
|
||||||
|
|
||||||
def _draw_image(self, game: dict, image: Image.Image):
|
def _draw_image(self, game: dict, image: Image.Image):
|
||||||
drawer = ImageDraw.Draw(image)
|
drawer = ImageDraw.Draw(image)
|
||||||
font = self._get_font(FONT_SIZE)
|
font = self._get_font(FONT_SIZE)
|
||||||
for i, guess in enumerate(game['guesses']):
|
for i, guess in enumerate(game['guesses']):
|
||||||
colors = self._determine_colors(game['results'][i])
|
colors = self._determine_colors(game['results'][i])
|
||||||
self._draw_row(i, drawer, font, guess, colors)
|
self._draw_row(i, drawer, font, guess, colors)
|
||||||
|
|
||||||
if len(game["guesses"]) < 6:
|
if len(game["guesses"]) < 6:
|
||||||
self._draw_row(
|
self._draw_row(
|
||||||
len(game['guesses']),
|
len(game['guesses']),
|
||||||
drawer,
|
drawer,
|
||||||
font,
|
font,
|
||||||
" "*len(game['word']),
|
" "*len(game['word']),
|
||||||
border_color=WRITING_BORDER_COLOR
|
border_color=WRITING_BORDER_COLOR
|
||||||
)
|
)
|
||||||
|
|
||||||
for i in range(5 - len(game['guesses'])):
|
for i in range(5 - len(game['guesses'])):
|
||||||
self._draw_row(
|
self._draw_row(
|
||||||
len(game['guesses']) + i + 1,
|
len(game['guesses']) + i + 1,
|
||||||
drawer,
|
drawer,
|
||||||
font, " "*len(game['word']),
|
font, " "*len(game['word']),
|
||||||
border_color=INACTIVE_BORDER_COLOR
|
border_color=INACTIVE_BORDER_COLOR
|
||||||
)
|
)
|
||||||
|
|
||||||
return super()._draw_image(game, image)
|
return super()._draw_image(game, image)
|
||||||
|
|||||||
@@ -5,217 +5,217 @@ import discord
|
|||||||
from gwendolyn_old.utils import cap
|
from gwendolyn_old.utils import cap
|
||||||
|
|
||||||
STATS = [
|
STATS = [
|
||||||
"strength",
|
"strength",
|
||||||
"dexterity",
|
"dexterity",
|
||||||
"constitution",
|
"constitution",
|
||||||
"intelligence",
|
"intelligence",
|
||||||
"wisdom",
|
"wisdom",
|
||||||
"charisma"
|
"charisma"
|
||||||
]
|
]
|
||||||
|
|
||||||
def mod(statistic):
|
def mod(statistic):
|
||||||
"""Calculates D&D modifier."""
|
"""Calculates D&D modifier."""
|
||||||
modifier = math.floor((statistic-10)/2)
|
modifier = math.floor((statistic-10)/2)
|
||||||
if modifier >= 0:
|
if modifier >= 0:
|
||||||
modifier = "+"+str(modifier)
|
modifier = "+"+str(modifier)
|
||||||
|
|
||||||
return modifier
|
return modifier
|
||||||
|
|
||||||
class LookupFuncs():
|
class LookupFuncs():
|
||||||
def __init__(self, bot):
|
def __init__(self, bot):
|
||||||
self.bot = bot
|
self.bot = bot
|
||||||
self.saves = [
|
self.saves = [
|
||||||
"strength_save",
|
"strength_save",
|
||||||
"dexterity_save",
|
"dexterity_save",
|
||||||
"constitution_save",
|
"constitution_save",
|
||||||
"intelligence_save",
|
"intelligence_save",
|
||||||
"wisdom_save",
|
"wisdom_save",
|
||||||
"charisma_save"
|
"charisma_save"
|
||||||
]
|
]
|
||||||
self.abilities = [
|
self.abilities = [
|
||||||
"acrobatics",
|
"acrobatics",
|
||||||
"animal_handling",
|
"animal_handling",
|
||||||
"arcana",
|
"arcana",
|
||||||
"athletics",
|
"athletics",
|
||||||
"deception",
|
"deception",
|
||||||
"history",
|
"history",
|
||||||
"insight",
|
"insight",
|
||||||
"intimidation",
|
"intimidation",
|
||||||
"investigation",
|
"investigation",
|
||||||
"medicine",
|
"medicine",
|
||||||
"nature",
|
"nature",
|
||||||
"perception",
|
"perception",
|
||||||
"performance",
|
"performance",
|
||||||
"persuasion",
|
"persuasion",
|
||||||
"religion",
|
"religion",
|
||||||
"sleight_of_hand",
|
"sleight_of_hand",
|
||||||
"stealth",
|
"stealth",
|
||||||
"survival"
|
"survival"
|
||||||
]
|
]
|
||||||
|
|
||||||
def _format_monster(self, monster):
|
def _format_monster(self, monster):
|
||||||
# Looks at the information about the monster and
|
# Looks at the information about the monster and
|
||||||
# returns that information in separate variables,
|
# returns that information in separate variables,
|
||||||
# allowing Gwendolyn to know where to separate
|
# allowing Gwendolyn to know where to separate
|
||||||
# the messages
|
# the messages
|
||||||
types = monster["type"]
|
types = monster["type"]
|
||||||
if monster["subtype"] != "":
|
if monster["subtype"] != "":
|
||||||
types += " ("+monster["subtype"]+")"
|
types += " ("+monster["subtype"]+")"
|
||||||
|
|
||||||
stats = []
|
stats = []
|
||||||
for stat in STATS:
|
for stat in STATS:
|
||||||
value = monster[stat]
|
value = monster[stat]
|
||||||
stats.append(f"**{cap(stat[:3])}:** {value} ({mod(value)})")
|
stats.append(f"**{cap(stat[:3])}:** {value} ({mod(value)})")
|
||||||
|
|
||||||
stats = "\t".join(stats[:3]) + "\n" + "\t".join(stats[3:])
|
stats = "\t".join(stats[:3]) + "\n" + "\t".join(stats[3:])
|
||||||
|
|
||||||
saving_throws = []
|
saving_throws = []
|
||||||
for save in self.saves:
|
for save in self.saves:
|
||||||
if save in monster:
|
if save in monster:
|
||||||
value = monster[save]
|
value = monster[save]
|
||||||
if monster[save] >= 0:
|
if monster[save] >= 0:
|
||||||
saving_throws.append(f"{cap(save[:3])} +{value}")
|
saving_throws.append(f"{cap(save[:3])} +{value}")
|
||||||
else:
|
|
||||||
saving_throws.append(f"{cap(save[:3])} {value}")
|
|
||||||
|
|
||||||
if saving_throws:
|
|
||||||
saving_throws = f"\n**Saving Throws:** {', '.join(saving_throws)}"
|
|
||||||
else:
|
else:
|
||||||
saving_throws = ""
|
saving_throws.append(f"{cap(save[:3])} {value}")
|
||||||
|
|
||||||
skills = []
|
if saving_throws:
|
||||||
for skill in self.abilities:
|
saving_throws = f"\n**Saving Throws:** {', '.join(saving_throws)}"
|
||||||
if skill in monster:
|
else:
|
||||||
skill_name = cap(skill.replace("_"," "))
|
saving_throws = ""
|
||||||
if monster[skill] >= 0:
|
|
||||||
skills.append(f"{skill_name} +{monster[skill]}")
|
|
||||||
else:
|
|
||||||
skills.append(f"{skill_name} {monster[skill]}")
|
|
||||||
|
|
||||||
if skills:
|
skills = []
|
||||||
skills = f"\n**Skills:** {', '.join(skills)}"
|
for skill in self.abilities:
|
||||||
|
if skill in monster:
|
||||||
|
skill_name = cap(skill.replace("_"," "))
|
||||||
|
if monster[skill] >= 0:
|
||||||
|
skills.append(f"{skill_name} +{monster[skill]}")
|
||||||
else:
|
else:
|
||||||
skills = ""
|
skills.append(f"{skill_name} {monster[skill]}")
|
||||||
|
|
||||||
vulnerabilities = monster["damage_vulnerabilities"]
|
if skills:
|
||||||
if vulnerabilities != "":
|
skills = f"\n**Skills:** {', '.join(skills)}"
|
||||||
vulnerabilities = "\n**Damage Vulnerabilities** "+vulnerabilities
|
else:
|
||||||
|
skills = ""
|
||||||
|
|
||||||
resistances = monster["damage_resistances"]
|
vulnerabilities = monster["damage_vulnerabilities"]
|
||||||
if resistances != "":
|
if vulnerabilities != "":
|
||||||
resistances = "\n**Damage Resistances** "+resistances
|
vulnerabilities = "\n**Damage Vulnerabilities** "+vulnerabilities
|
||||||
|
|
||||||
immunities = monster["damage_immunities"]
|
resistances = monster["damage_resistances"]
|
||||||
if immunities != "":
|
if resistances != "":
|
||||||
immunities = "\n**Damage Immunities** "+immunities
|
resistances = "\n**Damage Resistances** "+resistances
|
||||||
|
|
||||||
c_immunities = monster["condition_immunities"]
|
immunities = monster["damage_immunities"]
|
||||||
if c_immunities != "":
|
if immunities != "":
|
||||||
c_immunities = "\n**Condition Immunities** "+c_immunities
|
immunities = "\n**Damage Immunities** "+immunities
|
||||||
|
|
||||||
special_abilities = ""
|
c_immunities = monster["condition_immunities"]
|
||||||
if "special_abilities" in monster:
|
if c_immunities != "":
|
||||||
for ability in monster["special_abilities"]:
|
c_immunities = "\n**Condition Immunities** "+c_immunities
|
||||||
special_abilities += "\n\n***"+ability["name"]+".*** "+ability["desc"]
|
|
||||||
|
|
||||||
act = ""
|
special_abilities = ""
|
||||||
if "actions" in monster:
|
if "special_abilities" in monster:
|
||||||
for action in monster["actions"]:
|
for ability in monster["special_abilities"]:
|
||||||
act += "\n\n***"+action["name"]+".*** "+action["desc"]
|
special_abilities += "\n\n***"+ability["name"]+".*** "+ability["desc"]
|
||||||
|
|
||||||
react = ""
|
act = ""
|
||||||
if "reactions" in monster:
|
if "actions" in monster:
|
||||||
for reaction in monster["reactions"]:
|
for action in monster["actions"]:
|
||||||
react += "\n\n***"+reaction["name"]+".*** "+reaction["desc"]
|
act += "\n\n***"+action["name"]+".*** "+action["desc"]
|
||||||
|
|
||||||
legendaryActions = ""
|
react = ""
|
||||||
if "legendary_actions" in monster:
|
if "reactions" in monster:
|
||||||
for action in monster["legendary_actions"]:
|
for reaction in monster["reactions"]:
|
||||||
legendaryActions += "\n\n***"+action["name"]+".*** "+action["desc"]
|
react += "\n\n***"+reaction["name"]+".*** "+reaction["desc"]
|
||||||
|
|
||||||
hit_dice = monster["hit_dice"]
|
legendaryActions = ""
|
||||||
dice_amount = int(monster["hit_dice"].replace("d"," ").split()[0])
|
if "legendary_actions" in monster:
|
||||||
con_mod = math.floor((monster['constitution']-10)/2)
|
for action in monster["legendary_actions"]:
|
||||||
if con_mod < 0:
|
legendaryActions += "\n\n***"+action["name"]+".*** "+action["desc"]
|
||||||
hit_dice += f" - {abs(con_mod) * dice_amount}"
|
|
||||||
elif con_mod > 0:
|
|
||||||
hit_dice += (f" + {con_mod * dice_amount}")
|
|
||||||
|
|
||||||
new_part = "\n--------------------"
|
hit_dice = monster["hit_dice"]
|
||||||
|
dice_amount = int(monster["hit_dice"].replace("d"," ").split()[0])
|
||||||
|
con_mod = math.floor((monster['constitution']-10)/2)
|
||||||
|
if con_mod < 0:
|
||||||
|
hit_dice += f" - {abs(con_mod) * dice_amount}"
|
||||||
|
elif con_mod > 0:
|
||||||
|
hit_dice += (f" + {con_mod * dice_amount}")
|
||||||
|
|
||||||
monster_type = f"*{monster['size']} {types}, {monster['alignment']}*"
|
new_part = "\n--------------------"
|
||||||
|
|
||||||
basic_info = "\n**Armor Class** "+str(monster["armor_class"])+"\n**Hit Points** "+str(monster["hit_points"])+" ("+hit_dice+")\n**Speed **"+monster["speed"]+new_part+"\n"
|
monster_type = f"*{monster['size']} {types}, {monster['alignment']}*"
|
||||||
|
|
||||||
info = (monster_type+new_part+basic_info+stats+new_part+saving_throws+skills+vulnerabilities+resistances+immunities+c_immunities+"\n**Senses** "+monster["senses"]+"\n**Languages** "+monster["languages"]+"\n**Challenge** "+monster["challenge_rating"])
|
basic_info = "\n**Armor Class** "+str(monster["armor_class"])+"\n**Hit Points** "+str(monster["hit_points"])+" ("+hit_dice+")\n**Speed **"+monster["speed"]+new_part+"\n"
|
||||||
|
|
||||||
monster_info = [(info, monster['name']),
|
info = (monster_type+new_part+basic_info+stats+new_part+saving_throws+skills+vulnerabilities+resistances+immunities+c_immunities+"\n**Senses** "+monster["senses"]+"\n**Languages** "+monster["languages"]+"\n**Challenge** "+monster["challenge_rating"])
|
||||||
(special_abilities, "Special Abilities"),
|
|
||||||
(act, "Actions"),
|
|
||||||
(react, "Reactions"),
|
|
||||||
(legendaryActions, "Legendary Actions")]
|
|
||||||
|
|
||||||
self.bot.log("Returning monster information")
|
monster_info = [(info, monster['name']),
|
||||||
return monster_info
|
(special_abilities, "Special Abilities"),
|
||||||
|
(act, "Actions"),
|
||||||
|
(react, "Reactions"),
|
||||||
|
(legendaryActions, "Legendary Actions")]
|
||||||
|
|
||||||
# Looks up a monster
|
self.bot.log("Returning monster information")
|
||||||
async def monster_func(self, ctx, query):
|
return monster_info
|
||||||
query = cap(query)
|
|
||||||
self.bot.log("Looking up "+query)
|
|
||||||
|
|
||||||
# 1-letter monsters don't exist
|
# Looks up a monster
|
||||||
if len(query) < 2:
|
async def monster_func(self, ctx, query):
|
||||||
self.bot.log("Monster name too short")
|
query = cap(query)
|
||||||
await ctx.send("I don't know that monster...")
|
self.bot.log("Looking up "+query)
|
||||||
return
|
|
||||||
|
|
||||||
# Opens "monsters.json"
|
# 1-letter monsters don't exist
|
||||||
monster_file_path = "gwendolyn/resources/lookup/monsters.json"
|
if len(query) < 2:
|
||||||
with open(monster_file_path,"r", encoding="utf-8") as file_pointer:
|
self.bot.log("Monster name too short")
|
||||||
data = json.load(file_pointer)
|
await ctx.send("I don't know that monster...")
|
||||||
|
return
|
||||||
|
|
||||||
for monster in data:
|
# Opens "monsters.json"
|
||||||
if "name" in monster and str(query) == monster["name"]:
|
monster_file_path = "gwendolyn/resources/lookup/monsters.json"
|
||||||
self.bot.log("Found it!")
|
with open(monster_file_path,"r", encoding="utf-8") as file_pointer:
|
||||||
|
data = json.load(file_pointer)
|
||||||
|
|
||||||
monster_info = self._format_monster(monster)
|
for monster in data:
|
||||||
|
if "name" in monster and str(query) == monster["name"]:
|
||||||
|
self.bot.log("Found it!")
|
||||||
|
|
||||||
# Sends the received information. Separates into separate messages if
|
monster_info = self._format_monster(monster)
|
||||||
# there is too much text
|
|
||||||
await ctx.send(f"Result for \"{query}\"")
|
|
||||||
for text, title in monster_info:
|
|
||||||
if text != "":
|
|
||||||
if len(text) < 2000:
|
|
||||||
em = discord.Embed(title = title, description = text, colour=0xDEADBF)
|
|
||||||
await ctx.channel.send(embed = em)
|
|
||||||
else:
|
|
||||||
index = text[:2000].rfind(".")+1
|
|
||||||
em1 = discord.Embed(title = title, description = text[:index], colour=0xDEADBF)
|
|
||||||
await ctx.channel.send(embed = em1)
|
|
||||||
em2 = discord.Embed(title = "", description = text[index+1:], colour=0xDEADBF)
|
|
||||||
await ctx.channel.send(embed = em2)
|
|
||||||
|
|
||||||
break
|
# Sends the received information. Separates into separate messages if
|
||||||
else:
|
# there is too much text
|
||||||
self.bot.log("Monster not in database")
|
await ctx.send(f"Result for \"{query}\"")
|
||||||
await ctx.send("I don't know that monster...")
|
for text, title in monster_info:
|
||||||
|
if text != "":
|
||||||
|
if len(text) < 2000:
|
||||||
|
em = discord.Embed(title = title, description = text, colour=0xDEADBF)
|
||||||
|
await ctx.channel.send(embed = em)
|
||||||
|
else:
|
||||||
|
index = text[:2000].rfind(".")+1
|
||||||
|
em1 = discord.Embed(title = title, description = text[:index], colour=0xDEADBF)
|
||||||
|
await ctx.channel.send(embed = em1)
|
||||||
|
em2 = discord.Embed(title = "", description = text[index+1:], colour=0xDEADBF)
|
||||||
|
await ctx.channel.send(embed = em2)
|
||||||
|
|
||||||
# Looks up a spell
|
break
|
||||||
async def spell_func(self, ctx, query):
|
else:
|
||||||
query = cap(query)
|
self.bot.log("Monster not in database")
|
||||||
self.bot.log("Looking up "+query)
|
await ctx.send("I don't know that monster...")
|
||||||
|
|
||||||
# Opens "spells.json"
|
# Looks up a spell
|
||||||
data = json.load(open('gwendolyn/resources/lookup/spells.json', encoding = "utf8"))
|
async def spell_func(self, ctx, query):
|
||||||
if query in data:
|
query = cap(query)
|
||||||
self.bot.log("Returning spell information")
|
self.bot.log("Looking up "+query)
|
||||||
send_message = (f"***{query}***\n*{data[query]['level']} level {data[query]['school']}\nCasting Time: {data[query]['casting_time']}\nRange:{data[query]['range']}\nComponents:{data[query]['components']}\nDuration:{data[query]['duration']}*\n \n{data[query]['description']}")
|
|
||||||
else:
|
|
||||||
self.bot.log("I don't know that spell")
|
|
||||||
send_message = "I don't think that's a spell"
|
|
||||||
|
|
||||||
if len(send_message) > 2000:
|
# Opens "spells.json"
|
||||||
await ctx.send(send_message[:2000])
|
data = json.load(open('gwendolyn/resources/lookup/spells.json', encoding = "utf8"))
|
||||||
await ctx.send(send_message[2000:])
|
if query in data:
|
||||||
else:
|
self.bot.log("Returning spell information")
|
||||||
await ctx.send(send_message)
|
send_message = (f"***{query}***\n*{data[query]['level']} level {data[query]['school']}\nCasting Time: {data[query]['casting_time']}\nRange:{data[query]['range']}\nComponents:{data[query]['components']}\nDuration:{data[query]['duration']}*\n \n{data[query]['description']}")
|
||||||
|
else:
|
||||||
|
self.bot.log("I don't know that spell")
|
||||||
|
send_message = "I don't think that's a spell"
|
||||||
|
|
||||||
|
if len(send_message) > 2000:
|
||||||
|
await ctx.send(send_message[:2000])
|
||||||
|
await ctx.send(send_message[2000:])
|
||||||
|
else:
|
||||||
|
await ctx.send(send_message)
|
||||||
|
|||||||
@@ -1,94 +1,94 @@
|
|||||||
import random
|
import random
|
||||||
|
|
||||||
class Generators():
|
class Generators():
|
||||||
def __init__(self, bot):
|
def __init__(self, bot):
|
||||||
self.bot = bot
|
self.bot = bot
|
||||||
|
|
||||||
# Returns a list of all letter pairs in the text
|
# Returns a list of all letter pairs in the text
|
||||||
def make_pairs(self, corpus):
|
def make_pairs(self, corpus):
|
||||||
for i in range(len(corpus)-1):
|
for i in range(len(corpus)-1):
|
||||||
yield (corpus[i], corpus[i+1])
|
yield (corpus[i], corpus[i+1])
|
||||||
|
|
||||||
# Returns a list of all letter triplets in the text
|
# Returns a list of all letter triplets in the text
|
||||||
def make_triplets(self, corpus):
|
def make_triplets(self, corpus):
|
||||||
for i in range(len(corpus)-2):
|
for i in range(len(corpus)-2):
|
||||||
yield (corpus[i], corpus[i+1], corpus[i+2])
|
yield (corpus[i], corpus[i+1], corpus[i+2])
|
||||||
|
|
||||||
# Generates a random name
|
# Generates a random name
|
||||||
async def name_gen(self, ctx):
|
async def name_gen(self, ctx):
|
||||||
# Makes a list of all names from "names.txt"
|
# Makes a list of all names from "names.txt"
|
||||||
with open("gwendolyn/resources/names.txt", "r", encoding='utf8') as file_pointer:
|
with open("gwendolyn/resources/names.txt", "r", encoding='utf8') as file_pointer:
|
||||||
names = file_pointer.read()
|
names = file_pointer.read()
|
||||||
corpus = list(names)
|
corpus = list(names)
|
||||||
|
|
||||||
# Makes a list of pairs
|
# Makes a list of pairs
|
||||||
pairs = self.make_pairs(corpus)
|
pairs = self.make_pairs(corpus)
|
||||||
triplets = self.make_triplets(corpus)
|
triplets = self.make_triplets(corpus)
|
||||||
|
|
||||||
letter_dict = {}
|
letter_dict = {}
|
||||||
|
|
||||||
# Makes a dictionary of all letters that come after all other letters
|
# Makes a dictionary of all letters that come after all other letters
|
||||||
for letter_1, letter_2 in pairs:
|
for letter_1, letter_2 in pairs:
|
||||||
if letter_1 in letter_dict:
|
if letter_1 in letter_dict:
|
||||||
letter_dict[letter_1].append(letter_2)
|
letter_dict[letter_1].append(letter_2)
|
||||||
else:
|
else:
|
||||||
letter_dict[letter_1] = [letter_2]
|
letter_dict[letter_1] = [letter_2]
|
||||||
|
|
||||||
for letter_1, letter_2, letter_3 in triplets:
|
for letter_1, letter_2, letter_3 in triplets:
|
||||||
if letter_1+letter_2 in letter_dict:
|
if letter_1+letter_2 in letter_dict:
|
||||||
letter_dict[letter_1+letter_2].append(letter_3)
|
letter_dict[letter_1+letter_2].append(letter_3)
|
||||||
else:
|
else:
|
||||||
letter_dict[letter_1+letter_2] = [letter_3]
|
letter_dict[letter_1+letter_2] = [letter_3]
|
||||||
|
|
||||||
# Choses a random first letter
|
# Choses a random first letter
|
||||||
first_letter = random.choice(corpus)
|
first_letter = random.choice(corpus)
|
||||||
|
|
||||||
# Makes sure the first letter is not something a name can't start with.
|
# Makes sure the first letter is not something a name can't start with.
|
||||||
while first_letter.islower() or first_letter == " " or first_letter == "-" or first_letter == "\n":
|
while first_letter.islower() or first_letter == " " or first_letter == "-" or first_letter == "\n":
|
||||||
first_letter = random.choice(corpus)
|
first_letter = random.choice(corpus)
|
||||||
|
|
||||||
# Starts the name
|
# Starts the name
|
||||||
chain = [first_letter]
|
chain = [first_letter]
|
||||||
|
|
||||||
# Picks second letter
|
# Picks second letter
|
||||||
second_letter = random.choice(letter_dict[chain[-1]])
|
second_letter = random.choice(letter_dict[chain[-1]])
|
||||||
|
|
||||||
while second_letter == "\n":
|
while second_letter == "\n":
|
||||||
second_letter = random.choice(letter_dict[chain[-1]])
|
second_letter = random.choice(letter_dict[chain[-1]])
|
||||||
|
|
||||||
chain.append(second_letter)
|
chain.append(second_letter)
|
||||||
|
|
||||||
done = False
|
done = False
|
||||||
|
|
||||||
# Creates the name one letter at a time
|
# Creates the name one letter at a time
|
||||||
while not done:
|
while not done:
|
||||||
if random.randint(1,10) > 1:
|
if random.randint(1,10) > 1:
|
||||||
try:
|
try:
|
||||||
new_letter = random.choice(letter_dict[chain[-2]+chain[-1]])
|
new_letter = random.choice(letter_dict[chain[-2]+chain[-1]])
|
||||||
except KeyError():
|
except KeyError():
|
||||||
new_letter = random.choice(letter_dict[chain[-1]])
|
new_letter = random.choice(letter_dict[chain[-1]])
|
||||||
else:
|
else:
|
||||||
new_letter = random.choice(letter_dict[chain[-1]])
|
new_letter = random.choice(letter_dict[chain[-1]])
|
||||||
chain.append(new_letter)
|
chain.append(new_letter)
|
||||||
# Ends name if the name ends
|
# Ends name if the name ends
|
||||||
if new_letter == "\n":
|
if new_letter == "\n":
|
||||||
done = True
|
done = True
|
||||||
gen_name = "".join(chain)
|
gen_name = "".join(chain)
|
||||||
self.bot.log("Generated "+gen_name[:-1])
|
self.bot.log("Generated "+gen_name[:-1])
|
||||||
|
|
||||||
# Returns the name
|
# Returns the name
|
||||||
await ctx.send(gen_name)
|
await ctx.send(gen_name)
|
||||||
|
|
||||||
# Generates a random tavern name
|
# Generates a random tavern name
|
||||||
async def tavern_gen(self, ctx):
|
async def tavern_gen(self, ctx):
|
||||||
# _lists first parts, second parts and third parts of tavern names
|
# _lists first parts, second parts and third parts of tavern names
|
||||||
first_part = ["The Silver","The Golden","The Staggering","The Laughing","The Prancing","The Gilded","The Running","The Howling","The Slaughtered","The Leering","The Drunken","The Leaping","The Roaring","The Frowning","The Lonely","The Wandering","The Mysterious","The Barking","The Black","The Gleaming","The Tap-Dancing","The Sad","The Sexy","The Artificial","The Groovy","The Merciful","The Confused","The Pouting","The Horny","The Okay","The Friendly","The Hungry","The Handicapped","The Fire-breathing","The One-Eyed","The Psychotic","The Mad","The Evil","The Idiotic","The Trusty","The Busty"]
|
first_part = ["The Silver","The Golden","The Staggering","The Laughing","The Prancing","The Gilded","The Running","The Howling","The Slaughtered","The Leering","The Drunken","The Leaping","The Roaring","The Frowning","The Lonely","The Wandering","The Mysterious","The Barking","The Black","The Gleaming","The Tap-Dancing","The Sad","The Sexy","The Artificial","The Groovy","The Merciful","The Confused","The Pouting","The Horny","The Okay","The Friendly","The Hungry","The Handicapped","The Fire-breathing","The One-Eyed","The Psychotic","The Mad","The Evil","The Idiotic","The Trusty","The Busty"]
|
||||||
second_part = ["Eel","Dolphin","Dwarf","Pegasus","Pony","Rose","Stag","Wolf","Lamb","Demon","Goat","Spirit","Horde","Jester","Mountain","Eagle","Satyr","Dog","Spider","Star","Dad","Rat","Jeremy","Mouse","Unicorn","Pearl","Ant","Crab","Penguin","Octopus","Lawyer","Ghost","Toad","Handjob","Immigrant","SJW","Dragon","Bard","Sphinx","Soldier","Salmon","Owlbear","Kite","Frost Giant","Arsonist"]
|
second_part = ["Eel","Dolphin","Dwarf","Pegasus","Pony","Rose","Stag","Wolf","Lamb","Demon","Goat","Spirit","Horde","Jester","Mountain","Eagle","Satyr","Dog","Spider","Star","Dad","Rat","Jeremy","Mouse","Unicorn","Pearl","Ant","Crab","Penguin","Octopus","Lawyer","Ghost","Toad","Handjob","Immigrant","SJW","Dragon","Bard","Sphinx","Soldier","Salmon","Owlbear","Kite","Frost Giant","Arsonist"]
|
||||||
third_part = [" Tavern"," Inn","","","","","","","","",""]
|
third_part = [" Tavern"," Inn","","","","","","","","",""]
|
||||||
|
|
||||||
# Picks one of each
|
# Picks one of each
|
||||||
gen_tav = random.choice(first_part)+" "+random.choice(second_part)+random.choice(third_part)
|
gen_tav = random.choice(first_part)+" "+random.choice(second_part)+random.choice(third_part)
|
||||||
self.bot.log("Generated "+gen_tav)
|
self.bot.log("Generated "+gen_tav)
|
||||||
|
|
||||||
# Return the name
|
# Return the name
|
||||||
await ctx.send(gen_tav)
|
await ctx.send(gen_tav)
|
||||||
|
|||||||
@@ -6,80 +6,80 @@ import wolframalpha
|
|||||||
from PIL import Image, ImageDraw, ImageFont
|
from PIL import Image, ImageDraw, ImageFont
|
||||||
|
|
||||||
class NerdShit():
|
class NerdShit():
|
||||||
def __init__(self, bot):
|
def __init__(self, bot):
|
||||||
"""Runs misc commands."""
|
"""Runs misc commands."""
|
||||||
self.bot = bot
|
self.bot = bot
|
||||||
|
|
||||||
async def wolf_search(self,ctx,content):
|
async def wolf_search(self,ctx,content):
|
||||||
await self.bot.defer(ctx)
|
await self.bot.defer(ctx)
|
||||||
font = ImageFont.truetype('gwendolyn/resources/fonts/times-new-roman.ttf', 20)
|
font = ImageFont.truetype('gwendolyn/resources/fonts/times-new-roman.ttf', 20)
|
||||||
self.bot.log("Requesting data")
|
self.bot.log("Requesting data")
|
||||||
bot = wolframalpha.Client(self.bot.credentials["wolfram_alpha_key"])
|
bot = wolframalpha.Client(self.bot.credentials["wolfram_alpha_key"])
|
||||||
res = bot.query(content)
|
res = bot.query(content)
|
||||||
|
|
||||||
self.bot.log("Processing data")
|
self.bot.log("Processing data")
|
||||||
titles = []
|
titles = []
|
||||||
pods = []
|
pods = []
|
||||||
if int(res.numpods) > 0:
|
if int(res.numpods) > 0:
|
||||||
for pod in res.pods:
|
for pod in res.pods:
|
||||||
titles += [pod.title]
|
titles += [pod.title]
|
||||||
for i, sub in enumerate(pod.subpods):
|
for i, sub in enumerate(pod.subpods):
|
||||||
pods += [sub]
|
pods += [sub]
|
||||||
if i > 0:
|
if i > 0:
|
||||||
titles += [""]
|
titles += [""]
|
||||||
|
|
||||||
pod_chunks = [pods[x:x+2] for x in range(0, len(pods), 2)]
|
pod_chunks = [pods[x:x+2] for x in range(0, len(pods), 2)]
|
||||||
title_chunks = [titles[x:x+2] for x in range(0, len(titles), 2)]
|
title_chunks = [titles[x:x+2] for x in range(0, len(titles), 2)]
|
||||||
await ctx.send(f"Response for \"{content}\"")
|
await ctx.send(f"Response for \"{content}\"")
|
||||||
|
|
||||||
for i, chunk in enumerate(pod_chunks):
|
for i, chunk in enumerate(pod_chunks):
|
||||||
width = 0
|
width = 0
|
||||||
for title in title_chunks[i]:
|
for title in title_chunks[i]:
|
||||||
width = max(width,font.getsize(title)[0])
|
width = max(width,font.getsize(title)[0])
|
||||||
height = 5
|
height = 5
|
||||||
heights = []
|
heights = []
|
||||||
for count, pod in enumerate(chunk):
|
for count, pod in enumerate(chunk):
|
||||||
heights += [height]
|
heights += [height]
|
||||||
width = max(width,int(pod.img['@width']))
|
width = max(width,int(pod.img['@width']))
|
||||||
if title_chunks[i][count] == "":
|
if title_chunks[i][count] == "":
|
||||||
place_for_text = 0
|
place_for_text = 0
|
||||||
else:
|
else:
|
||||||
place_for_text = 30
|
place_for_text = 30
|
||||||
height += int(pod.img["@height"]) + 10 + place_for_text
|
height += int(pod.img["@height"]) + 10 + place_for_text
|
||||||
|
|
||||||
width += 10
|
width += 10
|
||||||
height += 5
|
height += 5
|
||||||
wolf_image = Image.new("RGB",(width,height),color=(255,255,255))
|
wolf_image = Image.new("RGB",(width,height),color=(255,255,255))
|
||||||
|
|
||||||
for count, pod in enumerate(chunk):
|
for count, pod in enumerate(chunk):
|
||||||
response = requests.get(pod.img["@src"])
|
response = requests.get(pod.img["@src"])
|
||||||
file = open("gwendolyn/resources/wolfTemp.png", "wb")
|
file = open("gwendolyn/resources/wolfTemp.png", "wb")
|
||||||
file.write(response.content)
|
file.write(response.content)
|
||||||
file.close()
|
file.close()
|
||||||
old_image = Image.open("gwendolyn/resources/wolfTemp.png")
|
old_image = Image.open("gwendolyn/resources/wolfTemp.png")
|
||||||
old_size = old_image.size
|
old_size = old_image.size
|
||||||
if title_chunks[i][count] == "":
|
if title_chunks[i][count] == "":
|
||||||
place_for_text = 0
|
place_for_text = 0
|
||||||
else:
|
else:
|
||||||
place_for_text = 30
|
place_for_text = 30
|
||||||
new_size = (width,int(old_size[1]+10+place_for_text))
|
new_size = (width,int(old_size[1]+10+place_for_text))
|
||||||
new_image = Image.new("RGB",new_size,color=(255,255,255))
|
new_image = Image.new("RGB",new_size,color=(255,255,255))
|
||||||
new_image.paste(old_image, (int((int(old_size[0]+10)-old_size[0])/2),int(((new_size[1]-place_for_text)-old_size[1])/2)+place_for_text))
|
new_image.paste(old_image, (int((int(old_size[0]+10)-old_size[0])/2),int(((new_size[1]-place_for_text)-old_size[1])/2)+place_for_text))
|
||||||
if title_chunks[i][count] != "":
|
if title_chunks[i][count] != "":
|
||||||
drawer = ImageDraw.Draw(new_image,"RGB")
|
drawer = ImageDraw.Draw(new_image,"RGB")
|
||||||
drawer.text((5,7),title_chunks[i][count],font=font,fill=(150,150,150))
|
drawer.text((5,7),title_chunks[i][count],font=font,fill=(150,150,150))
|
||||||
|
|
||||||
wolf_image.paste(new_image,(0,heights[count]))
|
wolf_image.paste(new_image,(0,heights[count]))
|
||||||
new_image.close()
|
new_image.close()
|
||||||
old_image.close()
|
old_image.close()
|
||||||
count += 1
|
count += 1
|
||||||
|
|
||||||
wolf_image.save("gwendolyn/resources/wolf.png")
|
wolf_image.save("gwendolyn/resources/wolf.png")
|
||||||
wolf_image.close()
|
wolf_image.close()
|
||||||
await ctx.channel.send(file = discord.File("gwendolyn/resources/wolf.png"))
|
await ctx.channel.send(file = discord.File("gwendolyn/resources/wolf.png"))
|
||||||
|
|
||||||
os.remove("gwendolyn/resources/wolf.png")
|
os.remove("gwendolyn/resources/wolf.png")
|
||||||
os.remove("gwendolyn/resources/wolfTemp.png")
|
os.remove("gwendolyn/resources/wolfTemp.png")
|
||||||
else:
|
else:
|
||||||
self.bot.log("No returned data")
|
self.bot.log("No returned data")
|
||||||
await ctx.send("Could not find anything relating to your search")
|
await ctx.send("Could not find anything relating to your search")
|
||||||
|
|||||||
@@ -17,176 +17,176 @@ fandom.set_lang("da")
|
|||||||
fandom.set_wiki("senkulpa")
|
fandom.set_wiki("senkulpa")
|
||||||
|
|
||||||
class MyStringifier(d20.MarkdownStringifier):
|
class MyStringifier(d20.MarkdownStringifier):
|
||||||
def _str_expression(self, node):
|
def _str_expression(self, node):
|
||||||
if node.comment is None:
|
if node.comment is None:
|
||||||
result_text = "Result"
|
result_text = "Result"
|
||||||
else:
|
else:
|
||||||
result_text = node.comment.capitalize()
|
result_text = node.comment.capitalize()
|
||||||
|
|
||||||
return f"**{result_text}**: {self._stringify(node.roll)}\n**Total**: {int(node.total)}"
|
return f"**{result_text}**: {self._stringify(node.roll)}\n**Total**: {int(node.total)}"
|
||||||
|
|
||||||
class Other():
|
class Other():
|
||||||
def __init__(self, bot):
|
def __init__(self, bot):
|
||||||
self.bot = bot
|
self.bot = bot
|
||||||
self.plex = Plex(self.bot)
|
self.plex = Plex(self.bot)
|
||||||
self.nerd_shit = NerdShit(self.bot)
|
self.nerd_shit = NerdShit(self.bot)
|
||||||
self.generators = Generators(self.bot)
|
self.generators = Generators(self.bot)
|
||||||
|
|
||||||
# Picks a random movie and returns information about it
|
# Picks a random movie and returns information about it
|
||||||
async def movie_func(self, ctx):
|
async def movie_func(self, ctx):
|
||||||
await self.bot.defer(ctx)
|
await self.bot.defer(ctx)
|
||||||
|
|
||||||
self.bot.log("Creating IMDb object")
|
self.bot.log("Creating IMDb object")
|
||||||
imdb_client = imdb.IMDb()
|
imdb_client = imdb.IMDb()
|
||||||
|
|
||||||
self.bot.log("Picking a movie")
|
self.bot.log("Picking a movie")
|
||||||
with open("gwendolyn/resources/movies.txt", "r") as file_pointer:
|
with open("gwendolyn/resources/movies.txt", "r") as file_pointer:
|
||||||
movie_list = file_pointer.read().split("\n")
|
movie_list = file_pointer.read().split("\n")
|
||||||
movie_name = random.choice(movie_list)
|
movie_name = random.choice(movie_list)
|
||||||
|
|
||||||
self.bot.log(f"Searching for {movie_name}")
|
self.bot.log(f"Searching for {movie_name}")
|
||||||
search_result = imdb_client.search_movie(movie_name)
|
search_result = imdb_client.search_movie(movie_name)
|
||||||
|
|
||||||
self.bot.log("Getting the data")
|
self.bot.log("Getting the data")
|
||||||
movie = search_result[0]
|
movie = search_result[0]
|
||||||
imdb_client.update(movie)
|
imdb_client.update(movie)
|
||||||
|
|
||||||
self.bot.log("Successfully ran /movie")
|
self.bot.log("Successfully ran /movie")
|
||||||
|
|
||||||
title = movie["title"]
|
title = movie["title"]
|
||||||
plot = movie['plot'][0].split("::")[0]
|
plot = movie['plot'][0].split("::")[0]
|
||||||
cover = movie['cover url'].replace("150","600").replace("101","404")
|
cover = movie['cover url'].replace("150","600").replace("101","404")
|
||||||
cast = ", ".join([i["name"] for i in movie['cast'][:5]])
|
cast = ", ".join([i["name"] for i in movie['cast'][:5]])
|
||||||
embed = discord.Embed(title=title, description=plot, color=0x24ec19)
|
embed = discord.Embed(title=title, description=plot, color=0x24ec19)
|
||||||
embed.set_thumbnail(url=cover)
|
embed.set_thumbnail(url=cover)
|
||||||
embed.add_field(name="Cast", value=cast,inline = True)
|
embed.add_field(name="Cast", value=cast,inline = True)
|
||||||
await ctx.send(embed = embed)
|
await ctx.send(embed = embed)
|
||||||
|
|
||||||
# Responds with a greeting of a time-appropriate maner
|
# Responds with a greeting of a time-appropriate maner
|
||||||
async def hello_func(self, ctx):
|
async def hello_func(self, ctx):
|
||||||
def time_in_range(start, end, i):
|
def time_in_range(start, end, i):
|
||||||
# Return true if i is in the range [start, end]
|
# Return true if i is in the range [start, end]
|
||||||
if start <= end:
|
if start <= end:
|
||||||
return start <= i <= end
|
return start <= i <= end
|
||||||
else:
|
else:
|
||||||
return start <= i or i <= end
|
return start <= i or i <= end
|
||||||
|
|
||||||
author = ctx.author.display_name
|
author = ctx.author.display_name
|
||||||
now = datetime.datetime.now()
|
now = datetime.datetime.now()
|
||||||
if time_in_range(now.replace(hour=5, minute=0, second=0, microsecond=0),now.replace(hour=10, minute=0, second=0, microsecond=0), now):
|
if time_in_range(now.replace(hour=5, minute=0, second=0, microsecond=0),now.replace(hour=10, minute=0, second=0, microsecond=0), now):
|
||||||
send_message = "Good morning, "+str(author)
|
send_message = "Good morning, "+str(author)
|
||||||
elif time_in_range(now.replace(hour=13, minute=0, second=0, microsecond=0),now.replace(hour=18, minute=0, second=0, microsecond=0), now):
|
elif time_in_range(now.replace(hour=13, minute=0, second=0, microsecond=0),now.replace(hour=18, minute=0, second=0, microsecond=0), now):
|
||||||
send_message = "Good afternoon, "+str(author)
|
send_message = "Good afternoon, "+str(author)
|
||||||
elif time_in_range(now.replace(hour=18, minute=0, second=0, microsecond=0),now.replace(hour=22, minute=0, second=0, microsecond=0), now):
|
elif time_in_range(now.replace(hour=18, minute=0, second=0, microsecond=0),now.replace(hour=22, minute=0, second=0, microsecond=0), now):
|
||||||
send_message = "Good evening, "+str(author)
|
send_message = "Good evening, "+str(author)
|
||||||
elif time_in_range(now.replace(hour=22, minute=0, second=0, microsecond=0),now.replace(hour=23, minute=59, second=59, microsecond=0), now):
|
elif time_in_range(now.replace(hour=22, minute=0, second=0, microsecond=0),now.replace(hour=23, minute=59, second=59, microsecond=0), now):
|
||||||
send_message = "Good night, "+str(author)
|
send_message = "Good night, "+str(author)
|
||||||
else:
|
else:
|
||||||
send_message = "Hello, "+str(author)
|
send_message = "Hello, "+str(author)
|
||||||
|
|
||||||
await ctx.send(send_message)
|
await ctx.send(send_message)
|
||||||
|
|
||||||
# Finds a random picture online
|
# Finds a random picture online
|
||||||
async def image_func(self, ctx):
|
async def image_func(self, ctx):
|
||||||
# Picks a type of camera, which decides the naming scheme
|
# Picks a type of camera, which decides the naming scheme
|
||||||
cams = ("one","two","three","four")
|
cams = ("one","two","three","four")
|
||||||
cam = random.choice(cams)
|
cam = random.choice(cams)
|
||||||
self.bot.log("Chose cam type "+cam)
|
self.bot.log("Chose cam type "+cam)
|
||||||
if cam == "one":
|
if cam == "one":
|
||||||
|
|
||||||
search = "img_" + ''.join(
|
search = "img_" + ''.join(
|
||||||
[str(random.randint(0,9)) for _ in range(4)]
|
[str(random.randint(0,9)) for _ in range(4)]
|
||||||
)
|
)
|
||||||
elif cam == "two":
|
elif cam == "two":
|
||||||
year = str(random.randint(2012,2016))
|
year = str(random.randint(2012,2016))
|
||||||
month = str(random.randint(1,12)).zfill(2)
|
month = str(random.randint(1,12)).zfill(2)
|
||||||
day = str(random.randint(1,29)).zfill(2)
|
day = str(random.randint(1,29)).zfill(2)
|
||||||
search = f"IMG_{year}{month}{day}"
|
search = f"IMG_{year}{month}{day}"
|
||||||
elif cam == "three":
|
elif cam == "three":
|
||||||
search = f"IMAG_{str(random.randint(1,500)).zfill(4)}"
|
search = f"IMAG_{str(random.randint(1,500)).zfill(4)}"
|
||||||
elif cam == "four":
|
elif cam == "four":
|
||||||
search = "DSC_" + ''.join(
|
search = "DSC_" + ''.join(
|
||||||
[str(random.randint(0,9)) for _ in range(4)]
|
[str(random.randint(0,9)) for _ in range(4)]
|
||||||
)
|
)
|
||||||
|
|
||||||
self.bot.log("Searching for "+search)
|
self.bot.log("Searching for "+search)
|
||||||
|
|
||||||
# Searches for the image and reads the resulting web page
|
# Searches for the image and reads the resulting web page
|
||||||
page = urllib.request.urlopen("https://www.bing.com/images/search?q="+search+"&safesearch=off")
|
page = urllib.request.urlopen("https://www.bing.com/images/search?q="+search+"&safesearch=off")
|
||||||
read = page.read()
|
read = page.read()
|
||||||
tree = lxml.etree.HTML(read)
|
tree = lxml.etree.HTML(read)
|
||||||
images = tree.xpath('//a[@class = "iusc"]/@m')
|
images = tree.xpath('//a[@class = "iusc"]/@m')
|
||||||
|
|
||||||
if len(images) == 0:
|
if len(images) == 0:
|
||||||
await ctx.send("Found no images")
|
await ctx.send("Found no images")
|
||||||
else:
|
else:
|
||||||
# Picks an image
|
# Picks an image
|
||||||
number = random.randint(1,len(images))-1
|
number = random.randint(1,len(images))-1
|
||||||
image = ast.literal_eval(str(images[number]))
|
image = ast.literal_eval(str(images[number]))
|
||||||
image_url = image["murl"]
|
image_url = image["murl"]
|
||||||
|
|
||||||
self.bot.log("Picked image number "+str(number))
|
self.bot.log("Picked image number "+str(number))
|
||||||
|
|
||||||
# Returns the image
|
# Returns the image
|
||||||
self.bot.log("Successfully returned an image")
|
self.bot.log("Successfully returned an image")
|
||||||
|
|
||||||
await ctx.send(image_url)
|
await ctx.send(image_url)
|
||||||
|
|
||||||
# Finds a page from the Senkulpa Wikia
|
# Finds a page from the Senkulpa Wikia
|
||||||
async def find_wiki_page(self, ctx, search : str):
|
async def find_wiki_page(self, ctx, search : str):
|
||||||
await self.bot.defer(ctx)
|
await self.bot.defer(ctx)
|
||||||
found_page = False
|
found_page = False
|
||||||
|
|
||||||
if search != "":
|
if search != "":
|
||||||
self.bot.log("Trying to find wiki page for "+search)
|
self.bot.log("Trying to find wiki page for "+search)
|
||||||
search_results = fandom.search(search)
|
search_results = fandom.search(search)
|
||||||
if len(search_results) > 0:
|
if len(search_results) > 0:
|
||||||
found_page = True
|
found_page = True
|
||||||
search_result = search_results[0]
|
search_result = search_results[0]
|
||||||
else:
|
else:
|
||||||
self.bot.log("Couldn't find the page")
|
self.bot.log("Couldn't find the page")
|
||||||
await ctx.send("Couldn't find page")
|
await ctx.send("Couldn't find page")
|
||||||
else:
|
else:
|
||||||
found_page = True
|
found_page = True
|
||||||
self.bot.log("Searching for a random page")
|
self.bot.log("Searching for a random page")
|
||||||
search_result = fandom.random()
|
search_result = fandom.random()
|
||||||
|
|
||||||
if found_page:
|
if found_page:
|
||||||
self.bot.log(f"Found page \"{search_result[0]}\"")
|
self.bot.log(f"Found page \"{search_result[0]}\"")
|
||||||
page = fandom.page(pageid = search_result[1])
|
page = fandom.page(pageid = search_result[1])
|
||||||
content = page.summary
|
content = page.summary
|
||||||
|
|
||||||
images = page.images
|
images = page.images
|
||||||
if len(images) > 0:
|
if len(images) > 0:
|
||||||
image = images[0]
|
image = images[0]
|
||||||
else:
|
else:
|
||||||
image = ""
|
image = ""
|
||||||
self.bot.log("Sending the embedded message",str(ctx.channel_id))
|
self.bot.log("Sending the embedded message",str(ctx.channel_id))
|
||||||
content += f"\n[Læs mere]({page.url})"
|
content += f"\n[Læs mere]({page.url})"
|
||||||
embed = discord.Embed(title = page.title, description = content, colour=0xDEADBF)
|
embed = discord.Embed(title = page.title, description = content, colour=0xDEADBF)
|
||||||
if image != "":
|
if image != "":
|
||||||
embed.set_thumbnail(url=image)
|
embed.set_thumbnail(url=image)
|
||||||
|
|
||||||
await ctx.send(embed = embed)
|
await ctx.send(embed = embed)
|
||||||
|
|
||||||
async def roll_dice(self, ctx, roll_string):
|
async def roll_dice(self, ctx, roll_string):
|
||||||
user = ctx.author.display_name
|
user = ctx.author.display_name
|
||||||
while len(roll_string) > 1 and roll_string[0] == " ":
|
while len(roll_string) > 1 and roll_string[0] == " ":
|
||||||
roll_string = roll_string[1:]
|
roll_string = roll_string[1:]
|
||||||
|
|
||||||
roll = d20.roll(roll_string, allow_comments=True, stringifier=MyStringifier())
|
roll = d20.roll(roll_string, allow_comments=True, stringifier=MyStringifier())
|
||||||
await ctx.send(f"{user} :game_die:\n{roll}")
|
await ctx.send(f"{user} :game_die:\n{roll}")
|
||||||
|
|
||||||
async def help_func(self, ctx, command):
|
async def help_func(self, ctx, command):
|
||||||
if command == "":
|
if command == "":
|
||||||
with open("gwendolyn/resources/help/help.txt",encoding="utf-8") as file_pointer:
|
with open("gwendolyn/resources/help/help.txt",encoding="utf-8") as file_pointer:
|
||||||
text = file_pointer.read()
|
text = file_pointer.read()
|
||||||
embed = discord.Embed(title = "Help", description = text,colour = 0x59f442)
|
embed = discord.Embed(title = "Help", description = text,colour = 0x59f442)
|
||||||
await ctx.send(embed = embed)
|
await ctx.send(embed = embed)
|
||||||
else:
|
else:
|
||||||
self.bot.log(f"Looking for help-{command}.txt",str(ctx.channel_id))
|
self.bot.log(f"Looking for help-{command}.txt",str(ctx.channel_id))
|
||||||
with open(f"gwendolyn/resources/help/help-{command}.txt",encoding="utf-8") as file_pointer:
|
with open(f"gwendolyn/resources/help/help-{command}.txt",encoding="utf-8") as file_pointer:
|
||||||
text = file_pointer.read()
|
text = file_pointer.read()
|
||||||
embed = discord.Embed(title = command.capitalize(), description = text,colour = 0x59f442)
|
embed = discord.Embed(title = command.capitalize(), description = text,colour = 0x59f442)
|
||||||
await ctx.send(embed = embed)
|
await ctx.send(embed = embed)
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -3,8 +3,8 @@ from .star_wars_roll import StarWarsRoll
|
|||||||
from .star_wars_destiny import StarWarsDestiny
|
from .star_wars_destiny import StarWarsDestiny
|
||||||
|
|
||||||
class StarWars():
|
class StarWars():
|
||||||
def __init__(self, bot):
|
def __init__(self, bot):
|
||||||
self.bot = bot
|
self.bot = bot
|
||||||
self.character = StarWarsChar(self.bot)
|
self.character = StarWarsChar(self.bot)
|
||||||
self.roll = StarWarsRoll(self.bot)
|
self.roll = StarWarsRoll(self.bot)
|
||||||
self.destiny = StarWarsDestiny(self.bot)
|
self.destiny = StarWarsDestiny(self.bot)
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -1,72 +1,72 @@
|
|||||||
class StarWarsDestiny():
|
class StarWarsDestiny():
|
||||||
def __init__(self, bot):
|
def __init__(self, bot):
|
||||||
self.bot = bot
|
self.bot = bot
|
||||||
|
|
||||||
def destiny_new(self, num : int):
|
def destiny_new(self, num : int):
|
||||||
self.bot.log("Creating a new destiny pool with "+str(num)+" players")
|
self.bot.log("Creating a new destiny pool with "+str(num)+" players")
|
||||||
roll, dice_results = self.bot.star_wars.roll.roll(0,0,0,0,0,0,num)
|
roll, dice_results = self.bot.star_wars.roll.roll(0,0,0,0,0,0,num)
|
||||||
roll = "".join(sorted(roll))
|
roll = "".join(sorted(roll))
|
||||||
|
|
||||||
|
with open("gwendolyn/resources/star_wars/destinyPoints.txt","wt") as file_pointer:
|
||||||
|
file_pointer.write(roll)
|
||||||
|
|
||||||
|
return "Rolled for Destiny Points and got:\n"+self.bot.star_wars.roll.diceResultToEmoji(dice_results)+"\n"+self.bot.star_wars.roll.resultToEmoji(roll)
|
||||||
|
|
||||||
|
def destiny_use(self, user : str):
|
||||||
|
with open("gwendolyn/resources/star_wars/destinyPoints.txt","rt") as file_pointer:
|
||||||
|
points = file_pointer.read()
|
||||||
|
|
||||||
|
if user == "Nikolaj":
|
||||||
|
self.bot.log("Trying to use a dark side destiny point")
|
||||||
|
if 'B' in points:
|
||||||
|
points = points.replace("B","L",1)
|
||||||
|
points = "".join(sorted(points))
|
||||||
with open("gwendolyn/resources/star_wars/destinyPoints.txt","wt") as file_pointer:
|
with open("gwendolyn/resources/star_wars/destinyPoints.txt","wt") as file_pointer:
|
||||||
file_pointer.write(roll)
|
file_pointer.write(points)
|
||||||
|
self.bot.log("Did it")
|
||||||
return "Rolled for Destiny Points and got:\n"+self.bot.star_wars.roll.diceResultToEmoji(dice_results)+"\n"+self.bot.star_wars.roll.resultToEmoji(roll)
|
return "Used a dark side destiny point. Destiny pool is now:\n"+self.bot.star_wars.roll.resultToEmoji(points)
|
||||||
|
else:
|
||||||
def destiny_use(self, user : str):
|
self.bot.log("There were no dark side destiny points")
|
||||||
with open("gwendolyn/resources/star_wars/destinyPoints.txt","rt") as file_pointer:
|
return "No dark side destiny points"
|
||||||
points = file_pointer.read()
|
else:
|
||||||
|
self.bot.log("Trying to use a light side destiny point")
|
||||||
if user == "Nikolaj":
|
if 'L' in points:
|
||||||
self.bot.log("Trying to use a dark side destiny point")
|
points = points.replace("L","B",1)
|
||||||
if 'B' in points:
|
points = "".join(sorted(points))
|
||||||
points = points.replace("B","L",1)
|
with open("gwendolyn/resources/star_wars/destinyPoints.txt","wt") as file_pointer:
|
||||||
points = "".join(sorted(points))
|
file_pointer.write(points)
|
||||||
with open("gwendolyn/resources/star_wars/destinyPoints.txt","wt") as file_pointer:
|
self.bot.log("Did it")
|
||||||
file_pointer.write(points)
|
return "Used a light side destiny point. Destiny pool is now:\n"+self.bot.star_wars.roll.resultToEmoji(points)
|
||||||
self.bot.log("Did it")
|
else:
|
||||||
return "Used a dark side destiny point. Destiny pool is now:\n"+self.bot.star_wars.roll.resultToEmoji(points)
|
self.bot.log("There were no dark side destiny points")
|
||||||
else:
|
return "No light side destiny points"
|
||||||
self.bot.log("There were no dark side destiny points")
|
|
||||||
return "No dark side destiny points"
|
|
||||||
else:
|
|
||||||
self.bot.log("Trying to use a light side destiny point")
|
|
||||||
if 'L' in points:
|
|
||||||
points = points.replace("L","B",1)
|
|
||||||
points = "".join(sorted(points))
|
|
||||||
with open("gwendolyn/resources/star_wars/destinyPoints.txt","wt") as file_pointer:
|
|
||||||
file_pointer.write(points)
|
|
||||||
self.bot.log("Did it")
|
|
||||||
return "Used a light side destiny point. Destiny pool is now:\n"+self.bot.star_wars.roll.resultToEmoji(points)
|
|
||||||
else:
|
|
||||||
self.bot.log("There were no dark side destiny points")
|
|
||||||
return "No light side destiny points"
|
|
||||||
|
|
||||||
async def parse_destiny(self, ctx, cmd : str):
|
|
||||||
user = f"#{ctx.author.id}"
|
|
||||||
if cmd != "":
|
|
||||||
while cmd[0] == ' ':
|
|
||||||
cmd = cmd[1:]
|
|
||||||
if cmd == "":
|
|
||||||
break
|
|
||||||
|
|
||||||
|
async def parse_destiny(self, ctx, cmd : str):
|
||||||
|
user = f"#{ctx.author.id}"
|
||||||
|
if cmd != "":
|
||||||
|
while cmd[0] == ' ':
|
||||||
|
cmd = cmd[1:]
|
||||||
if cmd == "":
|
if cmd == "":
|
||||||
self.bot.log("Retrieving destiny pool info")
|
break
|
||||||
with open("gwendolyn/resources/star_wars/destinyPoints.txt","rt") as file_pointer:
|
|
||||||
send_message = self.bot.star_wars.roll.resultToEmoji(file_pointer.read())
|
|
||||||
else:
|
|
||||||
commands = cmd.upper().split(" ")
|
|
||||||
if commands[0] == "N":
|
|
||||||
if len(commands) > 1:
|
|
||||||
send_message = self.destiny_new(int(commands[1]))
|
|
||||||
else:
|
|
||||||
send_message = "You need to give an amount of players"
|
|
||||||
elif commands[0] == "U":
|
|
||||||
send_message = self.destiny_use(user)
|
|
||||||
else:
|
|
||||||
send_message = "I didn't quite understand that"
|
|
||||||
|
|
||||||
message_list = send_message.split("\n")
|
if cmd == "":
|
||||||
await ctx.send(message_list[0])
|
self.bot.log("Retrieving destiny pool info")
|
||||||
if len(message_list) > 1:
|
with open("gwendolyn/resources/star_wars/destinyPoints.txt","rt") as file_pointer:
|
||||||
for message_item in message_list[1:]:
|
send_message = self.bot.star_wars.roll.resultToEmoji(file_pointer.read())
|
||||||
await ctx.channel.send(message_item)
|
else:
|
||||||
|
commands = cmd.upper().split(" ")
|
||||||
|
if commands[0] == "N":
|
||||||
|
if len(commands) > 1:
|
||||||
|
send_message = self.destiny_new(int(commands[1]))
|
||||||
|
else:
|
||||||
|
send_message = "You need to give an amount of players"
|
||||||
|
elif commands[0] == "U":
|
||||||
|
send_message = self.destiny_use(user)
|
||||||
|
else:
|
||||||
|
send_message = "I didn't quite understand that"
|
||||||
|
|
||||||
|
message_list = send_message.split("\n")
|
||||||
|
await ctx.send(message_list[0])
|
||||||
|
if len(message_list) > 1:
|
||||||
|
for message_item in message_list[1:]:
|
||||||
|
await ctx.channel.send(message_item)
|
||||||
|
|||||||
@@ -4,388 +4,388 @@ import string
|
|||||||
import json
|
import json
|
||||||
|
|
||||||
with open("gwendolyn/resources/star_wars/starwarsskills.json", "r") as f:
|
with open("gwendolyn/resources/star_wars/starwarsskills.json", "r") as f:
|
||||||
skill_data = json.load(f)
|
skill_data = json.load(f)
|
||||||
|
|
||||||
class StarWarsRoll():
|
class StarWarsRoll():
|
||||||
def __init__(self, bot):
|
def __init__(self, bot):
|
||||||
self.bot = bot
|
self.bot = bot
|
||||||
|
|
||||||
# Rolls the specified dice
|
# Rolls the specified dice
|
||||||
def roll(self, abi : int = 1, prof : int = 0, dif : int = 3, cha : int = 0, boo : int = 0, setb : int = 0, force : int = 0):
|
def roll(self, abi : int = 1, prof : int = 0, dif : int = 3, cha : int = 0, boo : int = 0, setb : int = 0, force : int = 0):
|
||||||
result = ""
|
result = ""
|
||||||
dice_result = []
|
dice_result = []
|
||||||
for _ in range(abi):
|
for _ in range(abi):
|
||||||
choice = random.choice(["","S","S","SS","A","A","SA","AA"])
|
choice = random.choice(["","S","S","SS","A","A","SA","AA"])
|
||||||
result += choice
|
result += choice
|
||||||
dice_result.append("abi"+choice)
|
dice_result.append("abi"+choice)
|
||||||
|
|
||||||
for _ in range(prof):
|
for _ in range(prof):
|
||||||
choice = random.choice(["","S","S","SS","SS","A","SA","SA","SA","AA","AA","R"])
|
choice = random.choice(["","S","S","SS","SS","A","SA","SA","SA","AA","AA","R"])
|
||||||
result += choice
|
result += choice
|
||||||
dice_result.append("prof"+choice)
|
dice_result.append("prof"+choice)
|
||||||
|
|
||||||
for _ in range(dif):
|
for _ in range(dif):
|
||||||
choice = random.choice(["","F","FF","H","H","H","HH","FH"])
|
choice = random.choice(["","F","FF","H","H","H","HH","FH"])
|
||||||
result += choice
|
result += choice
|
||||||
dice_result.append("dif"+choice)
|
dice_result.append("dif"+choice)
|
||||||
|
|
||||||
for _ in range(cha):
|
for _ in range(cha):
|
||||||
choice = random.choice(["","F","F","FF","FF","H","H","FH","FH","HH","HH","D"])
|
choice = random.choice(["","F","F","FF","FF","H","H","FH","FH","HH","HH","D"])
|
||||||
result += choice
|
result += choice
|
||||||
dice_result.append("cha"+choice)
|
dice_result.append("cha"+choice)
|
||||||
|
|
||||||
for _ in range(boo):
|
for _ in range(boo):
|
||||||
choice = random.choice(["","","S","SA","AA","A"])
|
choice = random.choice(["","","S","SA","AA","A"])
|
||||||
result += choice
|
result += choice
|
||||||
dice_result.append("boo"+choice)
|
dice_result.append("boo"+choice)
|
||||||
|
|
||||||
for _ in range(setb):
|
for _ in range(setb):
|
||||||
choice = random.choice(["","","F","F","H","H"])
|
choice = random.choice(["","","F","F","H","H"])
|
||||||
result += choice
|
result += choice
|
||||||
dice_result.append("setb"+choice)
|
dice_result.append("setb"+choice)
|
||||||
|
|
||||||
for _ in range (force):
|
for _ in range (force):
|
||||||
choice = random.choice(["B","B","B","B","B","B","BB","L","L","LL","LL","LL"])
|
choice = random.choice(["B","B","B","B","B","B","BB","L","L","LL","LL","LL"])
|
||||||
result += choice
|
result += choice
|
||||||
dice_result.append("force"+choice)
|
dice_result.append("force"+choice)
|
||||||
|
|
||||||
return result, dice_result
|
return result, dice_result
|
||||||
|
|
||||||
# Lets dice cancel each other out
|
# Lets dice cancel each other out
|
||||||
def simplify(self, result : str):
|
def simplify(self, result : str):
|
||||||
self.bot.log("Simplifying "+result)
|
self.bot.log("Simplifying "+result)
|
||||||
simp = ""
|
simp = ""
|
||||||
success = (result.count('S') + result.count('R')) - (result.count('F') + result.count('D'))
|
success = (result.count('S') + result.count('R')) - (result.count('F') + result.count('D'))
|
||||||
advantage = result.count('A') - result.count('H')
|
advantage = result.count('A') - result.count('H')
|
||||||
result = re.sub("S|A|F|H","",result)
|
result = re.sub("S|A|F|H","",result)
|
||||||
|
|
||||||
if success > 0:
|
if success > 0:
|
||||||
for _ in range(success):
|
for _ in range(success):
|
||||||
simp += "S"
|
simp += "S"
|
||||||
elif success < 0:
|
elif success < 0:
|
||||||
for _ in range(abs(success)):
|
for _ in range(abs(success)):
|
||||||
simp += "F"
|
simp += "F"
|
||||||
|
|
||||||
if advantage > 0:
|
if advantage > 0:
|
||||||
for _ in range(advantage):
|
for _ in range(advantage):
|
||||||
simp += "A"
|
simp += "A"
|
||||||
elif advantage < 0:
|
elif advantage < 0:
|
||||||
for _ in range(abs(advantage)):
|
for _ in range(abs(advantage)):
|
||||||
simp += "H"
|
simp += "H"
|
||||||
|
|
||||||
simp += result
|
simp += result
|
||||||
|
|
||||||
return simp
|
return simp
|
||||||
|
|
||||||
# Returns emoji that symbolize the dice results
|
# Returns emoji that symbolize the dice results
|
||||||
def dice_result_to_emoji(self, dice_results : list):
|
def dice_result_to_emoji(self, dice_results : list):
|
||||||
emoji = ""
|
emoji = ""
|
||||||
for result in dice_results:
|
for result in dice_results:
|
||||||
if result == "abiA":
|
if result == "abiA":
|
||||||
emoji += "<:abil1a:695267684476125264> "
|
emoji += "<:abil1a:695267684476125264> "
|
||||||
elif result == "abiSA":
|
elif result == "abiSA":
|
||||||
emoji += "<:abil1a1s:695267684484513842> "
|
emoji += "<:abil1a1s:695267684484513842> "
|
||||||
elif result == "abiS":
|
elif result == "abiS":
|
||||||
emoji += "<:abil1s:695267684514005013> "
|
emoji += "<:abil1s:695267684514005013> "
|
||||||
elif result == "abiAA":
|
elif result == "abiAA":
|
||||||
emoji += "<:abil2a:695267684547428352> "
|
emoji += "<:abil2a:695267684547428352> "
|
||||||
elif result == "abiSS":
|
elif result == "abiSS":
|
||||||
emoji += "<:abil2s:695267684761206914> "
|
emoji += "<:abil2s:695267684761206914> "
|
||||||
elif result == "abi":
|
elif result == "abi":
|
||||||
emoji += "<:abilbla:695267684660674602> "
|
emoji += "<:abilbla:695267684660674602> "
|
||||||
|
|
||||||
elif result == "profA":
|
elif result == "profA":
|
||||||
emoji += "<:prof1a:695267685361123338> "
|
emoji += "<:prof1a:695267685361123338> "
|
||||||
elif result == "profSA":
|
elif result == "profSA":
|
||||||
emoji += "<:prof1a1s:695267685067653140> "
|
emoji += "<:prof1a1s:695267685067653140> "
|
||||||
elif result == "profR":
|
elif result == "profR":
|
||||||
emoji += "<:prof1r:695267685067522088> "
|
emoji += "<:prof1r:695267685067522088> "
|
||||||
elif result == "profS":
|
elif result == "profS":
|
||||||
emoji += "<:prof1s:695267684899881012> "
|
emoji += "<:prof1s:695267684899881012> "
|
||||||
elif result == "profAA":
|
elif result == "profAA":
|
||||||
emoji += "<:prof2a:695267684996218982> "
|
emoji += "<:prof2a:695267684996218982> "
|
||||||
elif result == "profSS":
|
elif result == "profSS":
|
||||||
emoji += "<:prof2s:695267684878647327> "
|
emoji += "<:prof2s:695267684878647327> "
|
||||||
elif result == "prof":
|
elif result == "prof":
|
||||||
emoji += "<:profbla:695267684698292235> "
|
emoji += "<:profbla:695267684698292235> "
|
||||||
|
|
||||||
elif result == "difF":
|
elif result == "difF":
|
||||||
emoji += "<:dif1f:695267684924915804> "
|
emoji += "<:dif1f:695267684924915804> "
|
||||||
elif result == "difH":
|
elif result == "difH":
|
||||||
emoji += "<:dif1h:695267684908138506> "
|
emoji += "<:dif1h:695267684908138506> "
|
||||||
elif result == "difFH":
|
elif result == "difFH":
|
||||||
emoji += "<:dif1h1f:695267684908269678> "
|
emoji += "<:dif1h1f:695267684908269678> "
|
||||||
elif result == "difFF":
|
elif result == "difFF":
|
||||||
emoji += "<:dif2f:695267684924784680> "
|
emoji += "<:dif2f:695267684924784680> "
|
||||||
elif result == "difHH":
|
elif result == "difHH":
|
||||||
emoji += "<:dif2h:695267685071585340> "
|
emoji += "<:dif2h:695267685071585340> "
|
||||||
elif result == "dif":
|
elif result == "dif":
|
||||||
emoji += "<:difbla:695267685000544276> "
|
emoji += "<:difbla:695267685000544276> "
|
||||||
|
|
||||||
elif result == "chaD":
|
elif result == "chaD":
|
||||||
emoji += "<:cha1d:695267684962533447> "
|
emoji += "<:cha1d:695267684962533447> "
|
||||||
elif result == "chaF":
|
elif result == "chaF":
|
||||||
emoji += "<:cha1f:695267684601954346> "
|
emoji += "<:cha1f:695267684601954346> "
|
||||||
elif result == "chaH":
|
elif result == "chaH":
|
||||||
emoji += "<:cha1h:695267685046681620> "
|
emoji += "<:cha1h:695267685046681620> "
|
||||||
elif result == "chaFH":
|
elif result == "chaFH":
|
||||||
emoji += "<:cha1h1f:695267685063327784> "
|
emoji += "<:cha1h1f:695267685063327784> "
|
||||||
elif result == "chaFF":
|
elif result == "chaFF":
|
||||||
emoji += "<:cha2f:695267684832641097> "
|
emoji += "<:cha2f:695267684832641097> "
|
||||||
elif result == "chaHH":
|
elif result == "chaHH":
|
||||||
emoji += "<:cha2h:695267684631183381> "
|
emoji += "<:cha2h:695267684631183381> "
|
||||||
elif result == "cha":
|
elif result == "cha":
|
||||||
emoji += "<:chabla:695267684895686787> "
|
emoji += "<:chabla:695267684895686787> "
|
||||||
|
|
||||||
elif result == "booA":
|
elif result == "booA":
|
||||||
emoji += "<:boo1a:695267684975116329> "
|
emoji += "<:boo1a:695267684975116329> "
|
||||||
elif result == "booSA":
|
elif result == "booSA":
|
||||||
emoji += "<:boo1a1s:695267684970922024> "
|
emoji += "<:boo1a1s:695267684970922024> "
|
||||||
elif result == "booS":
|
elif result == "booS":
|
||||||
emoji += "<:boo1s:695267684979441714> "
|
emoji += "<:boo1s:695267684979441714> "
|
||||||
elif result == "booAA":
|
elif result == "booAA":
|
||||||
emoji += "<:boo2a:695267685100945488> "
|
emoji += "<:boo2a:695267685100945488> "
|
||||||
elif result == "boo":
|
elif result == "boo":
|
||||||
emoji += "<:boobla:695267684757012550> "
|
emoji += "<:boobla:695267684757012550> "
|
||||||
|
|
||||||
elif result == "setbF":
|
elif result == "setbF":
|
||||||
emoji += "<:set1f:695267685054939197> "
|
emoji += "<:set1f:695267685054939197> "
|
||||||
elif result == "setbH":
|
elif result == "setbH":
|
||||||
emoji += "<:set1h:695267685147082802> "
|
emoji += "<:set1h:695267685147082802> "
|
||||||
elif result == "setb":
|
elif result == "setb":
|
||||||
emoji += "<:setbla:695267685151408169> "
|
emoji += "<:setbla:695267685151408169> "
|
||||||
|
|
||||||
elif result == "forceB":
|
elif result == "forceB":
|
||||||
emoji += "<:for1b:695267684593434677> "
|
emoji += "<:for1b:695267684593434677> "
|
||||||
elif result == "forceL":
|
elif result == "forceL":
|
||||||
emoji += "<:for1l:695267684606148640> "
|
emoji += "<:for1l:695267684606148640> "
|
||||||
elif result == "forceBB":
|
elif result == "forceBB":
|
||||||
emoji += "<:for2b:695267684903944303> "
|
emoji += "<:for2b:695267684903944303> "
|
||||||
elif result == "forceLL":
|
elif result == "forceLL":
|
||||||
emoji += "<:for2l:695267684992024626> "
|
emoji += "<:for2l:695267684992024626> "
|
||||||
|
|
||||||
return emoji
|
return emoji
|
||||||
|
|
||||||
# Returns emoji that symbolize the results of the dice rolls
|
# Returns emoji that symbolize the results of the dice rolls
|
||||||
def result_to_emoji(self, result : str):
|
def result_to_emoji(self, result : str):
|
||||||
emoji = ""
|
emoji = ""
|
||||||
for char in result:
|
for char in result:
|
||||||
if char == 'S':
|
if char == 'S':
|
||||||
emoji += "<:success:826026925280854026> "
|
emoji += "<:success:826026925280854026> "
|
||||||
elif char == 'A':
|
elif char == 'A':
|
||||||
emoji += "<:advantage:826026925515604009> "
|
emoji += "<:advantage:826026925515604009> "
|
||||||
elif char == 'R':
|
elif char == 'R':
|
||||||
emoji += "<:triumph:826026925319127070> "
|
emoji += "<:triumph:826026925319127070> "
|
||||||
elif char == 'F':
|
elif char == 'F':
|
||||||
emoji += "<:failure:826026925288980511> "
|
emoji += "<:failure:826026925288980511> "
|
||||||
elif char == 'H':
|
elif char == 'H':
|
||||||
emoji += "<:threat:826026925280985108> "
|
emoji += "<:threat:826026925280985108> "
|
||||||
elif char == 'D':
|
elif char == 'D':
|
||||||
emoji += "<:despair:826026925272203294> "
|
emoji += "<:despair:826026925272203294> "
|
||||||
elif char == 'L':
|
elif char == 'L':
|
||||||
emoji += "<:light:826026925059211295>"
|
emoji += "<:light:826026925059211295>"
|
||||||
elif char == 'B':
|
elif char == 'B':
|
||||||
emoji += "<:dark:826026925289373717>"
|
emoji += "<:dark:826026925289373717>"
|
||||||
|
|
||||||
return emoji
|
return emoji
|
||||||
|
|
||||||
# Converts emoji into letters
|
# Converts emoji into letters
|
||||||
def emoji_to_result(self, emoji : str):
|
def emoji_to_result(self, emoji : str):
|
||||||
result = ""
|
result = ""
|
||||||
for char in emoji:
|
for char in emoji:
|
||||||
if char == "<:light:691010089905029171>":
|
if char == "<:light:691010089905029171>":
|
||||||
emoji += 'L'
|
emoji += 'L'
|
||||||
if char == "<:dark:691010101901000852>":
|
if char == "<:dark:691010101901000852>":
|
||||||
emoji += 'B'
|
emoji += 'B'
|
||||||
|
|
||||||
return result
|
return result
|
||||||
|
|
||||||
# Returns emoji that symbolize the dice
|
# Returns emoji that symbolize the dice
|
||||||
def dice_to_emoji(self, dice : list):
|
def dice_to_emoji(self, dice : list):
|
||||||
emoji = ""
|
emoji = ""
|
||||||
|
|
||||||
for _ in range(dice[0]):
|
for _ in range(dice[0]):
|
||||||
emoji += "<:ability:690974213397282826> "
|
emoji += "<:ability:690974213397282826> "
|
||||||
for _ in range(dice[1]):
|
for _ in range(dice[1]):
|
||||||
emoji += "<:proficiency:690973435354153071> "
|
emoji += "<:proficiency:690973435354153071> "
|
||||||
for _ in range(dice[2]):
|
for _ in range(dice[2]):
|
||||||
emoji += "<:difficulty:690973992470708296> "
|
emoji += "<:difficulty:690973992470708296> "
|
||||||
for _ in range(dice[3]):
|
for _ in range(dice[3]):
|
||||||
emoji += "<:challenge:690973419906400306> "
|
emoji += "<:challenge:690973419906400306> "
|
||||||
for _ in range(dice[4]):
|
for _ in range(dice[4]):
|
||||||
emoji += "<:boost:690972178216386561> "
|
emoji += "<:boost:690972178216386561> "
|
||||||
for _ in range(dice[5]):
|
for _ in range(dice[5]):
|
||||||
emoji += "<:setback:690972157890658415> "
|
emoji += "<:setback:690972157890658415> "
|
||||||
for _ in range(dice[6]):
|
for _ in range(dice[6]):
|
||||||
emoji += "<:force:690973451883774013> "
|
emoji += "<:force:690973451883774013> "
|
||||||
|
|
||||||
return emoji
|
return emoji
|
||||||
|
|
||||||
# Rolls for obligation
|
# Rolls for obligation
|
||||||
def obligation_roll(self):
|
def obligation_roll(self):
|
||||||
self.bot.log("Rolling for obligation")
|
self.bot.log("Rolling for obligation")
|
||||||
data = self.bot.database["starwarscharacters"]
|
data = self.bot.database["starwarscharacters"]
|
||||||
|
|
||||||
table = []
|
table = []
|
||||||
|
|
||||||
for character in data:
|
for character in data:
|
||||||
for obligation in data[character]["Obligations"]:
|
for obligation in data[character]["Obligations"]:
|
||||||
for _ in range(data[character]["Obligations"][obligation]):
|
for _ in range(data[character]["Obligations"][obligation]):
|
||||||
table.append(data[character]["Name"]+", "+obligation)
|
table.append(data[character]["Name"]+", "+obligation)
|
||||||
|
|
||||||
while len(table) < 100:
|
while len(table) < 100:
|
||||||
table.append("Nothing")
|
table.append("Nothing")
|
||||||
|
|
||||||
return random.choice(table)
|
return random.choice(table)
|
||||||
|
|
||||||
# Rolls for critical injury
|
# Rolls for critical injury
|
||||||
async def crit_roll(self, ctx, addington : int):
|
async def crit_roll(self, ctx, addington : int):
|
||||||
difficulty_die = "<:difficulty:690973992470708296>"
|
difficulty_die = "<:difficulty:690973992470708296>"
|
||||||
setback_die = "<:setback:690972157890658415>"
|
setback_die = "<:setback:690972157890658415>"
|
||||||
boost_die = "<:boost:690972178216386561>"
|
boost_die = "<:boost:690972178216386561>"
|
||||||
roll = random.randint(1,100) + addington
|
roll = random.randint(1,100) + addington
|
||||||
injuries = [
|
injuries = [
|
||||||
"**Minor nick**: The target suffers 1 strain, "+difficulty_die] * 5 + [
|
"**Minor nick**: The target suffers 1 strain, "+difficulty_die] * 5 + [
|
||||||
"**Slowed down**: The target can only act during the last allied initiative slot this turn, "+difficulty_die] * 5 + [
|
"**Slowed down**: The target can only act during the last allied initiative slot this turn, "+difficulty_die] * 5 + [
|
||||||
"**Sudden Jolt**: The target drops whatever is in hand, "+difficulty_die] * 5 + [
|
"**Sudden Jolt**: The target drops whatever is in hand, "+difficulty_die] * 5 + [
|
||||||
"**Distracted**: The target cannot perform a Free maneuver during his next turn, "+difficulty_die] * 5 + [
|
"**Distracted**: The target cannot perform a Free maneuver during his next turn, "+difficulty_die] * 5 + [
|
||||||
"**Off-Balance**: The target adds "+setback_die+" to his next skill check, "+difficulty_die] * 5 + [
|
"**Off-Balance**: The target adds "+setback_die+" to his next skill check, "+difficulty_die] * 5 + [
|
||||||
"**Discouraging Wound**: Flip one light side Destiny point to a dark side Destiny point (reverse if NPC), "+difficulty_die] * 5 + [
|
"**Discouraging Wound**: Flip one light side Destiny point to a dark side Destiny point (reverse if NPC), "+difficulty_die] * 5 + [
|
||||||
"**Stunned**: The target is staggered until the end of his next turn, "+difficulty_die] * 5 + [
|
"**Stunned**: The target is staggered until the end of his next turn, "+difficulty_die] * 5 + [
|
||||||
"**Stinger**: Increase the difficulty of next check by one, "+difficulty_die] * 5 + [
|
"**Stinger**: Increase the difficulty of next check by one, "+difficulty_die] * 5 + [
|
||||||
"**Bowled Over**: The target is knocked prone and suffers 1 strain, "+difficulty_die+difficulty_die] * 5 + [
|
"**Bowled Over**: The target is knocked prone and suffers 1 strain, "+difficulty_die+difficulty_die] * 5 + [
|
||||||
"**Head Ringer**: The target increases the difficulty of all Intellect and Cunning checks by one until the end of the encounter, "+difficulty_die+difficulty_die] * 5 + [
|
"**Head Ringer**: The target increases the difficulty of all Intellect and Cunning checks by one until the end of the encounter, "+difficulty_die+difficulty_die] * 5 + [
|
||||||
"**Fearsome Wound**: The target increases the difficulty of all Presence and Willpower checks by one until the end of the encounter, "+difficulty_die+difficulty_die] * 5 + [
|
"**Fearsome Wound**: The target increases the difficulty of all Presence and Willpower checks by one until the end of the encounter, "+difficulty_die+difficulty_die] * 5 + [
|
||||||
"**Agonizing Wound**: The target increases the difficulty of all Brawn and Agility checks by one until the end of the encounter, "+difficulty_die+difficulty_die] * 5 + [
|
"**Agonizing Wound**: The target increases the difficulty of all Brawn and Agility checks by one until the end of the encounter, "+difficulty_die+difficulty_die] * 5 + [
|
||||||
"**Slightly Dazed**: The target is disoriented until the end of the encounter, "+difficulty_die+difficulty_die] * 5 + [
|
"**Slightly Dazed**: The target is disoriented until the end of the encounter, "+difficulty_die+difficulty_die] * 5 + [
|
||||||
"**Scattered Senses**: The target removes all "+boost_die+" from skill checks until the end of the encounter, "+difficulty_die+difficulty_die] * 5 + [
|
"**Scattered Senses**: The target removes all "+boost_die+" from skill checks until the end of the encounter, "+difficulty_die+difficulty_die] * 5 + [
|
||||||
"**Hamstrung**: The target loses his free maneuver until the end of the encounter, "+difficulty_die+difficulty_die] * 5 + [
|
"**Hamstrung**: The target loses his free maneuver until the end of the encounter, "+difficulty_die+difficulty_die] * 5 + [
|
||||||
"**Overpowered**: The target leaves himself open, and the attacker may immediately attempt another free attack agains him, using the exact same pool as the original, "+difficulty_die+difficulty_die] * 5 + [
|
"**Overpowered**: The target leaves himself open, and the attacker may immediately attempt another free attack agains him, using the exact same pool as the original, "+difficulty_die+difficulty_die] * 5 + [
|
||||||
"**Winded**: Until the end of the encounter, the target cannot voluntarily suffer strain to activate any abilities or gain additional maneuvers, "+difficulty_die+difficulty_die] * 5 + [
|
"**Winded**: Until the end of the encounter, the target cannot voluntarily suffer strain to activate any abilities or gain additional maneuvers, "+difficulty_die+difficulty_die] * 5 + [
|
||||||
"**Compromised**: Incerase difficulty of all skill checks by one until the end of the encounter, "+difficulty_die+difficulty_die] * 5 + [
|
"**Compromised**: Incerase difficulty of all skill checks by one until the end of the encounter, "+difficulty_die+difficulty_die] * 5 + [
|
||||||
"**At the brink**: The target suffers 1 strain each time he performs an action, "+difficulty_die+difficulty_die+difficulty_die] * 5 + [
|
"**At the brink**: The target suffers 1 strain each time he performs an action, "+difficulty_die+difficulty_die+difficulty_die] * 5 + [
|
||||||
"**Crippled**: One of the target's limbs (selected by the GM) is crippled until healed or replaced. Increase difficulty of all checks that require use of that limb by one, "+difficulty_die+difficulty_die+difficulty_die] * 5 + [
|
"**Crippled**: One of the target's limbs (selected by the GM) is crippled until healed or replaced. Increase difficulty of all checks that require use of that limb by one, "+difficulty_die+difficulty_die+difficulty_die] * 5 + [
|
||||||
"**Maimed**: One of the target's limbs (selected by the GM) is permanently lost. Unless the target has a cybernetic replacement, the target cannot perform actions that would require the use of that limb. All other actions gain "+setback_die+", "+difficulty_die+difficulty_die+difficulty_die] * 5 + [
|
"**Maimed**: One of the target's limbs (selected by the GM) is permanently lost. Unless the target has a cybernetic replacement, the target cannot perform actions that would require the use of that limb. All other actions gain "+setback_die+", "+difficulty_die+difficulty_die+difficulty_die] * 5 + [
|
||||||
"HI"] * 5 + [
|
"HI"] * 5 + [
|
||||||
"**Temporarily Lame**: Until this critical injury is healed, the target cannot perform more than one maneuver during his turn, "+difficulty_die+difficulty_die+difficulty_die] * 5 + [
|
"**Temporarily Lame**: Until this critical injury is healed, the target cannot perform more than one maneuver during his turn, "+difficulty_die+difficulty_die+difficulty_die] * 5 + [
|
||||||
"**Blinded**: The target can no longer see. Upgrade the difficulty of all checks twice. Upgrade the difficulty of perception checks three times, "+difficulty_die+difficulty_die+difficulty_die] * 5 + [
|
"**Blinded**: The target can no longer see. Upgrade the difficulty of all checks twice. Upgrade the difficulty of perception checks three times, "+difficulty_die+difficulty_die+difficulty_die] * 5 + [
|
||||||
"**Knocked Senseless**: The target is staggered for the remainder of the encounter, "+difficulty_die+difficulty_die+difficulty_die] * 5 + [
|
"**Knocked Senseless**: The target is staggered for the remainder of the encounter, "+difficulty_die+difficulty_die+difficulty_die] * 5 + [
|
||||||
"GI"] * 5 + [
|
"GI"] * 5 + [
|
||||||
"**Bleeding Out**: Every round, the target suffers 1 wound and 1 strain at the beginning of his turn. For every five wounds he suffers beyond his wound threshold, he suffers one additional critical injury. (If he suffers this one again, roll again), "+difficulty_die+difficulty_die+difficulty_die+difficulty_die] * 10 + [
|
"**Bleeding Out**: Every round, the target suffers 1 wound and 1 strain at the beginning of his turn. For every five wounds he suffers beyond his wound threshold, he suffers one additional critical injury. (If he suffers this one again, roll again), "+difficulty_die+difficulty_die+difficulty_die+difficulty_die] * 10 + [
|
||||||
"**The End is Nigh**: The target will die after the last initiative slot during the next round, "+difficulty_die+difficulty_die+difficulty_die+difficulty_die] * 10 + [
|
"**The End is Nigh**: The target will die after the last initiative slot during the next round, "+difficulty_die+difficulty_die+difficulty_die+difficulty_die] * 10 + [
|
||||||
"**Dead**: U B Dead :("]
|
"**Dead**: U B Dead :("]
|
||||||
|
|
||||||
if roll >= len(injuries):
|
if roll >= len(injuries):
|
||||||
results = injuries[-1]
|
results = injuries[-1]
|
||||||
|
else:
|
||||||
|
results = injuries[roll]
|
||||||
|
|
||||||
|
if results == "HI":
|
||||||
|
characteristic = random.choice(["brawn"] * 3 + ["agility"] * 3 + ["intellect", "cunning", "presence"])
|
||||||
|
results = "**Horrific Injury**: Until this criticil injury is healed, treat the target's "+characteristic+" as if it's one lower, "+difficulty_die+difficulty_die+difficulty_die
|
||||||
|
|
||||||
|
if results == "GI":
|
||||||
|
characteristic = random.choice(["brawn"] * 3 + ["agility"] * 3 + ["intellect", "cunning", "presence"])
|
||||||
|
results = "**Gruesome Injury**: The target's "+characteristic+" is permanently one lower, "+difficulty_die+difficulty_die+difficulty_die+difficulty_die
|
||||||
|
|
||||||
|
send_message = "Roll: "+str(roll)+"\nInjury:\n"+results
|
||||||
|
|
||||||
|
message_list = send_message.split("\n")
|
||||||
|
await ctx.send(message_list[0])
|
||||||
|
if len(message_list) > 1:
|
||||||
|
for message_item in message_list[1:]:
|
||||||
|
await ctx.channel.send(message_item)
|
||||||
|
|
||||||
|
# Parses the command into something the other functions understand
|
||||||
|
async def parse_roll(self, ctx, cmd : str = ""):
|
||||||
|
user = f"#{ctx.author.id}"
|
||||||
|
cmd = re.sub(' +',' ',cmd.upper()) + " "
|
||||||
|
if cmd[0] == " ":
|
||||||
|
cmd = cmd[1:]
|
||||||
|
cmd = self.bot.star_wars.character.replaceSpaces(string.capwords(cmd))
|
||||||
|
commands = cmd.split(" ")
|
||||||
|
valid_command = False
|
||||||
|
|
||||||
|
if commands[0] == "":
|
||||||
|
roll_parameters = [1,0,3,0,0,0,0]
|
||||||
|
else:
|
||||||
|
roll_parameters = [0,0,0,0,0,0,0]
|
||||||
|
|
||||||
|
if string.capwords(commands[0]) == "Obligations":
|
||||||
|
send_message = self.obligation_roll()
|
||||||
|
|
||||||
|
elif string.capwords(commands[0]) in skill_data:
|
||||||
|
self.bot.log("Oh look! This guy has skills!")
|
||||||
|
if self.bot.star_wars.character.userHasChar(user):
|
||||||
|
self.bot.log("They have a character. That much we know")
|
||||||
|
skill_level = self.bot.star_wars.character.char_data(user,"Skills " + string.capwords(commands[0]))
|
||||||
|
|
||||||
|
if string.capwords(commands[0]) == "Lightsaber":
|
||||||
|
self.bot.log("The skill is lightsaber")
|
||||||
|
char_level = self.bot.star_wars.character.char_data(user,"Characteristics " + self.bot.star_wars.character.lightsaberChar(user))
|
||||||
else:
|
else:
|
||||||
results = injuries[roll]
|
char_level = self.bot.star_wars.character.char_data(user,"Characteristics " + skill_data[string.capwords(commands[0])])
|
||||||
|
|
||||||
if results == "HI":
|
ability_dice = abs(char_level-skill_level)
|
||||||
characteristic = random.choice(["brawn"] * 3 + ["agility"] * 3 + ["intellect", "cunning", "presence"])
|
proficiency_dice = min(skill_level,char_level)
|
||||||
results = "**Horrific Injury**: Until this criticil injury is healed, treat the target's "+characteristic+" as if it's one lower, "+difficulty_die+difficulty_die+difficulty_die
|
|
||||||
|
|
||||||
if results == "GI":
|
commands = [str(ability_dice)] + [str(proficiency_dice)] + commands[1:]
|
||||||
characteristic = random.choice(["brawn"] * 3 + ["agility"] * 3 + ["intellect", "cunning", "presence"])
|
self.bot.log("Converted skill to dice")
|
||||||
results = "**Gruesome Injury**: The target's "+characteristic+" is permanently one lower, "+difficulty_die+difficulty_die+difficulty_die+difficulty_die
|
valid_command = True
|
||||||
|
else:
|
||||||
|
self.bot.log("Okay, no they don't i guess")
|
||||||
|
send_message = "You don't have a user. You can make one with /starwarscharacter"
|
||||||
|
|
||||||
send_message = "Roll: "+str(roll)+"\nInjury:\n"+results
|
elif string.capwords(commands[0]) in ["Ranged","Piloting"]:
|
||||||
|
self.bot.log("They fucked up writing the name of a ranged or piloting skill")
|
||||||
|
if string.capwords(commands[0]) == "Ranged":
|
||||||
|
send_message = "Did you mean \"Ranged - Heavy\" or \"Ranged - Light\""
|
||||||
|
else:
|
||||||
|
send_message = "Did you mean \"Piloting - Planetary\" or \"Piloting - Space\""
|
||||||
|
else:
|
||||||
|
valid_command = True
|
||||||
|
|
||||||
message_list = send_message.split("\n")
|
if valid_command:
|
||||||
await ctx.send(message_list[0])
|
self.bot.log("Converting commands to dice")
|
||||||
if len(message_list) > 1:
|
for i, command in enumerate(commands):
|
||||||
for message_item in message_list[1:]:
|
if command != "":
|
||||||
await ctx.channel.send(message_item)
|
command = command.upper()
|
||||||
|
if command[0] == "A":
|
||||||
|
roll_parameters[0] = int(command.replace("A",""))
|
||||||
|
elif command[0] == "P":
|
||||||
|
roll_parameters[1] = int(command.replace("P",""))
|
||||||
|
elif command[0] == "D":
|
||||||
|
roll_parameters[2] = int(command.replace("D",""))
|
||||||
|
elif command[0] == "C":
|
||||||
|
roll_parameters[3] = int(command.replace("C",""))
|
||||||
|
elif command[0] == "B":
|
||||||
|
roll_parameters[4] = int(command.replace("B",""))
|
||||||
|
elif command[0] == "S":
|
||||||
|
roll_parameters[5] = int(command.replace("S",""))
|
||||||
|
elif command[0] == "F":
|
||||||
|
roll_parameters[6] = int(command.replace("F",""))
|
||||||
|
else:
|
||||||
|
roll_parameters[i] = int(command)
|
||||||
|
|
||||||
# Parses the command into something the other functions understand
|
self.bot.log("Rolling "+str(roll_parameters))
|
||||||
async def parse_roll(self, ctx, cmd : str = ""):
|
roll_results, dice_results = self.roll(roll_parameters[0],roll_parameters[1],roll_parameters[2],roll_parameters[3],roll_parameters[4],roll_parameters[5],roll_parameters[6])
|
||||||
user = f"#{ctx.author.id}"
|
|
||||||
cmd = re.sub(' +',' ',cmd.upper()) + " "
|
|
||||||
if cmd[0] == " ":
|
|
||||||
cmd = cmd[1:]
|
|
||||||
cmd = self.bot.star_wars.character.replaceSpaces(string.capwords(cmd))
|
|
||||||
commands = cmd.split(" ")
|
|
||||||
valid_command = False
|
|
||||||
|
|
||||||
if commands[0] == "":
|
simplified = self.simplify(roll_results)
|
||||||
roll_parameters = [1,0,3,0,0,0,0]
|
|
||||||
|
name = self.bot.star_wars.character.getChar_name(user)
|
||||||
|
|
||||||
|
self.bot.log("Returns results and simplified results")
|
||||||
|
|
||||||
|
if simplified == "":
|
||||||
|
send_message = name + " rolls: " + "\n" + self.dice_result_to_emoji(dice_results) + "\nEverything cancels out!"
|
||||||
|
else:
|
||||||
|
send_message = name + " rolls: " + "\n" + self.dice_result_to_emoji(dice_results) + "\n" + self.result_to_emoji(simplified)
|
||||||
|
|
||||||
|
message_list = send_message.split("\n")
|
||||||
|
await ctx.send(message_list[0])
|
||||||
|
if len(message_list) > 1:
|
||||||
|
for message_item in message_list[1:]:
|
||||||
|
if message_item == "":
|
||||||
|
self.bot.log("Tried to send empty message")
|
||||||
else:
|
else:
|
||||||
roll_parameters = [0,0,0,0,0,0,0]
|
await ctx.channel.send(message_item)
|
||||||
|
|
||||||
if string.capwords(commands[0]) == "Obligations":
|
|
||||||
send_message = self.obligation_roll()
|
|
||||||
|
|
||||||
elif string.capwords(commands[0]) in skill_data:
|
|
||||||
self.bot.log("Oh look! This guy has skills!")
|
|
||||||
if self.bot.star_wars.character.userHasChar(user):
|
|
||||||
self.bot.log("They have a character. That much we know")
|
|
||||||
skill_level = self.bot.star_wars.character.char_data(user,"Skills " + string.capwords(commands[0]))
|
|
||||||
|
|
||||||
if string.capwords(commands[0]) == "Lightsaber":
|
|
||||||
self.bot.log("The skill is lightsaber")
|
|
||||||
char_level = self.bot.star_wars.character.char_data(user,"Characteristics " + self.bot.star_wars.character.lightsaberChar(user))
|
|
||||||
else:
|
|
||||||
char_level = self.bot.star_wars.character.char_data(user,"Characteristics " + skill_data[string.capwords(commands[0])])
|
|
||||||
|
|
||||||
ability_dice = abs(char_level-skill_level)
|
|
||||||
proficiency_dice = min(skill_level,char_level)
|
|
||||||
|
|
||||||
commands = [str(ability_dice)] + [str(proficiency_dice)] + commands[1:]
|
|
||||||
self.bot.log("Converted skill to dice")
|
|
||||||
valid_command = True
|
|
||||||
else:
|
|
||||||
self.bot.log("Okay, no they don't i guess")
|
|
||||||
send_message = "You don't have a user. You can make one with /starwarscharacter"
|
|
||||||
|
|
||||||
elif string.capwords(commands[0]) in ["Ranged","Piloting"]:
|
|
||||||
self.bot.log("They fucked up writing the name of a ranged or piloting skill")
|
|
||||||
if string.capwords(commands[0]) == "Ranged":
|
|
||||||
send_message = "Did you mean \"Ranged - Heavy\" or \"Ranged - Light\""
|
|
||||||
else:
|
|
||||||
send_message = "Did you mean \"Piloting - Planetary\" or \"Piloting - Space\""
|
|
||||||
else:
|
|
||||||
valid_command = True
|
|
||||||
|
|
||||||
if valid_command:
|
|
||||||
self.bot.log("Converting commands to dice")
|
|
||||||
for i, command in enumerate(commands):
|
|
||||||
if command != "":
|
|
||||||
command = command.upper()
|
|
||||||
if command[0] == "A":
|
|
||||||
roll_parameters[0] = int(command.replace("A",""))
|
|
||||||
elif command[0] == "P":
|
|
||||||
roll_parameters[1] = int(command.replace("P",""))
|
|
||||||
elif command[0] == "D":
|
|
||||||
roll_parameters[2] = int(command.replace("D",""))
|
|
||||||
elif command[0] == "C":
|
|
||||||
roll_parameters[3] = int(command.replace("C",""))
|
|
||||||
elif command[0] == "B":
|
|
||||||
roll_parameters[4] = int(command.replace("B",""))
|
|
||||||
elif command[0] == "S":
|
|
||||||
roll_parameters[5] = int(command.replace("S",""))
|
|
||||||
elif command[0] == "F":
|
|
||||||
roll_parameters[6] = int(command.replace("F",""))
|
|
||||||
else:
|
|
||||||
roll_parameters[i] = int(command)
|
|
||||||
|
|
||||||
self.bot.log("Rolling "+str(roll_parameters))
|
|
||||||
roll_results, dice_results = self.roll(roll_parameters[0],roll_parameters[1],roll_parameters[2],roll_parameters[3],roll_parameters[4],roll_parameters[5],roll_parameters[6])
|
|
||||||
|
|
||||||
simplified = self.simplify(roll_results)
|
|
||||||
|
|
||||||
name = self.bot.star_wars.character.getChar_name(user)
|
|
||||||
|
|
||||||
self.bot.log("Returns results and simplified results")
|
|
||||||
|
|
||||||
if simplified == "":
|
|
||||||
send_message = name + " rolls: " + "\n" + self.dice_result_to_emoji(dice_results) + "\nEverything cancels out!"
|
|
||||||
else:
|
|
||||||
send_message = name + " rolls: " + "\n" + self.dice_result_to_emoji(dice_results) + "\n" + self.result_to_emoji(simplified)
|
|
||||||
|
|
||||||
message_list = send_message.split("\n")
|
|
||||||
await ctx.send(message_list[0])
|
|
||||||
if len(message_list) > 1:
|
|
||||||
for message_item in message_list[1:]:
|
|
||||||
if message_item == "":
|
|
||||||
self.bot.log("Tried to send empty message")
|
|
||||||
else:
|
|
||||||
await ctx.channel.send(message_item)
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ Contains the Gwendolyn class, a subclass of the discord command bot.
|
|||||||
|
|
||||||
*Classes*
|
*Classes*
|
||||||
---------
|
---------
|
||||||
Gwendolyn(discord.ext.commands.Bot)
|
Gwendolyn(discord.ext.commands.Bot)
|
||||||
"""
|
"""
|
||||||
import os # Used for loading cogs in Gwendolyn.addCogs
|
import os # Used for loading cogs in Gwendolyn.addCogs
|
||||||
import discord # Used for discord.Intents and discord.Status
|
import discord # Used for discord.Intents and discord.Status
|
||||||
@@ -14,119 +14,119 @@ from discord.ext import commands # Used to inherit from commands.bot
|
|||||||
from pymongo import MongoClient # Used for database management
|
from pymongo import MongoClient # Used for database management
|
||||||
from gwendolyn_old.funcs import Money, StarWars, Games, Other, LookupFuncs
|
from gwendolyn_old.funcs import Money, StarWars, Games, Other, LookupFuncs
|
||||||
from gwendolyn_old.utils import (get_options, get_credentials, log_this,
|
from gwendolyn_old.utils import (get_options, get_credentials, log_this,
|
||||||
DatabaseFuncs, EventHandler, ErrorHandler,
|
DatabaseFuncs, EventHandler, ErrorHandler,
|
||||||
long_strings)
|
long_strings)
|
||||||
|
|
||||||
|
|
||||||
class Gwendolyn(commands.Bot):
|
class Gwendolyn(commands.Bot):
|
||||||
|
"""
|
||||||
|
A multifunctional Discord bot.
|
||||||
|
|
||||||
|
*Methods*
|
||||||
|
---------
|
||||||
|
log(messages: Union[str, list], channel: str = "",
|
||||||
|
level: int = 20)
|
||||||
|
stop(ctx: interactions.SlashContext)
|
||||||
|
defer(ctx: interactions.SlashContext)
|
||||||
|
"""
|
||||||
|
# pylint: disable=too-many-instance-attributes
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
"""Initialize the bot."""
|
||||||
|
intents = discord.Intents.default()
|
||||||
|
intents.members = True
|
||||||
|
initiation_parameters = {
|
||||||
|
"command_prefix": " ",
|
||||||
|
"case_insensitive": True,
|
||||||
|
"intents": intents,
|
||||||
|
"status": discord.Status.dnd
|
||||||
|
}
|
||||||
|
super().__init__(**initiation_parameters)
|
||||||
|
|
||||||
|
self._add_clients_and_options()
|
||||||
|
self._add_util_classes()
|
||||||
|
self._add_function_containers()
|
||||||
|
self._add_cogs()
|
||||||
|
|
||||||
|
def _add_clients_and_options(self):
|
||||||
|
"""Add all the client, option and credentials objects."""
|
||||||
|
self.long_strings = long_strings()
|
||||||
|
self.options = get_options()
|
||||||
|
self.credentials = get_credentials()
|
||||||
|
mongo_user = self.credentials["mongo_db_user"]
|
||||||
|
mongo_password = self.credentials["mongo_db_password"]
|
||||||
|
mongo_url = f"mongodb+srv://{mongo_user}:{mongo_password}@gwendolyn"
|
||||||
|
mongo_url += ".qkwfy.mongodb.net/Gwendolyn?retryWrites=true&w=majority"
|
||||||
|
database_clint = MongoClient(mongo_url)
|
||||||
|
|
||||||
|
if self.options["testing"]:
|
||||||
|
self.log("Testing mode")
|
||||||
|
self.database = database_clint["Gwendolyn-Test"]
|
||||||
|
else:
|
||||||
|
self.database = database_clint["Gwendolyn"]
|
||||||
|
|
||||||
|
def _add_util_classes(self):
|
||||||
|
"""Add all the classes used as utility."""
|
||||||
|
self.database_funcs = DatabaseFuncs(self)
|
||||||
|
self.event_handler = EventHandler(self)
|
||||||
|
self.error_handler = ErrorHandler(self)
|
||||||
|
slash_parameters = {
|
||||||
|
"sync_commands": True,
|
||||||
|
"sync_on_cog_reload": True,
|
||||||
|
"override_type": True
|
||||||
|
}
|
||||||
|
self.slash = interactions.SlashCommand(self, **slash_parameters)
|
||||||
|
|
||||||
|
def _add_function_containers(self):
|
||||||
|
"""Add all the function containers used for commands."""
|
||||||
|
self.star_wars = StarWars(self)
|
||||||
|
self.other = Other(self)
|
||||||
|
self.lookup_funcs = LookupFuncs(self)
|
||||||
|
self.games = Games(self)
|
||||||
|
self.money = Money(self)
|
||||||
|
|
||||||
|
def _add_cogs(self):
|
||||||
|
"""Load cogs."""
|
||||||
|
for filename in os.listdir("./gwendolyn/cogs"):
|
||||||
|
if filename.endswith(".py"):
|
||||||
|
self.load_extension(f"gwendolyn.cogs.{filename[:-3]}")
|
||||||
|
|
||||||
|
def log(self, messages, channel: str = "", level: int = 20): # pylint:disable=no-self-use
|
||||||
|
"""Log a message. Described in utils/util_functions.py."""
|
||||||
|
log_this(messages, channel, level)
|
||||||
|
|
||||||
|
async def stop(self, ctx: interactions.SlashContext):
|
||||||
"""
|
"""
|
||||||
A multifunctional Discord bot.
|
Stop the bot, and stop running games.
|
||||||
|
|
||||||
*Methods*
|
Only stops the bot if the user in ctx.author is one of the
|
||||||
---------
|
admins given in options.txt.
|
||||||
log(messages: Union[str, list], channel: str = "",
|
|
||||||
level: int = 20)
|
*parameters*
|
||||||
stop(ctx: interactions.SlashContext)
|
------------
|
||||||
defer(ctx: interactions.SlashContext)
|
ctx: interactions.SlashContext
|
||||||
|
The context of the "/stop" slash command.
|
||||||
"""
|
"""
|
||||||
# pylint: disable=too-many-instance-attributes
|
if f"#{ctx.author.id}" in self.options["admins"]:
|
||||||
|
await ctx.send("Pulling git repo and restarting...")
|
||||||
|
|
||||||
def __init__(self):
|
await self.change_presence(status=discord.Status.offline)
|
||||||
"""Initialize the bot."""
|
|
||||||
intents = discord.Intents.default()
|
|
||||||
intents.members = True
|
|
||||||
initiation_parameters = {
|
|
||||||
"command_prefix": " ",
|
|
||||||
"case_insensitive": True,
|
|
||||||
"intents": intents,
|
|
||||||
"status": discord.Status.dnd
|
|
||||||
}
|
|
||||||
super().__init__(**initiation_parameters)
|
|
||||||
|
|
||||||
self._add_clients_and_options()
|
self.database_funcs.wipe_games()
|
||||||
self._add_util_classes()
|
if not self.options["testing"]:
|
||||||
self._add_function_containers()
|
git_client = git.cmd.Git("")
|
||||||
self._add_cogs()
|
git_client.pull()
|
||||||
|
|
||||||
def _add_clients_and_options(self):
|
self.log("Logging out", level=25)
|
||||||
"""Add all the client, option and credentials objects."""
|
await self.close()
|
||||||
self.long_strings = long_strings()
|
else:
|
||||||
self.options = get_options()
|
log_message = f"{ctx.author.display_name} tried to stop me!"
|
||||||
self.credentials = get_credentials()
|
self.log(log_message, str(ctx.channel_id))
|
||||||
mongo_user = self.credentials["mongo_db_user"]
|
await ctx.send(f"I don't think I will, {ctx.author.display_name}")
|
||||||
mongo_password = self.credentials["mongo_db_password"]
|
|
||||||
mongo_url = f"mongodb+srv://{mongo_user}:{mongo_password}@gwendolyn"
|
|
||||||
mongo_url += ".qkwfy.mongodb.net/Gwendolyn?retryWrites=true&w=majority"
|
|
||||||
database_clint = MongoClient(mongo_url)
|
|
||||||
|
|
||||||
if self.options["testing"]:
|
async def defer(self, ctx: interactions.SlashContext):
|
||||||
self.log("Testing mode")
|
"""Send a "Gwendolyn is thinking" message to the user."""
|
||||||
self.database = database_clint["Gwendolyn-Test"]
|
try:
|
||||||
else:
|
await ctx.defer()
|
||||||
self.database = database_clint["Gwendolyn"]
|
except interactions.error.AlreadyResponded:
|
||||||
|
self.log("defer failed")
|
||||||
def _add_util_classes(self):
|
|
||||||
"""Add all the classes used as utility."""
|
|
||||||
self.database_funcs = DatabaseFuncs(self)
|
|
||||||
self.event_handler = EventHandler(self)
|
|
||||||
self.error_handler = ErrorHandler(self)
|
|
||||||
slash_parameters = {
|
|
||||||
"sync_commands": True,
|
|
||||||
"sync_on_cog_reload": True,
|
|
||||||
"override_type": True
|
|
||||||
}
|
|
||||||
self.slash = interactions.SlashCommand(self, **slash_parameters)
|
|
||||||
|
|
||||||
def _add_function_containers(self):
|
|
||||||
"""Add all the function containers used for commands."""
|
|
||||||
self.star_wars = StarWars(self)
|
|
||||||
self.other = Other(self)
|
|
||||||
self.lookup_funcs = LookupFuncs(self)
|
|
||||||
self.games = Games(self)
|
|
||||||
self.money = Money(self)
|
|
||||||
|
|
||||||
def _add_cogs(self):
|
|
||||||
"""Load cogs."""
|
|
||||||
for filename in os.listdir("./gwendolyn/cogs"):
|
|
||||||
if filename.endswith(".py"):
|
|
||||||
self.load_extension(f"gwendolyn.cogs.{filename[:-3]}")
|
|
||||||
|
|
||||||
def log(self, messages, channel: str = "", level: int = 20): # pylint:disable=no-self-use
|
|
||||||
"""Log a message. Described in utils/util_functions.py."""
|
|
||||||
log_this(messages, channel, level)
|
|
||||||
|
|
||||||
async def stop(self, ctx: interactions.SlashContext):
|
|
||||||
"""
|
|
||||||
Stop the bot, and stop running games.
|
|
||||||
|
|
||||||
Only stops the bot if the user in ctx.author is one of the
|
|
||||||
admins given in options.txt.
|
|
||||||
|
|
||||||
*parameters*
|
|
||||||
------------
|
|
||||||
ctx: interactions.SlashContext
|
|
||||||
The context of the "/stop" slash command.
|
|
||||||
"""
|
|
||||||
if f"#{ctx.author.id}" in self.options["admins"]:
|
|
||||||
await ctx.send("Pulling git repo and restarting...")
|
|
||||||
|
|
||||||
await self.change_presence(status=discord.Status.offline)
|
|
||||||
|
|
||||||
self.database_funcs.wipe_games()
|
|
||||||
if not self.options["testing"]:
|
|
||||||
git_client = git.cmd.Git("")
|
|
||||||
git_client.pull()
|
|
||||||
|
|
||||||
self.log("Logging out", level=25)
|
|
||||||
await self.close()
|
|
||||||
else:
|
|
||||||
log_message = f"{ctx.author.display_name} tried to stop me!"
|
|
||||||
self.log(log_message, str(ctx.channel_id))
|
|
||||||
await ctx.send(f"I don't think I will, {ctx.author.display_name}")
|
|
||||||
|
|
||||||
async def defer(self, ctx: interactions.SlashContext):
|
|
||||||
"""Send a "Gwendolyn is thinking" message to the user."""
|
|
||||||
try:
|
|
||||||
await ctx.defer()
|
|
||||||
except interactions.error.AlreadyResponded:
|
|
||||||
self.log("defer failed")
|
|
||||||
|
|||||||
@@ -1,27 +1,27 @@
|
|||||||
{
|
{
|
||||||
"missing parameters" : "Missing command parameters. Try using `!help [command]` to find out how to use the command.",
|
"missing parameters" : "Missing command parameters. Try using `!help [command]` to find out how to use the command.",
|
||||||
"Can't log in": "Could not log in. Remember to write your bot token in the credentials.txt file",
|
"Can't log in": "Could not log in. Remember to write your bot token in the credentials.txt file",
|
||||||
"Blackjack all players standing": "All players are standing. The dealer now shows his cards and draws.",
|
"Blackjack all players standing": "All players are standing. The dealer now shows his cards and draws.",
|
||||||
"Blackjack first round": ". You can also double down with \"/blackjack double\" or split with \"/blackjack split\"",
|
"Blackjack first round": ". You can also double down with \"/blackjack double\" or split with \"/blackjack split\"",
|
||||||
"Blackjack commands": "You have 2 minutes to either hit or stand with \"/blackjack hit\" or \"/blackjack stand\"{}. It's assumed you're standing if you don't make a choice.",
|
"Blackjack commands": "You have 2 minutes to either hit or stand with \"/blackjack hit\" or \"/blackjack stand\"{}. It's assumed you're standing if you don't make a choice.",
|
||||||
"Blackjack double": "Adding another {} GwendoBucks to {}'s bet and drawing another card.",
|
"Blackjack double": "Adding another {} GwendoBucks to {}'s bet and drawing another card.",
|
||||||
"Blackjack different cards": "You can only split if your cards have the same value",
|
"Blackjack different cards": "You can only split if your cards have the same value",
|
||||||
"Blackjack split": "Splitting {}'s hand into 2. Adding their original bet to the second hand. You can use \"/blackjack hit/stand/double 1\" and \"/blackjack hit/stand/double 2\" to play the different hands.",
|
"Blackjack split": "Splitting {}'s hand into 2. Adding their original bet to the second hand. You can use \"/blackjack hit/stand/double 1\" and \"/blackjack hit/stand/double 2\" to play the different hands.",
|
||||||
"Blackjack started": "Blackjack game started. Use the buttons or \"/blackjack bet [amount]\" to enter the game within the next 30 seconds.",
|
"Blackjack started": "Blackjack game started. Use the buttons or \"/blackjack bet [amount]\" to enter the game within the next 30 seconds.",
|
||||||
"Blackjack going on": "There's already a blackjack game going on. Try again in a few minutes.",
|
"Blackjack going on": "There's already a blackjack game going on. Try again in a few minutes.",
|
||||||
"Stock value": "The current {} stock is valued at **{}** GwendoBucks",
|
"Stock value": "The current {} stock is valued at **{}** GwendoBucks",
|
||||||
"Stock parameters": "You must give both a stock name and an amount of GwendoBucks you wish to spend.",
|
"Stock parameters": "You must give both a stock name and an amount of GwendoBucks you wish to spend.",
|
||||||
"Trivia going on": "There's already a trivia question going on. Try again in like, a minute",
|
"Trivia going on": "There's already a trivia question going on. Try again in like, a minute",
|
||||||
"Trivia time up": "Time's up! The answer was \"*{}) {}*\". Anyone who answered that has gotten 1 GwendoBuck",
|
"Trivia time up": "Time's up! The answer was \"*{}) {}*\". Anyone who answered that has gotten 1 GwendoBuck",
|
||||||
"Connect 4 going on": "There's already a connect 4 game going on in this channel",
|
"Connect 4 going on": "There's already a connect 4 game going on in this channel",
|
||||||
"Connect 4 placed": "{} placed a piece in column {}. It's now {}'s turn",
|
"Connect 4 placed": "{} placed a piece in column {}. It's now {}'s turn",
|
||||||
"Hangman going on": "There's already a Hangman game going on in the channel",
|
"Hangman going on": "There's already a Hangman game going on in the channel",
|
||||||
"Hangman lost game": " You've guessed wrong six times and have lost the game.",
|
"Hangman lost game": " You've guessed wrong six times and have lost the game.",
|
||||||
"Hangman guessed word": " You've guessed the word! Congratulations! Adding 15 GwendoBucks to your account",
|
"Hangman guessed word": " You've guessed the word! Congratulations! Adding 15 GwendoBucks to your account",
|
||||||
"Already on Plex": "{} is either already on Plex, downloading, or not available",
|
"Already on Plex": "{} is either already on Plex, downloading, or not available",
|
||||||
"No torrent": "{}No torrent exists. Likely because the movie is not yet released on DVD",
|
"No torrent": "{}No torrent exists. Likely because the movie is not yet released on DVD",
|
||||||
"No torrents downloading": "There are no torrents downloading right. If the torrent you're looking for was added more than 24 hours ago, it might already be on Plex.",
|
"No torrents downloading": "There are no torrents downloading right. If the torrent you're looking for was added more than 24 hours ago, it might already be on Plex.",
|
||||||
"Update": "{}\nThis message will update every 10 seconds for {} more minutes\n```",
|
"Update": "{}\nThis message will update every 10 seconds for {} more minutes\n```",
|
||||||
"No updates": "{}\nThis message will not update anymore\n```",
|
"No updates": "{}\nThis message will not update anymore\n```",
|
||||||
"Invalid parameters": "Invalid or repeated parameters. Use '/help downloading' to see valid parameters."
|
"Invalid parameters": "Invalid or repeated parameters. Use '/help downloading' to see valid parameters."
|
||||||
}
|
}
|
||||||
@@ -1,401 +1,401 @@
|
|||||||
{
|
{
|
||||||
"add_movie" : {
|
"add_movie" : {
|
||||||
"name" : "add_movie",
|
"name" : "add_movie",
|
||||||
"description" : "Request a movie for Plex",
|
"description" : "Request a movie for Plex",
|
||||||
"options" : [
|
"options" : [
|
||||||
{
|
{
|
||||||
"name" : "movie",
|
|
||||||
"description" : "The movie to request",
|
|
||||||
"type" : 3,
|
|
||||||
"required" : "true"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"add_show" : {
|
|
||||||
"name" : "add_show",
|
|
||||||
"description" : "Request a show for Plex",
|
|
||||||
"options" : [
|
|
||||||
{
|
|
||||||
"name" : "show",
|
|
||||||
"description" : "The show to request",
|
|
||||||
"type" : 3,
|
|
||||||
"required" : "true"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"balance" : {
|
|
||||||
"name" : "balance",
|
|
||||||
"description" : "See your balance of GwendoBucks"
|
|
||||||
},
|
|
||||||
"blackjack_bet" : {
|
|
||||||
"base" : "blackjack",
|
|
||||||
"name" : "bet",
|
|
||||||
"description" : "Enter the current blackjack game with a bet",
|
|
||||||
"options" : [
|
|
||||||
{
|
|
||||||
"name" : "bet",
|
|
||||||
"description" : "Your bet",
|
|
||||||
"type" : 4,
|
|
||||||
"required" : "true"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"blackjack_cards" : {
|
|
||||||
"base" : "blackjack",
|
|
||||||
"name" : "cards",
|
|
||||||
"description" : "Get a count of the cards used in blackjack games"
|
|
||||||
},
|
|
||||||
"blackjack_hilo" : {
|
|
||||||
"base" : "blackjack",
|
|
||||||
"name" : "hilo",
|
|
||||||
"description" : "Get the current hi-lo value for the cards used in blackjack games"
|
|
||||||
},
|
|
||||||
"blackjack_shuffle" : {
|
|
||||||
"base" : "blackjack",
|
|
||||||
"name" : "shuffle",
|
|
||||||
"description" : "Shuffle the cards used in blackjack games"
|
|
||||||
},
|
|
||||||
"blackjack_start" : {
|
|
||||||
"base" : "blackjack",
|
|
||||||
"name" : "start",
|
|
||||||
"description" : "Start a game of blackjack"
|
|
||||||
},
|
|
||||||
"connect_four_start_gwendolyn" : {
|
|
||||||
"base" : "connect_four",
|
|
||||||
"subcommand_group" : "start",
|
|
||||||
"name" : "Gwendolyn",
|
|
||||||
"description" : "Start a game of connect four against Gwendolyn",
|
|
||||||
"options" : [
|
|
||||||
{
|
|
||||||
"name" : "difficulty",
|
|
||||||
"description" : "The difficulty of Gwendolyn's AI",
|
|
||||||
"type" : 4,
|
|
||||||
"required" : "false"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"connect_four_start_user" : {
|
|
||||||
"base" : "connect_four",
|
|
||||||
"subcommand_group" : "start",
|
|
||||||
"name" : "user",
|
|
||||||
"description" : "Start a game of connect four against another user",
|
|
||||||
"options" : [
|
|
||||||
{
|
|
||||||
"name" : "user",
|
|
||||||
"description" : "The user to start a game against",
|
|
||||||
"type" : 6,
|
|
||||||
"required" : "true"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"downloading" : {
|
|
||||||
"name" : "downloading",
|
|
||||||
"description" : "See current downloads for Plex",
|
|
||||||
"options" : [
|
|
||||||
{
|
|
||||||
"name" : "parameters",
|
|
||||||
"description" : "Parameters for the command",
|
|
||||||
"type" : 3,
|
|
||||||
"required" : "false"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"game" : {
|
|
||||||
"name" : "game",
|
|
||||||
"description" : "Set the 'playing' text for Gwendolyn",
|
|
||||||
"options" : [
|
|
||||||
{
|
|
||||||
"name" : "game_text",
|
|
||||||
"description" : "The game to set the 'playing' text to",
|
|
||||||
"type" : 3,
|
|
||||||
"required" : "true"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"give" : {
|
|
||||||
"name" : "give",
|
|
||||||
"description" : "Give GwendoBucks to another user",
|
|
||||||
"options" : [
|
|
||||||
{
|
|
||||||
"name" : "user",
|
|
||||||
"description" : "The user you're sending GwendoBucks to",
|
|
||||||
"type" : 6,
|
|
||||||
"required" : "true"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name" : "amount",
|
|
||||||
"description" : "The number of GwendoBucks you're sending",
|
|
||||||
"type" : 4,
|
|
||||||
"required" : "true"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"hangman" : {
|
|
||||||
"name" : "hangman",
|
|
||||||
"description" : "Start a game of hangman"
|
|
||||||
},
|
|
||||||
"hello" : {
|
|
||||||
"name" : "hello",
|
|
||||||
"description" : "Greet Gwendolyn"
|
|
||||||
},
|
|
||||||
"help" : {
|
|
||||||
"name" : "help",
|
|
||||||
"description" : "Get help with a command",
|
|
||||||
"options" : [
|
|
||||||
{
|
|
||||||
"name" : "command",
|
|
||||||
"description" : "The command you want help with",
|
|
||||||
"type" : 3,
|
|
||||||
"required" : "false"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"hex_place" : {
|
|
||||||
"base" : "hex",
|
|
||||||
"name" : "place",
|
|
||||||
"description" : "Place a piece on the hex board",
|
|
||||||
"options" : [
|
|
||||||
{
|
|
||||||
"name" : "coordinates",
|
|
||||||
"description" : "The coordinates to place the piece at",
|
|
||||||
"type" : 3,
|
|
||||||
"required" : "true"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"hex_start_gwendolyn" : {
|
|
||||||
"base" : "hex",
|
|
||||||
"subcommand_group" : "start",
|
|
||||||
"name" : "Gwendolyn",
|
|
||||||
"description" : "Start a game of hex against Gwendolyn",
|
|
||||||
"options" : [
|
|
||||||
{
|
|
||||||
"name" : "difficulty",
|
|
||||||
"description" : "The difficulty of Gwendolyn's AI",
|
|
||||||
"type" : 4,
|
|
||||||
"required" : "false"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"hex_start_user" : {
|
|
||||||
"base" : "hex",
|
|
||||||
"subcommand_group" : "start",
|
|
||||||
"name" : "user",
|
|
||||||
"description" : "Start a game of hex against another user",
|
|
||||||
"options" : [
|
|
||||||
{
|
|
||||||
"name" : "user",
|
|
||||||
"description" : "The user to start a game against",
|
|
||||||
"type" : 6,
|
|
||||||
"required" : "true"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"hex_surrender" : {
|
|
||||||
"base" : "hex",
|
|
||||||
"name" : "surrender",
|
|
||||||
"description" : "Surrender the game of hex"
|
|
||||||
},
|
|
||||||
"hex_swap" : {
|
|
||||||
"base" : "hex",
|
|
||||||
"name" : "swap",
|
|
||||||
"description" : "Perform a hex swap"
|
|
||||||
},
|
|
||||||
"hex_undo" : {
|
|
||||||
"base" : "hex",
|
|
||||||
"name" : "undo",
|
|
||||||
"description" : "Undo your last hex move"
|
|
||||||
},
|
|
||||||
"image" : {
|
|
||||||
"name" : "image",
|
|
||||||
"description" : "Get a random image from Bing"
|
|
||||||
},
|
|
||||||
"monster" : {
|
|
||||||
"name" : "monster",
|
|
||||||
"description" : "Look up a monster",
|
|
||||||
"options" : [
|
|
||||||
{
|
|
||||||
"name" : "query",
|
|
||||||
"description" : "The monster to look up",
|
|
||||||
"type" : 3,
|
|
||||||
"required" : "true"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"movie" : {
|
|
||||||
"name" : "movie",
|
"name" : "movie",
|
||||||
"description" : "Get the name and information of a random movie"
|
"description" : "The movie to request",
|
||||||
},
|
"type" : 3,
|
||||||
"name" : {
|
"required" : "true"
|
||||||
"name" : "name",
|
}
|
||||||
"description" : "Generate a random name"
|
]
|
||||||
},
|
},
|
||||||
"ping" : {
|
"add_show" : {
|
||||||
"name" : "ping",
|
"name" : "add_show",
|
||||||
"description" : "Get the Gwendolyn's latency to the server"
|
"description" : "Request a show for Plex",
|
||||||
},
|
"options" : [
|
||||||
"roll" : {
|
{
|
||||||
"name" : "roll",
|
"name" : "show",
|
||||||
"description" : "Roll rpg dice",
|
"description" : "The show to request",
|
||||||
"options" : [
|
"type" : 3,
|
||||||
{
|
"required" : "true"
|
||||||
"name" : "dice",
|
}
|
||||||
"description" : "The dice to roll",
|
]
|
||||||
"type" : 3,
|
},
|
||||||
"required" : "false"
|
"balance" : {
|
||||||
}
|
"name" : "balance",
|
||||||
|
"description" : "See your balance of GwendoBucks"
|
||||||
|
},
|
||||||
|
"blackjack_bet" : {
|
||||||
|
"base" : "blackjack",
|
||||||
|
"name" : "bet",
|
||||||
|
"description" : "Enter the current blackjack game with a bet",
|
||||||
|
"options" : [
|
||||||
|
{
|
||||||
|
"name" : "bet",
|
||||||
|
"description" : "Your bet",
|
||||||
|
"type" : 4,
|
||||||
|
"required" : "true"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"blackjack_cards" : {
|
||||||
|
"base" : "blackjack",
|
||||||
|
"name" : "cards",
|
||||||
|
"description" : "Get a count of the cards used in blackjack games"
|
||||||
|
},
|
||||||
|
"blackjack_hilo" : {
|
||||||
|
"base" : "blackjack",
|
||||||
|
"name" : "hilo",
|
||||||
|
"description" : "Get the current hi-lo value for the cards used in blackjack games"
|
||||||
|
},
|
||||||
|
"blackjack_shuffle" : {
|
||||||
|
"base" : "blackjack",
|
||||||
|
"name" : "shuffle",
|
||||||
|
"description" : "Shuffle the cards used in blackjack games"
|
||||||
|
},
|
||||||
|
"blackjack_start" : {
|
||||||
|
"base" : "blackjack",
|
||||||
|
"name" : "start",
|
||||||
|
"description" : "Start a game of blackjack"
|
||||||
|
},
|
||||||
|
"connect_four_start_gwendolyn" : {
|
||||||
|
"base" : "connect_four",
|
||||||
|
"subcommand_group" : "start",
|
||||||
|
"name" : "Gwendolyn",
|
||||||
|
"description" : "Start a game of connect four against Gwendolyn",
|
||||||
|
"options" : [
|
||||||
|
{
|
||||||
|
"name" : "difficulty",
|
||||||
|
"description" : "The difficulty of Gwendolyn's AI",
|
||||||
|
"type" : 4,
|
||||||
|
"required" : "false"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"connect_four_start_user" : {
|
||||||
|
"base" : "connect_four",
|
||||||
|
"subcommand_group" : "start",
|
||||||
|
"name" : "user",
|
||||||
|
"description" : "Start a game of connect four against another user",
|
||||||
|
"options" : [
|
||||||
|
{
|
||||||
|
"name" : "user",
|
||||||
|
"description" : "The user to start a game against",
|
||||||
|
"type" : 6,
|
||||||
|
"required" : "true"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"downloading" : {
|
||||||
|
"name" : "downloading",
|
||||||
|
"description" : "See current downloads for Plex",
|
||||||
|
"options" : [
|
||||||
|
{
|
||||||
|
"name" : "parameters",
|
||||||
|
"description" : "Parameters for the command",
|
||||||
|
"type" : 3,
|
||||||
|
"required" : "false"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"game" : {
|
||||||
|
"name" : "game",
|
||||||
|
"description" : "Set the 'playing' text for Gwendolyn",
|
||||||
|
"options" : [
|
||||||
|
{
|
||||||
|
"name" : "game_text",
|
||||||
|
"description" : "The game to set the 'playing' text to",
|
||||||
|
"type" : 3,
|
||||||
|
"required" : "true"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"give" : {
|
||||||
|
"name" : "give",
|
||||||
|
"description" : "Give GwendoBucks to another user",
|
||||||
|
"options" : [
|
||||||
|
{
|
||||||
|
"name" : "user",
|
||||||
|
"description" : "The user you're sending GwendoBucks to",
|
||||||
|
"type" : 6,
|
||||||
|
"required" : "true"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name" : "amount",
|
||||||
|
"description" : "The number of GwendoBucks you're sending",
|
||||||
|
"type" : 4,
|
||||||
|
"required" : "true"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"hangman" : {
|
||||||
|
"name" : "hangman",
|
||||||
|
"description" : "Start a game of hangman"
|
||||||
|
},
|
||||||
|
"hello" : {
|
||||||
|
"name" : "hello",
|
||||||
|
"description" : "Greet Gwendolyn"
|
||||||
|
},
|
||||||
|
"help" : {
|
||||||
|
"name" : "help",
|
||||||
|
"description" : "Get help with a command",
|
||||||
|
"options" : [
|
||||||
|
{
|
||||||
|
"name" : "command",
|
||||||
|
"description" : "The command you want help with",
|
||||||
|
"type" : 3,
|
||||||
|
"required" : "false"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"hex_place" : {
|
||||||
|
"base" : "hex",
|
||||||
|
"name" : "place",
|
||||||
|
"description" : "Place a piece on the hex board",
|
||||||
|
"options" : [
|
||||||
|
{
|
||||||
|
"name" : "coordinates",
|
||||||
|
"description" : "The coordinates to place the piece at",
|
||||||
|
"type" : 3,
|
||||||
|
"required" : "true"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"hex_start_gwendolyn" : {
|
||||||
|
"base" : "hex",
|
||||||
|
"subcommand_group" : "start",
|
||||||
|
"name" : "Gwendolyn",
|
||||||
|
"description" : "Start a game of hex against Gwendolyn",
|
||||||
|
"options" : [
|
||||||
|
{
|
||||||
|
"name" : "difficulty",
|
||||||
|
"description" : "The difficulty of Gwendolyn's AI",
|
||||||
|
"type" : 4,
|
||||||
|
"required" : "false"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"hex_start_user" : {
|
||||||
|
"base" : "hex",
|
||||||
|
"subcommand_group" : "start",
|
||||||
|
"name" : "user",
|
||||||
|
"description" : "Start a game of hex against another user",
|
||||||
|
"options" : [
|
||||||
|
{
|
||||||
|
"name" : "user",
|
||||||
|
"description" : "The user to start a game against",
|
||||||
|
"type" : 6,
|
||||||
|
"required" : "true"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"hex_surrender" : {
|
||||||
|
"base" : "hex",
|
||||||
|
"name" : "surrender",
|
||||||
|
"description" : "Surrender the game of hex"
|
||||||
|
},
|
||||||
|
"hex_swap" : {
|
||||||
|
"base" : "hex",
|
||||||
|
"name" : "swap",
|
||||||
|
"description" : "Perform a hex swap"
|
||||||
|
},
|
||||||
|
"hex_undo" : {
|
||||||
|
"base" : "hex",
|
||||||
|
"name" : "undo",
|
||||||
|
"description" : "Undo your last hex move"
|
||||||
|
},
|
||||||
|
"image" : {
|
||||||
|
"name" : "image",
|
||||||
|
"description" : "Get a random image from Bing"
|
||||||
|
},
|
||||||
|
"monster" : {
|
||||||
|
"name" : "monster",
|
||||||
|
"description" : "Look up a monster",
|
||||||
|
"options" : [
|
||||||
|
{
|
||||||
|
"name" : "query",
|
||||||
|
"description" : "The monster to look up",
|
||||||
|
"type" : 3,
|
||||||
|
"required" : "true"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"movie" : {
|
||||||
|
"name" : "movie",
|
||||||
|
"description" : "Get the name and information of a random movie"
|
||||||
|
},
|
||||||
|
"name" : {
|
||||||
|
"name" : "name",
|
||||||
|
"description" : "Generate a random name"
|
||||||
|
},
|
||||||
|
"ping" : {
|
||||||
|
"name" : "ping",
|
||||||
|
"description" : "Get the Gwendolyn's latency to the server"
|
||||||
|
},
|
||||||
|
"roll" : {
|
||||||
|
"name" : "roll",
|
||||||
|
"description" : "Roll rpg dice",
|
||||||
|
"options" : [
|
||||||
|
{
|
||||||
|
"name" : "dice",
|
||||||
|
"description" : "The dice to roll",
|
||||||
|
"type" : 3,
|
||||||
|
"required" : "false"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"spell" : {
|
||||||
|
"name" : "spell",
|
||||||
|
"description" : "Look up a spell",
|
||||||
|
"options" : [
|
||||||
|
{
|
||||||
|
"name" : "query",
|
||||||
|
"description" : "The spell to look up",
|
||||||
|
"type" : 3,
|
||||||
|
"required" : "true"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"star_wars_character" : {
|
||||||
|
"name" : "star_wars_character",
|
||||||
|
"description" : "Manage your Star Wars character sheet",
|
||||||
|
"options" : [
|
||||||
|
{
|
||||||
|
"name" : "parameters",
|
||||||
|
"description" : "The parameters for the command",
|
||||||
|
"type" : 3,
|
||||||
|
"required" : "false"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"star_wars_crit" : {
|
||||||
|
"name" : "star_wars_crit",
|
||||||
|
"description" : "Roll a Star Wars critical injury",
|
||||||
|
"options" : [
|
||||||
|
{
|
||||||
|
"name" : "severity",
|
||||||
|
"description" : "The severity of the hit",
|
||||||
|
"type" : 4,
|
||||||
|
"required" : "true"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"star_wars_destiny" : {
|
||||||
|
"name" : "star_wars_destiny",
|
||||||
|
"description" : "Use and see Star Wars Destiny points",
|
||||||
|
"options" : [
|
||||||
|
{
|
||||||
|
"name" : "parameters",
|
||||||
|
"description" : "The parameters for the command",
|
||||||
|
"type" : 3,
|
||||||
|
"required" : "false"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"star_wars_roll" : {
|
||||||
|
"name" : "star_wars_roll",
|
||||||
|
"description" : "Roll Star Wars dice",
|
||||||
|
"options" : [
|
||||||
|
{
|
||||||
|
"name" : "dice",
|
||||||
|
"description" : "The dice, or ability, to roll",
|
||||||
|
"type" : 3,
|
||||||
|
"required" : "false"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"stop" : {
|
||||||
|
"name" : "stop",
|
||||||
|
"description" : "Restart Gwendolyn"
|
||||||
|
},
|
||||||
|
"tavern" : {
|
||||||
|
"name" : "tavern",
|
||||||
|
"description" : "Generate a random tavern"
|
||||||
|
},
|
||||||
|
"thank" : {
|
||||||
|
"name" : "thank",
|
||||||
|
"description" : "Thank Gwendolyn for her service"
|
||||||
|
},
|
||||||
|
"trivia" : {
|
||||||
|
"name" : "trivia",
|
||||||
|
"description" : "Play a game of trivia",
|
||||||
|
"options" : [
|
||||||
|
{
|
||||||
|
"name" : "answer",
|
||||||
|
"description" : "Your answer to the trivia question",
|
||||||
|
"type" : 3,
|
||||||
|
"required" : "false",
|
||||||
|
"choices" : [
|
||||||
|
{
|
||||||
|
"name" : "a",
|
||||||
|
"value" : "a"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name" : "b",
|
||||||
|
"value" : "b"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name" : "c",
|
||||||
|
"value" : "c"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name" : "d",
|
||||||
|
"value" : "d"
|
||||||
|
}
|
||||||
]
|
]
|
||||||
},
|
}
|
||||||
"spell" : {
|
]
|
||||||
"name" : "spell",
|
},
|
||||||
"description" : "Look up a spell",
|
"wiki" : {
|
||||||
"options" : [
|
"name" : "wiki",
|
||||||
{
|
"description" : "Searches for and gets the info for a wiki page",
|
||||||
"name" : "query",
|
"options" : [
|
||||||
"description" : "The spell to look up",
|
{
|
||||||
"type" : 3,
|
"name" : "page",
|
||||||
"required" : "true"
|
"description" : "The page to find",
|
||||||
}
|
"type" : 3,
|
||||||
]
|
"required" : "false"
|
||||||
},
|
}
|
||||||
"star_wars_character" : {
|
]
|
||||||
"name" : "star_wars_character",
|
},
|
||||||
"description" : "Manage your Star Wars character sheet",
|
"wolf" : {
|
||||||
"options" : [
|
"name" : "wolf",
|
||||||
{
|
"description" : "Performs a search on Wolfram Alpha",
|
||||||
"name" : "parameters",
|
"options" : [
|
||||||
"description" : "The parameters for the command",
|
{
|
||||||
"type" : 3,
|
"name" : "query",
|
||||||
"required" : "false"
|
"description" : "What to search for on Wolfram Alpha",
|
||||||
}
|
"type" : 3,
|
||||||
]
|
"required" : "true"
|
||||||
},
|
}
|
||||||
"star_wars_crit" : {
|
]
|
||||||
"name" : "star_wars_crit",
|
},
|
||||||
"description" : "Roll a Star Wars critical injury",
|
"wordle_start": {
|
||||||
"options" : [
|
"base": "wordle",
|
||||||
{
|
"name" : "start",
|
||||||
"name" : "severity",
|
"description": "Start a game of wordle",
|
||||||
"description" : "The severity of the hit",
|
"options": [
|
||||||
"type" : 4,
|
{
|
||||||
"required" : "true"
|
"name": "letters",
|
||||||
}
|
"description" : "How many letters the word should be",
|
||||||
]
|
"type": 4,
|
||||||
},
|
"required": "false"
|
||||||
"star_wars_destiny" : {
|
}
|
||||||
"name" : "star_wars_destiny",
|
]
|
||||||
"description" : "Use and see Star Wars Destiny points",
|
},
|
||||||
"options" : [
|
"wordle_guess": {
|
||||||
{
|
"base": "wordle",
|
||||||
"name" : "parameters",
|
"name" : "guess",
|
||||||
"description" : "The parameters for the command",
|
"description": "Guess a word in wordle",
|
||||||
"type" : 3,
|
"options": [
|
||||||
"required" : "false"
|
{
|
||||||
}
|
"name": "guess",
|
||||||
]
|
"description" : "Your guess",
|
||||||
},
|
"type": 3,
|
||||||
"star_wars_roll" : {
|
"required": "true"
|
||||||
"name" : "star_wars_roll",
|
}
|
||||||
"description" : "Roll Star Wars dice",
|
]
|
||||||
"options" : [
|
}
|
||||||
{
|
|
||||||
"name" : "dice",
|
|
||||||
"description" : "The dice, or ability, to roll",
|
|
||||||
"type" : 3,
|
|
||||||
"required" : "false"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"stop" : {
|
|
||||||
"name" : "stop",
|
|
||||||
"description" : "Restart Gwendolyn"
|
|
||||||
},
|
|
||||||
"tavern" : {
|
|
||||||
"name" : "tavern",
|
|
||||||
"description" : "Generate a random tavern"
|
|
||||||
},
|
|
||||||
"thank" : {
|
|
||||||
"name" : "thank",
|
|
||||||
"description" : "Thank Gwendolyn for her service"
|
|
||||||
},
|
|
||||||
"trivia" : {
|
|
||||||
"name" : "trivia",
|
|
||||||
"description" : "Play a game of trivia",
|
|
||||||
"options" : [
|
|
||||||
{
|
|
||||||
"name" : "answer",
|
|
||||||
"description" : "Your answer to the trivia question",
|
|
||||||
"type" : 3,
|
|
||||||
"required" : "false",
|
|
||||||
"choices" : [
|
|
||||||
{
|
|
||||||
"name" : "a",
|
|
||||||
"value" : "a"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name" : "b",
|
|
||||||
"value" : "b"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name" : "c",
|
|
||||||
"value" : "c"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name" : "d",
|
|
||||||
"value" : "d"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"wiki" : {
|
|
||||||
"name" : "wiki",
|
|
||||||
"description" : "Searches for and gets the info for a wiki page",
|
|
||||||
"options" : [
|
|
||||||
{
|
|
||||||
"name" : "page",
|
|
||||||
"description" : "The page to find",
|
|
||||||
"type" : 3,
|
|
||||||
"required" : "false"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"wolf" : {
|
|
||||||
"name" : "wolf",
|
|
||||||
"description" : "Performs a search on Wolfram Alpha",
|
|
||||||
"options" : [
|
|
||||||
{
|
|
||||||
"name" : "query",
|
|
||||||
"description" : "What to search for on Wolfram Alpha",
|
|
||||||
"type" : 3,
|
|
||||||
"required" : "true"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"wordle_start": {
|
|
||||||
"base": "wordle",
|
|
||||||
"name" : "start",
|
|
||||||
"description": "Start a game of wordle",
|
|
||||||
"options": [
|
|
||||||
{
|
|
||||||
"name": "letters",
|
|
||||||
"description" : "How many letters the word should be",
|
|
||||||
"type": 4,
|
|
||||||
"required": "false"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"wordle_guess": {
|
|
||||||
"base": "wordle",
|
|
||||||
"name" : "guess",
|
|
||||||
"description": "Guess a word in wordle",
|
|
||||||
"options": [
|
|
||||||
{
|
|
||||||
"name": "guess",
|
|
||||||
"description" : "Your guess",
|
|
||||||
"type": 3,
|
|
||||||
"required": "true"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -1,36 +1,36 @@
|
|||||||
{
|
{
|
||||||
"Astrogation" : "Intellect",
|
"Astrogation" : "Intellect",
|
||||||
"Computers" : "Intellect",
|
"Computers" : "Intellect",
|
||||||
"Cool" : "Presence",
|
"Cool" : "Presence",
|
||||||
"Vigilance" : "Willpower",
|
"Vigilance" : "Willpower",
|
||||||
"Mechanics" : "Intellect",
|
"Mechanics" : "Intellect",
|
||||||
"Melee" : "Brawn",
|
"Melee" : "Brawn",
|
||||||
"Perception" : "Cunning",
|
"Perception" : "Cunning",
|
||||||
"Piloting-space" : "Agility",
|
"Piloting-space" : "Agility",
|
||||||
"Ranged-heavy" : "Agility",
|
"Ranged-heavy" : "Agility",
|
||||||
"Ranged-light" : "Agility",
|
"Ranged-light" : "Agility",
|
||||||
"Athletics" : "Brawn",
|
"Athletics" : "Brawn",
|
||||||
"Coercion" : "Willpower",
|
"Coercion" : "Willpower",
|
||||||
"Coordination" : "Agility",
|
"Coordination" : "Agility",
|
||||||
"Charm" : "Presence",
|
"Charm" : "Presence",
|
||||||
"Medicine" : "Intellect",
|
"Medicine" : "Intellect",
|
||||||
"Negotiation" : "Presence",
|
"Negotiation" : "Presence",
|
||||||
"Piloting-planetary" : "Agility",
|
"Piloting-planetary" : "Agility",
|
||||||
"Stealth" : "Agility",
|
"Stealth" : "Agility",
|
||||||
"skulduggery" : "Cunning",
|
"skulduggery" : "Cunning",
|
||||||
"Brawl" : "Brawn",
|
"Brawl" : "Brawn",
|
||||||
"Discipline" : "Willpower",
|
"Discipline" : "Willpower",
|
||||||
"Gunnery" : "Agility",
|
"Gunnery" : "Agility",
|
||||||
"Core-worlds" : "Intellect",
|
"Core-worlds" : "Intellect",
|
||||||
"Outer-rim" : "Intellect",
|
"Outer-rim" : "Intellect",
|
||||||
"Underworld" : "Intellect",
|
"Underworld" : "Intellect",
|
||||||
"Leadership" : "Presence",
|
"Leadership" : "Presence",
|
||||||
"Lore" : "Intellect",
|
"Lore" : "Intellect",
|
||||||
"Resilience" : "Brawn",
|
"Resilience" : "Brawn",
|
||||||
"Streetwise" : "Cunning",
|
"Streetwise" : "Cunning",
|
||||||
"Survival" : "Cunning",
|
"Survival" : "Cunning",
|
||||||
"Xenology" : "Intellect",
|
"Xenology" : "Intellect",
|
||||||
"Lightsaber" : "Brawn",
|
"Lightsaber" : "Brawn",
|
||||||
"Education" : "Intellect",
|
"Education" : "Intellect",
|
||||||
"Deception" : "Cunning"
|
"Deception" : "Cunning"
|
||||||
}
|
}
|
||||||
@@ -1,82 +1,82 @@
|
|||||||
{
|
{
|
||||||
"Character": {
|
"Character": {
|
||||||
"Name": "New Character",
|
"Name": "New Character",
|
||||||
"Species": "",
|
"Species": "",
|
||||||
"Career": "",
|
"Career": "",
|
||||||
"Specialization-trees": [],
|
"Specialization-trees": [],
|
||||||
"Soak": 0,
|
"Soak": 0,
|
||||||
"Wound-threshold": 0,
|
"Wound-threshold": 0,
|
||||||
"Wounds": 0,
|
"Wounds": 0,
|
||||||
"Strain-threshold": 0,
|
"Strain-threshold": 0,
|
||||||
"Strain": 0,
|
"Strain": 0,
|
||||||
"Defense-ranged": 0,
|
"Defense-ranged": 0,
|
||||||
"Defense-melee": 0,
|
"Defense-melee": 0,
|
||||||
"Force-rating": 0,
|
"Force-rating": 0,
|
||||||
"Characteristics": {
|
"Characteristics": {
|
||||||
"Brawn": 2,
|
"Brawn": 2,
|
||||||
"Agility": 2,
|
"Agility": 2,
|
||||||
"Intellect": 2,
|
"Intellect": 2,
|
||||||
"Cunning": 2,
|
"Cunning": 2,
|
||||||
"Willpower": 2,
|
"Willpower": 2,
|
||||||
"Presence": 2
|
"Presence": 2
|
||||||
},
|
|
||||||
"Skills": {
|
|
||||||
"Astrogation": 0,
|
|
||||||
"Athletics": 0,
|
|
||||||
"Brawl": 0,
|
|
||||||
"Charm": 0,
|
|
||||||
"Coercion": 0,
|
|
||||||
"Computers": 0,
|
|
||||||
"Cool": 0,
|
|
||||||
"Coordination": 0,
|
|
||||||
"Core-worlds": 0,
|
|
||||||
"Discipline": 0,
|
|
||||||
"Deception": 0,
|
|
||||||
"Education": 0,
|
|
||||||
"Gunnery": 0,
|
|
||||||
"Leadership": 0,
|
|
||||||
"Lightsaber": 0,
|
|
||||||
"Lore": 0,
|
|
||||||
"Mechanics": 0,
|
|
||||||
"Medicine": 0,
|
|
||||||
"Melee": 0,
|
|
||||||
"Negotiation": 0,
|
|
||||||
"Outer-rim": 0,
|
|
||||||
"Perception": 0,
|
|
||||||
"Piloting-planetary": 0,
|
|
||||||
"Piloting-space": 0,
|
|
||||||
"Ranged-heavy": 0,
|
|
||||||
"Ranged-light": 0,
|
|
||||||
"Resilience": 0,
|
|
||||||
"skulduggery": 0,
|
|
||||||
"Stealth": 0,
|
|
||||||
"Streetwise": 0,
|
|
||||||
"Survival": 0,
|
|
||||||
"Underworld": 0,
|
|
||||||
"Vigilance": 0,
|
|
||||||
"Xenology": 0
|
|
||||||
},
|
|
||||||
"Lightsaber-characteristic": "Brawn",
|
|
||||||
"Obligations": {},
|
|
||||||
"Morality": {
|
|
||||||
"Weakness": "",
|
|
||||||
"Strength": "",
|
|
||||||
"Conflict": "",
|
|
||||||
"Morality": ""
|
|
||||||
},
|
|
||||||
"Credits": 0,
|
|
||||||
"Equipment": [],
|
|
||||||
"Armor": "",
|
|
||||||
"Critical-injuries": {},
|
|
||||||
"Weapons": {},
|
|
||||||
"Talents": {},
|
|
||||||
"Force-powers": {}
|
|
||||||
},
|
},
|
||||||
"Weapon": {
|
"Skills": {
|
||||||
"Skill" : "",
|
"Astrogation": 0,
|
||||||
"Damage" : 0,
|
"Athletics": 0,
|
||||||
"Range" : "",
|
"Brawl": 0,
|
||||||
"Crit" : 0,
|
"Charm": 0,
|
||||||
"Special" : []
|
"Coercion": 0,
|
||||||
}
|
"Computers": 0,
|
||||||
|
"Cool": 0,
|
||||||
|
"Coordination": 0,
|
||||||
|
"Core-worlds": 0,
|
||||||
|
"Discipline": 0,
|
||||||
|
"Deception": 0,
|
||||||
|
"Education": 0,
|
||||||
|
"Gunnery": 0,
|
||||||
|
"Leadership": 0,
|
||||||
|
"Lightsaber": 0,
|
||||||
|
"Lore": 0,
|
||||||
|
"Mechanics": 0,
|
||||||
|
"Medicine": 0,
|
||||||
|
"Melee": 0,
|
||||||
|
"Negotiation": 0,
|
||||||
|
"Outer-rim": 0,
|
||||||
|
"Perception": 0,
|
||||||
|
"Piloting-planetary": 0,
|
||||||
|
"Piloting-space": 0,
|
||||||
|
"Ranged-heavy": 0,
|
||||||
|
"Ranged-light": 0,
|
||||||
|
"Resilience": 0,
|
||||||
|
"skulduggery": 0,
|
||||||
|
"Stealth": 0,
|
||||||
|
"Streetwise": 0,
|
||||||
|
"Survival": 0,
|
||||||
|
"Underworld": 0,
|
||||||
|
"Vigilance": 0,
|
||||||
|
"Xenology": 0
|
||||||
|
},
|
||||||
|
"Lightsaber-characteristic": "Brawn",
|
||||||
|
"Obligations": {},
|
||||||
|
"Morality": {
|
||||||
|
"Weakness": "",
|
||||||
|
"Strength": "",
|
||||||
|
"Conflict": "",
|
||||||
|
"Morality": ""
|
||||||
|
},
|
||||||
|
"Credits": 0,
|
||||||
|
"Equipment": [],
|
||||||
|
"Armor": "",
|
||||||
|
"Critical-injuries": {},
|
||||||
|
"Weapons": {},
|
||||||
|
"Talents": {},
|
||||||
|
"Force-powers": {}
|
||||||
|
},
|
||||||
|
"Weapon": {
|
||||||
|
"Skill" : "",
|
||||||
|
"Damage" : 0,
|
||||||
|
"Range" : "",
|
||||||
|
"Crit" : 0,
|
||||||
|
"Special" : []
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -1,74 +1,74 @@
|
|||||||
{
|
{
|
||||||
"json":{
|
"json":{
|
||||||
"gwendolyn/resources/lookup/spells.json" : {
|
"gwendolyn/resources/lookup/spells.json" : {
|
||||||
"Fireball" : {
|
"Fireball" : {
|
||||||
"casting_time" : "1 action",
|
"casting_time" : "1 action",
|
||||||
"components" : "V, S, M (a tiny ball of bat guano and sulfur)",
|
"components" : "V, S, M (a tiny ball of bat guano and sulfur)",
|
||||||
"description" : "A bright streak flashes from your pointing finger to a point you choose within range and then blossoms with a low roar into an explosion of flame. Each creature in a 20-foot-radius sphere centered on that point must make a Dexterity saving throw. A target takes 8d6 fire damage on a failed save, or half as much damage on a successful one. The fire spreads around corners. It ignites flammable objects in the area that aren’t being worn or carried. At Higher Levels. When you cast this spell using a spell slot of 4th level or higher, the damage increases by 1d6 for each slot level above 3rd.",
|
"description" : "A bright streak flashes from your pointing finger to a point you choose within range and then blossoms with a low roar into an explosion of flame. Each creature in a 20-foot-radius sphere centered on that point must make a Dexterity saving throw. A target takes 8d6 fire damage on a failed save, or half as much damage on a successful one. The fire spreads around corners. It ignites flammable objects in the area that aren’t being worn or carried. At Higher Levels. When you cast this spell using a spell slot of 4th level or higher, the damage increases by 1d6 for each slot level above 3rd.",
|
||||||
"duration" : "Instantaneous",
|
"duration" : "Instantaneous",
|
||||||
"level" : "3rd",
|
"level" : "3rd",
|
||||||
"range" : "150 feet",
|
"range" : "150 feet",
|
||||||
"school" : "Evocation",
|
"school" : "Evocation",
|
||||||
"ritual" : false
|
"ritual" : false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"gwendolyn/resources/lookup/monsters.json" : [
|
"gwendolyn/resources/lookup/monsters.json" : [
|
||||||
{
|
{
|
||||||
"name": "Bandit",
|
"name": "Bandit",
|
||||||
"size": "Medium",
|
"size": "Medium",
|
||||||
"type": "humanoid",
|
"type": "humanoid",
|
||||||
"subtype": "any race",
|
"subtype": "any race",
|
||||||
"alignment": "any non-lawful alignment",
|
"alignment": "any non-lawful alignment",
|
||||||
"armor_class": 12,
|
"armor_class": 12,
|
||||||
"hit_points": 11,
|
"hit_points": 11,
|
||||||
"hit_dice": "2d8",
|
"hit_dice": "2d8",
|
||||||
"speed": "30 ft.",
|
"speed": "30 ft.",
|
||||||
"strength": 11,
|
"strength": 11,
|
||||||
"dexterity": 12,
|
"dexterity": 12,
|
||||||
"constitution": 12,
|
"constitution": 12,
|
||||||
"intelligence": 10,
|
"intelligence": 10,
|
||||||
"wisdom": 10,
|
"wisdom": 10,
|
||||||
"charisma": 10,
|
"charisma": 10,
|
||||||
"damage_vulnerabilities": "",
|
"damage_vulnerabilities": "",
|
||||||
"damage_resistances": "",
|
"damage_resistances": "",
|
||||||
"damage_immunities": "",
|
"damage_immunities": "",
|
||||||
"condition_immunities": "",
|
"condition_immunities": "",
|
||||||
"senses": "passive Perception 10",
|
"senses": "passive Perception 10",
|
||||||
"languages": "any one language (usually Common)",
|
"languages": "any one language (usually Common)",
|
||||||
"challenge_rating": "1/8",
|
"challenge_rating": "1/8",
|
||||||
"actions": [
|
"actions": [
|
||||||
{
|
{
|
||||||
"name": "Scimitar",
|
"name": "Scimitar",
|
||||||
"desc": "Melee Weapon Attack: +3 to hit, reach 5 ft., one target. Hit: 4 (1d6 + 1) slashing damage.",
|
"desc": "Melee Weapon Attack: +3 to hit, reach 5 ft., one target. Hit: 4 (1d6 + 1) slashing damage.",
|
||||||
"attack_bonus": 3,
|
"attack_bonus": 3,
|
||||||
"damage_dice": "1d6",
|
"damage_dice": "1d6",
|
||||||
"damage_bonus": 1
|
"damage_bonus": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Light Crossbow",
|
"name": "Light Crossbow",
|
||||||
"desc": "Ranged Weapon Attack: +3 to hit, range 80 ft./320 ft., one target. Hit: 5 (1d8 + 1) piercing damage.",
|
"desc": "Ranged Weapon Attack: +3 to hit, range 80 ft./320 ft., one target. Hit: 5 (1d8 + 1) piercing damage.",
|
||||||
"attack_bonus": 3,
|
"attack_bonus": 3,
|
||||||
"damage_dice": "1d8",
|
"damage_dice": "1d8",
|
||||||
"damage_bonus": 1
|
"damage_bonus": 1
|
||||||
}
|
}
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
]
|
||||||
},
|
}
|
||||||
"txt": {
|
|
||||||
"gwendolyn/resources/star_wars/destinyPoints.txt": "",
|
|
||||||
"gwendolyn/resources/movies.txt": "The Room",
|
|
||||||
"gwendolyn/resources/names.txt": "Gandalf\n",
|
|
||||||
"credentials.txt" : "Bot token: TOKEN\nWordnik API Key: KEY\nMongoDB user: USERNAME\nMongoDB password: PASSWORD\nWolframAlpha AppID: APPID\nRadarr API key: KEY\nSonarr API key: KEY\nqBittorrent username: USER\nqBittorrent password: PASSWORD",
|
|
||||||
"options.txt" : "Testing: True\nTesting guild ids:\nAdmins:"
|
|
||||||
},
|
|
||||||
"folder" : [
|
|
||||||
"gwendolyn/resources/lookup",
|
|
||||||
"gwendolyn/resources/games/blackjack_tables",
|
|
||||||
"gwendolyn/resources/games/connect_four_boards",
|
|
||||||
"gwendolyn/resources/games/hex_boards",
|
|
||||||
"gwendolyn/resources/games/hangman_boards",
|
|
||||||
"gwendolyn/resources/plex",
|
|
||||||
"gwendolyn/resources/games/old_images"
|
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
"txt": {
|
||||||
|
"gwendolyn/resources/star_wars/destinyPoints.txt": "",
|
||||||
|
"gwendolyn/resources/movies.txt": "The Room",
|
||||||
|
"gwendolyn/resources/names.txt": "Gandalf\n",
|
||||||
|
"credentials.txt" : "Bot token: TOKEN\nWordnik API Key: KEY\nMongoDB user: USERNAME\nMongoDB password: PASSWORD\nWolframAlpha AppID: APPID\nRadarr API key: KEY\nSonarr API key: KEY\nqBittorrent username: USER\nqBittorrent password: PASSWORD",
|
||||||
|
"options.txt" : "Testing: True\nTesting guild ids:\nAdmins:"
|
||||||
|
},
|
||||||
|
"folder" : [
|
||||||
|
"gwendolyn/resources/lookup",
|
||||||
|
"gwendolyn/resources/games/blackjack_tables",
|
||||||
|
"gwendolyn/resources/games/connect_four_boards",
|
||||||
|
"gwendolyn/resources/games/hex_boards",
|
||||||
|
"gwendolyn/resources/games/hangman_boards",
|
||||||
|
"gwendolyn/resources/plex",
|
||||||
|
"gwendolyn/resources/games/old_images"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
@@ -1,12 +1,12 @@
|
|||||||
"""A collections of utilities used by Gwendolyn and her functions."""
|
"""A collections of utilities used by Gwendolyn and her functions."""
|
||||||
|
|
||||||
__all__ = ["get_options", "get_credentials", "DatabaseFuncs", "EventHandler",
|
__all__ = ["get_options", "get_credentials", "DatabaseFuncs", "EventHandler",
|
||||||
"ErrorHandler", "get_params", "log_this", "cap", "make_files",
|
"ErrorHandler", "get_params", "log_this", "cap", "make_files",
|
||||||
"replace_multiple", "emoji_to_command"]
|
"replace_multiple", "emoji_to_command"]
|
||||||
|
|
||||||
from .helper_classes import DatabaseFuncs
|
from .helper_classes import DatabaseFuncs
|
||||||
from .event_handlers import EventHandler, ErrorHandler
|
from .event_handlers import EventHandler, ErrorHandler
|
||||||
from .util_functions import (get_params, log_this, cap, make_files,
|
from .util_functions import (get_params, log_this, cap, make_files,
|
||||||
replace_multiple, emoji_to_command, long_strings,
|
replace_multiple, emoji_to_command, long_strings,
|
||||||
sanitize, get_options, get_credentials, encode_id,
|
sanitize, get_options, get_credentials, encode_id,
|
||||||
decode_id)
|
decode_id)
|
||||||
|
|||||||
@@ -3,15 +3,15 @@ Classes used to handle bot events and errors.
|
|||||||
|
|
||||||
*Classes*
|
*Classes*
|
||||||
---------
|
---------
|
||||||
EventHandler
|
EventHandler
|
||||||
ErrorHandler
|
ErrorHandler
|
||||||
"""
|
"""
|
||||||
import traceback # Used to get the traceback of errors
|
import traceback # Used to get the traceback of errors
|
||||||
|
|
||||||
import discord # Used to init discord.Game and discord.Status, as well
|
import discord # Used to init discord.Game and discord.Status, as well
|
||||||
# as compare errors to discord errors and as typehints
|
# as compare errors to discord errors and as typehints
|
||||||
from discord.ext import commands # Used to compare errors with command
|
from discord.ext import commands # Used to compare errors with command
|
||||||
# errors
|
# errors
|
||||||
|
|
||||||
from interactions import SlashContext, ComponentContext
|
from interactions import SlashContext, ComponentContext
|
||||||
from gwendolyn_old.utils.util_functions import decode_id
|
from gwendolyn_old.utils.util_functions import decode_id
|
||||||
@@ -19,88 +19,88 @@ from gwendolyn_old.exceptions import InvalidInteraction
|
|||||||
|
|
||||||
|
|
||||||
class EventHandler():
|
class EventHandler():
|
||||||
"""
|
"""
|
||||||
Handles bot events.
|
Handles bot events.
|
||||||
|
|
||||||
*Methods*
|
*Methods*
|
||||||
---------
|
---------
|
||||||
on_ready()
|
on_ready()
|
||||||
on_slash_command(ctx: interactions.SlashContext)
|
on_slash_command(ctx: interactions.SlashContext)
|
||||||
on_reaction_add(ctx: interactions.SlashContext)
|
on_reaction_add(ctx: interactions.SlashContext)
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, bot):
|
def __init__(self, bot):
|
||||||
"""Initialize the handler."""
|
"""Initialize the handler."""
|
||||||
self.bot = bot
|
self.bot = bot
|
||||||
|
|
||||||
async def on_ready(self):
|
async def on_ready(self):
|
||||||
"""Log and sets status when it logs in."""
|
"""Log and sets status when it logs in."""
|
||||||
await self.bot.database_funcs.imdb_commands()
|
await self.bot.database_funcs.imdb_commands()
|
||||||
name = self.bot.user.name
|
name = self.bot.user.name
|
||||||
userid = str(self.bot.user.id)
|
userid = str(self.bot.user.id)
|
||||||
logged_in_message = f"Logged in as {name}, {userid}"
|
logged_in_message = f"Logged in as {name}, {userid}"
|
||||||
self.bot.log(logged_in_message, level=25)
|
self.bot.log(logged_in_message, level=25)
|
||||||
game = discord.Game("Use /help for commands")
|
game = discord.Game("Use /help for commands")
|
||||||
|
|
||||||
online_status = discord.Status.online
|
online_status = discord.Status.online
|
||||||
await self.bot.change_presence(activity=game, status=online_status)
|
await self.bot.change_presence(activity=game, status=online_status)
|
||||||
|
|
||||||
async def on_slash_command(self, ctx: SlashContext):
|
async def on_slash_command(self, ctx: SlashContext):
|
||||||
"""Log when a slash command is given."""
|
"""Log when a slash command is given."""
|
||||||
if ctx.subcommand_name is not None:
|
if ctx.subcommand_name is not None:
|
||||||
subcommand = f" {ctx.subcommand_name} "
|
subcommand = f" {ctx.subcommand_name} "
|
||||||
else:
|
else:
|
||||||
subcommand = " "
|
subcommand = " "
|
||||||
|
|
||||||
if ctx.subcommand_group is not None:
|
if ctx.subcommand_group is not None:
|
||||||
sub_command_group = f"{ctx.subcommand_group} "
|
sub_command_group = f"{ctx.subcommand_group} "
|
||||||
else:
|
else:
|
||||||
sub_command_group = ""
|
sub_command_group = ""
|
||||||
|
|
||||||
args = " ".join([str(i) for i in ctx.args])
|
args = " ".join([str(i) for i in ctx.args])
|
||||||
full_command = f"/{ctx.command}{subcommand}{sub_command_group}{args}"
|
full_command = f"/{ctx.command}{subcommand}{sub_command_group}{args}"
|
||||||
log_message = f"{ctx.author.display_name} ran {full_command}"
|
log_message = f"{ctx.author.display_name} ran {full_command}"
|
||||||
self.bot.log(log_message, str(ctx.channel_id), level=25)
|
self.bot.log(log_message, str(ctx.channel_id), level=25)
|
||||||
|
|
||||||
async def on_component(self, ctx: ComponentContext):
|
async def on_component(self, ctx: ComponentContext):
|
||||||
"""Handle component interaction."""
|
"""Handle component interaction."""
|
||||||
info = decode_id(ctx.custom_id)
|
info = decode_id(ctx.custom_id)
|
||||||
self.bot.log(f"Component action with info {info}")
|
self.bot.log(f"Component action with info {info}")
|
||||||
channel = ctx.channel
|
channel = ctx.channel
|
||||||
author = str(ctx.author_id)
|
author = str(ctx.author_id)
|
||||||
|
|
||||||
if info[0].lower() == "plex":
|
if info[0].lower() == "plex":
|
||||||
if info[1].lower() == "movie":
|
if info[1].lower() == "movie":
|
||||||
await self.bot.other.plex.add_movie(
|
await self.bot.other.plex.add_movie(
|
||||||
ctx.origin_message,
|
ctx.origin_message,
|
||||||
info[2],
|
info[2],
|
||||||
not isinstance(channel, discord.DMChannel)
|
not isinstance(channel, discord.DMChannel)
|
||||||
)
|
)
|
||||||
return
|
return
|
||||||
|
|
||||||
elif info[1].lower() == "show":
|
elif info[1].lower() == "show":
|
||||||
await self.bot.other.plex.add_show(
|
await self.bot.other.plex.add_show(
|
||||||
ctx.origin_message,
|
ctx.origin_message,
|
||||||
info[2],
|
info[2],
|
||||||
not isinstance(channel, discord.DMChannel)
|
not isinstance(channel, discord.DMChannel)
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
raise InvalidInteraction(ctx.custom_id, info)
|
raise InvalidInteraction(ctx.custom_id, info)
|
||||||
|
|
||||||
elif info[0].lower() == "hangman" and author == info[2]:
|
elif info[0].lower() == "hangman" and author == info[2]:
|
||||||
if info[1].lower() == "guess":
|
if info[1].lower() == "guess":
|
||||||
await self.bot.games.hangman.guess(ctx, *info[3:])
|
await self.bot.games.hangman.guess(ctx, *info[3:])
|
||||||
elif info[1].lower() == "end":
|
elif info[1].lower() == "end":
|
||||||
await self.bot.games.hangman.stop(ctx, *info[3:])
|
await self.bot.games.hangman.stop(ctx, *info[3:])
|
||||||
else:
|
else:
|
||||||
raise InvalidInteraction(ctx.custom_id, info)
|
raise InvalidInteraction(ctx.custom_id, info)
|
||||||
elif info[0].lower() == "connectfour":
|
elif info[0].lower() == "connectfour":
|
||||||
connect_four = self.bot.games.connect_four
|
connect_four = self.bot.games.connect_four
|
||||||
if info[1].lower() == "place" and author == info[2]:
|
if info[1].lower() == "place" and author == info[2]:
|
||||||
await connect_four.place_piece(
|
await connect_four.place_piece(
|
||||||
ctx,
|
ctx,
|
||||||
info[3],
|
info[3],
|
||||||
int(info[4]),
|
int(info[4]),
|
||||||
[int(info[5]), int(info[6])],
|
[int(info[5]), int(info[6])],
|
||||||
int(info[7]),
|
int(info[7]),
|
||||||
ctx.author_id,
|
ctx.author_id,
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ Contains classes used for utilities.
|
|||||||
|
|
||||||
*Classes*
|
*Classes*
|
||||||
---------
|
---------
|
||||||
DatabaseFuncs()
|
DatabaseFuncs()
|
||||||
"""
|
"""
|
||||||
import os # Used to test if files exist
|
import os # Used to test if files exist
|
||||||
import time # Used to test how long it's been since commands were synced
|
import time # Used to test how long it's been since commands were synced
|
||||||
@@ -13,161 +13,161 @@ import discord # Used for type hints
|
|||||||
|
|
||||||
|
|
||||||
class DatabaseFuncs():
|
class DatabaseFuncs():
|
||||||
"""
|
"""
|
||||||
Manages database functions.
|
Manages database functions.
|
||||||
|
|
||||||
*Methods*
|
*Methods*
|
||||||
|
---------
|
||||||
|
get_name(user_id: str) -> str
|
||||||
|
get_id(user_name: str) -> str
|
||||||
|
delete_game(game_type: str, channel: str)
|
||||||
|
wipe_games()
|
||||||
|
connect_four_reaction_test(message: discord.Message,
|
||||||
|
user: discord.User) -> bool
|
||||||
|
imdb_commands()
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, bot):
|
||||||
|
"""Initialize the class."""
|
||||||
|
self.bot = bot
|
||||||
|
|
||||||
|
def get_name(self, user_id: str):
|
||||||
|
"""
|
||||||
|
Get the name of a user you have the # id of.
|
||||||
|
|
||||||
|
*Parameters:
|
||||||
|
------------
|
||||||
|
user_id: str
|
||||||
|
The id of the user you want the name of. The format is
|
||||||
|
"#" + str(discord.User.id)
|
||||||
|
|
||||||
|
*Returns*
|
||||||
---------
|
---------
|
||||||
get_name(user_id: str) -> str
|
user_name: str
|
||||||
get_id(user_name: str) -> str
|
The name of the user. If the user couldn't be found,
|
||||||
delete_game(game_type: str, channel: str)
|
returns the user_id.
|
||||||
wipe_games()
|
|
||||||
connect_four_reaction_test(message: discord.Message,
|
|
||||||
user: discord.User) -> bool
|
|
||||||
imdb_commands()
|
|
||||||
"""
|
"""
|
||||||
|
user = self.bot.database["users"].find_one({"_id": user_id})
|
||||||
|
|
||||||
def __init__(self, bot):
|
if user_id == f"#{self.bot.user.id}":
|
||||||
"""Initialize the class."""
|
return_name = "Gwendolyn"
|
||||||
self.bot = bot
|
elif user is not None:
|
||||||
|
return_name = user["user name"]
|
||||||
|
else:
|
||||||
|
self.bot.log(f"Couldn't find user {user_id}")
|
||||||
|
return_name = user_id
|
||||||
|
|
||||||
def get_name(self, user_id: str):
|
return return_name
|
||||||
"""
|
|
||||||
Get the name of a user you have the # id of.
|
|
||||||
|
|
||||||
*Parameters:
|
def get_id(self, user_name: str):
|
||||||
------------
|
"""
|
||||||
user_id: str
|
Get the id of a user you have the username of.
|
||||||
The id of the user you want the name of. The format is
|
|
||||||
"#" + str(discord.User.id)
|
|
||||||
|
|
||||||
*Returns*
|
*Parameters:
|
||||||
---------
|
------------
|
||||||
user_name: str
|
user_name: str
|
||||||
The name of the user. If the user couldn't be found,
|
The name of the user you want the id of.
|
||||||
returns the user_id.
|
|
||||||
"""
|
|
||||||
user = self.bot.database["users"].find_one({"_id": user_id})
|
|
||||||
|
|
||||||
if user_id == f"#{self.bot.user.id}":
|
*Returns*
|
||||||
return_name = "Gwendolyn"
|
---------
|
||||||
elif user is not None:
|
user_id: str
|
||||||
return_name = user["user name"]
|
The id of the user in the format "#" +
|
||||||
else:
|
str(discord.User.id). If the user couldn't be found,
|
||||||
self.bot.log(f"Couldn't find user {user_id}")
|
returns the user_name.
|
||||||
return_name = user_id
|
"""
|
||||||
|
user_search = {"user name": re.compile(user_name, re.IGNORECASE)}
|
||||||
|
user = self.bot.database["users"].find_one(user_search)
|
||||||
|
|
||||||
return return_name
|
if user is not None:
|
||||||
|
return_id = user["_id"]
|
||||||
|
else:
|
||||||
|
self.bot.log("Couldn't find user "+user_name)
|
||||||
|
return_id = None
|
||||||
|
|
||||||
def get_id(self, user_name: str):
|
return return_id
|
||||||
"""
|
|
||||||
Get the id of a user you have the username of.
|
|
||||||
|
|
||||||
*Parameters:
|
def delete_game(self, game_type: str, channel: str):
|
||||||
------------
|
"""
|
||||||
user_name: str
|
Remove a game from the database.
|
||||||
The name of the user you want the id of.
|
|
||||||
|
|
||||||
*Returns*
|
*Parameters*
|
||||||
---------
|
------------
|
||||||
user_id: str
|
game_type: str
|
||||||
The id of the user in the format "#" +
|
The name of the collection the game is in, like
|
||||||
str(discord.User.id). If the user couldn't be found,
|
"hangman games", "blackjack games" etc.
|
||||||
returns the user_name.
|
channel: str
|
||||||
"""
|
The channel id of the channel the game is on as a
|
||||||
user_search = {"user name": re.compile(user_name, re.IGNORECASE)}
|
string.
|
||||||
user = self.bot.database["users"].find_one(user_search)
|
"""
|
||||||
|
self.bot.database[game_type].delete_one({"_id": channel})
|
||||||
|
|
||||||
if user is not None:
|
def wipe_games(self):
|
||||||
return_id = user["_id"]
|
"""Delete all running games and pull from git."""
|
||||||
else:
|
game_types = [
|
||||||
self.bot.log("Couldn't find user "+user_name)
|
"trivia questions",
|
||||||
return_id = None
|
"blackjack games",
|
||||||
|
"connect 4 games"
|
||||||
|
"hex games",
|
||||||
|
"wordle games"
|
||||||
|
]
|
||||||
|
for game_type in game_types:
|
||||||
|
self.bot.database[game_type].delete_many({})
|
||||||
|
|
||||||
return return_id
|
def connect_four_reaction_test(self, message: discord.Message,
|
||||||
|
user: discord.User):
|
||||||
|
"""
|
||||||
|
Test if the given message is the current connect four game.
|
||||||
|
|
||||||
def delete_game(self, game_type: str, channel: str):
|
Also tests if the given user is the one who's turn it is.
|
||||||
"""
|
|
||||||
Remove a game from the database.
|
|
||||||
|
|
||||||
*Parameters*
|
*Parameters*
|
||||||
------------
|
------------
|
||||||
game_type: str
|
message: discord.Message
|
||||||
The name of the collection the game is in, like
|
The message to test.
|
||||||
"hangman games", "blackjack games" etc.
|
user: discord.User
|
||||||
channel: str
|
The user to test.
|
||||||
The channel id of the channel the game is on as a
|
*Returns*
|
||||||
string.
|
---------
|
||||||
"""
|
: bool
|
||||||
self.bot.database[game_type].delete_one({"_id": channel})
|
Whether the given message is the current connect four
|
||||||
|
game and if the user who reacted is the user who's turn
|
||||||
|
it is.
|
||||||
|
"""
|
||||||
|
channel = message.channel
|
||||||
|
channel_search = {"_id": str(channel.id)}
|
||||||
|
game = self.bot.database["connect 4 games"].find_one(channel_search)
|
||||||
|
|
||||||
def wipe_games(self):
|
old_images_path = "gwendolyn/resources/games/old_images/"
|
||||||
"""Delete all running games and pull from git."""
|
file_path = old_images_path + f"connect_four{channel.id}"
|
||||||
game_types = [
|
if os.path.isfile(file_path):
|
||||||
"trivia questions",
|
with open(file_path, "r", encoding="utf-8") as file_pointer:
|
||||||
"blackjack games",
|
old_image = int(file_pointer.read())
|
||||||
"connect 4 games"
|
else:
|
||||||
"hex games",
|
old_image = 0
|
||||||
"wordle games"
|
|
||||||
]
|
|
||||||
for game_type in game_types:
|
|
||||||
self.bot.database[game_type].delete_many({})
|
|
||||||
|
|
||||||
def connect_four_reaction_test(self, message: discord.Message,
|
if message.id == old_image:
|
||||||
user: discord.User):
|
self.bot.log("They reacted to the connect_four game")
|
||||||
"""
|
turn = game["turn"]
|
||||||
Test if the given message is the current connect four game.
|
if user == game["players"][turn]:
|
||||||
|
valid_reaction = True
|
||||||
|
else:
|
||||||
|
self.bot.log("It wasn't their turn")
|
||||||
|
valid_reaction = False
|
||||||
|
else:
|
||||||
|
valid_reaction = False
|
||||||
|
|
||||||
Also tests if the given user is the one who's turn it is.
|
return valid_reaction
|
||||||
|
|
||||||
*Parameters*
|
async def imdb_commands(self):
|
||||||
------------
|
"""Sync the slash commands with the discord API."""
|
||||||
message: discord.Message
|
collection = self.bot.database["last synced"]
|
||||||
The message to test.
|
last_synced = collection.find_one()
|
||||||
user: discord.User
|
now = time.time()
|
||||||
The user to test.
|
if last_synced["last synced"] < now - 86400:
|
||||||
*Returns*
|
slash_command_list = await self.bot.slash.to_dict()
|
||||||
---------
|
self.bot.log(f"Updating commands: {slash_command_list}")
|
||||||
: bool
|
await self.bot.slash.sync_all_commands()
|
||||||
Whether the given message is the current connect four
|
id_number = last_synced["_id"]
|
||||||
game and if the user who reacted is the user who's turn
|
query_filter = {"_id": id_number}
|
||||||
it is.
|
update = {"$set": {"last synced": now}}
|
||||||
"""
|
collection.update_one(query_filter, update)
|
||||||
channel = message.channel
|
|
||||||
channel_search = {"_id": str(channel.id)}
|
|
||||||
game = self.bot.database["connect 4 games"].find_one(channel_search)
|
|
||||||
|
|
||||||
old_images_path = "gwendolyn/resources/games/old_images/"
|
|
||||||
file_path = old_images_path + f"connect_four{channel.id}"
|
|
||||||
if os.path.isfile(file_path):
|
|
||||||
with open(file_path, "r", encoding="utf-8") as file_pointer:
|
|
||||||
old_image = int(file_pointer.read())
|
|
||||||
else:
|
|
||||||
old_image = 0
|
|
||||||
|
|
||||||
if message.id == old_image:
|
|
||||||
self.bot.log("They reacted to the connect_four game")
|
|
||||||
turn = game["turn"]
|
|
||||||
if user == game["players"][turn]:
|
|
||||||
valid_reaction = True
|
|
||||||
else:
|
|
||||||
self.bot.log("It wasn't their turn")
|
|
||||||
valid_reaction = False
|
|
||||||
else:
|
|
||||||
valid_reaction = False
|
|
||||||
|
|
||||||
return valid_reaction
|
|
||||||
|
|
||||||
async def imdb_commands(self):
|
|
||||||
"""Sync the slash commands with the discord API."""
|
|
||||||
collection = self.bot.database["last synced"]
|
|
||||||
last_synced = collection.find_one()
|
|
||||||
now = time.time()
|
|
||||||
if last_synced["last synced"] < now - 86400:
|
|
||||||
slash_command_list = await self.bot.slash.to_dict()
|
|
||||||
self.bot.log(f"Updating commands: {slash_command_list}")
|
|
||||||
await self.bot.slash.sync_all_commands()
|
|
||||||
id_number = last_synced["_id"]
|
|
||||||
query_filter = {"_id": id_number}
|
|
||||||
update = {"$set": {"last synced": now}}
|
|
||||||
collection.update_one(query_filter, update)
|
|
||||||
|
|||||||
12
main.py
12
main.py
@@ -4,13 +4,13 @@ from gwendolyn import Gwendolyn
|
|||||||
from gwendolyn.utils import make_files
|
from gwendolyn.utils import make_files
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
"""Starts the bot"""
|
"""Starts the bot"""
|
||||||
|
|
||||||
make_files()
|
make_files()
|
||||||
|
|
||||||
# Creates the Bot
|
# Creates the Bot
|
||||||
bot = Gwendolyn()
|
bot = Gwendolyn()
|
||||||
bot.start()
|
bot.start()
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
main()
|
main()
|
||||||
|
|||||||
Reference in New Issue
Block a user