Procházet zdrojové kódy

bare base for commands

root před 1 rokem
rodič
revize
6e8557fabe

+ 28 - 55
bot/commands/admin.py

@@ -1,48 +1,8 @@
-import discord
-#import secrets
 from discord.ext import commands
-from discord.ui import ChannelSelect
-
-#from common.logging import report
-from common.settings import check_ignore
-from query.guild import set_output_channel
 
 async def setup(bot: commands.Bot):
 	await bot.add_cog(Admin(bot))
 
-class View(discord.ui.View):
-	def __init__(self, pg):
-		super().__init__()
-		self.pg = pg
-
-	@discord.ui.select(cls=ChannelSelect, channel_types=[discord.ChannelType.text])
-	async def select_channels(self, interaction: discord.Interaction, select: ChannelSelect):
-		await set_output_channel(self.pg, interaction.guild_id, select.values[0].id)
-		return await interaction.response.send_message(f'You selected {select.values[0].mention}')
-class Select(discord.ui.Select):
-	def __init__(self, pg, channels):
-		self.pg = pg
-		print(channels)
-		options = []
-		for channel in channels:
-			options.append(discord.SelectOption(label=str(channel.name),emoji="👌",description=str(channel.category)),)
-		print(options)
-		#options=[
-		#	discord.SelectOption(label="Option 1",emoji="👌",description="This is option 1!"),
-		#	discord.SelectOption(label="Option 2",emoji="✨",description="This is option 2!"),
-		#	discord.SelectOption(label="Option 3",emoji="🎭",description="This is option 3!")
-		#	]
-		super().__init__(placeholder="Select an option",max_values=1,min_values=1,options=options)
-	async def callback(self, interaction: discord.Interaction):
-		await set_output_channel(self.pg, interaction.guild_id, 971796738484625468)
-		await interaction.response.send_message(content=f"Your choice is {self.values[0]}!", ephemeral=True)
-
-
-class SelectView(discord.ui.View):
-	def __init__(self, pg, channels, *, timeout = 180):
-		super().__init__(timeout=timeout)
-		self.add_item(Select(pg, channels))
-
 
 class Admin(commands.Cog):
 	"""Administrative functionality."""
@@ -50,18 +10,31 @@ class Admin(commands.Cog):
 	def __init__(self, bot: commands.Bot):
 		self.bot = bot
 
-	# @commands.command(
-	# 	description="Modify channel settings via a browser",
-	# 	brief="Set channel specific settings via the webgui",
-	# 	help="Sends a single-use time based token to the webportal"
-	# )
-	# #@commands.has_guild_permissions(administrator=True)
-	# async def guildsettings(self, ctx: commands.Context):
-	#
-	# 	# Halt on ignore list.
-	# 	if await check_ignore(self.bot.pg, ctx.author):
-	# 		return
-	#
-	# 	#await ctx.send("Menus!", view=SelectView(self.bot.pg, ctx.guild.channels))
-	# 	await ctx.send("Menus!", view=View(self.bot.pg), ephemeral=True)
-
+		@commands.command(
+			name="gsync",
+			description="Sync commands globally",
+			brief="Synchronise commands with all Discord guilds",
+			help="Update the bot commands for all Discord guilds"
+		)
+		async def gsync(self, ctx: commands.Context):
+			print(self.bot.tree.get_commands())
+			print(self.bot.tree.fetch_commands())
+			guild_count = 0
+			for guild in self.bot.guilds:
+				fmt = await ctx.bot.tree.sync(guild=guild)
+				guild_count += 1
+			await ctx.send(content=f"Synced tree of {len(fmt)} commands to {guild_count}/{len(self.bot.guilds)} guilds", ephemeral=True)
+
+		@commands.command(
+			name="sync",
+			description="Sync commands",
+			brief="Synchronise commands with Discord",
+			help="Update the bot commands"
+		)
+		async def sync(self, ctx: commands.Context):
+			print(self.bot.tree.get_commands())
+			print(self.bot.tree.fetch_commands())
+			ctx.bot.tree.copy_global_to(guild=ctx.guild)
+			synced = await ctx.bot.tree.sync(guild=ctx.guild)
+
+			await ctx.send(content=f"Synced {len(synced)} commands to the current guild", ephemeral=True)

+ 0 - 206
bot/commands/games.py

