Fully converted to slash commands

This commit is contained in:
NikolajDanger
2021-03-31 00:38:51 +02:00
parent a8a7e5eabd
commit b345720468
50 changed files with 1102 additions and 1111 deletions

View File

@ -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")
bot.log("Could not log in. Remember to write your bot token in the credentials.txt file")

View File

@ -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)")
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))

View File

@ -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))
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))

View File

@ -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))
def setup(bot):
bot.add_cog(LookupCog(bot))

View File

@ -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))

View File

@ -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))

View File

@ -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))
def setup(bot):
bot.add_cog(starWarsCog(bot))

View File

@ -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

View File

@ -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

View File

@ -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)")

View File

@ -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)

View File

@ -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()

View File

@ -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)

View File

@ -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))

View File

@ -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)

View File

@ -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, []

View File

@ -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)

View File

@ -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

View File

@ -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)")

View File

@ -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:

View File

@ -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"

View File

@ -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

View File

@ -1,5 +1,5 @@
"""Gwendolyn functions for looking things up."""
__all__ = ["spellFunc", "monsterFunc"]
__all__ = ["LookupFuncs"]
from .lookupFuncs import spellFunc, monsterFunc
from .lookupFuncs import LookupFuncs

View File

@ -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)

View File

@ -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 ""

View File

@ -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
from .other import Other

View File

@ -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)

View File

@ -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)

View File

@ -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","","")

View File

@ -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")

151
funcs/other/other.py Normal file
View File

@ -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()))

View File

@ -1,5 +0,0 @@
"""Rolling dice."""
__all__ = ["roll_dice"]
from .dice import roll_dice

View File

@ -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()))

View File

@ -0,0 +1,5 @@
"""Functions related to the Star Wars TTRPG."""
__all__ = ["StarWars"]
from .starWars import StarWars

View File

@ -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)

View File

@ -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

View File

@ -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":

View File

@ -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!"

View File

@ -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

View File

@ -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.

View File

@ -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]".

View File

@ -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"
}
]
}
]
},

View File

@ -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
from .helperClasses import Options, Credentials, databaseFuncs
from .utilFunctions import getParams, logThis, cap, makeFiles, replaceMultiple, emojiToCommand

View File

@ -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"]
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

121
utils/utilFunctions.py Normal file
View File

@ -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 ""