diff --git a/Gwendolyn.py b/Gwendolyn.py index 677ff02..6f81b1e 100644 --- a/Gwendolyn.py +++ b/Gwendolyn.py @@ -1,10 +1,10 @@ -import discord, os, finnhub, platform, asyncio, traceback +import os, finnhub, platform, asyncio from discord.ext import commands from discord_slash import SlashCommand from pymongo import MongoClient -from funcs import logThis, makeFiles, Money, Funcs, SwChar, SwDestiny, SwRoll, Games, Generators, BedreNetflix, NerdShit -from utils import Options, Credentials +from funcs import Money, StarWars, Games, Other, LookupFuncs +from utils import Options, Credentials, logThis, makeFiles, databaseFuncs class Gwendolyn(commands.Bot): def __init__(self): @@ -14,26 +14,24 @@ class Gwendolyn(commands.Bot): self.MongoClient = MongoClient(f"mongodb+srv://{self.credentials.mongoDBUser}:{self.credentials.mongoDBPassword}@gwendolyn.qkwfy.mongodb.net/Gwendolyn?retryWrites=true&w=majority") if self.options.testing: - logThis("Testing mode") + self.log("Testing mode") self.database = self.MongoClient["Gwendolyn-Test"] else: self.database = self.MongoClient["Gwendolyn"] - self.swchar = SwChar(self) - self.swroll = SwRoll(self) - self.swdestiny = SwDestiny(self) - - self.generator = Generators() - self.bedreNetflix = BedreNetflix(self) - self.nerdShit = NerdShit(self) - - Games(self) - + self.starWars = StarWars(self) + self.other = Other(self) + self.lookupFuncs = LookupFuncs(self) + self.games = Games(self) self.money = Money(self) - self.funcs = Funcs(self) + self.databaseFuncs = databaseFuncs(self) super().__init__(command_prefix=" ", case_insensitive=True) + def log(self, messages, channel : str = "", level : int = 20): + logThis(messages, channel, level) + + if __name__ == "__main__": if platform.system() == "Windows": @@ -43,16 +41,16 @@ if __name__ == "__main__": makeFiles() # Creates the Bot - client = Gwendolyn() - slash = SlashCommand(client, sync_commands=True, sync_on_cog_reload=True, override_type=True) + bot = Gwendolyn() + bot.slash = SlashCommand(bot, sync_commands=True, sync_on_cog_reload=True, override_type=True) #Loads cogs for filename in os.listdir("./cogs"): if filename.endswith(".py"): - client.load_extension(f"cogs.{filename[:-3]}") + bot.load_extension(f"cogs.{filename[:-3]}") try: # Runs the whole shabang - client.run(client.credentials.token) + bot.run(bot.credentials.token) except: - logThis("Could not log in. Remember to write your bot token in the credentials.txt file") \ No newline at end of file + bot.log("Could not log in. Remember to write your bot token in the credentials.txt file") \ No newline at end of file diff --git a/cogs/EventCog.py b/cogs/EventCog.py index 4832c2b..1332886 100644 --- a/cogs/EventCog.py +++ b/cogs/EventCog.py @@ -1,28 +1,29 @@ +import discord, traceback from discord.ext import commands -class EventCog(commands.cog): - def __init__(bot): +class EventCog(commands.Cog): + def __init__(self, bot): self.bot = bot # Sets the game and logs when the bot logs in - @client.event - async def on_ready(): - logThis("Logged in as "+client.user.name+", "+str(client.user.id)) - game = discord.Game("Some weeb shit") - await client.change_presence(activity=game) + @commands.Cog.listener() + async def on_ready(self): + self.bot.log("Logged in as "+self.bot.user.name+", "+str(self.bot.user.id)) + game = discord.Game("Use /help for commands") + await self.bot.change_presence(activity=game) # Logs when user sends a command - @client.event - async def on_slash_command(ctx): - logThis(f"{ctx.author.display_name} ran {ctx.name}") + @commands.Cog.listener() + async def on_slash_command(self, ctx): + self.bot.log(f"{ctx.author.display_name} ran /{ctx.name}") # Logs if a command experiences an error - @client.event - async def on_slash_command_error(ctx, error): + @commands.Cog.listener() + async def on_slash_command_error(self, ctx, error): if isinstance(error, commands.CommandNotFound): await ctx.send("That's not a command (error code 001)") elif isinstance(error,commands.errors.MissingRequiredArgument): - logThis(f"{error}",str(ctx.channel_id)) + self.bot.log(f"{error}",str(ctx.channel_id)) await ctx.send("Missing command parameters (error code 002). Try using `!help [command]` to find out how to use the command.") else: exception = traceback.format_exception(type(error), error, error.__traceback__) @@ -32,5 +33,8 @@ class EventCog(commands.cog): exception = exception[:index] exceptionString = "".join(exception) - logThis([f"exception in {ctx.name} command", f"{exceptionString}"],str(ctx.channel_id), 40) - await ctx.send("Something went wrong (error code 000)") \ No newline at end of file + self.bot.log([f"exception in /{ctx.name}", f"{exceptionString}"],str(ctx.channel_id), 40) + await ctx.send("Something went wrong (error code 000)") + +def setup(bot): + bot.add_cog(EventCog(bot)) diff --git a/cogs/GamesCog.py b/cogs/GameCogs.py similarity index 59% rename from cogs/GamesCog.py rename to cogs/GameCogs.py index 7e75d66..4e48881 100644 --- a/cogs/GamesCog.py +++ b/cogs/GameCogs.py @@ -3,20 +3,11 @@ from discord.ext import commands from discord_slash import cog_ext from discord_slash import SlashCommandOptionType as scot -from funcs import logThis -from utils import Options +from utils import getParams -with open("resources/slashParameters.json", "r") as f: - params = json.load(f) - -options = Options() - -if options.testing: - for p in params: - params[p]["guild_ids"] = options.guildIds +params = getParams() class GamesCog(commands.Cog): - def __init__(self,bot): """Runs game stuff.""" self.bot = bot @@ -39,7 +30,7 @@ class GamesCog(commands.Cog): commands = parameters.split(" ") amount = int(commands[-1]) username = " ".join(commands[:-1]) - if self.bot.funcs.getID(username) == None: + if self.bot.databaseFuncs.getID(username) == None: async for member in ctx.guild.fetch_members(limit=None): if member.display_name.lower() == username.lower(): username = member.display_name @@ -52,7 +43,7 @@ class GamesCog(commands.Cog): @cog_ext.cog_slash(**params["invest"]) async def invest(self, ctx, parameters = "check"): await ctx.defer() - response = self.bot.invest.parseInvest(parameters,"#"+str(ctx.author.id)) + response = self.bot.games.invest.parseInvest(parameters,"#"+str(ctx.author.id)) if response.startswith("**"): responses = response.split("\n") em = discord.Embed(title=responses[0],description="\n".join(responses[1:]),colour=0x00FF00) @@ -65,7 +56,7 @@ class GamesCog(commands.Cog): async def trivia(self, ctx, answer = ""): await ctx.defer() if answer == "": - question, options, correctAnswer = self.bot.trivia.triviaStart(str(ctx.channel_id)) + question, options, correctAnswer = self.bot.games.trivia.triviaStart(str(ctx.channel_id)) if options != "": results = "**"+question+"**\n" for x, option in enumerate(options): @@ -75,95 +66,135 @@ class GamesCog(commands.Cog): await asyncio.sleep(60) - self.bot.trivia.triviaCountPoints(str(ctx.channel_id)) + self.bot.games.trivia.triviaCountPoints(str(ctx.channel_id)) - self.bot.funcs.deleteGame("trivia questions",str(ctx.channel_id)) + self.bot.databaseFuncs.deleteGame("trivia questions",str(ctx.channel_id)) - logThis("Time's up for the trivia question",str(ctx.channel_id)) + self.bot.log("Time's up for the trivia question",str(ctx.channel_id)) await ctx.send("Time's up The answer was \""+chr(correctAnswer)+") "+options[correctAnswer-97]+"\". Anyone who answered that has gotten 1 GwendoBuck") else: await ctx.send(question, hidden=True) elif answer in ["a","b","c","d"]: - response = self.bot.trivia.triviaAnswer("#"+str(ctx.author.id),str(ctx.channel_id),answer) + response = self.bot.games.trivia.triviaAnswer("#"+str(ctx.author.id),str(ctx.channel_id),answer) if response.startswith("Locked in "): await ctx.send(f"{ctx.author.display_name} answered {answer}") else: await ctx.send(response) else: - logThis("I didn't understand that (error code 1101)",str(ctx.channel_id)) + self.bot.log("I didn't understand that (error code 1101)",str(ctx.channel_id)) await ctx.send("I didn't understand that (error code 1101)") - # Runs a game of blackjack - @cog_ext.cog_slash(**params["blackjack"]) - async def blackjack(self, ctx, parameters = ""): - await ctx.defer() - await self.bot.blackjack.parseBlackjack(parameters, ctx) +class BlackjackCog(commands.Cog): + def __init__(self,bot): + """Runs game stuff.""" + self.bot = bot + + # Starts a game of blackjack + @cog_ext.cog_subcommand(**params["blackjackStart"]) + async def blackjackStart(self, ctx): + await ctx.defer() + await self.bot.games.blackjack.parseBlackjack("", ctx) + + @cog_ext.cog_subcommand(**params["blackjackBet"]) + async def blackjackBet(self, ctx, bet): + await ctx.defer() + await self.bot.games.blackjack.parseBlackjack(f"bet {bet}", ctx) + + @cog_ext.cog_subcommand(**params["blackjackStand"]) + async def blackjackStand(self, ctx, hand = ""): + await ctx.defer() + await self.bot.games.blackjack.parseBlackjack(f"stand {hand}", ctx) + + @cog_ext.cog_subcommand(**params["blackjackHit"]) + async def blackjackHit(self, ctx, hand = ""): + await ctx.defer() + await self.bot.games.blackjack.parseBlackjack(f"hit {hand}", ctx) + + +class ConnectFourCog(commands.Cog): + def __init__(self,bot): + """Runs game stuff.""" + self.bot = bot # Start a game of connect four against a user @cog_ext.cog_subcommand(**params["connectFourStartUser"]) async def connectFourStartUser(self, ctx, user): await ctx.defer() - await self.bot.gameLoops.connectFour(ctx, "start "+user.display_name) + await self.bot.games.gameLoops.connectFour(ctx, "start "+user.display_name) # Start a game of connect four against gwendolyn @cog_ext.cog_subcommand(**params["connectFourStartGwendolyn"]) async def connectFourStartGwendolyn(self, ctx, difficulty = 3): await ctx.defer() - await self.bot.gameLoops.connectFour(ctx, "start "+str(difficulty)) + await self.bot.games.gameLoops.connectFour(ctx, "start "+str(difficulty)) # Stop the current game of connect four @cog_ext.cog_subcommand(**params["connectFourStop"]) async def connectFourStop(self, ctx): - await self.bot.gameLoops.connectFour(ctx, "stop") + await self.bot.games.gameLoops.connectFour(ctx, "stop") # Place a piece in the current game of connect four @cog_ext.cog_subcommand(**params["connectFourPlace"]) async def connectFourPlace(self, ctx, column): - await self.bot.gameLoops.connectFour(ctx, "place "+str(column)) + await self.bot.games.gameLoops.connectFour(ctx, "place "+str(column)) + +class HangmanCog(commands.Cog): + def __init__(self,bot): + """Runs game stuff.""" + self.bot = bot # Starts a game of Hangman @cog_ext.cog_subcommand(**params["hangmanStart"]) async def hangmanStart(self, ctx): await ctx.defer() - await self.bot.gameLoops.runHangman(ctx.channel,"#"+str(ctx.author.id),"start", ctx) + await self.bot.games.gameLoops.runHangman(ctx.channel,"#"+str(ctx.author.id),"start", ctx) # Stops a game of Hangman @cog_ext.cog_subcommand(**params["hangmanStop"]) async def hangmanStop(self, ctx): - await self.bot.gameLoops.runHangman(ctx.channel,"#"+str(ctx.author.id),"stop", ctx) + await self.bot.games.gameLoops.runHangman(ctx.channel,"#"+str(ctx.author.id),"stop", ctx) + +class HexCog(commands.Cog): + def __init__(self,bot): + """Runs game stuff.""" + self.bot = bot # Start a game of Hex against another user @cog_ext.cog_subcommand(**params["hexStartUser"]) async def hexStartUser(self, ctx, user): await ctx.defer() - await self.bot.gameLoops.runHex(ctx, "start "+user.display_name, "#"+str(ctx.author.id)) - + await self.bot.games.gameLoops.runHex(ctx, "start "+user.display_name, "#"+str(ctx.author.id)) + # Start a game of Hex against Gwendolyn @cog_ext.cog_subcommand(**params["hexStartGwendolyn"]) async def hexStartGwendolyn(self, ctx, difficulty = 2): await ctx.defer() - await self.bot.gameLoops.runHex(ctx, "start "+str(difficulty), "#"+str(ctx.author.id)) + await self.bot.games.gameLoops.runHex(ctx, "start "+str(difficulty), "#"+str(ctx.author.id)) # Undo your last hex move @cog_ext.cog_subcommand(**params["hexUndo"]) async def hexUndo(self, ctx): - await self.bot.gameLoops.runHex(ctx, "undo", "#"+str(ctx.author.id)) + await self.bot.games.gameLoops.runHex(ctx, "undo", "#"+str(ctx.author.id)) # Perform a hex swap @cog_ext.cog_subcommand(**params["hexSwap"]) async def hexSwap(self, ctx): - await self.bot.gameLoops.runHex(ctx, "swap", "#"+str(ctx.author.id)) + await self.bot.games.gameLoops.runHex(ctx, "swap", "#"+str(ctx.author.id)) # Surrender the hex game @cog_ext.cog_subcommand(**params["hexSurrender"]) async def hexSurrender(self, ctx): - await self.bot.gameLoops.runHex(ctx, "surrender", "#"+str(ctx.author.id)) + await self.bot.games.gameLoops.runHex(ctx, "surrender", "#"+str(ctx.author.id)) # Place a piece in the hex game @cog_ext.cog_subcommand(**params["hexPlace"]) async def hexPlace(self, ctx, coordinates): - await self.bot.gameLoops.runHex(ctx, "place "+coordinates, "#"+str(ctx.author.id)) + await self.bot.games.gameLoops.runHex(ctx, "place "+coordinates, "#"+str(ctx.author.id)) def setup(bot): - bot.add_cog(GamesCog(bot)) \ No newline at end of file + bot.add_cog(GamesCog(bot)) + bot.add_cog(BlackjackCog(bot)) + bot.add_cog(ConnectFourCog(bot)) + bot.add_cog(HangmanCog(bot)) + bot.add_cog(HexCog(bot)) \ No newline at end of file diff --git a/cogs/LookupCog.py b/cogs/LookupCog.py index b272fda..aa1366e 100644 --- a/cogs/LookupCog.py +++ b/cogs/LookupCog.py @@ -3,28 +3,19 @@ from discord.ext import commands from discord_slash import cog_ext from discord_slash import SlashCommandOptionType as scot -from funcs import spellFunc, monsterFunc, cap -from utils import Options +from utils import getParams, cap -with open("resources/slashParameters.json", "r") as f: - params = json.load(f) - -options = Options() - -if options.testing: - for p in params: - params[p]["guild_ids"] = options.guildIds +params = getParams() class LookupCog(commands.Cog): - - def __init__(self,client): + def __init__(self, bot): """Runs lookup commands.""" - self.client = client + self.bot = bot # Looks up a spell @cog_ext.cog_slash(**params["spell"]) async def spell(self, ctx, query): - spell = spellFunc(cap(query)) + spell = self.bot.lookupFuncs.spellFunc(cap(query)) if len(spell) > 2000: await ctx.send(spell[:2000]) await ctx.send(spell[2000:]) @@ -34,7 +25,7 @@ class LookupCog(commands.Cog): # Looks up a monster @cog_ext.cog_slash(**params["monster"]) async def monster(self, ctx, query): - title, text1, text2, text3, text4, text5 = monsterFunc(cap(query)) + title, text1, text2, text3, text4, text5 = self.bot.lookupFuncs.monsterFunc(cap(query)) em1 = discord.Embed(title = title, description = text1, colour=0xDEADBF) # Sends the received information. Separates into separate messages if @@ -77,5 +68,5 @@ class LookupCog(commands.Cog): em5_2 = discord.Embed(title = "", description = text5[2048:], colour=0xDEADBF) await ctx.send(embed = em5_2) -def setup(client): - client.add_cog(LookupCog(client)) \ No newline at end of file +def setup(bot): + bot.add_cog(LookupCog(bot)) \ No newline at end of file diff --git a/cogs/MiscCog.py b/cogs/MiscCog.py index 18aeef0..7ac34bf 100644 --- a/cogs/MiscCog.py +++ b/cogs/MiscCog.py @@ -2,7 +2,6 @@ import discord, codecs, string, json from discord.ext import commands from discord_slash import cog_ext -from funcs import logThis, helloFunc, roll_dice, imageFunc, movieFunc, cap, findWikiPage from utils import Options with open("resources/slashParameters.json", "r") as f: @@ -15,31 +14,31 @@ if options.testing: params[p]["guild_ids"] = options.guildIds class MiscCog(commands.Cog): - def __init__(self,client): + def __init__(self, bot): """Runs misc commands.""" - self.client = client - self.client.remove_command("help") - self.generator = client.generator - self.bedreNetflix = client.bedreNetflix - self.nerdShit = client.nerdShit + self.bot = bot + self.bot.remove_command("help") + self.generators = bot.other.generators + self.bedreNetflix = bot.other.bedreNetflix + self.nerdShit = bot.other.nerdShit # Sends the bot's latency @cog_ext.cog_slash(**params["ping"]) async def ping(self, ctx): - await ctx.send(f"Pong!\nLatency is {round(self.client.latency * 1000)}ms") + await ctx.send(f"Pong!\nLatency is {round(self.bot.latency * 1000)}ms") # Restarts the bot @cog_ext.cog_slash(**params["stop"]) async def stop(self, ctx): - if "#"+str(ctx.author.id) in self.client.options.admins: + if "#"+str(ctx.author.id) in self.bot.options.admins: await ctx.send("Pulling git repo and restarting...") - self.client.funcs.stopServer() + self.bot.databaseFuncs.stopServer() - logThis("Logging out.") - await self.client.logout() + self.bot.log("Logging out.") + await self.bot.logout() else: - logThis(f"{ctx.author.display_name} tried to stop me! (error code 201)",str(ctx.channel_id)) + self.bot.log(f"{ctx.author.display_name} tried to stop me! (error code 201)",str(ctx.channel_id)) await ctx.send(f"I don't think I will, {ctx.author.display_name} (error code 201)") # Gets help for specific command @@ -51,13 +50,13 @@ class MiscCog(commands.Cog): em = discord.Embed(title = "Help", description = text,colour = 0x59f442) await ctx.send(embed = em) else: - logThis(f"Looking for help-{command}.txt",str(ctx.channel_id)) + self.bot.log(f"Looking for help-{command}.txt",str(ctx.channel_id)) with codecs.open(f"resources/help/help-{command}.txt",encoding="utf-8") as f: text = f.read() em = discord.Embed(title = command.capitalize(), description = text,colour = 0x59f442) await ctx.send(embed = em) - # Let's you thank the bot + # Lets you thank the bot @cog_ext.cog_slash(**params["thank"]) async def thank(self, ctx): await ctx.send("You're welcome :blush:") @@ -65,61 +64,42 @@ class MiscCog(commands.Cog): # Sends a friendly message @cog_ext.cog_slash(**params["hello"]) async def hello(self, ctx): - await ctx.send(helloFunc(ctx.author.display_name)) + await ctx.send(self.bot.other.helloFunc(ctx.author.display_name)) # Rolls dice @cog_ext.cog_slash(**params["roll"]) async def roll(self, ctx, dice = "1d20"): - await ctx.send(roll_dice(ctx.author.display_name,dice)) + await ctx.send(self.bot.other.rollDice(ctx.author.display_name, dice)) # Sends a random image @cog_ext.cog_slash(**params["image"]) async def image(self, ctx): - randomImage = imageFunc() - await ctx.send(randomImage) + await ctx.defer() + await ctx.send(self.bot.other.imageFunc()) # Finds a random movie @cog_ext.cog_slash(**params["movie"]) async def movie(self,ctx): - await ctx.defer() - title, plot, cover, cast = movieFunc() - if title == "error": - await ctx.send("An error occurred. Try again (error code "+plot+")") - else: - try: - embed = discord.Embed(title=title, description=plot, color=0x24ec19) - embed.set_thumbnail(url=cover) - embed.add_field(name="Cast", value=cast,inline = True) - await ctx.send(embed = embed) - except: - logThis("Error embedding (error code 805)") + await self.bot.other.movieFunc(ctx) # Generates a random name @cog_ext.cog_slash(**params["name"]) async def name(self, ctx): - await ctx.send(self.generator.nameGen()) + await ctx.send(self.generators.nameGen()) # Generates a random tavern name @cog_ext.cog_slash(**params["tavern"]) async def tavern(self, ctx): - await ctx.send(self.generator.tavernGen()) - - # Sets the game Gwendolyn's playing - @cog_ext.cog_slash(**params["game"]) - async def game(self, ctx, gameText): - gamePlaying = cap(gameText) - game = discord.Game(gamePlaying) - await self.client.change_presence(activity=game) - await ctx.send(f"Setting game to \"{gamePlaying}\"") + await ctx.send(self.generators.tavernGen()) # Finds a page on the Senkulpa wiki @cog_ext.cog_slash(**params["wiki"]) async def wiki(self, ctx, wikiPage): await ctx.defer() command = string.capwords(wikiPage) - title, content, thumbnail = findWikiPage(command) + title, content, thumbnail = self.bot.otherfindWikiPage(command) if title != "": - logThis("Sending the embedded message",str(ctx.channel_id)) + self.bot.log("Sending the embedded message",str(ctx.channel_id)) content += "\n[Læs mere](https://senkulpa.fandom.com/da/wiki/"+title.replace(" ","_")+")" embed = discord.Embed(title = title, description = content, colour=0xDEADBF) if thumbnail != "": @@ -152,5 +132,5 @@ class MiscCog(commands.Cog): async def wolf(self, ctx, query): await self.nerdShit.wolfSearch(ctx, query) -def setup(client): - client.add_cog(MiscCog(client)) +def setup(bot): + bot.add_cog(MiscCog(bot)) diff --git a/cogs/ReactionCog.py b/cogs/ReactionCog.py index 708a1fe..c791a89 100644 --- a/cogs/ReactionCog.py +++ b/cogs/ReactionCog.py @@ -1,28 +1,28 @@ from discord.ext import commands -from funcs import logThis, emojiToCommand +from utils import emojiToCommand class ReactionCog(commands.Cog): - def __init__(self, client): + def __init__(self, bot): """Listens for reactions.""" - self.client = client + self.bot = bot @commands.Cog.listener() - async def on_reaction_add(self, reaction,user): + async def on_reaction_add(self, reaction, user): if user.bot == False: message = reaction.message channel = message.channel - logThis(user.display_name+" reacted to a message",str(channel.id)) + self.bot.log(f"{user.display_name} reacted to a message",str(channel.id), level = 10) try: - connectFourTheirTurn, piece = self.client.funcs.connectFourReactionTest(channel,message,"#"+str(user.id)) + connectFourTheirTurn, piece = self.bot.databaseFuncs.connectFourReactionTest(channel,message,"#"+str(user.id)) except: connectFourTheirTurn = False - bedreNetflixMessage, addMovie, imdbIds = self.client.funcs.bedreNetflixReactionTest(channel,message) + bedreNetflixMessage, addMovie, imdbIds = self.bot.databaseFuncs.bedreNetflixReactionTest(channel, message) if connectFourTheirTurn: place = emojiToCommand(reaction.emoji) - await self.client.gameLoops.connectFour(message,"place "+str(piece)+" "+str(place),user.id, str(message.channel.id)) + await self.bot.games.gameLoops.connectFour(message,"place "+str(piece)+" "+str(place),user.id, str(message.channel.id)) elif bedreNetflixMessage and addMovie: moviePick = emojiToCommand(reaction.emoji) await message.delete() @@ -30,7 +30,7 @@ class ReactionCog(commands.Cog): imdbID = None else: imdbID = imdbIds[moviePick-1] - await self.client.bedreNetflix.addMovie(channel,imdbID) + await self.bot.other.bedreNetflix.addMovie(channel,imdbID) elif bedreNetflixMessage and not addMovie: showPick = emojiToCommand(reaction.emoji) await message.delete() @@ -38,9 +38,9 @@ class ReactionCog(commands.Cog): imdbName = None else: imdbName = imdbIds[showPick-1] - await self.client.bedreNetflix.addShow(channel,imdbName) - elif self.client.funcs.hangmanReactionTest(channel,message) and ord(reaction.emoji) in range(127462,127488): + await self.bot.other.bedreNetflix.addShow(channel,imdbName) + elif self.bot.databaseFuncs.hangmanReactionTest(channel,message) and ord(reaction.emoji) in range(127462,127488): guess = chr(ord(reaction.emoji)-127397) - await self.client.gameLoops.runHangman(channel,"#"+str(user.id),command="guess "+guess) -def setup(client): - client.add_cog(ReactionCog(client)) + await self.bot.games.gameLoops.runHangman(channel,"#"+str(user.id),command="guess "+guess) +def setup(bot): + bot.add_cog(ReactionCog(bot)) diff --git a/cogs/SwCog.py b/cogs/StarWarsCog.py similarity index 77% rename from cogs/SwCog.py rename to cogs/StarWarsCog.py index 66d8ad6..850e4f2 100644 --- a/cogs/SwCog.py +++ b/cogs/StarWarsCog.py @@ -2,8 +2,7 @@ import discord, string, json from discord.ext import commands from discord_slash import cog_ext -from funcs import cap -from utils import Options +from utils import Options, cap with open("resources/slashParameters.json", "r") as f: params = json.load(f) @@ -14,17 +13,17 @@ if options.testing: for p in params: params[p]["guild_ids"] = options.guildIds -class SwCog(commands.Cog): +class starWarsCog(commands.Cog): - def __init__(self,client): + def __init__(self, bot): """Runs star wars commands.""" - self.client = client + self.bot = bot # Rolls star wars dice @cog_ext.cog_slash(**params["starWarsRoll"]) async def starWarsRoll(self, ctx, dice = ""): command = cap(dice) - newMessage = self.client.swroll.parseRoll("#"+str(ctx.author.id),command) + newMessage = self.bot.starWars.roll.parseRoll("#"+str(ctx.author.id),command) messageList = newMessage.split("\n") await ctx.send(messageList[0]) if len(messageList) > 1: @@ -34,7 +33,7 @@ class SwCog(commands.Cog): # Controls destiny points @cog_ext.cog_slash(**params["starWarsDestiny"]) async def starWarsDestiny(self, ctx, parameters = ""): - newMessage = self.client.swdestiny.parseDestiny("#"+str(ctx.author.id),parameters) + newMessage = self.bot.starWars.destiny.parseDestiny("#"+str(ctx.author.id),parameters) messageList = newMessage.split("\n") await ctx.send(messageList[0]) if len(messageList) > 1: @@ -44,7 +43,7 @@ class SwCog(commands.Cog): # Rolls for critical injuries @cog_ext.cog_slash(**params["starWarsCrit"]) async def starWarsCrit(self, ctx, severity : int = 0): - newMessage = self.client.swroll.critRoll(int(severity)) + newMessage = self.bot.starWars.roll.critRoll(int(severity)) messageList = newMessage.split("\n") await ctx.send(messageList[0]) @@ -53,16 +52,16 @@ class SwCog(commands.Cog): await ctx.channel.send(messageItem) # Accesses and changes character sheet data with the parseChar function - # from funcs/swfuncs/swchar.py + # from funcs/starWarsFuncs/starWarsCharacter.py @cog_ext.cog_slash(**params["starWarsCharacter"]) async def starWarsCharacter(self, ctx, parameters = ""): command = string.capwords(parameters.replace("+","+ ").replace("-","- ").replace(",",", ")) - title, desc = self.client.swchar.parseChar("#"+str(ctx.author.id),command) + title, desc = self.bot.starWars.character.parseChar("#"+str(ctx.author.id),command) if title != "": em1 = discord.Embed(title = title, description = desc, colour=0xDEADBF) await ctx.send(embed = em1) else: await ctx.send(desc) -def setup(client): - client.add_cog(SwCog(client)) \ No newline at end of file +def setup(bot): + bot.add_cog(starWarsCog(bot)) \ No newline at end of file diff --git a/funcs/__init__.py b/funcs/__init__.py index cfc28f7..729f445 100644 --- a/funcs/__init__.py +++ b/funcs/__init__.py @@ -1,17 +1,11 @@ """A collection of all Gwendolyn functions.""" -__all__ = ["Games" ,"helloFunc", "cap", "imageFunc", "logThis", "findWikiPage", "makeFiles", "emojiToCommand", "Money", "spellFunc", "monsterFunc", "Generators", "movieFunc", "roll_dice", "SwChar", "SwDestiny", "SwRoll", "replaceMultiple","Funcs"] - -from .miscFuncs import helloFunc, cap, imageFunc, logThis, findWikiPage, makeFiles, replaceMultiple, emojiToCommand - -from .funcs import Funcs +__all__ = ["Games" , "Money", "LookupFuncs", "StarWars"] from .games import Money, Games -from .lookup import spellFunc, monsterFunc +from .lookup import LookupFuncs -from .other import Generators, movieFunc, BedreNetflix, NerdShit +from .other import Other -from .roll import roll_dice - -from .swfuncs import SwChar, SwDestiny, SwRoll +from .starWarsFuncs import StarWars diff --git a/funcs/funcs.py b/funcs/funcs.py deleted file mode 100644 index fa2f1cd..0000000 --- a/funcs/funcs.py +++ /dev/null @@ -1,87 +0,0 @@ -from .miscFuncs import logThis -import git # Used by stopServer() -import re, json - -class Funcs(): - def __init__(self,bot): - self.bot = bot - - def getName(self,userID): - user = self.bot.database["users"].find_one({"_id":userID}) - - if user != None: - return user["user name"] - elif userID == "Gwendolyn": - return userID - else: - logThis("Couldn't find user "+userID) - return userID - - def getID(self,userName): - user = self.bot.database["users"].find_one({"user name":re.compile(userName, re.IGNORECASE)}) - - if user != None: - return user["_id"] - else: - logThis("Couldn't find user "+userName) - return None - - def deleteGame(self, gameType,channel): - self.bot.database[gameType].delete_one({"_id":channel}) - - def stopServer(self): - self.bot.database["trivia questions"].delete_many({}) - self.bot.database["blackjack games"].delete_many({}) - self.bot.database["connect 4 games"].delete_many({}) - self.bot.database["hangman games"].delete_many({}) - - if not self.bot.options.testing: - g = git.cmd.Git("") - g.pull() - - def connectFourReactionTest(self,channel,message,user): - game = self.bot.database["connect 4 games"].find_one({"_id":str(channel.id)}) - - with open("resources/games/oldImages/connectFour"+str(channel.id), "r") as f: - oldImage = int(f.read()) - - if message.id == oldImage: - logThis("They reacted to the connectFour game") - turn = game["turn"] - if user == game["players"][turn]: - return True, turn+1 - else: - logThis("It wasn't their turn") - return False, 0 - else: - return False, 0 - - def hangmanReactionTest(self, channel,message): - try: - with open("resources/games/oldImages/hangman"+str(channel.id), "r") as f: - oldMessages = f.read().splitlines() - except: - return False - gameMessage = False - - for oldMessage in oldMessages: - oldMessageID = int(oldMessage) - if message.id == oldMessageID: - logThis("They reacted to the hangman game") - gameMessage = True - - return gameMessage - - def bedreNetflixReactionTest(self,channel,message): - try: - with open("resources/bedreNetflix/oldMessage"+str(channel.id),"r") as f: - data = json.load(f) - except: - return False, None, None - if data["messageID"] == message.id: - if "imdbIds" in data: - return True, True, data["imdbIds"] - else: - return True, False, data["imdbNames"] - else: - return False, None, None \ No newline at end of file diff --git a/funcs/games/blackjack.py b/funcs/games/blackjack.py index 64c87f5..5f60609 100644 --- a/funcs/games/blackjack.py +++ b/funcs/games/blackjack.py @@ -6,7 +6,7 @@ import discord from shutil import copyfile -from funcs import logThis, replaceMultiple +from utils import replaceMultiple from .blackjackDraw import DrawBlackjack class Blackjack(): @@ -16,7 +16,7 @@ class Blackjack(): # Shuffles the blackjack cards def blackjackShuffle(self, decks, channel): - logThis("Shuffling the blackjack deck") + self.bot.log("Shuffling the blackjack deck") with open("resources/games/deckofCards.txt","r") as f: deck = f.read() @@ -27,7 +27,7 @@ class Blackjack(): self.bot.database["blackjack cards"].update_one({"_id":channel},{"$set":{"_id":channel,"cards":allDecks}},upsert=True) # Creates hilo file - logThis("creating hilo doc for "+channel) + self.bot.log("creating hilo doc for "+channel) data = 0 self.bot.database["hilo"].update_one({"_id":channel},{"$set":{"_id":channel,"hilo":data}},upsert=True) @@ -35,7 +35,7 @@ class Blackjack(): # Calculates the value of a blackjack hand def calcHandValue(self, hand : list): - logThis("Calculating hand value") + self.bot.log("Calculating hand value", level = 10) values = [] values.append(0) @@ -58,13 +58,13 @@ class Blackjack(): if value <= 21: handValue = value - logThis("Calculated "+str(hand)+" to be "+str(handValue)) + self.bot.log("Calculated "+str(hand)+" to be "+str(handValue), level = 10) return handValue # Draws a card from the deck def drawCard(self, channel): - logThis("drawing a card") + self.bot.log("drawing a card", level = 10) drawnCard = self.bot.database["blackjack cards"].find_one({"_id":channel})["cards"][0] self.bot.database["blackjack cards"].update_one({"_id":channel},{"$pop":{"cards":-1}}) @@ -97,7 +97,7 @@ class Blackjack(): # Goes to the next round and calculates some stuff def blackjackContinue(self, channel): - logThis("Continuing blackjack game") + self.bot.log("Continuing blackjack game", level = 10) game = self.bot.database["blackjack games"].find_one({"_id":channel}) done = False @@ -109,20 +109,20 @@ class Blackjack(): message = "All players are standing. The dealer now shows his cards and draws." if game["all standing"]: - logThis("All are standing") + self.bot.log("All are standing") done = self.dealerDraw(channel) message = "The dealer draws a card." game = self.bot.database["blackjack games"].find_one({"_id":channel}) - logThis("Testing if all are standing") + self.bot.log("Testing if all are standing", level = 10) for user in game["user hands"]: try: newUser, allStanding, preAllStanding = self.testIfStanding(game["user hands"][user],allStanding,preAllStanding,True) self.bot.database["blackjack games"].update_one({"_id":channel},{"$set":{"user hands."+user:newUser}}) except: - logThis("Error in testing if all are standing (error code 1331)") + self.bot.log("Error in testing if all are standing (error code 1331)") if allStanding: self.bot.database["blackjack games"].update_one({"_id":channel},{"$set":{"all standing":True}}) @@ -130,7 +130,7 @@ class Blackjack(): try: self.draw.drawImage(channel) except: - logThis("Error drawing blackjack table (error code 1340)") + self.bot.log("Error drawing blackjack table (error code 1340)") if allStanding: if done == False: @@ -209,19 +209,19 @@ class Blackjack(): return response + str(roundDone)[0] + str(game["round"]) else: - logThis(user+" is already standing") + self.bot.log(user+" is already standing") return "You can't hit when you're standing" else: - logThis(user+" has already hit this round") + self.bot.log(user+" has already hit this round") return "You've already hit this round" else: - logThis(user+" tried to hit on the 0th round") + self.bot.log(user+" tried to hit on the 0th round") return "You can't hit before you see your cards" else: - logThis(user+" didn't specify a hand") + self.bot.log(user+" didn't specify a hand") return "You need to specify a hand" else: - logThis(user+" tried to hit without being in the game") + self.bot.log(user+" tried to hit without being in the game") return "You have to enter the game before you can hit" @@ -267,27 +267,27 @@ class Blackjack(): roundDone = self.isRoundDone(self.bot.database["blackjack games"].find_one({"_id":channel})) - return "Adding another "+str(bet)+" GwendoBucks to "+self.bot.funcs.getName(user)+"'s bet and drawing another card.",str(roundDone)[0] + str(game["round"]) + return "Adding another "+str(bet)+" GwendoBucks to "+self.bot.databaseFuncs.getName(user)+"'s bet and drawing another card.",str(roundDone)[0] + str(game["round"]) else: - logThis(user+" doesn't have enough GwendoBucks") + self.bot.log(user+" doesn't have enough GwendoBucks") return "You don't have enough GwendoBucks","" else: - logThis(user+" tried to double on round "+str(game["round"])) + self.bot.log(user+" tried to double on round "+str(game["round"])) return "You can only double down on the first round","" else: - logThis(user+" is already standing") + self.bot.log(user+" is already standing") return "You can't double when you're standing","" else: - logThis(user+" has already hit this round") + self.bot.log(user+" has already hit this round") return "You've already hit this round","" else: - logThis(user+" tried to double on the 0th round") + self.bot.log(user+" tried to double on the 0th round") return "You can't double down before you see your cards","" else: - logThis(user+" didn't specify a hand") + self.bot.log(user+" didn't specify a hand") return "You need to specify which hand" else: - logThis(user+" tried to double without being in the game") + self.bot.log(user+" tried to double without being in the game") return "You can't double when you're not in the game","" # When players try to stand @@ -322,19 +322,19 @@ class Blackjack(): return response + str(roundDone)[0] + str(game["round"]) else: - logThis(user+" is already standing") + self.bot.log(user+" is already standing") return "You're already standing" else: - logThis(user+" has already hit this round") + self.bot.log(user+" has already hit this round") return "You've already hit this round" else: - logThis(user+" tried to stand on the first round") + self.bot.log(user+" tried to stand on the first round") return "You can't stand before you see your cards" else: - logThis(user+" didn't specify a hand") + self.bot.log(user+" didn't specify a hand") return "You need to specify which hand" else: - logThis(user+" tried to stand without being in the game") + self.bot.log(user+" tried to stand without being in the game") return "You have to enter the game before you can stand" # When players try to split @@ -355,7 +355,7 @@ class Blackjack(): elif handNumber == 3: hand = game["user hands"][user]["third hand"] else: - logThis(user+" tried to hit without specifying which hand") + self.bot.log(user+" tried to hit without specifying which hand") return "You have to specify the hand you're hitting with." if game["user hands"][user]["split"] == 1: @@ -365,7 +365,7 @@ class Blackjack(): newHand = game["user hands"][user]["fourth hand"] otherHand = 4 else: - logThis(user+" tried to split without specifying which hand") + self.bot.log(user+" tried to split without specifying which hand") return "You have to specify the hand you're splitting.","" if game["user hands"][user]["split"] < 3: @@ -430,34 +430,34 @@ class Blackjack(): roundDone = self.isRoundDone(self.bot.database["blackjack games"].find_one({"_id":channel})) - return "Splitting "+self.bot.funcs.getName(user)+"'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.",str(roundDone)[0] + str(game["round"]) + return "Splitting "+self.bot.databaseFuncs.getName(user)+"'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.",str(roundDone)[0] + str(game["round"]) else: - logThis(user+" doesn't have enough GwendoBucks") + self.bot.log(user+" doesn't have enough GwendoBucks") return "You don't have enough GwendoBucks","" else: - logThis(user+" tried to split 2 different cards") + self.bot.log(user+" tried to split 2 different cards") return "Your cards need to have the same value to split","" else: - logThis(user+" tried to split later than they could") + self.bot.log(user+" tried to split later than they could") return "You can only split on the first round","" else: - logThis(user+" is already standing") + self.bot.log(user+" is already standing") return "You can't split when you're standing","" else: - logThis(user+" has already hit this round") + self.bot.log(user+" has already hit this round") return "You've already hit this round","" else: - logThis(user+" tried to split on the 0th round") + self.bot.log(user+" tried to split on the 0th round") return "You can't split before you see your cards","" else: - logThis(user+" tried to split more than three times") + self.bot.log(user+" tried to split more than three times") return "You can only split 3 times","" # Player enters the game and draws a hand def blackjackPlayerDrawHand(self,channel,user,bet): game = self.bot.database["blackjack games"].find_one({"_id":channel}) - logThis(self.bot.funcs.getName(user)+" is trying to join the game in "+channel) + self.bot.log(self.bot.databaseFuncs.getName(user)+" is trying to join the game in "+channel) if game != None: if user not in game["user hands"]: @@ -481,32 +481,32 @@ class Blackjack(): self.bot.database["blackjack games"].update_one({"_id":channel}, {"$set":{"user hands."+user:newHand}}) - logThis(f"{self.bot.funcs.getName(user)} entered the game with a bet of {bet}") - return f"{self.bot.funcs.getName(user)} entered the game with a bet of {bet}" + self.bot.log(f"{self.bot.databaseFuncs.getName(user)} entered the game with a bet of {bet}") + return f"{self.bot.databaseFuncs.getName(user)} entered the game with a bet of {bet}" else: - logThis(user+" doesn't have enough GwendoBucks") + self.bot.log(user+" doesn't have enough GwendoBucks") return "You don't have enough GwendoBucks to place that bet" else: - logThis(user+" tried to bet a negative amount") + self.bot.log(user+" tried to bet a negative amount") return "You can't bet a negative amount" else: - logThis("The table is no longer open for bets") + self.bot.log("The table is no longer open for bets") return "The table is no longer open for bets" else: - logThis("There are already 5 players in the game.") + self.bot.log("There are already 5 players in the game.") return "There's already a maximum of players at the table." else: - logThis(user+" is already in the game") + self.bot.log(user+" is already in the game") return "You've already entered this game" else: - logThis("There is no game going on in "+channel) + self.bot.log("There is no game going on in "+channel) return "There is no game going on in this channel" # Starts a game of blackjack def blackjackStart(self,channel:str): game = self.bot.database["blackjack games"].find_one({"_id":channel}) - logThis("Trying to start a blackjack game in "+channel) + self.bot.log("Trying to start a blackjack game in "+channel) if game == None: @@ -524,7 +524,7 @@ class Blackjack(): return "started" else: - logThis("There is already a blackjack game going on in "+channel) + self.bot.log("There is already a blackjack game going on in "+channel) return "There's already a blackjack game going on. Try again in a few minutes." # Ends the game and calculates winnings @@ -540,26 +540,23 @@ class Blackjack(): try: for user in game["user hands"]: - try: - winnings, netWinnings, reason = self.calcWinnings(game["user hands"][user],dealerValue,True,dealerBlackjack,dealerBusted) - except: - logThis("Error calculating winnings for "+str(user)+" (error code 1312)") + winnings, netWinnings, reason = self.calcWinnings(game["user hands"][user],dealerValue,True,dealerBlackjack,dealerBusted) if winnings < 0: if winnings == -1: - finalWinnings += self.bot.funcs.getName(user)+" lost "+str(-1 * winnings)+" GwendoBuck "+reason+"\n" + finalWinnings += self.bot.databaseFuncs.getName(user)+" lost "+str(-1 * winnings)+" GwendoBuck "+reason+"\n" else: - finalWinnings += self.bot.funcs.getName(user)+" lost "+str(-1 * winnings)+" GwendoBucks "+reason+"\n" + finalWinnings += self.bot.databaseFuncs.getName(user)+" lost "+str(-1 * winnings)+" GwendoBucks "+reason+"\n" else: if winnings == 1: - finalWinnings += self.bot.funcs.getName(user)+" won "+str(winnings)+" GwendoBuck "+reason+"\n" + finalWinnings += self.bot.databaseFuncs.getName(user)+" won "+str(winnings)+" GwendoBuck "+reason+"\n" else: - finalWinnings += self.bot.funcs.getName(user)+" won "+str(winnings)+" GwendoBucks "+reason+"\n" + finalWinnings += self.bot.databaseFuncs.getName(user)+" won "+str(winnings)+" GwendoBucks "+reason+"\n" self.bot.money.addMoney(user,netWinnings) except: - logThis("Error calculating winnings (error code 1311)") + self.bot.log("Error calculating winnings (error code 1311)") self.bot.database["blackjack games"].delete_one({"_id":channel}) @@ -567,7 +564,7 @@ class Blackjack(): def calcWinnings(self,hand, dealerValue, topLevel, dealerBlackjack, dealerBusted): - logThis("Calculating winnings") + self.bot.log("Calculating winnings", level = 10) reason = "" bet = hand["bet"] winnings = -1 * bet @@ -637,7 +634,7 @@ class Blackjack(): return hand, handNumber except: - logThis("Problem with getHandNumber() (error code 1322)") + self.bot.log("Problem with getHandNumber() (error code 1322)") def isRoundDone(self,game): roundDone = True @@ -662,14 +659,14 @@ class Blackjack(): # Loop of blackjack game rounds async def blackjackLoop(self,channel,gameRound,gameID): - logThis("Loop "+str(gameRound),str(channel.id)) + self.bot.log("Loop "+str(gameRound),str(channel.id), level = 10) with open("resources/games/oldImages/blackjack"+str(channel.id), "r") as f: oldImage = await channel.fetch_message(int(f.read())) new_message, allStanding, gamedone = self.blackjackContinue(str(channel.id)) if new_message != "": - logThis(new_message,str(channel.id)) + self.bot.log(new_message,str(channel.id), level = 10) await channel.send(new_message) if gamedone == False: await oldImage.delete() @@ -683,7 +680,7 @@ class Blackjack(): else: await asyncio.sleep(120) except: - logThis("Loop "+str(gameRound)+" interrupted (error code 1321)") + self.bot.log("Loop "+str(gameRound)+" interrupted (error code 1321)") game = self.bot.database["blackjack games"].find_one({"_id":str(channel.id)}) @@ -693,18 +690,18 @@ class Blackjack(): if gameRound == realRound and realGameID == gameID: if gamedone == False: - logThis("Loop "+str(gameRound)+" calling self.blackjackLoop()",str(channel.id)) + self.bot.log("Loop "+str(gameRound)+" calling self.blackjackLoop()",str(channel.id)) await self.blackjackLoop(channel,gameRound+1,gameID) else: try: new_message = self.blackjackFinish(str(channel.id)) except: - logThis("Something fucked up (error code 1310)") + self.bot.log("Something fucked up (error code 1310)") await channel.send(new_message) else: - logThis("Ending loop on round "+str(gameRound),str(channel.id)) + self.bot.log("Ending loop on round "+str(gameRound),str(channel.id), level = 10) else: - logThis("Ending loop on round "+str(gameRound),str(channel.id)) + self.bot.log("Ending loop on round "+str(gameRound),str(channel.id), level = 10) async def parseBlackjack(self,content, ctx): # Blackjack shuffle variables @@ -714,7 +711,7 @@ class Blackjack(): channel = ctx.channel_id # Starts the game if content == "": - await ctx.send("Staring a new game of blackjack") + await ctx.send("Starting a new game of blackjack") cardsLeft = 0 cards = self.bot.database["blackjack cards"].find_one({"_id":str(channel)}) if cards != None: @@ -723,7 +720,7 @@ class Blackjack(): # Shuffles if not enough cards if cardsLeft < blackjackMinCards: self.blackjackShuffle(blackjackDecks,str(channel)) - logThis("Shuffling the blackjack deck...",str(channel)) + self.bot.log("Shuffling the blackjack deck...",str(channel)) await ctx.channel.send("Shuffling the deck...") new_message = self.blackjackStart(str(channel)) @@ -749,7 +746,7 @@ class Blackjack(): # Loop of game rounds if gamedone == False: - logThis("!blackjack calling self.blackjackLoop()",str(channel)) + self.bot.log("!blackjack calling self.blackjackLoop()",str(channel)) await self.blackjackLoop(ctx.channel,1,gameID) else: new_message = self.blackjackFinish(str(channel)) @@ -781,10 +778,10 @@ class Blackjack(): #try: if response[6] == "T": gameID = self.bot.database["blackjack games"].find_one({"_id":str(channel)})["gameID"] - logThis("Hit calling self.blackjackLoop()",str(channel)) + self.bot.log("Hit calling self.blackjackLoop()",str(channel)) await self.blackjackLoop(ctx.channel,int(response[7:])+1,gameID) #except: - # logThis("Something fucked up (error code 1320)",str(channel)) + # self.bot.log("Something fucked up (error code 1320)",str(channel)) else: await ctx.send(response) @@ -806,10 +803,10 @@ class Blackjack(): #try: if response[6] == "T": gameID = self.bot.database["blackjack games"].find_one({"_id":str(channel)})["gameID"] - logThis("Stand calling self.blackjackLoop()",str(channel)) + self.bot.log("Stand calling self.blackjackLoop()",str(channel)) await self.blackjackLoop(ctx.channel,int(response[7:])+1,gameID) #except: - # logThis("Something fucked up (error code 1320)",str(channel)) + # self.bot.log("Something fucked up (error code 1320)",str(channel)) else: await ctx.send(response) @@ -827,10 +824,10 @@ class Blackjack(): try: if roundDone[0] == "T": gameID = self.bot.database["blackjack games"].find_one({"_id":str(channel)})["gameID"] - logThis("Double calling self.blackjackLoop()",str(channel)) + self.bot.log("Double calling self.blackjackLoop()",str(channel)) await self.blackjackLoop(ctx.channel,int(roundDone[1:])+1,gameID) except: - logThis("Something fucked up (error code 1320)",str(channel)) + self.bot.log("Something fucked up (error code 1320)",str(channel)) # Splitting hand elif content.startswith("split"): @@ -846,10 +843,10 @@ class Blackjack(): try: if roundDone[0] == "T": gameID = self.bot.database["blackjack games"].find_one({"_id":str(channel)})["gameID"] - logThis("Split calling self.blackjackLoop()",str(channel)) + self.bot.log("Split calling self.blackjackLoop()",str(channel)) await self.blackjackLoop(ctx.channel,int(roundDone[1:])+1,gameID) except: - logThis("Something fucked up (error code 1320)") + self.bot.log("Something fucked up (error code 1320)") # Returning current hi-lo value elif content.startswith("hilo"): @@ -863,7 +860,7 @@ class Blackjack(): # Shuffles the blackjack deck elif content.startswith("shuffle"): self.blackjackShuffle(blackjackDecks,str(channel)) - logThis("Shuffling the blackjack deck...",str(channel)) + self.bot.log("Shuffling the blackjack deck...",str(channel)) await ctx.send("Shuffling the deck...") @@ -878,6 +875,6 @@ class Blackjack(): await ctx.send(str(cardsLeft)+" cards, "+str(decksLeft)+" decks", hidden=True) else: - logThis("Not a command (error code 1301)") + self.bot.log("Not a command (error code 1301)") await ctx.send("I didn't quite understand that (error code 1301)") diff --git a/funcs/games/blackjackDraw.py b/funcs/games/blackjackDraw.py index 6e9a4c3..7c5b870 100644 --- a/funcs/games/blackjackDraw.py +++ b/funcs/games/blackjackDraw.py @@ -1,5 +1,4 @@ from PIL import Image, ImageDraw, ImageFont -from funcs import logThis border = 100 placement = [0,0] @@ -10,11 +9,11 @@ class DrawBlackjack(): self.bot = bot def drawImage(self,channel): - logThis("Drawing blackjack table",channel) + self.bot.log("Drawing blackjack table",channel, level = 10) game = self.bot.database["blackjack games"].find_one({"_id":channel}) - fnt = ImageFont.truetype('resources/futura-bold.ttf', 50) - fntSmol = ImageFont.truetype('resources/futura-bold.ttf', 40) + fnt = ImageFont.truetype('resources/fonts/futura-bold.ttf', 50) + fntSmol = ImageFont.truetype('resources/fonts/futura-bold.ttf', 40) borderSmol = int(border/3.5) table = Image.open("resources/games/blackjackTable.png") @@ -31,14 +30,14 @@ class DrawBlackjack(): else: dealerHand = self.drawHand(game["dealer hand"],False,dealerBusted,dealerBlackjack) except: - logThis("Error drawing dealer hand (error code 1341a)") + self.bot.log("Error drawing dealer hand (error code 1341a)") table.paste(dealerHand,(800-borderSmol,20-borderSmol),dealerHand) for x in range(len(hands)): key, value = list(hands.items())[x] - key = self.bot.funcs.getName(key) - #logThis("Drawing "+key+"'s hand") + key = self.bot.databaseFuncs.getName(key) + #self.bot.log("Drawing "+key+"'s hand") userHand = self.drawHand(value["hand"],False,value["busted"],value["blackjack"]) try: if value["split"] == 3: @@ -62,7 +61,7 @@ class DrawBlackjack(): else: table.paste(userHand,(32-borderSmol+(384*placement[x]),680-borderSmol),userHand) except: - logThis("Error drawing player hands (error code 1341b)") + self.bot.log("Error drawing player hands (error code 1341b)") textWidth = fnt.getsize(key)[0] if textWidth < 360: @@ -79,15 +78,15 @@ class DrawBlackjack(): textImage.text((32+(384*placement[x])+117-int(textWidth/2)+2,1020+2),key,fill=(0,0,0), font=fntSmol) textImage.text((32+(384*placement[x])+117-int(textWidth/2),1015),key,fill=(255,255,255), font=fntSmol) - logThis("Saving table image") + self.bot.log("Saving table image", level = 10) table.save("resources/games/blackjackTables/blackjackTable"+channel+".png") return def drawHand(self, hand, dealer, busted, blackjack): - logThis("Drawing hand "+str(hand)+", "+str(busted)+", "+str(blackjack)) - fnt = ImageFont.truetype('resources/futura-bold.ttf', 200) - fnt2 = ImageFont.truetype('resources/futura-bold.ttf', 120) + self.bot.log("Drawing hand "+str(hand)+", "+str(busted)+", "+str(blackjack), level = 10) + fnt = ImageFont.truetype('resources/fonts/futura-bold.ttf', 200) + fnt2 = ImageFont.truetype('resources/fonts/futura-bold.ttf', 120) length = len(hand) background = Image.new("RGBA", ((border*2)+691+(125*(length-1)),(border*2)+1065),(0,0,0,0)) textImage = ImageDraw.Draw(background) @@ -114,7 +113,7 @@ class DrawBlackjack(): w, h = background.size textHeight = 290+border - #logThis("Drawing busted/blackjack") + #self.bot.log("Drawing busted/blackjack") if busted: textWidth = fnt.getsize("BUSTED")[0] textImage.text((int(w/2)-int(textWidth/2)-10,textHeight+20-10),"BUSTED",fill=(0,0,0), font=fnt) @@ -138,5 +137,5 @@ class DrawBlackjack(): textImage.text((int(w/2)-int(textWidth/2)+3,textHeight+3),"BLACKJACK",fill=(255,255,255), font=fnt2) textImage.text((int(w/2)-int(textWidth/2),textHeight),"BLACKJACK",fill=(155,123,0), font=fnt2) - #logThis("Returning resized image") + #self.bot.log("Returning resized image") return background.resize((int(w/3.5),int(h/3.5)),resample=Image.BILINEAR) diff --git a/funcs/games/connectFour.py b/funcs/games/connectFour.py index 9a93333..d5d7cff 100644 --- a/funcs/games/connectFour.py +++ b/funcs/games/connectFour.py @@ -3,7 +3,6 @@ import copy import math from .connectFourDraw import drawConnectFour -from funcs import logThis AIScores = { "middle": 3, @@ -45,7 +44,7 @@ class connectFour(): return "That difficulty doesn't exist", False, False, False, False except: # Opponent is another player - opponent = self.bot.funcs.getID(opponent) + opponent = self.bot.databaseFuncs.getID(opponent) if opponent != None: difficulty = 5 diffText = "" @@ -71,7 +70,7 @@ class connectFour(): if players[0] == "Gwendolyn": gwendoTurn = True - return "Started game against "+self.bot.funcs.getName(opponent)+diffText+". It's "+self.bot.funcs.getName(players[0])+"'s turn", True, False, False, gwendoTurn + return "Started game against "+self.bot.databaseFuncs.getName(opponent)+diffText+". It's "+self.bot.databaseFuncs.getName(players[0])+"'s turn", True, False, False, gwendoTurn else: return "There's already a connect 4 game going on in this channel", False, False, False, False @@ -89,7 +88,7 @@ class connectFour(): turn = (game["turn"]+1)%2 self.bot.database["connect 4 games"].update_one({"_id":channel},{"$set":{"turn":turn}}) - logThis("Checking for win") + self.bot.log("Checking for win", level = 10) won, winDirection, winCoordinates = self.isWon(board) if won != 0: @@ -99,7 +98,7 @@ class connectFour(): self.bot.database["connect 4 games"].update_one({"_id":channel}, {"$set":{"win coordinates":winCoordinates}}) - message = self.bot.funcs.getName(game["players"][won-1])+" placed a piece in column "+str(column+1)+" and won." + message = self.bot.databaseFuncs.getName(game["players"][won-1])+" placed a piece in column "+str(column+1)+" and won." winAmount = int(game["difficulty"])**2+5 if game["players"][won-1] != "Gwendolyn": message += " Adding "+str(winAmount)+" GwendoBucks to their account." @@ -108,12 +107,12 @@ class connectFour(): message = "It's a draw!" else: gameWon = False - message = self.bot.funcs.getName(game["players"][player-1])+" placed a piece in column "+str(column+1)+". It's now "+self.bot.funcs.getName(game["players"][turn])+"'s turn." + message = self.bot.databaseFuncs.getName(game["players"][player-1])+" placed a piece in column "+str(column+1)+". It's now "+self.bot.databaseFuncs.getName(game["players"][turn])+"'s turn." gwendoTurn = False if game["players"][turn] == "Gwendolyn": - logThis("It's Gwendolyn's turn") + self.bot.log("It's Gwendolyn's turn", level = 10) gwendoTurn = True self.draw.drawImage(channel) @@ -166,7 +165,7 @@ class connectFour(): if user == game["players"][turn]: piece = turn + 1 else: - logThis("It wasn't their turn") + self.bot.log("It wasn't their turn", level = 10) return "It's not your turn!", False, False, False, False column = int(commands[1])-1 else: @@ -236,7 +235,7 @@ class connectFour(): # Plays as the AI async def connectFourAI(self, channel): - logThis("Figuring out best move") + self.bot.log("Figuring out best move", level = 10) game = self.bot.database["connect 4 games"].find_one({"_id":channel}) board = game["board"] @@ -249,7 +248,7 @@ class connectFour(): testBoard = self.placeOnBoard(testBoard,player,column) if testBoard != None: scores[column] = await self.minimax(testBoard,difficulty,player%2+1,player,-math.inf,math.inf,False) - logThis("Best score for column "+str(column)+" is "+str(scores[column])) + self.bot.log("Best score for column "+str(column)+" is "+str(scores[column]), level = 10) possibleScores = scores.copy() diff --git a/funcs/games/connectFourDraw.py b/funcs/games/connectFourDraw.py index 9176260..0c52491 100644 --- a/funcs/games/connectFourDraw.py +++ b/funcs/games/connectFourDraw.py @@ -1,15 +1,14 @@ import math from PIL import Image, ImageDraw, ImageFont -from funcs import logThis class drawConnectFour(): - def __init__(self,bot): + def __init__(self, bot): self.bot = bot # Draws the whole thing def drawImage(self, channel): - logThis("Drawing connect four board") + self.bot.log("Drawing connect four board", level = 10) game = self.bot.database["connect 4 games"].find_one({"_id":channel}) board = game["board"] @@ -34,7 +33,7 @@ class drawConnectFour(): white = (255,255,255,160) winBarColor = (250,250,250,255) - fnt = ImageFont.truetype('resources/futura-bold.ttf', exampleCircles) + fnt = ImageFont.truetype('resources/fonts/futura-bold.ttf', exampleCircles) boardSize = [w-(2*(border+gridBorder)),h-(2*(border+gridBorder))] placeGridSize = [math.floor(boardSize[0]/7),math.floor(boardSize[1]/6)] @@ -44,12 +43,12 @@ class drawConnectFour(): if game["players"][0] == "Gwendolyn": player1 = "Gwendolyn" else: - player1 = self.bot.funcs.getName(game["players"][0]) + player1 = self.bot.databaseFuncs.getName(game["players"][0]) if game["players"][1] == "Gwendolyn": player2 = "Gwendolyn" else: - player2 = self.bot.funcs.getName(game["players"][1]) + player2 = self.bot.databaseFuncs.getName(game["players"][1]) background = Image.new("RGB", (w,h+bottomBorder),backgroundColor) diff --git a/funcs/games/gameLoops.py b/funcs/games/gameLoops.py index 0d3d90c..8096726 100644 --- a/funcs/games/gameLoops.py +++ b/funcs/games/gameLoops.py @@ -1,8 +1,6 @@ import asyncio import discord -from funcs import logThis - class GameLoops(): def __init__(self,bot): self.bot = bot @@ -16,7 +14,7 @@ class GameLoops(): for message in messages: oldMessage = await channel.fetch_message(int(message)) - logThis("Deleting old message") + self.bot.log("Deleting old message", level = 10) await oldMessage.delete() except: oldMessage = "" @@ -31,22 +29,22 @@ class GameLoops(): if channelId is None: channelId = str(ctx.channel_id) - response, showImage, deleteImage, gameDone, gwendoTurn = self.bot.connectFour.parseconnectFour(command,channelId, user) + response, showImage, deleteImage, gameDone, gwendoTurn = self.bot.games.connectFour.parseconnectFour(command,channelId, user) if hasattr(ctx, "send"): await ctx.send(response) else: await ctx.channel.send(response) - logThis(response,channelId) + self.bot.log(response, channelId, level = 10) if showImage: if deleteImage: oldImage = await self.deleteMessage("connectFour"+channelId,ctx.channel) oldImage = await ctx.channel.send(file = discord.File("resources/games/connect4Boards/board"+channelId+".png")) if gameDone == False: if gwendoTurn: - response, showImage, deleteImage, gameDone, gwendoTurn = await self.bot.connectFour.connectFourAI(channelId) + response, showImage, deleteImage, gameDone, gwendoTurn = await self.bot.games.connectFour.connectFourAI(channelId) await ctx.channel.send(response) - logThis(response,channelId) + self.bot.log(response,channelId, level = 10) if showImage: if deleteImage: await oldImage.delete() @@ -60,7 +58,7 @@ class GameLoops(): await oldImage.add_reaction(reaction) except: - logThis("Image deleted before I could react to all of them") + self.bot.log("Image deleted before I could react to all of them", level = 10) else: with open("resources/games/oldImages/connectFour"+channelId, "w") as f: @@ -70,7 +68,7 @@ class GameLoops(): for reaction in reactions: await oldImage.add_reaction(reaction) except: - logThis("Image deleted before I could react to all of them") + self.bot.log("Image deleted before I could react to all of them", level = 10) if gameDone: game = self.bot.database["connect 4 games"].find_one({"_id":channelId}) @@ -81,7 +79,7 @@ class GameLoops(): await oldImage.delete() except: - logThis("The old image was already deleted") + self.bot.log("The old image was already deleted") winner = game["winner"] difficulty = int(game["difficulty"]) @@ -90,19 +88,19 @@ class GameLoops(): if game["players"][winner-1].lower() != "gwendolyn": self.bot.money.addMoney(game["players"][winner-1].lower(),reward) - self.bot.funcs.deleteGame("connect 4 games",channelId) + self.bot.databaseFuncs.deleteGame("connect 4 games",channelId) async def runHangman(self,channel,user,command = "start", ctx = None): try: - response, showImage, deleteImage, remainingLetters = self.bot.hangman.parseHangman(str(channel.id),user,command) + response, showImage, deleteImage, remainingLetters = self.bot.games.hangman.parseHangman(str(channel.id),user,command) except: - logThis("Error parsing command (error code 1701)") + self.bot.log("Error parsing command (error code 1701)") if response != "": if ctx is None: await channel.send(response) else: await ctx.send(response) - logThis(response,str(channel.id)) + self.bot.log(response,str(channel.id), level = 10) if showImage: if deleteImage: await self.deleteMessage("hangman"+str(channel.id),channel) @@ -127,34 +125,34 @@ class GameLoops(): emoji = chr(ord(letter)+127397) await message.add_reaction(emoji) except: - logThis("Image deleted before adding all reactions") + self.bot.log("Image deleted before adding all reactions", level = 10) # Runs Hex async def runHex(self,ctx,command,user): channelId = ctx.channel_id try: - response, showImage, deleteImage, gameDone, gwendoTurn = self.bot.hex.parseHex(command,str(channelId),user) + response, showImage, deleteImage, gameDone, gwendoTurn = self.bot.games.hex.parseHex(command,str(channelId),user) except: - logThis("Error parsing command (error code 1510)") + self.bot.log("Error parsing command (error code 1510)") await ctx.send(response) - logThis(response,str(channelId)) + self.bot.log(response,str(channelId), level = 10) if showImage: if deleteImage: try: oldImage = await self.deleteMessage("hex"+str(channelId),ctx.channel) except: - logThis("Error deleting old image (error code 1501)") + self.bot.log("Error deleting old image (error code 1501)") oldImage = await ctx.channel.send(file = discord.File("resources/games/hexBoards/board"+str(channelId)+".png")) if gwendoTurn and not gameDone: try: - response, showImage, deleteImage, gameDone, gwendoTurn = self.bot.hex.hexAI(str(channelId)) + response, showImage, deleteImage, gameDone, gwendoTurn = self.bot.games.hex.hexAI(str(channelId)) except: response, showImage, deleteImage, gameDone, gwendoTurn = "An AI error ocurred",False,False,False,False - logThis("AI error (error code 1520)") + self.bot.log("AI error (error code 1520)") await ctx.channel.send(response) - logThis(response,str(channelId)) + self.bot.log(response,str(channelId), level = 10) if showImage: if deleteImage: await oldImage.delete() @@ -171,4 +169,4 @@ class GameLoops(): winnings = game["difficulty"]*10 self.bot.money.addMoney(game["players"][winner-1].lower(),winnings) - self.bot.funcs.deleteGame("hex games",str(channelId)) + self.bot.databaseFuncs.deleteGame("hex games",str(channelId)) diff --git a/funcs/games/games.py b/funcs/games/games.py index 9000138..1afee45 100644 --- a/funcs/games/games.py +++ b/funcs/games/games.py @@ -10,10 +10,10 @@ class Games(): def __init__(self, bot): self.bot = bot - bot.invest = Invest(bot) - bot.trivia = Trivia(bot) - bot.blackjack = Blackjack(bot) - bot.connectFour = connectFour(bot) - bot.gameLoops = GameLoops(bot) - bot.hangman = Hangman(bot) - bot.hex = HexGame(bot) + self.invest = Invest(bot) + self.trivia = Trivia(bot) + self.blackjack = Blackjack(bot) + self.connectFour = connectFour(bot) + self.gameLoops = GameLoops(bot) + self.hangman = Hangman(bot) + self.hex = HexGame(bot) diff --git a/funcs/games/hangman.py b/funcs/games/hangman.py index a116b3e..2dcac9b 100644 --- a/funcs/games/hangman.py +++ b/funcs/games/hangman.py @@ -1,7 +1,6 @@ import json, urllib, datetime, string from .hangmanDraw import DrawHangman -from funcs import logThis apiUrl = "https://api.wordnik.com/v4/words.json/randomWords?hasDictionaryDef=true&minCorpusCount=5000&maxCorpusCount=-1&minDictionaryCount=1&maxDictionaryCount=-1&minLength=3&maxLength=11&limit=1&api_key=" @@ -19,7 +18,7 @@ class Hangman(): while "-" in word or "." in word: with urllib.request.urlopen(apiUrl+apiKey) as p: word = list(json.load(p)[0]["word"].upper()) - logThis("Found the word \""+"".join(word)+"\"") + self.bot.log("Found the word \""+"".join(word)+"\"", level = 10) guessed = [False] * len(word) gameID = datetime.datetime.now().strftime('%Y%m%d%H%M%S') newGame = {"_id":channel,"player" : user,"guessed letters" : [],"word" : word,"game ID" : gameID,"misses" : 0,"guessed" : guessed} @@ -30,8 +29,8 @@ class Hangman(): try: self.draw.drawImage(channel) except: - logThis("Error drawing image (error code 1710)") - return f"{self.bot.funcs.getName(user)} started game of hangman.", True, False, remainingLetters + self.bot.log("Error drawing image (error code 1710)") + return f"{self.bot.databaseFuncs.getName(user)} started game of hangman.", True, False, remainingLetters else: return "There's already a Hangman game going on in the channel", False, False, [] @@ -74,7 +73,7 @@ class Hangman(): try: self.draw.drawImage(channel) except: - logThis("Error drawing image (error code 1710)") + self.bot.log("Error drawing image (error code 1710)") if game["misses"] == 6: self.hangmanStop(channel) @@ -99,7 +98,7 @@ class Hangman(): try: return self.hangmanStart(channel,user) except: - logThis("Error starting game (error code 1730)") + self.bot.log("Error starting game (error code 1730)") elif command == "stop": return self.hangmanStop(channel) elif command.startswith("guess "): @@ -107,6 +106,6 @@ class Hangman(): try: return self.hangmanGuess(channel,user,guess) except: - logThis("Error in guessing (Error Code 1720)") + self.bot.log("Error in guessing (Error Code 1720)") else: return "I didn't understand that", False, False, [] diff --git a/funcs/games/hangmanDraw.py b/funcs/games/hangmanDraw.py index 4019e85..23b7a9c 100644 --- a/funcs/games/hangmanDraw.py +++ b/funcs/games/hangmanDraw.py @@ -1,7 +1,6 @@ import math, random from PIL import ImageDraw, Image, ImageFont -from funcs import logThis circleDegrees = 360 circleSize = 120 @@ -23,8 +22,8 @@ letterLineDistance = 30 gallowx, gallowy = 360,600 goldenRatio = 1-(1 / ((1 + 5 ** 0.5) / 2)) -fnt = ImageFont.truetype('resources/comic-sans-bold.ttf', letterSize) -smolfnt = ImageFont.truetype('resources/comic-sans-bold.ttf', textSize) +fnt = ImageFont.truetype('resources/fonts/comic-sans-bold.ttf', letterSize) +smolfnt = ImageFont.truetype('resources/fonts/comic-sans-bold.ttf', textSize) backgroundColor = (255,255,255,255) @@ -213,7 +212,7 @@ class DrawHangman(): return background def drawImage(self,channel): - logThis("Drawing hangman image",channel) + self.bot.log("Drawing hangman image", channel, level = 10) game = self.bot.database["hangman games"].find_one({"_id":channel}) random.seed(game["game ID"]) @@ -222,24 +221,24 @@ class DrawHangman(): try: gallow = self.drawGallows() except: - logThis("Error drawing gallows (error code 1711)") + self.bot.log("Error drawing gallows (error code 1711)") try: man = self.drawMan(game["misses"]) except: - logThis("Error drawing stick figure (error code 1712)") + self.bot.log("Error drawing stick figure (error code 1712)") random.seed(game["game ID"]) try: letterLines = self.drawLetterLines(game["word"],game["guessed"],game["misses"]) except: - logThis("error drawing letter lines (error code 1713)") + self.bot.log("error drawing letter lines (error code 1713)") random.seed(game["game ID"]) try: misses = self.drawMisses(game["guessed letters"],game["word"]) except: - logThis("Error drawing misses (error code 1714)") + self.bot.log("Error drawing misses (error code 1714)") background.paste(gallow,(100,100),gallow) background.paste(man,(300,210),man) diff --git a/funcs/games/hex.py b/funcs/games/hex.py index 6924aa3..d173390 100644 --- a/funcs/games/hex.py +++ b/funcs/games/hex.py @@ -3,7 +3,6 @@ import copy import math from .hexDraw import DrawHex -from funcs import logThis BOARDWIDTH = 11 ALL_POSITIONS = [(i,j) for i in range(11) for j in range(11)] @@ -29,7 +28,7 @@ class HexGame(): # Starting a game if len(commands) == 1: # if the commands is "!hex start", the opponent is Gwendolyn at difficulty 2 commands.append("2") - logThis("Starting a hex game with hexStart(). "+str(user)+" challenged "+commands[1]) + self.bot.log("Starting a hex game with hexStart(). "+str(user)+" challenged "+commands[1], level = 10) return self.hexStart(channel,user,commands[1]) # commands[1] is the opponent # If using a command with no game, return error @@ -60,7 +59,7 @@ class HexGame(): if user in players: opponent = (players.index(user) + 1) % 2 self.bot.database["hex games"].update_one({"_id":channel},{"$set":{"winner":opponent + 1}}) - return "{} surrendered. That means {} won! Adding 30 Gwendobucks to their account.".format(self.bot.funcs.getName(user),self.bot.funcs.getName(players[opponent])), False, False, True, False + return "{} surrendered. That means {} won! Adding 30 Gwendobucks to their account.".format(self.bot.databaseFuncs.getName(user),self.bot.databaseFuncs.getName(players[opponent])), False, False, True, False else: return "You can't surrender when you're not a player.", False, False, False, False @@ -99,7 +98,7 @@ class HexGame(): int(opponent) return "That difficulty doesn't exist", False, False, False, False except: - opponent = self.bot.funcs.getID(opponent) + opponent = self.bot.databaseFuncs.getID(opponent) if opponent == None: return "I can't find that user", False, False, False, False else: @@ -123,7 +122,7 @@ class HexGame(): gwendoTurn = True if players[0] == "Gwendolyn" else False showImage = True - return "Started Hex game against "+self.bot.funcs.getName(opponent)+ diffText+". It's "+self.bot.funcs.getName(players[0])+"'s turn", showImage, False, False, gwendoTurn + return "Started Hex game against "+self.bot.databaseFuncs.getName(opponent)+ diffText+". It's "+self.bot.databaseFuncs.getName(players[0])+"'s turn", showImage, False, False, gwendoTurn else: return "There's already a hex game going on in this channel", False, False, False, False @@ -143,7 +142,7 @@ class HexGame(): if player == turn: board = game["board"] - logThis("Placing a piece on the board with placeHex()") + self.bot.log("Placing a piece on the board with placeHex()", level = 10) # Places on board board = self.placeOnHexBoard(board,player,position) @@ -154,17 +153,17 @@ class HexGame(): self.bot.database["hex games"].update_one({"_id":channel},{"$set":{"turn":turn}}) # Checking for a win - logThis("Checking for win") + self.bot.log("Checking for win", level = 10) winner = self.evaluateBoard(game["board"])[1] if winner == 0: # Continue with the game. gameWon = False - message = self.bot.funcs.getName(game["players"][player-1])+" placed at "+position.upper()+". It's now "+self.bot.funcs.getName(game["players"][turn-1])+"'s turn."# The score is "+str(score) + message = self.bot.databaseFuncs.getName(game["players"][player-1])+" placed at "+position.upper()+". It's now "+self.bot.databaseFuncs.getName(game["players"][turn-1])+"'s turn."# The score is "+str(score) else: # Congratulations! gameWon = True self.bot.database["hex games"].update_one({"_id":channel},{"$set":{"winner":winner}}) - message = self.bot.funcs.getName(game["players"][player-1])+" placed at "+position.upper()+" and won!" + message = self.bot.databaseFuncs.getName(game["players"][player-1])+" placed at "+position.upper()+" and won!" if game["players"][winner-1] != "Gwendolyn": winAmount = game["difficulty"]*10 message += " Adding "+str(winAmount)+" GwendoBucks to their account." @@ -175,7 +174,7 @@ class HexGame(): # Is it now Gwendolyn's turn? gwendoTurn = False if game["players"][turn-1] == "Gwendolyn": - logThis("It's Gwendolyn's turn") + self.bot.log("It's Gwendolyn's turn", level = 10) gwendoTurn = True # Update the board @@ -188,10 +187,10 @@ class HexGame(): return message, False, False, False, False else: # Move out of turn - message = "It isn't your turn, it is "+self.bot.funcs.getName(game["players"][turn-1])+"'s turn." + message = "It isn't your turn, it is "+self.bot.databaseFuncs.getName(game["players"][turn-1])+"'s turn." return message, False, False, False, False else: - message = "You can't place when you're not in the game. The game's players are: "+self.bot.funcs.getName(game["players"][0])+" and "+self.bot.funcs.getName(game["players"][1])+"." + message = "You can't place when you're not in the game. The game's players are: "+self.bot.databaseFuncs.getName(game["players"][0])+" and "+self.bot.databaseFuncs.getName(game["players"][1])+"." return message, False, False, False, False else: return "There's no game in this channel", False, False, False, False @@ -205,17 +204,17 @@ class HexGame(): column = ord(position[0]) - 97 # ord() translates from letter to number row = int(position[1:]) - 1 if column not in range(BOARDWIDTH) or row not in range(BOARDWIDTH): - logThis("Position out of bounds (error code 1533)") + self.bot.log("Position out of bounds (error code 1533)") return "Error. That position is out of bounds." except: - logThis("Invalid position (error code 1531)") + self.bot.log("Invalid position (error code 1531)") return "Error. The position should be a letter followed by a number, e.g. \"e2\"." # Place at the position if board[row][column] == 0: board[row][column] = player return board else: - logThis("Cannot place on existing piece (error code 1532)") + self.bot.log("Cannot place on existing piece (error code 1532)") return "Error. You must place on an empty space." # After your move, you have the option to undo get your turn back #TimeTravel @@ -227,7 +226,7 @@ class HexGame(): turn = game["turn"] # You can only undo after your turn, which is the opponent's turn. if user == game["players"][(turn % 2)]: # If it's not your turn - logThis("Undoing {}'s last move".format(self.bot.funcs.getName(user))) + self.bot.log("Undoing {}'s last move".format(self.bot.databaseFuncs.getName(user)), level = 10) lastMove = game["gameHistory"].pop() game["board"][lastMove[0]][lastMove[1]] = 0 @@ -252,7 +251,7 @@ class HexGame(): # Plays as the AI def hexAI(self, channel): - logThis("Figuring out best move") + self.bot.log("Figuring out best move", level = 10) game = self.bot.database["hex games"].find_one({"_id":channel}) board = game["board"] @@ -286,7 +285,7 @@ class HexGame(): if evaluateBoard(testBoard)[0] != current_score: # only think about a move if it improves the score (it's impossible to get worse) # Testing a move and evaluating it judgements[i] = minimaxHex(testBoard,difficulty,-math.inf,math.inf,GwenColor==2) - logThis("Best score for place {} is {}".format((i // BOARDWIDTH,i % BOARDWIDTH),judgements[i])) + self.bot.log("Best score for place {} is {}".format((i // BOARDWIDTH,i % BOARDWIDTH),judgements[i])) bestScore = max(judgements) if (GwenColor == 1) else min(judgements) # this line has an error indices = [i for i, x in enumerate(judgements) if x == bestScore] # which moves got that score? @@ -294,7 +293,7 @@ class HexGame(): chosenMove = (i // BOARDWIDTH , i % BOARDWIDTH) """ placement = "abcdefghijk"[chosenMove[1]]+str(chosenMove[0]+1) - logThis("ChosenMove is {} at {}".format(chosenMove,placement)) + self.bot.log("ChosenMove is {} at {}".format(chosenMove,placement), level = 10) return self.placeHex(channel,placement, "Gwendolyn") @@ -323,12 +322,12 @@ class HexGame(): Distance[v] = min(Distance[v], new_dist) # After a hex has been visited, this is noted visited.add(u) - #logThis("Distance from player {}'s start to {} is {}".format(player,u,Distance[u])) + #self.bot.log("Distance from player {}'s start to {} is {}".format(player,u,Distance[u])) if u[player-1] == 10: # if the right coordinate of v is 10, it means we're at the goal scores[player] = Distance[u] # A player's score is the shortest distance to goal. Which equals the number of remaining moves they need to win if unblocked by the opponent. break else: - logThis("For some reason, no path to the goal was found. ") + self.bot.log("For some reason, no path to the goal was found. ", level = 10) if scores[player] == 0: winner = player break # We don't need to check the other player's score, if player1 won. @@ -344,7 +343,7 @@ class HexGame(): if maximizingPlayer: # red player predicts next move maxEval = -math.inf possiblePlaces = [i for i,v in enumerate(sum(board,[])) if v == 0] - #logThis("Judging a red move at depth {}".format(depth)) + #self.bot.log("Judging a red move at depth {}".format(depth)) for i in possiblePlaces: testBoard = copy.deepcopy(board) testBoard[i // BOARDWIDTH][i % BOARDWIDTH] = 1 # because maximizingPlayer is Red which is number 1 @@ -352,13 +351,13 @@ class HexGame(): maxEval = max(maxEval, evaluation) alpha = max(alpha, evaluation) if beta <= alpha: - #logThis("Just pruned something!") + #self.bot.log("Just pruned something!") break return maxEval else: # blue player predicts next move minEval = math.inf possiblePlaces = [i for i,v in enumerate(sum(board,[])) if v == 0] - #logThis("Judging a blue move at depth {}".format(depth)) + #self.bot.log("Judging a blue move at depth {}".format(depth)) for i in possiblePlaces: testBoard = copy.deepcopy(board) testBoard[i // BOARDWIDTH][i % BOARDWIDTH] = 2 # because minimizingPlayer is Blue which is number 2 @@ -366,7 +365,7 @@ class HexGame(): minEval = min(minEval, evaluation) beta = min(beta, evaluation) if beta <= alpha: - #logThis("Just pruned something!") + #self.bot.log("Just pruned something!") break return minEval diff --git a/funcs/games/hexDraw.py b/funcs/games/hexDraw.py index 0966102..44a064c 100644 --- a/funcs/games/hexDraw.py +++ b/funcs/games/hexDraw.py @@ -1,7 +1,6 @@ import math from PIL import Image, ImageDraw, ImageFont -from funcs import logThis # Defining all the variables CANVAS_WIDTH = 2400 @@ -13,7 +12,7 @@ HEXAGONWIDTH = math.sqrt(3) * SIDELENGTH # the whole width of one hexagon HEXAGONHEIGHT = 1.5 * SIDELENGTH # not really the entire height, but the height difference between two layers FONTSIZE = 45 TEXTCOLOR = (0,0,0) -fnt = ImageFont.truetype('resources/futura-bold.ttf', FONTSIZE) +fnt = ImageFont.truetype('resources/fonts/futura-bold.ttf', FONTSIZE) LINETHICKNESS = 15 HEXTHICKNESS = 6 # This is half the width of the background lining between every hex @@ -29,7 +28,7 @@ COLX_THICKNESS = COLHEXTHICKNESS * math.cos(math.pi/6) COLY_THICKNESS = COLHEXTHICKNESS * math.sin(math.pi/6) # The Name display things: NAMESIZE = 60 -NAME_fnt = ImageFont.truetype('resources/futura-bold.ttf', NAMESIZE) +NAME_fnt = ImageFont.truetype('resources/fonts/futura-bold.ttf', NAMESIZE) X_NAME = {1:175, 2:CANVAS_WIDTH-100} Y_NAME = {1:CANVAS_HEIGHT-150, 2:150} NAMEHEXPADDING = 90 @@ -41,7 +40,7 @@ class DrawHex(): self.bot = bot def drawBoard(self, channel): - logThis("Drawing empty Hex board") + self.bot.log("Drawing empty Hex board") # Creates the empty image im = Image.new('RGB', size=(CANVAS_WIDTH, CANVAS_HEIGHT),color = BACKGROUND_COLOR) @@ -99,7 +98,7 @@ class DrawHex(): game = self.bot.database["hex games"].find_one({"_id":channel}) for p in [1,2]: - playername = self.bot.funcs.getName(game["players"][p-1]) + playername = self.bot.databaseFuncs.getName(game["players"][p-1]) # Draw name x = X_NAME[p] x -= NAME_fnt.getsize(playername)[0] if p==2 else 0 # player2's name is right-aligned @@ -123,7 +122,7 @@ class DrawHex(): def drawHexPlacement(self, channel,player,position): FILEPATH = "resources/games/hexBoards/board"+channel+".png" - logThis("Drawing a newly placed hex. Filepath: "+FILEPATH) + self.bot.log("Drawing a newly placed hex. Filepath: "+FILEPATH) # Translates position # We don't need to error-check, because the position is already checked in placeOnHexBoard() @@ -151,7 +150,7 @@ class DrawHex(): # Save im.save(FILEPATH) except: - logThis("Error drawing new hex on board (error code 1541") + self.bot.log("Error drawing new hex on board (error code 1541") def drawSwap(self, channel): FILEPATH = "resources/games/hexBoards/board"+channel+".png" @@ -163,7 +162,7 @@ class DrawHex(): # Write player names and color for p in [1,2]: - playername = self.bot.funcs.getName(game["players"][p%2]) + playername = self.bot.databaseFuncs.getName(game["players"][p%2]) x = X_NAME[p] x -= NAME_fnt.getsize(playername)[0] if p==2 else 0 # player2's name is right-aligned @@ -183,4 +182,4 @@ class DrawHex(): # Save im.save(FILEPATH) except: - logThis("Error drawing swap (error code 1542)") + self.bot.log("Error drawing swap (error code 1542)") diff --git a/funcs/games/invest.py b/funcs/games/invest.py index f955032..65c1cc0 100644 --- a/funcs/games/invest.py +++ b/funcs/games/invest.py @@ -1,5 +1,5 @@ class Invest(): - def __init__(self,bot): + def __init__(self, bot): self.bot = bot def getPrice(self, symbol : str): @@ -13,9 +13,9 @@ class Invest(): userInvestments = self.bot.database["investments"].find_one({"_id":user}) if userInvestments in [None,{}]: - return f"{self.bot.funcs.getName(user)} does not have a stock portfolio." + return f"{self.bot.databaseFuncs.getName(user)} does not have a stock portfolio." else: - portfolio = f"**Stock portfolio for {self.bot.funcs.getName(user)}**" + portfolio = f"**Stock portfolio for {self.bot.databaseFuncs.getName(user)}**" for key, value in list(userInvestments["investments"].items()): purchaseValue = value["purchased for"] @@ -60,7 +60,7 @@ class Invest(): newUser = {"_id":user,"investments":{stock : {"purchased" : buyAmount, "value at purchase" : stockPrice, "purchased for" : buyAmount}}} self.bot.database["investments"].insert_one(newUser) - return f"{self.bot.funcs.getName(user)} bought {buyAmount} GwendoBucks worth of {stock} stock" + return f"{self.bot.databaseFuncs.getName(user)} bought {buyAmount} GwendoBucks worth of {stock} stock" else: return f"{stock} is not traded on the american market." else: @@ -95,7 +95,7 @@ class Invest(): self.bot.database["investments"].update_one({"_id":user}, {"$unset":{"investments."+stock:""}}) - return f"{self.bot.funcs.getName(user)} sold {sellAmount} GwendoBucks worth of {stock} stock" + return f"{self.bot.databaseFuncs.getName(user)} sold {sellAmount} GwendoBucks worth of {stock} stock" else: return f"You don't have enough {stock} stocks to do that" else: diff --git a/funcs/games/money.py b/funcs/games/money.py index ca5b030..20aadd2 100644 --- a/funcs/games/money.py +++ b/funcs/games/money.py @@ -1,5 +1,3 @@ -from funcs import logThis - class Money(): def __init__(self, bot): @@ -8,7 +6,7 @@ class Money(): # Returns the account balance for a user def checkBalance(self, user): - logThis("checking "+user+"'s account balance") + self.bot.log("checking "+user+"'s account balance", level = 10) userData = self.database["users"].find_one({"_id":user}) @@ -18,19 +16,19 @@ class Money(): # Adds money to the account of a user def addMoney(self,user,amount): - logThis("adding "+str(amount)+" to "+user+"'s account") + self.bot.log("adding "+str(amount)+" to "+user+"'s account", level = 10) userData = self.database["users"].find_one({"_id":user}) if userData != None: self.database["users"].update_one({"_id":user},{"$inc":{"money":amount}}) else: - self.database["users"].insert_one({"_id":user,"user name":self.bot.funcs.getName(user),"money":amount}) + self.database["users"].insert_one({"_id":user,"user name":self.bot.databaseFuncs.getName(user),"money":amount}) # Transfers money from one user to another def giveMoney(self,user,targetUser,amount): userData = self.database["users"].find_one({"_id":user}) - targetUser = self.bot.funcs.getID(targetUser) + targetUser = self.bot.databaseFuncs.getID(targetUser) if amount > 0: if targetUser != None: @@ -38,16 +36,16 @@ class Money(): if userData["money"] >= amount: self.addMoney(user,-1 * amount) self.addMoney(targetUser,amount) - return "Transferred "+str(amount)+" GwendoBucks to "+self.bot.funcs.getName(targetUser) + return "Transferred "+str(amount)+" GwendoBucks to "+self.bot.databaseFuncs.getName(targetUser) else: - logThis("They didn't have enough GwendoBucks (error code 1223b)") + self.bot.log("They didn't have enough GwendoBucks (error code 1223b)") return "You don't have that many GwendoBucks (error code 1223b)" else: - logThis("They didn't have enough GwendoBucks (error code 1223a)") + self.bot.log("They didn't have enough GwendoBucks (error code 1223a)") return "You don't have that many GwendoBucks (error code 1223a)" else: - logThis("They weren't in the system") + self.bot.log("They weren't in the system") return "The target doesn't exist" else: - logThis("They tried to steal") + self.bot.log("They tried to steal") return "Yeah, no. You can't do that" diff --git a/funcs/games/trivia.py b/funcs/games/trivia.py index 8638ad6..3b75cdf 100644 --- a/funcs/games/trivia.py +++ b/funcs/games/trivia.py @@ -2,8 +2,6 @@ import json import urllib import random -from funcs import logThis - class Trivia(): def __init__(self, bot): self.bot = bot @@ -13,13 +11,13 @@ class Trivia(): def triviaStart(self, channel : str): question = self.bot.database["trivia questions"].find_one({"_id":channel}) - logThis("Trying to find a trivia question for "+channel) + self.bot.log("Trying to find a trivia question for "+channel) if question == None: with urllib.request.urlopen("https://opentdb.com/api.php?amount=10&type=multiple") as response: data = json.loads(response.read()) - logThis("Found the question \""+data["results"][0]["question"]+"\"") + self.bot.log("Found the question \""+data["results"][0]["question"]+"\"") answers = data["results"][0]["incorrect_answers"] answers.append(data["results"][0]["correct_answer"]) random.shuffle(answers) @@ -43,7 +41,7 @@ class Trivia(): return question, answers, correctAnswer else: - logThis("There was already a trivia question for that channel (error code 1106)") + self.bot.log("There was already a trivia question for that channel (error code 1106)") return "There's already a trivia question going on. Try again in like, a minute (error code 1106)", "", "" # Lets players answer a trivia question @@ -53,19 +51,19 @@ class Trivia(): if command in ["a","b","c","d"]: if question != None: if user not in question["players"]: - logThis(user+" answered the question in "+channel) + self.bot.log(user+" answered the question in "+channel) self.bot.database["trivia questions"].update_one({"_id":channel},{"$set":{"players."+user : command}}) return "Locked in "+user+"'s answer" else: - logThis(user+" has already answered this question (error code 1105)") + self.bot.log(user+" has already answered this question (error code 1105)") return user+" has already answered this question (error code 1105)" else: - logThis("There's no question right now (error code 1104)") + self.bot.log("There's no question right now (error code 1104)") return "There's no question right now (error code 1104)" else: - logThis("I didn't quite understand that (error code 1103)") + self.bot.log("I didn't quite understand that (error code 1103)") return "I didn't quite understand that (error code 1103)" @@ -73,7 +71,7 @@ class Trivia(): def triviaCountPoints(self, channel : str): question = self.bot.database["trivia questions"].find_one({"_id":channel}) - logThis("Counting points for question in "+channel) + self.bot.log("Counting points for question in "+channel) if question != None: for player, answer in question["players"].items(): @@ -82,6 +80,6 @@ class Trivia(): else: - logThis("Couldn't find the question (error code 1102)") + self.bot.log("Couldn't find the question (error code 1102)") return None diff --git a/funcs/lookup/__init__.py b/funcs/lookup/__init__.py index 7b46bbf..2216bf2 100644 --- a/funcs/lookup/__init__.py +++ b/funcs/lookup/__init__.py @@ -1,5 +1,5 @@ """Gwendolyn functions for looking things up.""" -__all__ = ["spellFunc", "monsterFunc"] +__all__ = ["LookupFuncs"] -from .lookupFuncs import spellFunc, monsterFunc \ No newline at end of file +from .lookupFuncs import LookupFuncs \ No newline at end of file diff --git a/funcs/lookup/lookupFuncs.py b/funcs/lookup/lookupFuncs.py index 27f99ac..a9091a2 100644 --- a/funcs/lookup/lookupFuncs.py +++ b/funcs/lookup/lookupFuncs.py @@ -1,136 +1,139 @@ import math -#import discord import json -from funcs import cap, logThis +from utils import cap -# Calculates D&D stat modifier -def modifier(statistic): - mods = math.floor((statistic-10)/2) - if mods >= 0: - mods = "+"+str(mods) - return(str(mods)) -saves = ["strength_save","dexterity_save","constitution_save","intelligence_save","wisdom_save","charisma_save"] -abilities = ["acrobatics","animal_handling","arcana","athletics","deception","history","insight","intimidation","investigation","medicine","nature","perception","performance","persuasion","religion","sleight_of_hand","stealth","survival"] +class LookupFuncs(): + def __init__(self, bot): + self.bot = bot + self.saves = ["strength_save","dexterity_save","constitution_save","intelligence_save","wisdom_save","charisma_save"] + self.abilities = ["acrobatics","animal_handling","arcana","athletics","deception","history","insight","intimidation","investigation","medicine","nature","perception","performance","persuasion","religion","sleight_of_hand","stealth","survival"] -# Looks up a monster -def monsterFunc(command): - logThis("Looking up "+command) + # Calculates D&D stat modifier + def modifier(self, statistic): + mods = math.floor((statistic-10)/2) + if mods >= 0: + mods = "+"+str(mods) + return(str(mods)) - # 1-letter monsters don't exist - if len(command) < 2: - logThis("Monster name too short (error code 601)") - return("I don't know that monster... (error code 601)","","","","","") - else: - # Opens "mensters.json" - data = json.load(open('resources/lookup/monsters.json', encoding = "utf8")) - for monster in data: - if "name" in monster and str(command) == monster["name"]: - logThis("Found it!") + # Looks up a monster + def monsterFunc(self, command): + self.bot.log("Looking up "+command) - # Looks at the information about the monster and returns that information - # in seperate variables, allowing Gwendolyn to know where to seperate - # the messages - if monster["subtype"] != "": - typs = (monster["type"]+" ("+monster["subtype"]+")") - else: - typs = monster["type"] - con_mod = math.floor((monster["constitution"]-10)/2) - hit_dice = monster["hit_dice"] + # 1-letter monsters don't exist + if len(command) < 2: + self.bot.log("Monster name too short (error code 601)") + return("I don't know that monster... (error code 601)","","","","","") + else: + # Opens "monsters.json" + data = json.load(open('resources/lookup/monsters.json', encoding = "utf8")) + for monster in data: + if "name" in monster and str(command) == monster["name"]: + self.bot.log("Found it!") - stats = ("**Str:** "+str(monster["strength"])+" ("+modifier(monster["strength"])+")\t**Dex:** "+str(monster["dexterity"])+" ("+modifier(monster["dexterity"])+")\t**Con:** "+str(monster["constitution"])+" ("+modifier(monster["constitution"])+")\n**Int: **"+str(monster["intelligence"])+" ("+modifier(monster["intelligence"])+")\t**Wis: **"+str(monster["wisdom"])+" ("+modifier(monster["wisdom"])+")\t**Cha: **"+str(monster["charisma"])+" ("+modifier(monster["charisma"])+")") + # Looks at the information about the monster and returns that information + # in separate variables, allowing Gwendolyn to know where to separate + # the messages + if monster["subtype"] != "": + typs = (monster["type"]+" ("+monster["subtype"]+")") + else: + typs = monster["type"] + con_mod = math.floor((monster["constitution"]-10)/2) + hit_dice = monster["hit_dice"] - saving_throws = "" - for save in saves: - if save in monster: - if monster[save] >= 0: - saving_throws += " "+cap(save[:3])+" +"+str(monster[save])+"," - else: - saving_throws += " "+cap(save[:3])+" "+str(monster[save])+"," - if saving_throws != "": - saving_throws = "\n**Saving Throws**"+saving_throws[:-1] + stats = ("**Str:** "+str(monster["strength"])+" ("+self.modifier(monster["strength"])+")\t**Dex:** "+str(monster["dexterity"])+" ("+self.modifier(monster["dexterity"])+")\t**Con:** "+str(monster["constitution"])+" ("+self.modifier(monster["constitution"])+")\n**Int: **"+str(monster["intelligence"])+" ("+self.modifier(monster["intelligence"])+")\t**Wis: **"+str(monster["wisdom"])+" ("+self.modifier(monster["wisdom"])+")\t**Cha: **"+str(monster["charisma"])+" ("+self.modifier(monster["charisma"])+")") - skills = "" - for skill in abilities: - if skill in monster: - if monster[skill] >= 0: - skills += " "+cap(skill.replace("_"," "))+" +"+str(monster[skill])+"," - else: - skills += " "+cap(skill.replace("_"," "))+" "+str(monster[skill])+"," - if skills != "": - skills = "\n**Skills**"+skills[:-1] + saving_throws = "" + for save in self.saves: + if save in monster: + if monster[save] >= 0: + saving_throws += " "+cap(save[:3])+" +"+str(monster[save])+"," + else: + saving_throws += " "+cap(save[:3])+" "+str(monster[save])+"," + if saving_throws != "": + saving_throws = "\n**Saving Throws**"+saving_throws[:-1] - vulnerabilities = monster["damage_vulnerabilities"] - if vulnerabilities != "": - vulnerabilities = "\n**Damage Vulnerabilities** "+vulnerabilities + skills = "" + for skill in self.abilities: + if skill in monster: + if monster[skill] >= 0: + skills += " "+cap(skill.replace("_"," "))+" +"+str(monster[skill])+"," + else: + skills += " "+cap(skill.replace("_"," "))+" "+str(monster[skill])+"," + if skills != "": + skills = "\n**Skills**"+skills[:-1] - resistances = monster["damage_resistances"] - if resistances != "": - resistances = "\n**Damage Resistances** "+resistances + vulnerabilities = monster["damage_vulnerabilities"] + if vulnerabilities != "": + vulnerabilities = "\n**Damage Vulnerabilities** "+vulnerabilities - immunities = monster["damage_immunities"] - if immunities != "": - immunities = "\n**Damage Immunities** "+immunities + resistances = monster["damage_resistances"] + if resistances != "": + resistances = "\n**Damage Resistances** "+resistances - c_immunities = monster["condition_immunities"] - if c_immunities != "": - c_immunities = "\n**Condition Immunities** "+c_immunities + immunities = monster["damage_immunities"] + if immunities != "": + immunities = "\n**Damage Immunities** "+immunities - spec_ab = "" - if "special_abilities" in monster: - for ability in monster["special_abilities"]: - spec_ab += "\n\n***"+ability["name"]+".*** "+ability["desc"] + c_immunities = monster["condition_immunities"] + if c_immunities != "": + c_immunities = "\n**Condition Immunities** "+c_immunities - act = "" - if "actions" in monster: - for action in monster["actions"]: - act += "\n\n***"+action["name"]+".*** "+action["desc"] + spec_ab = "" + if "special_abilities" in monster: + for ability in monster["special_abilities"]: + spec_ab += "\n\n***"+ability["name"]+".*** "+ability["desc"] - react = "" - if "reactions" in monster: - for reaction in monster["reactions"]: - react += "\n\n***"+reaction["name"]+".*** "+reaction["desc"] + act = "" + if "actions" in monster: + for action in monster["actions"]: + act += "\n\n***"+action["name"]+".*** "+action["desc"] - leg_act = "" - if "legendary_actions" in monster: - for action in monster["legendary_actions"]: - leg_act += "\n\n***"+action["name"]+".*** "+action["desc"] + react = "" + if "reactions" in monster: + for reaction in monster["reactions"]: + react += "\n\n***"+reaction["name"]+".*** "+reaction["desc"] - if con_mod < 0: - hit_dice += (" - "+str(con_mod * int(monster["hit_dice"].replace("d"," ").split()[0])*(-1))) - if con_mod > 0: - hit_dice += (" + "+str(con_mod * int(monster["hit_dice"].replace("d"," ").split()[0]))) + leg_act = "" + if "legendary_actions" in monster: + for action in monster["legendary_actions"]: + leg_act += "\n\n***"+action["name"]+".*** "+action["desc"] - new_part = "\n--------------------" + if con_mod < 0: + hit_dice += (" - "+str(con_mod * int(monster["hit_dice"].replace("d"," ").split()[0])*(-1))) + if con_mod > 0: + hit_dice += (" + "+str(con_mod * int(monster["hit_dice"].replace("d"," ").split()[0]))) - monster_type = monster["size"]+" "+typs+", "+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 = monster["size"]+" "+typs+", "+monster["alignment"]+"*" - text1 = (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" - text2 = (spec_ab) - text3 = (act) - text4 = (react) - text5 = (leg_act) + text1 = (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"]) - logThis("Returning monster information") - return(str(command),text1,text2,text3,text4,text5) - logThis("Monster not in database (error code 602)") - return("I don't know that monster... (error code 602)","","","","","") + text2 = (spec_ab) + text3 = (act) + text4 = (react) + text5 = (leg_act) -# Looks up a spell -def spellFunc(command): - logThis("Looking up "+command) + self.bot.log("Returning monster information") + return(str(command),text1,text2,text3,text4,text5) + self.bot.log("Monster not in database (error code 602)") + return("I don't know that monster... (error code 602)","","","","","") - # Opens "spells.json" - data = json.load(open('resources/lookup/spells.json', encoding = "utf8")) - if str(command) in data: - logThis("Returning spell information") - spell_output = ("***"+str(command)+"***\n*"+str(data[str(command)]["level"])+" level "+str(data[str(command)]["school"])+"\nCasting Time: "+str(data[str(command)]["casting_time"])+"\nRange: "+str(data[str(command)]["range"])+"\nComponents: "+str(data[str(command)]["components"])+"\nDuration: "+str(data[str(command)]["duration"])+"*\n \n"+str(data[str(command)]["description"])) - else: - logThis("I don't know that spell (error code 501)") - spell_output = "I don't think that's a spell (error code 501)" - logThis("Successfully ran !spell") - return(spell_output) + # Looks up a spell + def spellFunc(self, command): + self.bot.log("Looking up "+command) + + # Opens "spells.json" + data = json.load(open('resources/lookup/spells.json', encoding = "utf8")) + if str(command) in data: + self.bot.log("Returning spell information") + spell_output = ("***"+str(command)+"***\n*"+str(data[str(command)]["level"])+" level "+str(data[str(command)]["school"])+"\nCasting Time: "+str(data[str(command)]["casting_time"])+"\nRange: "+str(data[str(command)]["range"])+"\nComponents: "+str(data[str(command)]["components"])+"\nDuration: "+str(data[str(command)]["duration"])+"*\n \n"+str(data[str(command)]["description"])) + else: + self.bot.log("I don't know that spell (error code 501)") + spell_output = "I don't think that's a spell (error code 501)" + self.bot.log("Successfully ran !spell") + return(spell_output) diff --git a/funcs/miscFuncs.py b/funcs/miscFuncs.py deleted file mode 100644 index d7d7fae..0000000 --- a/funcs/miscFuncs.py +++ /dev/null @@ -1,222 +0,0 @@ -from typing import Union -import lxml.etree # Used by imageFunc -import datetime # Used by helloFunc -import json # Used by spellFunc -import random # Used by imageFunc -import urllib # Used by imageFunc -import time # Used for logging -import logging # Used for... you know... logging -import wikia # Used by findWikiPage -import os # Used by makeFiles - -logging.basicConfig(filename="gwendolyn.log", level=logging.INFO) - -# Capitalizes all words except some of them -no_caps_list = ["of","the"] -def cap(s): - # Capitalizes a strink like a movie title - word_number = 0 - lst = s.split() - res = '' - for word in lst: - word_number += 1 - if word not in no_caps_list or word_number == 1: - word = word.capitalize() - res += word+" " - res = res[:-1] - return res - -def time_in_range(start, end, x): - # Return true if x is in the range [start, end] - if start <= end: - return start <= x <= end - else: - return start <= x or x <= end - -# Responds with a greeting of a time-appropriate maner -def helloFunc(author): - 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): - return("Good morning, "+str(author)) - elif time_in_range(now.replace(hour=10, minute=0, second=0, microsecond=0),now.replace(hour=13, minute=0, second=0, microsecond=0), now): - return("Good day, "+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): - return("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): - return("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): - return("Good night, "+str(author)) - else: - return("Why hello, "+str(author)) - -# Finds a random picture online -def imageFunc(): - # Picks a type of camera, which decides the naming scheme - try: - cams = ("one","two","three","four") - cam = random.choice(cams) - logThis("Chose cam type "+cam) - if cam == "one": - a = str(random.randint(0 ,9)) - b = str(random.randint(0,9)) - c = str(random.randint(0,9)) - d = str(random.randint(0,9)) - search = ("img_"+a+b+c+d) - elif cam == "two": - a = str(random.randint(2012,2016)) - b = str(random.randint(1,12)).zfill(2) - c = str(random.randint(1,29)).zfill(2) - search = ("IMG_"+a+b+c) - elif cam == "three": - a = str(random.randint(1,500)).zfill(4) - search = ("IMAG_"+a) - elif cam == "four": - a = str(random.randint(0,9)) - b = str(random.randint(0,9)) - c = str(random.randint(0,9)) - d = str(random.randint(0,9)) - search = ("DSC_"+a+b+c+d) - except: - logThis("error picking camera type (error code 702)") - - logThis("Searching for "+search) - - # Searches for the image and reads the resulting web page - try: - page = urllib.request.urlopen("https://www.bing.com/images/search?q="+search+"&safesearch=off") - read = page.read() - tree = lxml.etree.HTML(read) - images = tree.xpath('//a[@class = "thumb"]/@href') - - # Picks an image - number = random.randint(1,len(images))-1 - image = images[number] - - logThis("Picked image number "+str(number)) - - # Returns the image - logThis("Successfully returned an image") - except: - image = "Couldn't connect to bing (error code 701)" - logThis("Couldn't connect to bing (error code 701)") - return(image) - -def logThis(messages : Union[str, list], channel = "", level = 20): - localtime = time.asctime(time.localtime(time.time())) - channel = channel.replace("Direct Message with ","") - if type(messages) is str: - messages = [messages] - - for x, msg in enumerate(messages): - if channel == "": - messages[x] = localtime+" - "+msg - else: - messages[x] = localtime+" ("+channel+") - "+msg - - if len(messages) > 1: - messages[0] += " (details in log)" - - if level != 10: - print(messages[0]) - - for logMessage in messages: - logging.log(level, logMessage) - -# Finds a page from the Senkulpa Wikia -def findWikiPage(search : str): - logThis("Trying to find wiki page for "+search) - wikia.set_lang("da") - searchResults = wikia.search("senkulpa",search) - if len(searchResults) > 0: - try: - searchResult = searchResults[0].replace(",","%2C") - logThis("Found page \""+searchResult+"\"") - page = wikia.page("senkulpa",searchResult) - content = page.content.replace(u'\xa0', u' ').split("\n")[0] - - images = page.images - if len(images) > 0: - image = images[len(images)-1]+"/revision/latest?path-prefix=da" - return page.title, content, image - else: - return page.title, content, "" - except: - logThis("Fucked up (error code 1001)") - return "", "Sorry. Fucked that one up (error code 1001)", "" - else: - logThis("Couldn't find the page (error code 1002)") - return "", "Couldn't find page (error code 1002)", "" - -def makeJsonFile(path,content): - # Creates json file if it doesn't exist - try: - f = open(path,"r") - except: - logThis(path.split("/")[-1]+" didn't exist. Making it now.") - with open(path,"w") as f: - json.dump(content,f,indent = 4) - finally: - f.close() - -def makeTxtFile(path,content): - # Creates txt file if it doesn't exist - try: - f = open(path,"r") - except: - logThis(path.split("/")[-1]+" didn't exist. Making it now.") - with open(path,"w") as f: - f.write(content) - finally: - f.close() - -def makeFolder(path): - if os.path.isdir(path) == False: - os.makedirs(path) - logThis("The "+path.split("/")[-1]+" directory didn't exist") - -def makeFiles(): - with open("resources/startingFiles.json") as f: - data = json.load(f) - - for path, content in data["json"].items(): - makeJsonFile(path,content) - - for path, content in data["txt"].items(): - makeTxtFile(path,content) - - for path in data["folder"]: - makeFolder(path) - -# Replaces multiple things with the same thing -def replaceMultiple(mainString, toBeReplaces, newString): - # Iterate over the strings to be replaced - for elem in toBeReplaces : - # Check if string is in the main string - if elem in mainString : - # Replace the string - mainString = mainString.replace(elem, newString) - - return mainString - -def emojiToCommand(emoji): - if emoji == "1️⃣": - return 1 - elif emoji == "2️⃣": - return 2 - elif emoji == "3️⃣": - return 3 - elif emoji == "4️⃣": - return 4 - elif emoji == "5️⃣": - return 5 - elif emoji == "6️⃣": - return 6 - elif emoji == "7️⃣": - return 7 - elif emoji == "🎲": - return "roll" - elif emoji == "❌": - return "none" - elif emoji == "✔️": - return 1 - else: return "" diff --git a/funcs/other/__init__.py b/funcs/other/__init__.py index 3d936c6..8612103 100644 --- a/funcs/other/__init__.py +++ b/funcs/other/__init__.py @@ -1,8 +1,5 @@ """Misc. functions for Gwendolyn.""" -__all__ = ["Generators", "movieFunc","BedreNetflix","NerdShit"] +__all__ = ["Other"] -from .bedreNetflix import BedreNetflix -from .generators import Generators -from .movie import movieFunc -from .nerdShit import NerdShit \ No newline at end of file +from .other import Other \ No newline at end of file diff --git a/funcs/other/bedreNetflix.py b/funcs/other/bedreNetflix.py index 034befe..eab30ce 100644 --- a/funcs/other/bedreNetflix.py +++ b/funcs/other/bedreNetflix.py @@ -1,5 +1,4 @@ import requests, imdb, discord, json, math, time, asyncio -from funcs import logThis class BedreNetflix(): def __init__(self,bot): @@ -14,7 +13,7 @@ class BedreNetflix(): #Returns a list of no more than 5 options when user requests a movie async def requestMovie(self, ctx, movieName): - logThis("Searching for "+movieName) + self.bot.log("Searching for "+movieName) movieList = imdb.IMDb().search_movie(movieName) movies = [] for movie in movieList: @@ -41,7 +40,7 @@ class BedreNetflix(): messageText += "Error" imdbIds.append(movie.movieID) - logThis("Returning a list of "+str(len(movies))+" possible movies: "+str(imdbIds)) + self.bot.log("Returning a list of "+str(len(movies))+" possible movies: "+str(imdbIds), level = 10) em = discord.Embed(title=messageTitle,description=messageText,colour=0x00FF00) @@ -63,10 +62,10 @@ class BedreNetflix(): #Adds the requested movie to Bedre Netflix async def addMovie(self,channel,imdbId): if imdbId == None: - logThis("Did not find what the user was searching for") + self.bot.log("Did not find what the user was searching for") await channel.send("Try searching for the IMDB id") else: - logThis("Trying to add movie "+str(imdbId)) + self.bot.log("Trying to add movie "+str(imdbId)) apiKey = self.bot.credentials.radarrKey response = requests.get(self.radarrURL+"movie/lookup/imdb?imdbId=tt"+imdbId+"&apiKey="+apiKey) lookupData = response.json() @@ -81,16 +80,16 @@ class BedreNetflix(): if r.status_code == 201: await channel.send(postData["title"]+" successfully added to Bedre Netflix") - logThis("Added "+postData["title"]+" to Bedre Netflix") + self.bot.log("Added "+postData["title"]+" to Bedre Netflix") elif r.status_code == 400: await channel.send("The movie is already requested for or added to Bedre Netflix") else: await channel.send("Something went wrong") - logThis(str(r.status_code)+" "+r.reason) + self.bot.log(str(r.status_code)+" "+r.reason) #Returns a list of no more than 5 options when user requests a show async def requestShow(self, ctx, showName): - logThis("Searching for "+showName) + self.bot.log("Searching for "+showName) movies = imdb.IMDb().search_movie(showName) #Replace with tvdb shows = [] for movie in movies: @@ -117,7 +116,7 @@ class BedreNetflix(): messageText += "Error" imdbNames.append(show["title"]) - logThis("Returning a list of "+str(len(shows))+" possible shows: "+str(imdbNames)) + self.bot.log("Returning a list of "+str(len(shows))+" possible shows: "+str(imdbNames), level = 10) em = discord.Embed(title=messageTitle,description=messageText,colour=0x00FF00) @@ -139,10 +138,10 @@ class BedreNetflix(): #Adds the requested show to Bedre Netflix async def addShow(self,channel,imdbName): if imdbName == None: - logThis("Did not find what the user was searching for") + self.bot.log("Did not find what the user was searching for") await channel.send("Try searching for the IMDB id") else: - logThis("Trying to add show "+str(imdbName)) + self.bot.log("Trying to add show "+str(imdbName)) apiKey = self.bot.credentials.sonarrKey response = requests.get(self.sonarrURL+"series/lookup?term="+imdbName.replace(" ","%20")+"&apiKey="+apiKey) lookupData = response.json()[0] @@ -157,16 +156,16 @@ class BedreNetflix(): if r.status_code == 201: await channel.send(postData["title"]+" successfully added to Bedre Netflix") - logThis("Added a "+postData["title"]+" to Bedre Netflix") + self.bot.log("Added a "+postData["title"]+" to Bedre Netflix") elif r.status_code == 400: await channel.send("The show is already requested for or added to Bedre Netflix") else: await channel.send("Something went wrong") - logThis(str(r.status_code)+" "+r.reason) + self.bot.log(str(r.status_code)+" "+r.reason) #Generates a list of all torrents and returns formatted list and whether all torrents are downloaded async def genDownloadList(self, showDM, showMovies, showShows, episodes): - logThis("Generating torrent list") + self.bot.log("Generating torrent list") titleWidth = 100 message = [] allDownloaded = True @@ -366,10 +365,10 @@ class BedreNetflix(): if messageText.startswith("```"): if allDownloaded: - logThis("All torrents are downloaded") + self.bot.log("All torrents are downloaded") else: messageText = messageText[:-3]+"\nThis message will not update anymore\n```" - logThis("The message updated 20 times") + self.bot.log("The message updated 20 times") await oldMessage.edit(content = messageText) diff --git a/funcs/other/generators.py b/funcs/other/generators.py index 032704c..febe219 100644 --- a/funcs/other/generators.py +++ b/funcs/other/generators.py @@ -1,9 +1,9 @@ -#import numpy as np import random -from funcs import logThis - class Generators(): + def __init__(self, bot): + self.bot = bot + # Returns a list of all letter pairs in the text def make_pairs(self, corpus): for i in range(len(corpus)-1): @@ -73,7 +73,7 @@ class Generators(): if new_letter == "\n": done = True genName = "".join(chain) - logThis("Generated "+genName) + self.bot.log("Generated "+genName[:-1]) # Returns the name return(genName) @@ -86,7 +86,7 @@ class Generators(): # Picks one of each genTav = random.choice(fp)+" "+random.choice(sp)+random.choice(tp) - logThis("Generated "+genTav) + self.bot.log("Generated "+genTav) # Return the name return(genTav) diff --git a/funcs/other/movie.py b/funcs/other/movie.py deleted file mode 100644 index fc448b0..0000000 --- a/funcs/other/movie.py +++ /dev/null @@ -1,46 +0,0 @@ -import imdb -import random - -from funcs import logThis - -# Picks a random movie and returns information about it -def movieFunc(): - try: - logThis("Creating IMDb object") - ia = imdb.IMDb() - - try: - logThis("Picking a movie") - movs = open("resources/movies.txt", "r") - movlist = movs.read().split("\n") - mov = random.choice(movlist) - movs.close() - except: - logThis("Problem picking the movie (error code 801)") - return("error","804","","") - - try: - logThis("Searching for "+mov) - s_result = ia.search_movie(mov) - except: - logThis("Couldn't find on imdb (error code 802)") - return("error","802","","") - - try: - logThis("Getting the data") - movie = s_result[0] - ia.update(movie) - cast = movie['cast'] - pcast = "" - for x in range(3): - if cast[x]: - pcast += cast[x]['name']+", " - except: - logThis("Couldn't extract data (error code 803)") - return("error","803","","") - - logThis("Successfully ran !movie") - return(movie['title'], movie['plot'][0].split("::")[0], movie['cover url'].replace("150","600").replace("101","404"), pcast[:-2]) - except: - logThis("Something bad happened... (error code 801)") - return("error","801","","") diff --git a/funcs/other/nerdShit.py b/funcs/other/nerdShit.py index 21730f3..e2e64f8 100644 --- a/funcs/other/nerdShit.py +++ b/funcs/other/nerdShit.py @@ -1,20 +1,19 @@ import discord, wolframalpha, requests, os from PIL import Image, ImageDraw, ImageFont -from funcs import logThis class NerdShit(): - def __init__(self,client): + def __init__(self, bot): """Runs misc commands.""" - self.client = client + self.bot = bot async def wolfSearch(self,ctx,content): - fnt = ImageFont.truetype('resources/times-new-roman.ttf', 20) + fnt = ImageFont.truetype('resources/fonts/times-new-roman.ttf', 20) await ctx.defer() - logThis("Requesting data") - client = wolframalpha.Client(self.client.credentials.wolfKey) - res = client.query(content) + self.bot.log("Requesting data") + bot = wolframalpha.Client(self.bot.credentials.wolfKey) + res = bot.query(content) - logThis("Processing data") + self.bot.log("Processing data") titles = [] pods = [] if int(res.numpods) > 0: @@ -73,10 +72,10 @@ class NerdShit(): wolfImage.save("resources/wolf.png") wolfImage.close() - await ctx.send(file = discord.File("resources/wolf.png")) + await ctx.channel.send(file = discord.File("resources/wolf.png")) os.remove("resources/wolf.png") os.remove("resources/wolfTemp.png") else: - logThis("No returned data") + self.bot.log("No returned data") await ctx.send("Could not find anything relating to your search") \ No newline at end of file diff --git a/funcs/other/other.py b/funcs/other/other.py new file mode 100644 index 0000000..c8c98ac --- /dev/null +++ b/funcs/other/other.py @@ -0,0 +1,151 @@ +import imdb # Used in movieFunc +import random # Used in movieFunc +import discord # Used in movieFunc +import datetime # Used in helloFunc +import urllib # Used in imageFunc +import lxml # Used in imageFunc +import wikia # Used in findWikiPage +import d20 # Used in rollDice +from .bedreNetflix import BedreNetflix +from .nerdShit import NerdShit +from .generators import Generators + +class MyStringifier(d20.MarkdownStringifier): + def _str_expression(self, node): + if node.comment == None: + resultText = "Result" + else: + resultText = node.comment.capitalize() + + return f"**{resultText}**: {self._stringify(node.roll)}\n**Total**: {int(node.total)}" + +class Other(): + def __init__(self, bot): + self.bot = bot + self.bedreNetflix = BedreNetflix(self.bot) + self.nerdShit = NerdShit(self.bot) + self.generators = Generators(self.bot) + + # Picks a random movie and returns information about it + async def movieFunc(self, ctx): + await ctx.defer() + + self.bot.log("Creating IMDb object") + imdbClient = imdb.IMDb() + + self.bot.log("Picking a movie") + with open("resources/movies.txt", "r") as f: + movieList = f.read().split("\n") + movieName = random.choice(movieList) + + self.bot.log(f"Searching for {movieName}") + searchResult = imdbClient.search_movie(movieName) + + self.bot.log("Getting the data") + movie = searchResult[0] + imdbClient.update(movie) + + self.bot.log("Successfully ran !movie") + + title = movie["title"] + plot = movie['plot'][0].split("::")[0] + cover = movie['cover url'].replace("150","600").replace("101","404") + cast = ", ".join([i["name"] for i in movie['cast'][:5]]) + embed = discord.Embed(title=title, description=plot, color=0x24ec19) + embed.set_thumbnail(url=cover) + embed.add_field(name="Cast", value=cast,inline = True) + await ctx.send(embed = embed) + + # Responds with a greeting of a time-appropriate maner + def helloFunc(self, author): + def time_in_range(start, end, x): + # Return true if x is in the range [start, end] + if start <= end: + return start <= x <= end + else: + return start <= x or x <= end + 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): + return("Good morning, "+str(author)) + elif time_in_range(now.replace(hour=10, minute=0, second=0, microsecond=0),now.replace(hour=13, minute=0, second=0, microsecond=0), now): + return("Good day, "+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): + return("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): + return("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): + return("Good night, "+str(author)) + else: + return("Hello, "+str(author)) + + # Finds a random picture online + def imageFunc(self): + # Picks a type of camera, which decides the naming scheme + cams = ("one","two","three","four") + cam = random.choice(cams) + self.bot.log("Chose cam type "+cam) + if cam == "one": + a = str(random.randint(0 ,9)) + b = str(random.randint(0,9)) + c = str(random.randint(0,9)) + d = str(random.randint(0,9)) + search = ("img_"+a+b+c+d) + elif cam == "two": + a = str(random.randint(2012,2016)) + b = str(random.randint(1,12)).zfill(2) + c = str(random.randint(1,29)).zfill(2) + search = ("IMG_"+a+b+c) + elif cam == "three": + a = str(random.randint(1,500)).zfill(4) + search = ("IMAG_"+a) + elif cam == "four": + a = str(random.randint(0,9)) + b = str(random.randint(0,9)) + c = str(random.randint(0,9)) + d = str(random.randint(0,9)) + search = ("DSC_"+a+b+c+d) + + self.bot.log("Searching for "+search) + + # Searches for the image and reads the resulting web page + page = urllib.request.urlopen("https://www.bing.com/images/search?q="+search+"&safesearch=off") + read = page.read() + tree = lxml.etree.HTML(read) + images = tree.xpath('//a[@class = "thumb"]/@href') + + # Picks an image + number = random.randint(1,len(images))-1 + image = images[number] + + self.bot.log("Picked image number "+str(number)) + + # Returns the image + self.bot.log("Successfully returned an image") + return(image) + + # Finds a page from the Senkulpa Wikia + def findWikiPage(self, search : str): + self.bot.log("Trying to find wiki page for "+search) + wikia.set_lang("da") + searchResults = wikia.search("senkulpa",search) + if len(searchResults) > 0: + searchResult = searchResults[0].replace(",","%2C") + self.bot.log("Found page \""+searchResult+"\"") + page = wikia.page("senkulpa",searchResult) + content = page.content.replace(u'\xa0', u' ').split("\n")[0] + + images = page.images + if len(images) > 0: + image = images[len(images)-1]+"/revision/latest?path-prefix=da" + return page.title, content, image + else: + return page.title, content, "" + else: + self.bot.log("Couldn't find the page (error code 1002)") + return "", "Couldn't find page (error code 1002)", "" + + def rollDice(self, user, rollString): + while len(rollString) > 1 and rollString[0] == " ": + rollString = rollString[1:] + return user+" :game_die:\n"+str(d20.roll(rollString, allow_comments=True,stringifier=MyStringifier())) + diff --git a/funcs/roll/__init__.py b/funcs/roll/__init__.py deleted file mode 100644 index e356957..0000000 --- a/funcs/roll/__init__.py +++ /dev/null @@ -1,5 +0,0 @@ -"""Rolling dice.""" - -__all__ = ["roll_dice"] - -from .dice import roll_dice \ No newline at end of file diff --git a/funcs/roll/dice.py b/funcs/roll/dice.py deleted file mode 100644 index 03385d8..0000000 --- a/funcs/roll/dice.py +++ /dev/null @@ -1,20 +0,0 @@ -import d20 - -class MyStringifier(d20.MarkdownStringifier): - - def _str_expression(self, node): - - if node.comment == None: - resultText = "Result" - else: - resultText = node.comment.capitalize() - - return f"**{resultText}**: {self._stringify(node.roll)}\n**Total**: {int(node.total)}" - -def roll_dice(user, rollString): - while len(rollString) > 1 and rollString[0] == " ": - rollString = rollString[1:] - return user+" :game_die:\n"+str(d20.roll(rollString, allow_comments=True,stringifier=MyStringifier())) - - - diff --git a/funcs/starWarsFuncs/__init__.py b/funcs/starWarsFuncs/__init__.py new file mode 100644 index 0000000..041ebad --- /dev/null +++ b/funcs/starWarsFuncs/__init__.py @@ -0,0 +1,5 @@ +"""Functions related to the Star Wars TTRPG.""" + +__all__ = ["StarWars"] + +from .starWars import StarWars \ No newline at end of file diff --git a/funcs/starWarsFuncs/starWars.py b/funcs/starWarsFuncs/starWars.py new file mode 100644 index 0000000..48e6f84 --- /dev/null +++ b/funcs/starWarsFuncs/starWars.py @@ -0,0 +1,10 @@ +from .starWarsChar import StarWarsChar +from .starWarsRoll import StarWarsRoll +from .starWarsDestiny import StarWarsDestiny + +class StarWars(): + def __init__(self, bot): + self.bot = bot + self.character = StarWarsChar(self.bot) + self.roll = StarWarsRoll(self.bot) + self.destiny = StarWarsDestiny(self.bot) diff --git a/funcs/swfuncs/swchar.py b/funcs/starWarsFuncs/starWarsChar.py similarity index 69% rename from funcs/swfuncs/swchar.py rename to funcs/starWarsFuncs/starWarsChar.py index de8150c..95caa17 100644 --- a/funcs/swfuncs/swchar.py +++ b/funcs/starWarsFuncs/starWarsChar.py @@ -1,25 +1,23 @@ import json import string -from funcs import logThis - -class SwChar(): +class StarWarsChar(): def __init__(self, bot): self.bot = bot def getCharName(self, user : str): - logThis("Getting name for "+self.bot.funcs.getName(user)+"'s character") - userCharacter = self.bot.database["swcharacters"].find_one({"_id":user}) + self.bot.log("Getting name for "+self.bot.databaseFuncs.getName(user)+"'s character") + userCharacter = self.bot.database["starwars characters"].find_one({"_id":user}) if userCharacter != None: - logThis("Name is "+userCharacter["Name"]) + self.bot.log("Name is "+userCharacter["Name"]) return userCharacter["Name"] else: - logThis("Just using "+self.bot.funcs.getName(user)) - return self.bot.funcs.getName(user) + self.bot.log("Just using "+self.bot.databaseFuncs.getName(user)) + return self.bot.databaseFuncs.getName(user) def setUpDict(self, cmd : dict): - logThis("Setting up a dictionary in a nice way") + self.bot.log("Setting up a dictionary in a nice way") if bool(cmd): keys = list(cmd) values = list(cmd.values()) @@ -38,10 +36,10 @@ class SwChar(): result += "**" + key + "**" + ": " + str(values[x]) + " " else: result += "**" + key + "**" + ": " + str(values[x]) + "\n" - logThis("Returning a dictionary, but well formatted") + self.bot.log("Returning a dictionary, but well formatted") return result else: - logThis("Couldn't find anything") + self.bot.log("Couldn't find anything") return "There doesn't seem to be anything here..." def lookUp(self, data : dict, key : str, cmd : str = ""): @@ -53,87 +51,87 @@ class SwChar(): if cmd == "": break - logThis("Looking up "+key) + self.bot.log("Looking up "+key) if key in data: - logThis(key+" exists") + self.bot.log(key+" exists") if cmd == "": if type(data[key]) is dict and key != "Weapons": return self.setUpDict(data[key]) elif key == "Weapons": - logThis("Does this even get used? I'm too scared to delete it") + self.bot.log("Does this even get used? I'm too scared to delete it") if bool(data[key]): - logThis("Found "+(", ".join(list(data[key])))) + self.bot.log("Found "+(", ".join(list(data[key])))) return ", ".join(list(data[key])) else: - logThis("There is nothing here") + self.bot.log("There is nothing here") return "There doesn't seem to be anything here..." else: if str(data[key]) != "": - logThis("Returning "+str(data[key])) + self.bot.log("Returning "+str(data[key])) return data[key] else: - logThis("There was nothing there") + self.bot.log("There was nothing there") return "There doesn't seem to be anything here" elif cmd[0] == '+': - logThis("Trying to add to "+key) + self.bot.log("Trying to add to "+key) try: cmd = cmd[1:] while cmd[0] == ' ': cmd = cmd[1:] except: - logThis("Yeah, that fucked up") + self.bot.log("Yeah, that fucked up") return "Can't do that" if type(data[key]) is int: try: newValue = data[key] + int(cmd) data[key] = newValue - logThis("Added "+cmd+" to "+key) + self.bot.log("Added "+cmd+" to "+key) return data except: - logThis("Couldn't add "+cmd+" to "+key) + self.bot.log("Couldn't add "+cmd+" to "+key) return "Can't add that" elif type(data[key]) is list: try: data[key].append(cmd) - logThis("Added "+cmd+" to "+key) + self.bot.log("Added "+cmd+" to "+key) return data except: - logThis("Couldn't add "+cmd+" to "+key) + self.bot.log("Couldn't add "+cmd+" to "+key) return "Can't add that" else: - logThis("Yeah, I can't add that to "+key) + self.bot.log("Yeah, I can't add that to "+key) return "Can't add that" elif cmd[0] == '-': - logThis("Trying to remove/subtract from "+key) + self.bot.log("Trying to remove/subtract from "+key) try: cmd = cmd[1:] while cmd[0] == ' ': cmd = cmd[1:] except: - logThis("Yeah, that fucked up") + self.bot.log("Yeah, that fucked up") return "Can't do that" if type(data[key]) is int: try: newValue = data[key] - int(cmd) data[key] = newValue - logThis("Subtracted "+cmd+" from "+key) + self.bot.log("Subtracted "+cmd+" from "+key) return data except: - logThis("Couldn't subtract "+cmd+" from "+key) + self.bot.log("Couldn't subtract "+cmd+" from "+key) return "Can't remove that" elif type(data[key]) is list: try: data[key].remove(cmd) - logThis("Removed "+cmd+" from "+key) + self.bot.log("Removed "+cmd+" from "+key) return data except: - logThis("Couldn't remove "+cmd+" from "+key) + self.bot.log("Couldn't remove "+cmd+" from "+key) return "Can't remove that" else: - logThis("Yeah, I can't remove/subtract that from "+key) + self.bot.log("Yeah, I can't remove/subtract that from "+key) return "Can't remove that" else: while cmd[0] == ' ': @@ -147,7 +145,7 @@ class SwChar(): cmd = cmd[1:] if cmd == "": break - logThis("Looking up "+newKey+" in "+key) + self.bot.log("Looking up "+newKey+" in "+key) lookUpResult = self.lookUp(data[key],newKey,cmd) if type(lookUpResult) is dict: data[key] = lookUpResult @@ -155,21 +153,21 @@ class SwChar(): else: return lookUpResult elif type(data[key]) != list: - logThis("Trying to change "+key+" to "+cmd) + self.bot.log("Trying to change "+key+" to "+cmd) try: cmd = type(data[key])(cmd) data[key] = cmd - logThis("Did that") + self.bot.log("Did that") return data except: - logThis("No. That did not work") + self.bot.log("No. That did not work") return "Wrong data type" else: - logThis("Yeah, that didn't work") + self.bot.log("Yeah, that didn't work") return "Wrong data type" else: - logThis("Couldn't find "+key) - logThis("Testing to see if it's a multi-word key") + self.bot.log("Couldn't find "+key) + self.bot.log("Testing to see if it's a multi-word key") cmd = key + " " + cmd words = cmd.split(" ") search = "" @@ -179,11 +177,11 @@ class SwChar(): search += " " + words[i] i += 1 except: - logThis("It wasn't. "+search+" doesn't exist") + self.bot.log("It wasn't. "+search+" doesn't exist") return search + " doesn't exist" if search[0] == " ": search = search[1:] - logThis("Yeah! Did that! The key was "+search) + self.bot.log("Yeah! Did that! The key was "+search) cmd = cmd[len(search):] if cmd != "": @@ -193,7 +191,7 @@ class SwChar(): break if cmd == "": - logThis("Returning "+search) + self.bot.log("Returning "+search) return self.setUpDict(data[search]) else: newKey = cmd.split(" ")[0] @@ -211,7 +209,7 @@ class SwChar(): return lookUpResult def characterSheet(self,character : dict): - logThis("Setting up a character sheet for "+character["Name"]) + self.bot.log("Setting up a character sheet for "+character["Name"]) divider = "--------------------\n" name = character["Name"] textf = "" @@ -241,7 +239,7 @@ class SwChar(): return name, text1+text2+"\n\n"+text3+divider+text4+"\n"+divider+text5+text6+text7+text8 def charData(self,user : str,cmd : str): - userCharacter = self.bot.database["swcharacters"].find_one({"_id":user}) + userCharacter = self.bot.database["starwars characters"].find_one({"_id":user}) key = string.capwords(cmd.split(" ")[0]) cmd = cmd[len(key):] @@ -253,40 +251,40 @@ class SwChar(): if cmd == "": break - logThis("Looking for "+self.bot.funcs.getName(user)+"'s character") + self.bot.log("Looking for "+self.bot.databaseFuncs.getName(user)+"'s character") if userCharacter != None: - logThis("Foundt it! Looking for "+key+" in the data") + self.bot.log("Found it! Looking for "+key+" in the data") if key in userCharacter: - logThis("Found it!") + self.bot.log("Found it!") if type(userCharacter[key]) is dict: - logThis("It's a dictionary!") + self.bot.log("It's a dictionary!") if cmd == "": - logThis("Retrieving data") + self.bot.log("Retrieving data") if key == "Weapons": if bool(userCharacter[key]): - logThis("Returning a list of weapons") + self.bot.log("Returning a list of weapons") return ", ".join(list(userCharacter[key])) else: - logThis("The character doesn't have any weapons. Which is probably for the best. Like, who just walks around with weapons? (error code 941)") + self.bot.log("The character doesn't have any weapons. Which is probably for the best. Like, who just walks around with weapons? (error code 941)") return "There doesn't seem to be anything there... (error code 941)" else: return self.setUpDict(userCharacter[key]) elif cmd[0] == "+": - logThis("Gonna add something!!!") + self.bot.log("Gonna add something!!!") try: cmd = cmd[1:] while cmd[0] == ' ': cmd = cmd[1:] except: - logThis("Nope. That didn't happen (error code 942)") + self.bot.log("Nope. That didn't happen (error code 942)") return "Can't do that (error code 942)" if (key == "Talents" or key == "Force-powers") and "," in cmd: cmd = cmd.split(",") while cmd[1][0] == " ": cmd[1] = cmd[1][1:] - logThis("Adding "+cmd[0]+" to "+key) - self.bot.database["swcharacters"].update_one({"_id":user}, + self.bot.log("Adding "+cmd[0]+" to "+key) + self.bot.database["starwars characters"].update_one({"_id":user}, {"$set": {key+"."+cmd[0] : cmd[1]}}) return cmd[0]+" added to "+key+" for " + userCharacter["Name"] @@ -294,55 +292,55 @@ class SwChar(): cmd = cmd.split(",") while cmd[1][0] == " ": cmd[1] = cmd[1][1:] - logThis("Adding "+cmd[0]+" to "+key) + self.bot.log("Adding "+cmd[0]+" to "+key) try: - self.bot.database["swcharacters"].update_one({"_id":user}, + self.bot.database["starwars characters"].update_one({"_id":user}, {"$set": {key+"."+cmd[0] : int(cmd[1])}}) except: - logThis("Fucked that up (error code 949)") + self.bot.log("Fucked that up (error code 949)") return "Wrong data type (error code 949)" return cmd[0]+" added to "+key+" for " + userCharacter["Name"] elif key == "Weapons": - with open("resources/starWars/swtemplates.json", "r") as f: + with open("resources/starWars/starwarstemplates.json", "r") as f: templates = json.load(f) newWeapon = templates["Weapon"] - logThis("Adding "+cmd+" to "+key) - self.bot.database["swcharacters"].update_one({"_id":user}, + self.bot.log("Adding "+cmd+" to "+key) + self.bot.database["starwars characters"].update_one({"_id":user}, {"$set": {key+"."+cmd : newWeapon}}) return cmd+" added to weapons for " + userCharacter["Name"] else: - logThis("That's not happening (error code 947d)") + self.bot.log("That's not happening (error code 947d)") return "Can't add that (error code 947d)" elif cmd[0] == "-": - logThis("Gonna subtract/remove something") + self.bot.log("Gonna subtract/remove something") try: cmd = cmd[1:] while cmd[0] == ' ': cmd = cmd[1:] except: - logThis("AAAAAAAAAAAA (error code 948)") + self.bot.log("AAAAAAAAAAAA (error code 948)") return "Can't do that (error code 948)" if key == "Talents" or key == "Force-powers" or key == "Weapons" or key == "Obligations": - logThis("Trying to remove "+cmd+" from "+key) + self.bot.log("Trying to remove "+cmd+" from "+key) if cmd in userCharacter[key]: - self.bot.database["swcharacters"].update_one({"_id":user}, + self.bot.database["starwars characters"].update_one({"_id":user}, {"$unset": {cmd}}) - logThis("I did that") + self.bot.log("I did that") return cmd+" removed from "+key+" from "+userCharacter["Name"] else: - logThis("Welp. I fucked that up (error code 946e)") + self.bot.log("Welp. I fucked that up (error code 946e)") return "Can't remove that (error code 946e)" else: - logThis("Urgh! (error code 946d)") + self.bot.log("Urgh! (error code 946d)") return "Can't remove that (error code 946d)" else: - logThis("Looking up "+cmd+" in "+key) + self.bot.log("Looking up "+cmd+" in "+key) if key == "Talents" or key == "Force-powers": newKey = cmd newcmd = "" @@ -353,106 +351,106 @@ class SwChar(): lookUpResult = self.lookUp(userCharacter[key],newKey,newcmd) if type(lookUpResult) is dict: - self.bot.database["swcharacters"].update_one({"_id":user}, + self.bot.database["starwars characters"].update_one({"_id":user}, {"$set": {key : lookUpResult}}) return "Changed " + userCharacter["Name"] + "'s " + key else: return lookUpResult else: if cmd == "": - logThis("Retrieving data") + self.bot.log("Retrieving data") if type(userCharacter[key]) is list: return key+":\n"+", ".join(userCharacter[key]) else: return userCharacter[key] elif cmd[0] == '+': - logThis("Adding") + self.bot.log("Adding") try: cmd = cmd[1:] while cmd[0] == ' ': cmd = cmd[1:] except: - logThis("Error message (error code 948)") + self.bot.log("Error message (error code 948)") return "Can't do that (error code 948)" if type(userCharacter[key]) is int: try: - logThis("Adding "+cmd+" to "+key) - self.bot.database["swcharacters"].update_one({"_id":user}, + self.bot.log("Adding "+cmd+" to "+key) + self.bot.database["starwars characters"].update_one({"_id":user}, {"$inc": {key : int(cmd)}}) return "Added " + cmd + " to " + userCharacter["Name"] + "'s " + key except: - logThis("BITCH SANDWICH (error code 947c)") + self.bot.log("BITCH SANDWICH (error code 947c)") return "Can't add that (error code 947c)" elif type(userCharacter[key]) is list: try: - logThis("Adding "+cmd+" to "+key) - self.bot.database["swcharacters"].update_one({"_id":user}, + self.bot.log("Adding "+cmd+" to "+key) + self.bot.database["starwars characters"].update_one({"_id":user}, {"$push": {key : cmd}}) return "Added " + cmd + " to " + userCharacter["Name"] + "'s " + key except: - logThis("tstststststs (error code 947b)") + self.bot.log("tstststststs (error code 947b)") return "Can't add that (error code 947b)" else: - logThis("Help (error code 947a)") + self.bot.log("Help (error code 947a)") return "Can't add that (error code 947a)" elif cmd[0] == '-': - logThis("Removing/subtracting") + self.bot.log("Removing/subtracting") try: cmd = cmd[1:] while cmd[0] == ' ': cmd = cmd[1:] except: - logThis("lalalala (error code 948)") + self.bot.log("lalalala (error code 948)") return "Can't do that (error code 948)" if type(userCharacter[key]) is int: try: - logThis("Subtracting "+cmd+" from "+key) - self.bot.database["swcharacters"].update_one({"_id":user}, + self.bot.log("Subtracting "+cmd+" from "+key) + self.bot.database["starwars characters"].update_one({"_id":user}, {"$inc": {key : -int(cmd)}}) return "Subtracted " + cmd + " from " + userCharacter["Name"] + "'s " + key except: - logThis("Tried it. Didn't want to (error code 946c)") + self.bot.log("Tried it. Didn't want to (error code 946c)") return "Can't remove that (error code 946c)" elif type(userCharacter[key]) is list: try: - logThis("removing "+cmd+" from "+key) + self.bot.log("removing "+cmd+" from "+key) try: - self.bot.database["swcharacters"].update_one({"_id":user}, + self.bot.database["starwars characters"].update_one({"_id":user}, {"$pull": {key : cmd}}) except: - logThis("They can only remove stuff that's actually in the list") + self.bot.log("They can only remove stuff that's actually in the list") return "Not in list (error code 944b)" return "Removed " + cmd + " from " + userCharacter["Name"] + "'s " + key except: - logThis("nah (error code 946b)") + self.bot.log("nah (error code 946b)") return "Can't remove that (error code 946b)" else: - logThis("nyope (error code 946a)") + self.bot.log("nyope (error code 946a)") return "Can't remove that (error code 946a)" else: - logThis("Changing "+key+" to "+cmd) + self.bot.log("Changing "+key+" to "+cmd) if type(userCharacter[key]) is int: try: - self.bot.database["swcharacters"].update_one({"_id":user}, + self.bot.database["starwars characters"].update_one({"_id":user}, {"$set": {key : int(cmd)}}) except: - logThis("I don't wanna tho (error code 945b)") + self.bot.log("I don't wanna tho (error code 945b)") return "Can't do that (error code 945b)" elif type(userCharacter[key]) is str: - self.bot.database["swcharacters"].update_one({"_id":user}, + self.bot.database["starwars characters"].update_one({"_id":user}, {"$set": {key : cmd}}) else: - logThis("I don't wanna tho (error code 945a)") + self.bot.log("I don't wanna tho (error code 945a)") return "Can't do that (error code 945a)" return "Changed " + userCharacter["Name"] + "'s " + key +" to " + cmd else: - logThis(key+" isn't in there (error code 944)") + self.bot.log(key+" isn't in there (error code 944)") return "Couldn't find that data. Are you sure you spelled it correctly? (error code 944)" else: - logThis(user+" doesn't have a character (error code 943)") - return "You don't have a character. You can make one with !swchar (error code 943)" + self.bot.log(user+" doesn't have a character (error code 943)") + return "You don't have a character. You can make one with !starwarscharacter (error code 943)" def replaceSpaces(self,cmd : str): withSpaces = ["Specialization Trees","Wound Threshold","Strain Threshold","Defense - Ranged","Defense - Melee","Force Rating","Core Worlds","Outer Rim","Piloting - Planetary","Piloting - Space","Ranged - Heavy","Ranged - Light","Lightsaber Characteristic","Critical Injuries","Force Powers"] @@ -476,7 +474,7 @@ class SwChar(): cmd = self.replaceSpaces(cmd) - userCharacter = self.bot.database["swcharacters"].find_one({"_id":user}) + userCharacter = self.bot.database["starwars characters"].find_one({"_id":user}) if cmd == " ": cmd = "" @@ -492,29 +490,29 @@ class SwChar(): text1, text2 = self.characterSheet(userCharacter) return text1, self.replaceWithSpaces(text2) else: - logThis("Makin' a character for "+self.bot.funcs.getName(user)) - with open("resources/starWars/swtemplates.json", "r") as f: + self.bot.log("Makin' a character for "+self.bot.databaseFuncs.getName(user)) + with open("resources/starWars/starwarstemplates.json", "r") as f: templates = json.load(f) newChar = templates["Character"] newChar["_id"] = user - self.bot.database["swcharacters"].insert_one(newChar) - return "", "Character for " + self.bot.funcs.getName(user) + " created" + self.bot.database["starwars characters"].insert_one(newChar) + return "", "Character for " + self.bot.databaseFuncs.getName(user) + " created" else: if cmd == "Purge": - logThis("Deleting "+self.bot.funcs.getName(user)+"'s character") - self.bot.database["swcharacters"].delete_one({"_id":user}) - return "", "Character for " + self.bot.funcs.getName(user) + " deleted" + self.bot.log("Deleting "+self.bot.databaseFuncs.getName(user)+"'s character") + self.bot.database["starwars characters"].delete_one({"_id":user}) + return "", "Character for " + self.bot.databaseFuncs.getName(user) + " deleted" else: return "", self.replaceWithSpaces(str(self.charData(user,cmd))) def lightsaberChar(self,user : str): - userCharacter = self.bot.database["swcharacters"].find_one({"_id":user}) + userCharacter = self.bot.database["starwars characters"].find_one({"_id":user}) if userCharacter != None: return userCharacter["Lightsaber-characteristic"] def userHasChar(self,user : str): - userCharacter = self.bot.database["swcharacters"].find_one({"_id":user}) + userCharacter = self.bot.database["starwars characters"].find_one({"_id":user}) return userCharacter != None diff --git a/funcs/swfuncs/swdestiny.py b/funcs/starWarsFuncs/starWarsDestiny.py similarity index 69% rename from funcs/swfuncs/swdestiny.py rename to funcs/starWarsFuncs/starWarsDestiny.py index 56a0698..f12ddac 100644 --- a/funcs/swfuncs/swdestiny.py +++ b/funcs/starWarsFuncs/starWarsDestiny.py @@ -1,46 +1,44 @@ -from funcs import logThis - -class SwDestiny(): +class StarWarsDestiny(): def __init__(self, bot): self.bot = bot def destinyNew(self, num : int): - logThis("Creating a new destiny pool with "+str(num)+" players") - roll, diceResults = self.bot.swroll.roll(0,0,0,0,0,0,num) + self.bot.log("Creating a new destiny pool with "+str(num)+" players") + roll, diceResults = self.bot.starwarsroll.roll(0,0,0,0,0,0,num) roll = "".join(sorted(roll)) with open("resources/starWars/destinyPoints.txt","wt") as f: f.write(roll) - return "Rolled for Destiny Points and got:\n"+self.bot.swroll.diceResultToEmoji(diceResults)+"\n"+self.bot.swroll.resultToEmoji(roll) + return "Rolled for Destiny Points and got:\n"+self.bot.starwarsroll.diceResultToEmoji(diceResults)+"\n"+self.bot.starwarsroll.resultToEmoji(roll) def destinyUse(self, user : str): with open("resources/starWars/destinyPoints.txt","rt") as f: points = f.read() if user == "Nikolaj": - logThis("Trying to use a dark side destiny point") + 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("resources/starWars/destinyPoints.txt","wt") as f: f.write(points) - logThis("Did it") - return "Used a dark side destiny point. Destiny pool is now:\n"+self.bot.swroll.resultToEmoji(points) + self.bot.log("Did it") + return "Used a dark side destiny point. Destiny pool is now:\n"+self.bot.starwarsroll.resultToEmoji(points) else: - logThis("There were no dark side destiny points") + self.bot.log("There were no dark side destiny points") return "No dark side destiny points" else: - logThis("Trying to use a light side destiny point") + 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("resources/starWars/destinyPoints.txt","wt") as f: f.write(points) - logThis("Did it") - return "Used a light side destiny point. Destiny pool is now:\n"+self.bot.swroll.resultToEmoji(points) + self.bot.log("Did it") + return "Used a light side destiny point. Destiny pool is now:\n"+self.bot.starwarsroll.resultToEmoji(points) else: - logThis("There were no dark side destiny points") + self.bot.log("There were no dark side destiny points") return "No light side destiny points" def parseDestiny(self, user : str, cmd : str): @@ -52,9 +50,9 @@ class SwDestiny(): if cmd == "": - logThis("Retrieving destiny pool info") + self.bot.log("Retrieving destiny pool info") with open("resources/starWars/destinyPoints.txt","rt") as f: - return self.bot.swroll.resultToEmoji(f.read()) + return self.bot.starwarsroll.resultToEmoji(f.read()) else: commands = cmd.upper().split(" ") if commands[0] == "N": diff --git a/funcs/swfuncs/swroll.py b/funcs/starWarsFuncs/starWarsRoll.py similarity index 90% rename from funcs/swfuncs/swroll.py rename to funcs/starWarsFuncs/starWarsRoll.py index ec6573c..cc24a92 100644 --- a/funcs/swfuncs/swroll.py +++ b/funcs/starWarsFuncs/starWarsRoll.py @@ -3,12 +3,10 @@ import re import string import json -from funcs import logThis - -with open("resources/starWars/swskills.json", "r") as f: +with open("resources/starWars/starwarsskills.json", "r") as f: skillData = json.load(f) -class SwRoll(): +class StarWarsRoll(): def __init__(self, bot): self.bot = bot @@ -55,7 +53,7 @@ class SwRoll(): # Lets dice cancel each other out def simplify(self, result : str): - logThis("Simplifying "+result) + self.bot.log("Simplifying "+result) simp = "" success = (result.count('S') + result.count('R')) - (result.count('F') + result.count('D')) advantage = result.count('A') - result.count('H') @@ -225,8 +223,8 @@ class SwRoll(): # Rolls for obligation def obligationRoll(self): - logThis("Rolling for obligation") - data = self.bot.database["swcharacters"] + self.bot.log("Rolling for obligation") + data = self.bot.database["starwarscharacters"] table = [] @@ -297,7 +295,7 @@ class SwRoll(): cmd = re.sub(' +',' ',cmd.upper()) + " " if cmd[0] == " ": cmd = cmd[1:] - cmd = self.bot.swchar.replaceSpaces(string.capwords(cmd)) + cmd = self.bot.starwarschar.replaceSpaces(string.capwords(cmd)) commands = cmd.split(" ") if commands[0] == "": rollParameters = [1,0,3,0,0,0,0] @@ -308,39 +306,39 @@ class SwRoll(): try: return self.obligationRoll() except: - logThis("Obligation fucked up (error code 911)") - return "An error occured (error code 911)" + self.bot.log("Obligation fucked up (error code 911)") + return "An error ocurred (error code 911)" elif string.capwords(commands[0]) in skillData: - logThis("Oh look! This guy has skills!") - if self.bot.swchar.userHasChar: - logThis("They have a character. That much we know") - skillLevel = self.bot.swchar.charData(user,"Skills " + string.capwords(commands[0])) + self.bot.log("Oh look! This guy has skills!") + if self.bot.starwarschar.userHasChar: + self.bot.log("They have a character. That much we know") + skillLevel = self.bot.starwarschar.charData(user,"Skills " + string.capwords(commands[0])) if string.capwords(commands[0]) == "Lightsaber": - logThis("The skill is lightsaber") - charLevel = self.bot.swchar.charData(user,"Characteristics " + self.bot.swchar.lightsaberChar(user)) + self.bot.log("The skill is lightsaber") + charLevel = self.bot.starwarschar.charData(user,"Characteristics " + self.bot.starwarschar.lightsaberChar(user)) else: - charLevel = self.bot.swchar.charData(user,"Characteristics " + skillData[string.capwords(commands[0])]) + charLevel = self.bot.starwarschar.charData(user,"Characteristics " + skillData[string.capwords(commands[0])]) abilityDice = abs(charLevel-skillLevel) proficiencyDice = min(skillLevel,charLevel) commands = [str(abilityDice)] + [str(proficiencyDice)] + commands[1:] - logThis("Converted skill to dice") + self.bot.log("Converted skill to dice") else: - logThis("Okay, no they don't i guess (error code 912)") - return "You don't have a user. You can make one with !swchar (error code 912)" + self.bot.log("Okay, no they don't i guess (error code 912)") + return "You don't have a user. You can make one with !starwarscharacter (error code 912)" elif string.capwords(commands[0]) in ["Ranged","Piloting"]: - logThis("They fucked up writing the name of a ranged or piloting skill") + self.bot.log("They fucked up writing the name of a ranged or piloting skill") if string.capwords(commands[0]) == "Ranged": return "Did you mean \"Ranged - Heavy\" or \"Ranged - Light\" (error code 913)" else: return "Did you mean \"Piloting - Planetary\" or \"Piloting - Space\" (error code 913)" try: - logThis("Converting commands to dice") + self.bot.log("Converting commands to dice") for x, command in enumerate(commands): if command != "": command = command.upper() @@ -361,17 +359,17 @@ class SwRoll(): else: rollParameters[x] = int(command) except: - logThis("Someone fucked u-up! (it was them) (error code 914)") + self.bot.log("Someone fucked u-up! (it was them) (error code 914)") return "Invalid input! (error code 914)" - logThis("Rolling "+str(rollParameters)) + self.bot.log("Rolling "+str(rollParameters)) rollResults, diceResults = self.roll(rollParameters[0],rollParameters[1],rollParameters[2],rollParameters[3],rollParameters[4],rollParameters[5],rollParameters[6]) simplified = self.simplify(rollResults) - name = self.bot.swchar.getCharName(user) + name = self.bot.starwarschar.getCharName(user) - logThis("Returns results and simplified results") + self.bot.log("Returns results and simplified results") if simplified == "": return name + " rolls: " + "\n" + self.diceResultToEmoji(diceResults) + "\nEverything cancels out!" diff --git a/funcs/swfuncs/__init__.py b/funcs/swfuncs/__init__.py deleted file mode 100644 index 30e7ee4..0000000 --- a/funcs/swfuncs/__init__.py +++ /dev/null @@ -1,7 +0,0 @@ -"""Functions related to the Star Wars TTRPG.""" - -__all__ = ["SwChar", "SwRoll", "SwDestiny"] - -from .swchar import SwChar -from .swroll import SwRoll -from .swdestiny import SwDestiny \ No newline at end of file diff --git a/project-guidelines.md b/project-guidelines.md index 5442fee..2befabb 100644 --- a/project-guidelines.md +++ b/project-guidelines.md @@ -31,16 +31,19 @@ There are no rules for which emoji to use where, but here's some inspiration: # Terminology Comments, strings, variable names, class names, docstrings, as well as all other text in your code, filenames and directory names should use this terminology correctly. +**bot** - The current discord client and instance of the Gwendolyn class. + **cog** - A class that contains an amount of bot commands. **ctx** - The [context](https://discordpy.readthedocs.io/en/latest/ext/commands/api.html#context) of a command. All command and error functions should use `ctx` as the context variable. -**internal** - Functions, classes and methods that are only used by the bot and don't use the Discord API. +**utils** - Functions, classes and methods that are only used by the bot and don't use the Discord API. # Code ## Code Style -+ All the Python code should follow the [PEP 8 guidelines](https://www.python.org/dev/peps/pep-0008/). +All the Python code should follow the [PEP 8 guidelines](https://www.python.org/dev/peps/pep-0008/), with the following differences: ++ Variable and function names must be camelCase, and must fully consist of either full words or common/understandable abbreviations. ### Documentation + Comment lines should not exede 72 characters. @@ -86,7 +89,7 @@ The `Command` methods in cogs should only exist to perform small tasks or call c ## Codebase Management ### Folders + `cogs/` contains the command cogs. -+ `funcs/` contains all functions and classes called on by the rest of the code. ++ `funcs/` contains all functions and classes called on to perform commands. All functions must be accessible through a class, of which the `Gwendolyn` class has an instance as an attribute. + `resources/` contains the images, lookup databases, fonts etc. that the rest of the code uses. ### Important files @@ -94,15 +97,16 @@ The `Command` methods in cogs should only exist to perform small tasks or call c ## Logging Things you should know about the logging: -+ The `logThis()` function can be found in `.funcs/miscFuncs.py. ++ `log()` is a method of the `Gwendolyn` class. + It is used to log to the log-file (`gwendolyn.log`) and print to the command line. + The function can take either a list of strings or a string as its first parameter. If the parameter is a string, it is converted to a list of 1 string. + The first string in the list is printed. All strings in the list are logged to the log-file. + If the list is longer than 1 string, `(details in log)` is added to the printed string. -+ The level parameter is 20 by default, which means the level is `INFO`. 40 corresponds to a level of `ERROR`, and 10 corresponds to a level of `DEBUG`. ++ The level parameter is 20 by default, which means the level is `INFO`. 40 corresponds to a level of `ERROR`, and 10 corresponds to a level of `DEBUG`. Only use these levels when logging. + Logs of level `DEBUG` are not printed. + Logs of level `ERROR` should only be created in the `on_command_error()` or `Command.error()` functions. ### Logging rules +1. Never call the `logThis()` function from `/utils/utilFuncs/`. Always call `bot.log`. 1. There should be at most 3 `INFO` level logs while executing a single command. This includes the log created in the `on_command()` function in `Gwendolyn.py`, so your code for a command can at most make 2 logs of level `INFO`. `DEBUG` level logs should be used for all other logging. 1. Always provide the channel id if available. Although you shouldn't pass the channel id to a function purely to use it in logs. diff --git a/resources/comic-sans-bold.ttf b/resources/fonts/comic-sans-bold.ttf similarity index 100% rename from resources/comic-sans-bold.ttf rename to resources/fonts/comic-sans-bold.ttf diff --git a/resources/futura-bold.ttf b/resources/fonts/futura-bold.ttf similarity index 100% rename from resources/futura-bold.ttf rename to resources/fonts/futura-bold.ttf diff --git a/resources/times-new-roman.ttf b/resources/fonts/times-new-roman.ttf similarity index 100% rename from resources/times-new-roman.ttf rename to resources/fonts/times-new-roman.ttf diff --git a/resources/help/help.txt b/resources/help/help.txt index bec5171..9066015 100644 --- a/resources/help/help.txt +++ b/resources/help/help.txt @@ -1,47 +1,24 @@ `!hello` - En venlig hilsen. - `!roll` - Rul terninger i xdy format. - `!spell` - Slå en besværgelse op. - `!monster` - Slå et monster op. - `!image` - Finder et tilfældigt billede fra internettet. - `!movie` - Giver titlen på en tilfældig film fra Bedre Netflix - `!name` - Genererer et tilfældigt navn. - `!tavern` - Genererer en tilfældig tavern. - `!give` - Lader dig give GwendoBucks til andre. - `!starWarsCharacter` - Lader dig lave en Star Wars karakter. - `!starWarsRoll` - Lader dig rulle Star Wars terninger. - `!balance` - Viser dig hvor mange GwendoBucks du har. - `!invest` - Lader dig investere dine GwendoBucks i aktiemarkedet. - `!blackjack` - Lader dig spille et spil blackjack. - `!trivia` - Lader dig spille et spil trivia, hvor du kan tjene GwendoBucks. - `!connectFour` - Lader dig spille et spil fire på stribe. - `!hex` - Lader dig spille et spil Hex. - `!hangman` - Lader dig spille et spil hangman. - `!wolf` - Lader dig slå ting op på Wolfram Alpha. - `!addmovie` - Lader dig tilføje film til Bedre Netflix. - `!addshow` - Lader dig tilføje tv shows til Bedre Netflix. - `!downloading` - Viser dig hvor langt de torrents der er ved at downloade er kommet. - `!thank` - Lader dig takke Gwendolyn. - Du kan få ekstra information om kommandoerne med "!help [kommando]". diff --git a/resources/slashParameters.json b/resources/slashParameters.json index 24341e7..d398d8b 100644 --- a/resources/slashParameters.json +++ b/resources/slashParameters.json @@ -27,18 +27,50 @@ "name" : "balance", "description" : "See your balance of GwendoBucks" }, - "blackjack" : { - "name" : "blackjack", - "description" : "Run a game of blackjack", + "blackjackBet" : { + "base" : "blackjack", + "name" : "bet", + "description" : "Enter the current blackjack game with a bet", "options" : [ { - "name" : "parameters", - "description" : "The parameters for the command", - "type" : 3, + "name" : "bet", + "description" : "Your bet", + "type" : 4, + "required" : "true" + } + ] + }, + "blackjackHit" : { + "base" : "blackjack", + "name" : "hit", + "description" : "Hit on your hand in blackjack", + "options" : [ + { + "name" : "hand", + "description" : "The number of the hand to hit if you've split", + "type" : 4, "required" : "false" } ] }, + "blackjackStand" : { + "base" : "blackjack", + "name" : "stand", + "description" : "Stand on your hand in blackjack", + "options" : [ + { + "name" : "hand", + "description" : "The number of the hand to stand if you've split", + "type" : 4, + "required" : "false" + } + ] + }, + "blackjackStart" : { + "base" : "blackjack", + "name" : "start", + "description" : "Start a game of blackjack" + }, "connectFourStartGwendolyn" : { "base" : "connectFour", "subcommand_group" : "start", @@ -335,7 +367,25 @@ "name" : "answer", "description" : "Your answer to the trivia question", "type" : 3, - "required" : "false" + "required" : "false", + "choices" : [ + { + "name" : "a", + "value" : "a" + }, + { + "name" : "b", + "value" : "b" + }, + { + "name" : "c", + "value" : "c" + }, + { + "name" : "d", + "value" : "d" + } + ] } ] }, diff --git a/resources/starWars/swskills.json b/resources/starWars/starwarsskills.json similarity index 100% rename from resources/starWars/swskills.json rename to resources/starWars/starwarsskills.json diff --git a/resources/starWars/swtemplates.json b/resources/starWars/starwarstemplates.json similarity index 100% rename from resources/starWars/swtemplates.json rename to resources/starWars/starwarstemplates.json diff --git a/utils/__init__.py b/utils/__init__.py index 429f6d0..4598629 100644 --- a/utils/__init__.py +++ b/utils/__init__.py @@ -1,5 +1,6 @@ """A collections of utilities used by Gwendolyn and her functions""" -__all__ = ["Options", "Credentials"] +__all__ = ["Options", "Credentials", "databaseFuncs", "getParams", "logThis", "cap", "makeFiles", "replaceMultiple", "emojiToCommand"] -from .helperClasses import Options, Credentials \ No newline at end of file +from .helperClasses import Options, Credentials, databaseFuncs +from .utilFunctions import getParams, logThis, cap, makeFiles, replaceMultiple, emojiToCommand \ No newline at end of file diff --git a/utils/helperClasses.py b/utils/helperClasses.py index 4c5f213..bc4846a 100644 --- a/utils/helperClasses.py +++ b/utils/helperClasses.py @@ -1,3 +1,4 @@ +import re, git, os, json def sanitize(data : str, options : bool = False): data = data.splitlines() @@ -19,7 +20,7 @@ def sanitize(data : str, options : bool = False): lineValues[1] = (lineValues[1] == "true") dct[lineValues[0]] = lineValues[1] - + return dct class Options(): @@ -43,4 +44,89 @@ class Credentials(): self.mongoDBPassword = data["mongodb password"] self.wolfKey = data["wolframalpha appid"] self.radarrKey = data["radarr api key"] - self.sonarrKey = data["sonarr api key"] \ No newline at end of file + self.sonarrKey = data["sonarr api key"] + +class databaseFuncs(): + def __init__(self, bot): + self.bot = bot + + def getName(self, userID): + user = self.bot.database["users"].find_one({"_id":userID}) + + if user != None: + return user["user name"] + elif userID == "Gwendolyn": + return userID + else: + self.bot.log("Couldn't find user "+userID) + return userID + + def getID(self,userName): + user = self.bot.database["users"].find_one({"user name":re.compile(userName, re.IGNORECASE)}) + + if user != None: + return user["_id"] + else: + self.bot.log("Couldn't find user "+userName) + return None + + def deleteGame(self, gameType,channel): + self.bot.database[gameType].delete_one({"_id":channel}) + + def stopServer(self): + self.bot.database["trivia questions"].delete_many({}) + self.bot.database["blackjack games"].delete_many({}) + self.bot.database["connect 4 games"].delete_many({}) + self.bot.database["hangman games"].delete_many({}) + + if not self.bot.options.testing: + g = git.cmd.Git("") + g.pull() + + def connectFourReactionTest(self,channel,message,user): + game = self.bot.database["connect 4 games"].find_one({"_id":str(channel.id)}) + + with open("resources/games/oldImages/connectFour"+str(channel.id), "r") as f: + oldImage = int(f.read()) + + if message.id == oldImage: + self.bot.log("They reacted to the connectFour game", level = 10) + turn = game["turn"] + if user == game["players"][turn]: + return True, turn+1 + else: + self.bot.log("It wasn't their turn") + return False, 0 + else: + return False, 0 + + def hangmanReactionTest(self, channel,message): + try: + with open("resources/games/oldImages/hangman"+str(channel.id), "r") as f: + oldMessages = f.read().splitlines() + except: + return False + gameMessage = False + + for oldMessage in oldMessages: + oldMessageID = int(oldMessage) + if message.id == oldMessageID: + self.bot.log("They reacted to the hangman game", level = 10) + gameMessage = True + + return gameMessage + + def bedreNetflixReactionTest(self, channel, message): + if os.path.isfile(f"resources/bedreNetflix/oldMessage{str(channel.id)}"): + with open("resources/bedreNetflix/oldMessage"+str(channel.id),"r") as f: + data = json.load(f) + else: + return False, None, None + + if data["messageID"] == message.id: + if "imdbIds" in data: + return True, True, data["imdbIds"] + else: + return True, False, data["imdbNames"] + else: + return False, None, None diff --git a/utils/utilFunctions.py b/utils/utilFunctions.py new file mode 100644 index 0000000..58a1406 --- /dev/null +++ b/utils/utilFunctions.py @@ -0,0 +1,121 @@ +import json +import time +import logging +import os +from .helperClasses import Options + +logging.basicConfig(filename="gwendolyn.log", level=logging.INFO) + +def getParams(): + with open("resources/slashParameters.json", "r") as f: + params = json.load(f) + + options = Options() + + if options.testing: + for p in params: + params[p]["guild_ids"] = options.guildIds + + return params + +def logThis(messages, channel : str = "", level : int = 20): + localtime = time.asctime(time.localtime(time.time())) + channel = channel.replace("Direct Message with ","") + if type(messages) is str: + messages = [messages] + + for x, msg in enumerate(messages): + if channel == "": + messages[x] = localtime+" - "+msg + else: + messages[x] = localtime+" ("+channel+") - "+msg + + if len(messages) > 1: + messages[0] += " (details in log)" + + if level != 10: + print(messages[0]) + + for logMessage in messages: + logging.log(level, logMessage) + +# Capitalizes all words except some of them +def cap(s): + no_caps_list = ["of","the"] + # Capitalizes a strink like a movie title + word_number = 0 + lst = s.split() + res = '' + for word in lst: + word_number += 1 + if word not in no_caps_list or word_number == 1: + word = word.capitalize() + res += word+" " + res = res[:-1] + return res + +def makeFiles(): + def makeJsonFile(path,content): + # Creates json file if it doesn't exist + if not os.path.isfile(path): + logThis(path.split("/")[-1]+" didn't exist. Making it now.") + with open(path,"w") as f: + json.dump(content,f,indent = 4) + + def makeTxtFile(path,content): + # Creates txt file if it doesn't exist + if not os.path.isfile(path): + logThis(path.split("/")[-1]+" didn't exist. Making it now.") + with open(path,"w") as f: + f.write(content) + + def directory(path): + if not os.path.isdir(path): + os.makedirs(path) + logThis("The "+path.split("/")[-1]+" directory didn't exist") + + with open("resources/startingFiles.json") as f: + data = json.load(f) + + for path, content in data["json"].items(): + makeJsonFile(path,content) + + for path, content in data["txt"].items(): + makeTxtFile(path,content) + + for path in data["folder"]: + directory(path) + +# Replaces multiple things with the same thing +def replaceMultiple(mainString, toBeReplaces, newString): + # Iterate over the strings to be replaced + for elem in toBeReplaces : + # Check if string is in the main string + if elem in mainString : + # Replace the string + mainString = mainString.replace(elem, newString) + + return mainString + +def emojiToCommand(emoji): + if emoji == "1️⃣": + return 1 + elif emoji == "2️⃣": + return 2 + elif emoji == "3️⃣": + return 3 + elif emoji == "4️⃣": + return 4 + elif emoji == "5️⃣": + return 5 + elif emoji == "6️⃣": + return 6 + elif emoji == "7️⃣": + return 7 + elif emoji == "🎲": + return "roll" + elif emoji == "❌": + return "none" + elif emoji == "✔️": + return 1 + else: return ""