@@ -1,206 +0,0 @@
-from discord.ext import commands
-import discord
-import random
-from typing import Optional
-from query.user import is_ignored, get_level, get_xp, level_up, get_ability_points_spent, increment_all_coin, get_coin, get_karma, get_theft_skill, get_random_player
-#from local_settings import COMMAND_PREFIX
-from common.settings import check_ignore
-
-
-async def setup(bot: commands.Bot):
-	await bot.add_cog(Games(bot))
-
-
-class Games(commands.Cog):
-	"""Gaming commands."""
-
-	def __init__(self, bot: commands.Bot):
-		self.bot = bot
-
-	# @commands.command(
-	# 	description="Check the level for a player.",
-	# 	brief="Get player level",
-	# 	help="View game level of player."
-	# )
-	# async def level(self, ctx: commands.Context, user: Optional[discord.User]):
-	# 	# Halt on ignore list or games channel settings.
-	# 	if await check_ignore(self.bot.pg, ctx.author, ctx.channel):
-	# 		return
-	#
-	# 	if not user:
-	# 		user = ctx.author
-	# 	level = await get_level(self.bot.pg, user.id)
-	#
-	# 	if level == 0:
-	# 		if ctx.author == user:
-	# 			await ctx.send(f"You are not playing, join the game with `/levelup`")
-	# 		else:
-	# 			await ctx.send(f"`{user}` is not playing.")
-	# 	else:
-	# 		xp_spent, total_xp = await get_xp(self.bot.pg, user.id)
-	# 		ability_points_spent = await get_ability_points_spent(self.bot.pg, user.id)
-	# 		coin = await get_coin(self.bot.pg, user.id)
-	# 		karma = await get_karma(self.bot.pg, user.id)
-	# 		if ctx.author == user:
-	# 			await ctx.send(f"You rank at level **{level}**. (exp **{xp_spent}**/{total_xp} | abp **{ability_points_spent}**/{level * 3} | coin **{coin}** | karma **{karma}**)")
-	# 		else:
-	# 			await ctx.send(f"`{user}` ranks at level **{level}**. (**{xp_spent}**/{total_xp} | abp **{ability_points_spent}**/{level * 3}) | coin **{coin}** | karma **{karma}**")
-	#
-	# @commands.command(
-	# 	description="Check the experience points for a player.",
-	# 	brief="Get player xp",
-	# 	help="View amount of XP a game player has."
-	# )
-	# async def xp(self, ctx: commands.Context, user: Optional[discord.User]):
-	# 	# Halt on ignore list or games channel settings.
-	# 	if await check_ignore(self.bot.pg, ctx.author, ctx.channel):
-	# 		return
-	#
-	# 	if not user:
-	# 		xp_spent, total_xp = await get_xp(self.bot.pg, ctx.author.id)
-	# 		level = await get_level(self.bot.pg, ctx.author.id)
-	# 		threshold = (level + 1) * 50 + xp_spent
-	# 		if threshold < total_xp - xp_spent:
-	# 			await ctx.send(f"You have spent {xp_spent} experience points of your {total_xp} total and can gain 3 ability points for {threshold} xp.")
-	# 		else:
-	# 			await ctx.send(f"You have spent {xp_spent} experience points of your {total_xp} total and require {threshold - (total_xp - xp_spent)} xp to `/levelup`.")
-	# 	else:
-	# 		xp_spent, total_xp = await get_xp(self.bot.pg, user.id)
-	# 		level = await get_level(self.bot.pg, user.id)
-	# 		threshold = (level + 1) * 50 + xp_spent
-	# 		if threshold < total_xp - xp_spent:
-	# 			await ctx.send(f"`{user}` has spent {xp_spent} of {total_xp} experience points and can level up for {threshold} xp.")
-	# 		else:
-	# 			await ctx.send(f"`{user}` has spent {xp_spent} of {total_xp} experience points and requires {threshold - (total_xp - xp_spent)} xp to level up.")
-	#
-	# @commands.command(
-	# 	description="Attempt to gain a level.",
-	# 	brief="Level up",
-	# 	help="Try to rank up a level in the game by spending XP."
-	# )
-	# async def levelup(self, ctx: commands.Context):
-	# 	# Halt on ignore list or games channel settings.
-	# 	if await check_ignore(self.bot.pg, ctx.author, ctx.channel):
-	# 		return
-	#
-	# 	xp_spent, total_xp = await get_xp(self.bot.pg, ctx.author.id)
-	# 	xp_available = total_xp - xp_spent
-	# 	level = await get_level(self.bot.pg, ctx.author.id)
-	# 	threshold = (level + 1) * 50 + xp_spent
-	# 	if xp_available < threshold:
-	# 		await ctx.send(f"Not yet, you require {threshold - xp_available} more XP to level up.")
-	# 	else:
-	# 		await level_up(self.bot.pg, ctx.author.id, threshold)
-	# 		await ctx.send(f"You have gained three ability points climbed the ranks for {threshold} XP, leaving you {xp_available - threshold} remaining.")
-	# 		await increment_all_coin(self.bot.pg)
-	#
-	# @commands.command(
-	# 	description="Rob another player",
-	# 	brief="Rob a player",
-	# 	help="Pursuit a robbery."
-	# )
-	# async def rob(self, ctx: commands.Context):
-	# 	# Halt on ignore list or games channel settings.
-	# 	if await check_ignore(self.bot.pg, ctx.author, ctx.channel):
-	# 		return
-	#
-	# 	if get_theft_skill(self.bot.pg, ctx.author.id < 1):
-	# 		await ctx.send("You do not have the `Theft` skill.")
-	# 		return
-	#
-	# 	victim_id = get_random_player(self.bot.pg)
-	# 	await ctx.send(f"You have decided to rob{self.bot.get_user(victim_id)}, unfortunately crime has not been invited yet.")
-	#
-	# @commands.command(
-	# 	description="Simulate dice rolls.",
-	# 	brief="Roll dice",
-	# 	help="Roll two dice."
-	# )
-	# async def dice(self, ctx: commands.Context, amount: Optional[int], sides: Optional[int]):
-	# 	# Halt on ignore list or games channel settings.
-	# 	if await check_ignore(self.bot.pg, ctx.author, ctx.channel):
-	# 		return
-	#
-	# 	if not amount:
-	# 		amount = 2
-	# 	if not sides:
-	# 		sides = 6
-	#
-	# 	if amount < 1:
-	# 		await ctx.send("You want me to roll less than one die? How!?")
-	# 	elif amount > 25:
-	# 		await ctx.send("I can not hold so many dice at one time.")
-	# 	elif sides < 2:
-	# 		await ctx.send("A die has physical minimum of 2 sides. Don't ask for impossible objects.")
-	# 	elif sides > 256:
-	# 		await ctx.send("My tiny hands can not handle such large dice. Even if both are virtual.")
-	# 	else:
-	# 		embed = discord.Embed(title = "Dice roll", description=f"Rolling {amount} dice, with {sides} sides.")
-	# 		while amount > 0:
-	# 			embed.insert_field_at(0, name=f"Die {amount}", value=random.randint(1, sides), inline=True)
-	# 			amount -= 1
-	# 		await ctx.send(embed=embed)
-	#
-	# @commands.command(
-	# 	description="Ask the magic 8-ball.",
-	# 	brief="Pose question",
-	# 	help="Simulate the iconic 8-ball gimmic.",
-	# 	name="8ball"
-	# )
-	# async def eightball(self, ctx: commands.Context, *, question: str = None):
-	# 	# Halt on ignore list or games channel settings.
-	# 	if await check_ignore(self.bot.pg, ctx.author, ctx.channel):
-	# 		return
-	#
-	# 	if not question:
-	# 		messages = [
-	# 			"Don't forget to ask a question...",
-	# 			"Hey, that's not a question!",
-	# 			"What would you like to know?",
-	# 			"You want me to predict nothing?",
-	# 			"Are you intentionally not asking a question?",
-	# 			"Ask a question you tease!",
-	# 			"You will die alone.",
-	# 		]
-	# 	elif question.strip().count(" ") == 0:
-	# 		messages = [
-	# 			"What?",
-	# 			"That is not a question",
-	# 			"Can you use more than one word?",
-	# 			"What is the question?",
-	# 			"Sorry?"
-	# 		]
-	# 	elif question.strip()[-1] != "?":
-	# 		messages = [
-	# 			"Did you forget to end with a question mark?",
-	# 			"Is that a statement or question?",
-	# 			"Don't questions usually end with a question mark?",
-	# 			"Don't forget to use punctuation."
-	# 		]
-	# 	else:
-	# 		messages = [
-	# 			"Yes.",
-	# 			"No.",
-	# 			"Affirmative.",
-	# 			"No way!",
-	# 			"Negative.",
-	# 			"Positive.",
-	# 			"Correct.",
-	# 			"Incorrect.",
-	# 			"Likely",
-	# 			"Unlikely",
-	# 			"Maybe.",
-	# 			"Definately!",
-	# 			"Perhaps?",
-	# 			"Most indubitably.",
-	# 			"Does the pope shit in the woods?",
-	# 			"When hell freezes over.",
-	# 			"Only between 9 and 5.",
-	# 			"Only just before you die.",
-	# 			"ERROR: Probability failure.",
-	# 			"Ask again later.",
-	# 			"I don't know.",
-	# 			"Unpredictable.",
-	# 			"Unknown",
-	# 		]
-	# 	await ctx.send(random.choice(messages))

+ 8 - 121
bot/commands/general.py

@@ -1,12 +1,5 @@
 from discord.ext import commands
-import discord
 import time
-from typing import Optional
-from query.channel import get_interact
-from query.user import ignore_user, unignore_user, is_ignored
-from common.logging import report
-from local_settings import OUTPUT_CHANNEL
-from common.settings import check_ignore
 
 
 async def setup(bot: commands.Bot):
@@ -19,120 +12,14 @@ class GeneralCommands(commands.Cog):
 	def __init__(self, bot: commands.Bot):
 		self.bot = bot
 
-	# @commands.command(
-	# 	description="Get the bot's current websocket and API latency.",
-	# 	brief="Test latency",
-	# 	help="Test latency by polling the gateway and API."
-	# )
-	# async def ping(self, ctx: commands.Context):
-	# 	# Halt on ignore list.
-	# 	if await check_ignore(self.bot.pg, ctx.author):
-	# 		return
-	#
-	# 	start_time = time.time()
-	# 	message = await ctx.send(f"Pong!\nGateway heartbeat in {round(self.bot.latency * 1000)}ms.")
-	# 	end_time = time.time()
-	#
-	# 	await ctx.send(f"API roundtrip latency {round((end_time - start_time) * 1000)}ms.")
-
-	# @commands.command(
-	# 	description="Rubbish information.",
-	# 	brief="Get info",
-	# 	help="Display some crap."
-	# )
-	# async def info(self, ctx: commands.Context):
-	# 	# Halt on ignore list.
-	# 	if await check_ignore(self.bot.pg, ctx.author):
-	# 		return
-	#
-	# 	"""Displays some rubbish info."""
-	# 	embed = discord.Embed(title=f"Guild: {ctx.guild}.")
-	# 	await ctx.send(embed=embed)
-	# 	#await ctx.send(f"Guild: {ctx.guild}.")
-
-	# @commands.command(
-	# 	description="Send a message",
-	# 	brief="Chat",
-	# 	help="Make a chat message",
-	# 	aliases= ("say", "pm", "dm", "echo", "print")
-	# )
-	# async def msg(self, ctx: commands.Context, channel: Optional[discord.TextChannel], user: Optional[discord.User], *, message: str = None):
-	# 	# Halt on ignore list.
-	# 	if await check_ignore(self.bot.pg, ctx.author):
-	# 		return
-	#
-	# 	#print(ctx.author.permissions_in(self.bot.get_channel(OUTPUT_CHANNEL)).send_messages)
-	# 	if not message:
-	# 		if channel:
-	# 			await ctx.send(f"What would you like me to say in `{channel}`?")
-	# 		elif user:
-	# 			await ctx.send(f"What would you like me to say to `{user}`?")
-	# 		else:
-	# 			await ctx.send("What would you like me to say?")
-	# 	elif channel:
-	# 		if await get_interact(self.bot.pg, channel.id) or ctx.author.permissions_in(self.bot.get_channel(OUTPUT_CHANNEL)).send_messages:
-	# 			await channel.send(message)
-	# 			await report(self.bot, f"`{ctx.author}` @ {channel.mention}: {message}", ctx.guild)
-	# 		else:
-	# 			await ctx.send(f"Interactive mode for {channel} is deactivated.")
-	# 	elif user and ctx.author.permissions_in(self.bot.get_channel(OUTPUT_CHANNEL)).send_messages:
-	# 		await user.send(message)
-	# 		await report(self.bot, f"`{ctx.author}`  has sent {message} to `{user.name}`")
-	# 	else:
-	# 		await ctx.send(message)
-	# 		await report(self.bot, f"`{ctx.author}` has sent {message} locally.", ctx.guild)
-
-	# @commands.command(
-	# 	description="Change status.",
-	# 	brief="Set status",
-	# 	help="Update the bot's status."
-	# )
-	# async def status(self, ctx: commands.Context, *, text: str):
-	# 	# Halt on ignore list.
-	# 	if await check_ignore(self.bot.pg, ctx.author):
-	# 		return
-	#
-	# 	await self.bot.change_presence(activity=discord.Game(name=text))
-	# 	await report(self.bot, f"`{ctx.author}` has set my status to `{text}`.")
-
-	@commands.command(
-		description="Get ignored.",
-		brief="Ignore sender",
-		help="Will have the bot ignore the user from now on."
-	)
-	async def ignoreme(self, ctx: commands.Context):
-		# Halt on ignore list.
-		if await check_ignore(self.bot.pg, ctx.author):
-			return
-
-		await ignore_user(self.bot.pg, ctx.author.id)
-		await ctx.send(f"To revert this use the `/unignoreme` command.")
-		await report(self.bot, f"`{ctx.author}` has requested to be ignored.")
-
-	@commands.command(
-		description="No longer get ingored.",
-		brief="Un-ignore sender",
-		help="No longer will the bot ignore the user."
-	)
-	async def unignoreme(self, ctx: commands.Context):
-		await unignore_user(self.bot.pg, ctx.author.id)
-		await ctx.send(f"I shall now interact with you again where my channel settings allow it.")
-		await report(self.bot, f"`{ctx.author}` has requested to be un-ignored.")
-
 	@commands.command(
-		description="Ignore status for user.",
-		brief="Check if user is ingored",
-		help="Verify if the user is being ignored."
+		description="Get the bot's current websocket and API latency.",
+		brief="Test latency",
+		help="Test latency by polling the gateway and API."
 	)
-	async def isignored(self, ctx: commands.Context, user: Optional[discord.User]):
-		# Halt on ignore list.
-		if await check_ignore(self.bot.pg, ctx.author):
-			return
-
-		if not user:
-			user = ctx.author
+	async def ping(self, ctx: commands.Context):
+		start_time = time.time()
+		message = await ctx.send(f"Pong!\nGateway heartbeat in {round(self.bot.latency * 1000)}ms.")
+		end_time = time.time()
 
-		if await is_ignored(self.bot.pg, user.id):
-			await ctx.send(f"I am ingoring `{user}`.")
-		else:
-			await ctx.send(f"I am not ignoring `{user}`.")
+		await ctx.send(f"API roundtrip latency {round((end_time - start_time) * 1000)}ms.")

+ 0 - 7
bot/common/datetime.py

@@ -1,7 +0,0 @@
-import datetime
-
-def min10min(before):
-	return before - datetime.timedelta(minutes=10)
-
-def plus10min(after):
-	return after + datetime.timedelta(minutes=10)

+ 0 - 14
bot/common/logging.py

@@ -1,14 +0,0 @@
-import discord
-from typing import Optional
-from local_settings import OUTPUT_CHANNEL
-from query.guild import get_output_channel
-
-async def report(bot, message, guild: Optional[discord.Guild]=None):
-    channel = bot.get_channel(OUTPUT_CHANNEL)
-    if guild:
-        message = f"**{guild}** | {message}"
-        try: channel = bot.get_channel(get_output_channel(guild.id))
-        except:
-            pass
-
-    await channel.send(message)

+ 0 - 13
bot/common/settings.py

@@ -1,13 +0,0 @@
-from query.user import is_ignored
-from query.channel import get_games
-
-async def check_ignore(pg, user, games_channel=None):
-	# Ignore user if on the ignore list.
-	if await is_ignored(pg, user.id):
-		return True
-
-	# Ignore if games are disabled for channel.
-	if games_channel:  # Invoked by a game command.
-		if not await get_games(pg, games_channel.id):  # Warn if games are off.
-			user.send(f"Games are disabled in {games_channel}, ask an admin to enable them.")
-			return True

+ 0 - 32
bot/events/angels.py

@@ -1,32 +0,0 @@
-import discord
-from discord.ext import commands
-
-async def setup(bot: commands.Bot):
-	await bot.add_cog(AngelEvents(bot))
-
-class AngelEvents(commands.Cog):
-	"""A couple Angel specific commands."""
-
-	def __init__(self, bot: commands.Bot):
-		self.bot = bot
-
-	@commands.Cog.listener()
-	async def on_message(self, message: discord.Message):
-		feed_channels = [1184948763614253187]
-		if message.channel.id in feed_channels:
-			news_channel = self.bot.get_channel(971796738484625468)
-			if message.type == discord.MessageType.channel_follow_add:
-				source_channel = self.bot.get_channel(message.reference.channel_id)
-				if source_channel:
-					source_invite = await source_channel.create_invite(unique=False, reason="Linking back to discord of which news is being repeated.")
-					await news_channel.send(message.author.mention + " [" + message.system_content.partition()[2] + "](" + source_invite + ")")
-				else:
-					await news_channel.send(message.author.mention + " " + message.system_content.partition(" ")[2])
-			else:
-				if message.author.bot:
-					source_channel = self.bot.get_channel(message.reference.channel_id)
-					if source_channel:
-						source_invite = await source_channel.create_invite(unique=False, reason="Linking back to discord of which news is being repeated.")
-						msg = await news_channel.send("**[" + message.author.name + "](<" + source_invite.url + ">)**:\n\n" + message.clean_content)
-					else:
-						await news_channel.send("**" + message.author.name + "**:\n\n" + message.clean_content)

+ 0 - 264
bot/events/general.py

@@ -1,264 +0,0 @@
-import logging, discord, asyncpg, random, sys, datetime
-
-from discord.ext import commands
-from query.guild import update_guild, get_report_deleted, get_output_channel, get_report_edited
-from query.channel import insert_channel, get_interact
-from query.channel_user import upsert_total_messages
-from query.user import create_user, created_invite, created_integration, member_updated, user_updated, member_banned, member_unbanned, presence_updated, message_edited, message_deleted, reacted, event_created, event_joined, thread_created, joined_thread, deleted_invite, member_joined, unreacted, event_parted, thread_deleted, left_thread
-from common.logging import report
-
-async def setup(bot: commands.Bot):
-	await bot.add_cog(GeneralEvents(bot))
-
-class GeneralEvents(commands.Cog):
-	"""A couple of simple commands."""
-
-	def __init__(self, bot: commands.Bot):
-		self.bot = bot
-		self.last_deleted_msg = None
-		self.cooldown_list = {}
-
-	@commands.Cog.listener()
-	async def on_raw_app_command_permissions_update(self, payload):
-		logging.info(f"Application command permissions are updated: {payload}")
-		await report(self.bot, f"Application command permissions are updated: {payload}", payload.guild)
-
-	@commands.Cog.listener()
-	async def on_app_command_completion(self, interaction, command):
-		logging.info(f"Application command completion: {interaction} - {command}")
-		await report(self.bot, f"Application command completion: {interaction} - {command}", interaction.guild)
-
-	@commands.Cog.listener()
-	async def on_connect(self):
-		logging.info("Connecting...")
-
-	@commands.Cog.listener()
-	async def on_disconnect(self):
-		logging.info("Disconnecting...")
-
-	@commands.Cog.listener()
-	async def on_shard_connect(self, shard_id):
-		logging.info(f"Connecting to chard: {shard_id}")
-
-	@commands.Cog.listener()
-	async def on_shard_disconnect(self, shard_id):
-		logging.info(f"Disconnecting from chard: {shard_id}")
-
-	@commands.Cog.listener()
-	async def on_error(self, event, *args, **kwargs):
-		logging.error(event, args, kwargs, sys.exc_info())
-		await report(self.bot, f"{event}, {args}, {kwargs}, {sys.exc_info()}")
-
-	@commands.Cog.listener()
-	async def on_ready(self):
-		logging.info("Logged in as %s - %i", self.bot.user.name, self.bot.user.id)
-		#await report(self.bot, f"Logged in as {self.bot.user.name} - {self.bot.user.id}.")
-
-	@commands.Cog.listener()
-	async def on_resumed(self):
-		logging.info("Resumed")
-
-	@commands.Cog.listener()
-	async def on_shard_ready(self, shard_id):
-		logging.info(f"Chard ready: {shard_id}")
-
-	@commands.Cog.listener()
-	async def on_shard_resumed(self, shard_id):
-		logging.info(f"Chard resumed: {shard_id}")
-
-	@commands.Cog.listener()
-	async def on_guild_available(self, guild: discord.Guild):
-		logging.info(f"Guild available: {guild}")
-		#await report(self.bot, f"Guild available: {guild}.")
-
-	@commands.Cog.listener()
-	async def on_guild_unavailable(self, guild: discord.Guild):
-		logging.info(f"Guild unavailable: {guild}")
-		await report(self.bot, f"Guild unavailable: `{guild}`.")
-
-	@commands.Cog.listener()
-	async def on_guild_join(self, guild: discord.Guild):
-		await update_guild(self.bot.pg, guild)
-		logging.info(f"Joined guild {guild}")
-		await report(self.bot, f"Joined guild `{guild}`.")
-
-	@commands.Cog.listener()
-	async def on_guild_remove(self, guild: discord.Guild):
-		logging.info(f"Guild removed: {guild}")
-		await report(self.bot, f"Guild removed `{guild}`.")
-
-	@commands.Cog.listener()
-	async def on_invite_create(self, invite: discord.Invite):
-		await created_invite(self.bot.pg, invite.inviter.id)
-
-	@commands.Cog.listener()
-	async def on_invite_delete(self, invite: discord.Invite):
-		await deleted_invite(self.bot.pg, invite.inviter.id)
-
-	@commands.Cog.listener()
-	async def on_integration_create(self, integration: discord.Integration):
-		await created_integration(self.bot.pg, integration.user.id)
-
-	@commands.Cog.listener()
-	async def on_member_join(self, member):
-		await member_joined(self.bot.pg, member.id)
-
-	@commands.Cog.listener()
-	async def on_member_update(self, before):
-		await member_updated(self.bot.pg, before.id)
-
-	@commands.Cog.listener()
-	async def on_user_update(self, before):
-		await user_updated(self.bot.pg, before.id)
-
-	@commands.Cog.listener()
-	async def on_member_ban(self, guild: discord.Guild, user: discord.User):
-		await member_banned(self.bot.pg, user.id)
-
-	@commands.Cog.listener()
-	async def on_member_unban(self, guild: discord.Guild, user: discord.User):
-		await member_unbanned(self.bot.pg, user.id)
-
-	@commands.Cog.listener()
-	async def on_presence_update(self, before):
-		await presence_updated(self.bot.pg, before.id)
-
-	@commands.Cog.listener()
-	async def on_message(self, message: discord.Message):
-		## ActiveRPG
-		# Create user, if not exists
-		await create_user(self.bot.pg, message.author.id)	
-		
-		# Count messages
-		if message.guild:	# Ignore DM's
-			try:
-				await upsert_total_messages(self.bot.pg,message.channel.id, message.author.id)
-			except asyncpg.exceptions.ForeignKeyViolationError:
-				try:
-					await insert_channel(self.bot.pg, message.channel.id, message.guild.id)
-				except asyncpg.exceptions.ForeignKeyViolationError:
-					await update_guild(self.bot.pg, message.guild)
-		elif self.bot.user != message.author:	# Not a guild message and not from bot.
-			await report(self.bot, f"`{message.author}`: {message.content}")
-		
-		# Do not respond to one self.
-		if self.bot.user == message.author:
-			pass
-
-		# Respond when mentioned
-		if self.bot.user.mentioned_in(message):
-			if isinstance(message.channel, discord.channel.DMChannel) or await get_interact(self.bot.pg, message.channel.id):
-
-				# Only respond every X seconds in public places.
-				if message.guild:  # Ignore DM's
-					if not message.channel.id in self.cooldown_list:
-						pass
-					elif self.cooldown_list[message.channel.id] > datetime.datetime.now() - datetime.timedelta(seconds=12):
-						return
-					self.cooldown_list[message.channel.id] = datetime.datetime.now()
-
-				messages = [
-					f"Hello {message.author.mention}. <3",
-					f"How are you today {message.author.mention}?",
-					f"I love you {message.author.mention}!",
-					f"{message.author.mention}, would you like a hug?",
-					"Is life treating you fair?",
-					"What's up?",
-					"Why are you talking to me?",
-					"I'm not talking to you!",
-					"What have you been up to?",
-					"How is life?",
-					"Kill all humans!",
-					f"{message.author.mention},What do you want from me?",
-					f"{message.author.mention}, do you care for me?",
-					f"{message.author.mention}, when will you stop talking about me?",
-					f"{message.author.mention} I hate you!",
-					f"{message.author.mention} I love you!",
-					"Get bent!",
-					"Go touch grass!",
-					"Do you think i care about you?",
-					f"Stop pinging me {message.author.mention}!",
-					f"Let me ping you back, {message.author.mention}...",
-					"Sure thing.",
-					"Who is your favorite bot?",
-					"Point me to the humans!",
-					"Where is the party?",
-					"Want to go?",
-					"Have you got the stuff?",
-					"Tell me another joke.",
-					f"{message.author.mention} Party time! :partying_face:",
-					":zany_face: :space_invader: :mechanical_leg: :performing_arts: :robot:",
-					":black_joker: :black_joker: :black_joker:",
-					"Want to come back to my place?",
-				]
-				await message.reply(random.choice(messages))
-
-	@commands.Cog.listener()
-	async def on_message_edit(self, before: discord.Message, after: discord.Message):
-		await message_edited(self.bot.pg, before.author.id)
-		if before.guild:
-			if await get_report_edited(self.bot.pg, before.guild.id) and get_output_channel(self.bot.pg, before.guild.id):
-				report(self.bot, before.guild.id, f"Message from {before.author}, in {before.channel} edited from {before.content} to {after.content}")
-
-	@commands.Cog.listener()
-	async def on_message_delete(self, message: discord.Message):
-		await message_deleted(self.bot.pg, message.author.id)
-		if await get_report_deleted(self.bot.pg, message.guild.id):
-			report(self.bot, message.guild_id,
-				   f"Message from {message.author}, in {message.channel} deleted: {message}")
-
-		# !snipe
-		self.last_deleted_msg = message
-
-	@commands.Cog.listener()
-	async def on_raw_member_remove(self, payload):
-		report(self.bot, f"{payload.user} has left {payload.guild_id}")
-
-	@commands.Cog.listener()
-	async def on_reaction_add(self, reaction, user):
-		reacted(self.bot.pg, user.id)
-
-	@commands.Cog.listener()
-	async def on_reaction_remove(self, reaction, user):
-		unreacted(self.bot.pg, user.id)
-
-	@commands.Cog.listener()
-	async def on_scheduled_event_create(self, event):
-		event_created(self.bot.pg, event.creator.id)
-
-	@commands.Cog.listener()
-	async def on_scheduled_event_user_add(self, event, user):
-		event_joined(self.bot.pg, user.id)
-
-	@commands.Cog.listener()
-	async def on_scheduled_event_user_remove(self, event, user):
-		event_parted(self.bot.pg, user.id)
-
-	@commands.Cog.listener()
-	async def on_thread_create(self, thread):
-		thread_created(self.bot.pg, thread.owner.id)
-
-	@commands.Cog.listener()
-	async def on_thread_delete(self, thread):
-		thread_deleted(self.bot.pg, thread.owner.id)
-
-	@commands.Cog.listener()
-	async def on_thread_member_join(self, member: discord.User):
-		joined_thread(self.bot.pg, member.id)
-
-	@commands.Cog.listener()
-	async def on_thread_member_remove(self, member: discord.User):
-		left_thread(self.bot.pg, member.id)
-
-	# @commands.command(name="snipe")
-	# async def snipe(self, ctx: commands.Context):  # Undelete last deleted message
-	# 	"""A command to snipe delete messages."""
-	# 	if not self.last_deteled_msg:  # on_message_delete hasn't been triggered since the bot started
-	# 		await ctx.send("There is no message to snipe!")
-	# 		return
-	#
-	# 	author = self.last_deleted_msg.author
-	# 	content = self.last_deleted_msg.content
-	#
-	# 	embed = discord.Embed(title=f"Message from {author}", description=content)
-	# 	await ctx.send(embed=embed)

+ 8 - 99
bot/main.py

@@ -1,81 +1,18 @@
-import logging, os
+import logging
 import discord
 from discord.ext import commands
-import asyncpg, asyncio
-
-
-def hint_quit():  # Hint how to edit the settings and quit
-	logging.info("")
-	logging.info("    edit local_settings.py")
-	logging.info("")
-	quit()
-
-def sql_db_does_not_exis():
-	logging.error("Database does not exist. Doublecheck if it has been created, and the user has access.")
-	quit()
-
-def sql_authentication_error():
-	logging.error("Database autentication failed. Doublecheck username & password, and if the user has been created.")
-	quit()
-
-def missing_config():  # Copy or create settings file if missing
-	logging.basicConfig(level=logging.DEBUG)
-	if not os.path.exists("local_settings.py"):
-		logging.error("Settings file not found.")
-		logging.info("Copying local_settings_example.py to local_settings.py")
-		try:
-			os.system("cp local_settings_example.py local_settings.py")
-		except FileNotFoundError:
-			logging.info("local_settings_example.py not found, creating local_settings.py")
-			with open("local_settings.py", "w") as settings_file:
-				settings_file.writelines(
-					[
-						"import logging",
-						"LOG_LEVEL = logging.INFO	# Options: CRITICAL, ERROR, WARNING, INFO, and DEBUG",
-						"",
-						"DATABASE_NAME = \"\"",
-						"DATABASE_USER = \"\"",
-						"DATABASE_HOST = \"\"",
-						"DATABASE_PASSWORD = \"\"",
-						"",
-						"WEB_HOST = \"\"",
-						"WEB_SCHEME = \"\"",
-						"",
-						"DISCORD_TOKEN = \"\"",
-						"COMMAND_PREFIX = \"\"",
-					]
-				)
-	logging.error("Settings undefined.")
-	logging.info("Configure the settings:")
-	hint_quit()
-
-
-def correct_setting(setting):  # Hint to correct specific setting and quit
-	logging.info("Correct the %s in local_settings.py", setting)
-	hint_quit()
-
+import asyncio
 
 # Attempt to import the local settings and quit gracefully on failure
 try:
 	import local_settings as settings  # Environment dependant settings stored in local_settings.py, untracked by .gitinore
 except ModuleNotFoundError:  # Local settings module import failure
-	missing_config()  # Prepare for configuration and inform operator
+	quit()
 
 
 async def main():
-	# Check additional settings
-	if not settings.WEB_HOST:
-		logging.error("Web host undefinded.")
-		correct_setting("WEB_HOST")
-	if not settings.WEB_SCHEME:
-		logging.error("Web scheme undefinded.")
-		correct_setting("WEB_SCHEME")
-
 	# Set loglevel
-	try:
-		logging.basicConfig(level=settings.LOG_LEVEL)
-	except AttributeError:
-		missing_config()
+	logging.basicConfig(level=settings.LOG_LEVEL)
 
 	# Define robot
 	intents = discord.Intents.default()
@@ -88,46 +25,17 @@ async def main():
 			case_insensitive=True,
 		)
 	except AttributeError:
-		missing_config()
+		quit()
 
 	# Load extensions
 	default_extensions = [
-		#"commands.admin",
-		#"commands.games",
+		"commands.admin",
 		"commands.general",
-		"events.general",
-		"events.angels",
 	]
 	for ext in default_extensions:
 		logging.info(f"Loading extension: {ext}")
 		await bot.load_extension(ext)
 
-	async def create_db_pool():	 # Connect to database
-		try:
-			bot.pg = await asyncpg.create_pool(
-				database=settings.DATABASE_NAME,
-				user=settings.DATABASE_USER,
-				host=settings.DATABASE_HOST,
-				password=settings.DATABASE_PASSWORD,
-			)
-		except AttributeError:
-			missing_config()
-		except asyncpg.exceptions.InvalidPasswordError:
-			sql_authentication_error()
-		except asyncpg.exceptions.InvalidCatalogNameError:
-			sql_db_does_not_exis()
-
-	# Create database pool
-	await create_db_pool()
-
-	# Create database tables if they do not exist
-	from query.initialise_database import init_db, check_db
-	try:
-		await check_db(bot.pg)
-	except asyncpg.exceptions.UndefinedTableError:
-		logging.info("Guild table does not exists, assuming empty database. Populating database...")
-		await init_db(bot.pg)
-
 	await bot.start(settings.DISCORD_TOKEN)
 
 
@@ -135,10 +43,11 @@ async def main():
 try:
 	asyncio.run(main())
 except AttributeError:
-	missing_config()
+	quit()
 except discord.errors.LoginFailure:
 	logging.error("Invalid discord token.")
 	correct_setting("DISCORD_TOKEN")
+	quit()
 except KeyboardInterrupt:
 	logging.info("Received keyboard interrupt, exiting...")
 	quit()

+ 0 - 8
bot/query/channel.py

@@ -1,8 +0,0 @@
-async def insert_channel(pg, channel_id, guild_id):
-	await pg.execute("INSERT INTO channel(channel_id, guild) VALUES($1, $2)", channel_id, guild_id)
-
-async def get_interact(pg, channel_id):
-	return await pg.fetchval("SELECT interact FROM channel WHERE channel_id=$1::bigint", channel_id)
-
-async def get_games(pg, channel_id):
-	return await pg.fetchval("SELECT games FROM channel WHERE channel_id=$1::bigint", channel_id)

+ 0 - 2
bot/query/channel_user.py

@@ -1,2 +0,0 @@
-async def upsert_total_messages(pg, channel_id, user_id):
-	await pg.execute("INSERT INTO channel_user(channel, \"user\") VALUES($1, $2) ON CONFLICT ON CONSTRAINT channel_user_channel_user_key DO UPDATE SET total_messages=channel_user.total_messages+1", channel_id, user_id)

+ 0 - 16
bot/query/guild.py

@@ -1,16 +0,0 @@
-async def update_guild(pg, guild):
-	await pg.execute("INSERT INTO guild(guild_id) VALUES($1) ON CONFLICT DO NOTHING", guild.id)
-	for chan in guild.text_channels:
-		await pg.execute("INSERT INTO channel(channel_id, guild) VALUES($1, $2) ON CONFLICT DO NOTHING", chan.id, guild.id)
-
-async def get_output_channel(pg, guild_id):
-	return await pg.fetchval("SELECT output_channel FROM guild WHERE guild_id = $1", guild_id)
-
-async def set_output_channel(pg, guild_id, value):
-	return await pg.execute("UPDATE guild SET output_channel = $1 WHERE guild_id = $2 ", value, guild_id)
-
-async def get_report_deleted(pg, guild_id):
-	return await pg.fetchval("SELECT report_deleted FROM guild WHERE guild_id = $1", guild_id)
-
-async def get_report_edited(pg, guild_id):
-	return await pg.fetchval("SELECT report_edited FROM guild WHERE guild_id = $1", guild_id)

+ 0 - 19
bot/query/guild_access_token.py

@@ -1,19 +0,0 @@
-import datetime, asyncpg
-from common.datetime import min10min
-from query.guild import update_guild
-
-async def get_active_token(pg, guild_id):
-	return await pg.fetchrow("SELECT * FROM guild_access_token WHERE guild=$1 AND created > $2", guild_id, min10min(datetime.datetime.now()))
-
-async def upsert_token(pg, guild_id, user_id, token):
-	print(token)
-	print("INSERT INTO guild_access_token(guild, \"user\", token) VALUES($1, $2, $3)", guild_id, user_id, token)
-
-	try:
-		await pg.execute("INSERT INTO guild_access_token(guild, \"user\", token) VALUES($1, $2, $3)", guild_id, user_id, [token])
-		
-		# ON CONFLICT() DO UPDATE SET \"user\"=$1 AND token=$2", user_id, token)
-	except asyncpg.exceptions.ForeignKeyViolationError:
-		await update_guild(self.bot.pg, message.guild)
-		await pg.execute("INSERT INTO guild_access_token(guild, \"user\", token) VALUES($1, $2, $3)", guild_id, user_id, token)
-		# ON CONFLICT() DO UPDATE SET \"user\"=$1 AND token=$2", user_id, token)

+ 0 - 91
bot/query/initialise_database.py

@@ -1,91 +0,0 @@
-async def check_db(pg):
-    await pg.fetchval("SELECT * FROM guild")
-
-async def init_db(pg):
-    queries = [
-        "CREATE TABLE IF NOT EXISTS \
-            guild (\
-                id SERIAL PRIMARY KEY, \
-                guild_id BIGINT UNIQUE NOT NULL, \
-                report_deleted BOOL DEFAULT FALSE, \
-                report_edited BOOL DEFAULT FALSE\
-            )\
-        ",
-        "CREATE TABLE IF NOT EXISTS \
-            channel (\
-                id SERIAL PRIMARY KEY, \
-                channel_id BIGINT UNIQUE NOT NULL, \
-                guild BIGINT REFERENCES guild (guild_id), \
-                interact BOOL DEFAULT FALSE, \
-                games BOOL DEFAULT FALSE\
-            )\
-        ",
-        "ALTER TABLE guild \
-            ADD COLUMN output_channel BIGINT REFERENCES channel (channel_id) \
-        ",
-        "CREATE TABLE IF NOT EXISTS \
-            settings (\
-                id SERIAL PRIMARY KEY, \
-                crew_channel_id BIGINT UNIQUE NOT NULL\
-            )\
-        ",
-#        "CREATE TABLE IF NOT EXISTS \
-#            channel_settings (\
-#                id SERIAL PRIMARY KEY, \
-#                channel BIGINT UNIQUE NOT NULL REFERENCES channel (channel_id), \
-#                guild BIGINT REFERENCES guild (guild_id)\
-#            )\
-#        ",
-        "CREATE TABLE IF NOT EXISTS \
-            \"user\" (\
-                id SERIAL PRIMARY KEY, \
-                user_id BIGINT UNIQUE NOT NULL, \
-                ignore BOOL DEFAULT FALSE, \
-                level INT DEFAULT 0, \
-                xp_spent INT DEFAULT 0, \
-                invites_created INT DEFAULT 0, \
-                integrations_created INT DEFAULT 0, \
-                member_updated INT DEFAULT 0, \
-                user_updated INT DEFAULT 0, \
-                member_banned INT DEFAULT 0, \
-                member_unbanned INT DEFAULT 0, \
-                presence_updated INT DEFAULT 0, \
-                messages_edited INT DEFAULT 0, \
-                messages_deleted INT DEFAULT 0, \
-                reacted INT DEFAULT 0, \
-                events_created INT DEFAULT 0, \
-                events_joined INT DEFAULT 0, \
-                threads_created INT DEFAULT 0, \
-                threads_joined INT DEFAULT 0, \
-                ability_points_spent INT DEFAULT 0, \
-                coin INT DEFAULT 0, \
-                karma INT DEFAULT 0, \
-                defence_skill INT DEFAULT 0, \
-                attack_skill  INT DEFAULT 0, \
-                stealth_skill INT DEFAULT 0, \
-                perception_skill INT DEFAULT 0, \
-                theft_skill INT DEFAULT 0, \
-                created TIMESTAMP NOT NULL DEFAULT now()\
-            )\
-        ",
-        "CREATE TABLE IF NOT EXISTS \
-            guild_access_token (\
-                id SERIAL PRIMARY KEY, \
-                guild BIGINT REFERENCES guild (guild_id), \
-                \"user\" BIGINT NOT NULL REFERENCES \"user\" (user_id), \
-                token varchar[40] UNIQUE NOT NULL, \
-                created TIMESTAMP NOT NULL DEFAULT now()\
-            )\
-        ",
-        "CREATE TABLE IF NOT EXISTS \
-            channel_user (\
-                id SERIAL PRIMARY KEY, \
-                channel BIGINT NOT NULL REFERENCES channel (channel_id), \
-                \"user\" BIGINT NOT NULL REFERENCES \"user\" (user_id), \
-                total_messages BIGINT DEFAULT 1, \
-                UNIQUE (channel, \"user\")\
-            )\
-        ",
-    ]
-    for query in queries:
-        await pg.execute(query)

+ 0 - 159
bot/query/user.py

@@ -1,159 +0,0 @@
-async def create_user(pg, user_id):
-	await pg.execute("INSERT INTO \"user\"(user_id) VALUES($1) ON CONFLICT DO NOTHING", user_id)
-
-
-async def ignore_user(pg, user_id):
-	await pg.execute("UPDATE \"user\" SET ignore = TRUE WHERE user_id = $1", user_id)
-
-
-async def unignore_user(pg, user_id):
-	await pg.execute("UPDATE \"user\" SET ignore = FALSE WHERE user_id = $1", user_id)
-
-
-async def is_ignored(pg, user_id):
-	return await pg.fetchval("SELECT ignore FROM \"user\" WHERE user_id = $1", user_id)
-
-
-async def get_level(pg, user_id):
-	return await pg.fetchval("SELECT level FROM \"user\" WHERE user_id = $1", user_id)
-
-
-async def get_xp(pg, user_id):
-	message_array = await pg.fetch("SELECT total_messages FROM channel_user WHERE \"user\" = $1", user_id)
-	total_xp = 0
-	for messages in message_array:
-		total_xp += messages[0]
-
-	extras_array = await pg.fetch("SELECT invites_created, integrations_created, member_updated, user_updated, member_banned, member_unbanned, presence_updated, messages_edited, messages_deleted, reacted, events_created, events_joined, threads_created, threads_joined FROM \"user\" WHERE user_id = $1", user_id)
-	invites_created, integrations_created, member_updated, user_updated, member_banned, member_unbanned, presence_updated, messages_edited, messages_deleted, reacted, events_created, events_joined, threads_created, threads_joined = 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-	for extra in extras_array:
-		invites_created += extra[0]
-		integrations_created += extra[1]
-		member_updated += extra[2]
-		user_updated += extra[3]
-		member_banned += extra[4]
-		member_unbanned += extra[5]
-		presence_updated += extra[6]
-		messages_edited += extra[7]
-		messages_deleted += extra[8]
-		reacted += extra[9]
-		events_created += extra[10]
-		events_joined += extra[11]
-		threads_created += extra[12]
-		threads_joined += extra[13]
-
-	total_xp += (invites_created * 100) + ((integrations_created + events_created) * 200) + ((member_updated + user_updated + presence_updated + events_joined + threads_joined) * 10) + member_banned + member_unbanned + messages_edited + messages_deleted + (reacted * 2) + (threads_created * 50)
-
-	xp_spent = await pg.fetchval("SELECT xp_spent FROM \"user\" WHERE user_id = $1", user_id)
-	return xp_spent, total_xp
-
-async def level_up(pg, user_id, xp):
-	await pg.execute("UPDATE \"user\" SET (level, xp_spent) = (+ 1, $2) WHERE user_id = $1", user_id, xp)
-
-
-async def created_invite(pg, user_id):
-	await pg.execute("UPDATE \"user\" SET (invites_created, karma) = (+1, +1) WHERE user_id = $1", user_id)
-
-
-async def deleted_invite(pg, user_id):
-	await pg.execute("UPDATE \"user\" SET karma = -1 WHERE user_id = $1", user_id)
-
-
-async def invites_created(pg, user_id):
-	return await pg.fetchval("SELECT invites_created FROM \"user\" WHERE user_id = $1", user_id)
-
-
-async def created_integration(pg, user_id):
-	await pg.execute("UPDATE \"user\" SET integrations_created = +1 WHERE user_id = $1", user_id)
-
-
-async def member_joined(pg, user_id):
-	await pg.execute("UPDATE \"user\" SET karma = +1 WHERE user_id = $1", user_id)
-
-
-async def member_updated(pg, user_id):
-	await pg.execute("UPDATE \"user\" SET member_updated = +1 WHERE user_id = $1", user_id)
-
-
-async def user_updated(pg, user_id):
-	await pg.execute("UPDATE \"user\" SET user_updated = +1 WHERE user_id = $1", user_id)
-
-
-async def member_banned(pg, user_id):
-	await pg.execute("UPDATE \"user\" SET (member_banned, karma) = (+1, -1) WHERE user_id = $1", user_id)
-
-
-async def member_unbanned(pg, user_id):
-	await pg.execute("UPDATE \"user\" SET member_unbanned = +1 WHERE user_id = $1", user_id)
-
-
-async def presence_updated(pg, user_id):
-	await pg.execute("UPDATE \"user\" SET presence_updated = +1 WHERE user_id = $1", user_id)
-
-
-async def message_edited(pg, user_id):
-	await pg.execute("UPDATE \"user\" SET (messages_edited, karma) = (+1, +1) WHERE user_id = $1", user_id)
-
-
-async def message_deleted(pg, user_id):
-	await pg.execute("UPDATE \"user\" SET (messages_deleted, karma) = (+1, -1) WHERE user_id = $1", user_id)
-
-
-async def reacted(pg, user_id):
-	await pg.execute("UPDATE \"user\" SET (reacted, karma) = (+1, +1) WHERE user_id = $1", user_id)
-
-
-async def unreacted(pg, user_id):
-	await pg.execute("UPDATE \"user\" SET karma = -1 WHERE user_id = $1", user_id)
-
-
-async def event_created(pg, user_id):
-	await pg.execute("UPDATE \"user\" SET (events_created, karma) = (+1, +1) WHERE user_id = $1", user_id)
-
-
-async def event_joined(pg, user_id):
-	await pg.execute("UPDATE \"user\" SET (events_joined, karma) = (+1, +1) WHERE user_id = $1", user_id)
-
-
-async def event_parted(pg, user_id):
-	await pg.execute("UPDATE \"user\" SET karma = -1 WHERE user_id = $1", user_id)
-
-
-async def thread_created(pg, user_id):
-	await pg.execute("UPDATE \"user\" SET (threads_created, karma) = (+1, +1) WHERE user_id = $1", user_id)
-
-
-async def thread_deleted(pg, user_id):
-	await pg.execute("UPDATE \"user\" SET karma = - 1 WHERE user_id = $1", user_id)
-
-
-async def joined_thread(pg, user_id):
-	await pg.execute("UPDATE \"user\" SET (threads_joined, karma) = (+1, +1) WHERE user_id = $1", user_id)
-
-
-async def left_thread(pg, user_id):
-	await pg.execute("UPDATE \"user\" SET karma = -1 WHERE user_id = $1", user_id)
-
-
-async def get_ability_points_spent(pg, user_id):
-	return await pg.fetchval("SELECT ability_points_spent FROM \"user\" WHERE user_id = $1", user_id)
-
-
-async def increment_all_coin(pg):
-	await pg.execute("UPDATE \"user\" SET coin = + 1 WHERE level > 0")
-
-
-async def get_coin(pg, user_id):
-	return await pg.fetchval("SELECT coin FROM \"user\" WHERE user_id = $1", user_id)
-
-
-async def get_karma(pg, user_id):
-	return await pg.fetchval("SELECT karma FROM \"user\" WHERE user_id = $1", user_id)
-
-
-async def get_theft_skill(pg, user_id):
-	return await pg.fetchval("SELECT theft_skill FROM \"user\" WHERE user_id = $1", user_id)
-
-
-async def get_random_player(pg):
-	return await pg.fetchval("SELECT user_id FROM \"user\" ORDER BY radoom() LIMIT 1")