Skip to content

Instantly share code, notes, and snippets.

@blha303
Created November 13, 2019 03:56
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save blha303/a3ad0ae55d155d221d61c96c6a61c812 to your computer and use it in GitHub Desktop.
Save blha303/a3ad0ae55d155d221d61c96c6a61c812 to your computer and use it in GitHub Desktop.
A brief musing on the plausibility of a cards against humanity bot for discord
#!/usr/bin/env python
import discord
from json import load
from random import shuffle
client = discord.Client()
# https://github.com/crhallberg/json-against-humanity
with open("full.md.json") as f:
cards = load(f)
channels = {}
number_emoji = ":one: :two: :three: :four: :five: :six: :seven: :eight: :nine: :keycap_ten:".split(" ")
async def delete_message(message):
try:
await client.delete_message(message)
return True
except discord.errors.NotFound:
return False
async def cleanup(channel, important=False):
global channels
for msg in channels.get(channel, {}).get("for_deletion", []):
await delete_message(msg)
if important:
for msg in channels.get(channel, {}).get("important_msgs", []):
await delete_message(msg)
async def send_message_cleanup(channel, message):
global channels
print(message)
resp = await client.send_message(channel, message)
channels[channel]["for_deletion"].append(resp)
return resp
async def cmd_start(message, *args):
global channels
channel = message.channel
owner = message.author
await delete_message(message)
if not args:
args = ["base", "cahe1", "cahe2", "cahe3"]
selected = []
for pack in args:
for _pack in cards["metadata"].keys():
if pack.lower() == _pack.lower():
selected.append(_pack)
channels[channel]["white"] += [c for c in cards["white"] if c["deck"] == _pack]
channels[channel]["black"] += [c for c in cards["black"] if c["deck"] == _pack]
break
channels[channel]["selected"] = selected
channels[channel]["active"] = True
channels[channel]["owner"] = owner
await send_message_cleanup(channel, "Starting a game with packs:\n" + "\n".join(selected))
channels[channel]["joining"] = True
await send_message_cleanup(channel, "Say anything to join the game, say ready when it's time to start")
async def cmd_packs(message, *args):
global channels
channel = message.channel
await delete_message(message)
if channels[channel]["active"]:
return
packs = cards["metadata"]
out = ""
for k in sorted(packs.keys()):
this = "{}: {}{}\n".format(k, packs[k]["name"], " (official)" if packs[k]["official"] else "")
if len(out+this) > 2000:
await send_message_cleanup(channel, out.strip())
out = this
else:
out += this
await send_message_cleanup(channel, out.strip())
async def cmd_stop(message, *args):
global channels
channel = message.channel
await delete_message(message)
if channels[channel]["owner"] and channels[channel]["owner"] != message.author:
await send_message_cleanup(channel, "Only the game owner can stop a game")
return
await cleanup(channel, important=True)
del channels[channel]
def draw(count, deck):
out = []
if len(deck) < count:
return False
for _ in range(1, count+1):
shuffle(deck)
out.append(deck.pop())
return out
@client.event
async def on_message(message):
if message.author == client.user:
return
global channels
if not message.channel in channels:
channels[message.channel] = {
"important_msgs": [],
"for_deletion": [],
"active": False,
"joining": False,
"white": [],
"black": [],
"owner": None,
"players": {}
}
channel = message.channel
content = message.content
author = message.author
info = channels[channel]
players = info["players"]
if info["joining"]:
if content.lower() == "ready":
await delete_message(message)
if author == info["owner"]:
info["joining"] = False
await cleanup(channel)
await send_message_cleanup(channel, "Here we gooo")
else:
await send_message_cleanup(channel, "You didn't start the game! Only the person that started the game can ready up")
return
if author.id in players:
return
await delete_message(message)
players[author.id] = {
"hand": draw(10, info["white"])
}
print(players)
await send_message_cleanup(channel, "{} has joined the game!".format(author.nick or author.name))
await client.send_message(
author,
"Your white cards are:\n" +
"\n".join(
"{}: {}".format(number_emoji[n], c["text"]) for n,c in enumerate(players[author.id]["hand"])
)
)
return
if (content[0] == "!" and len(content) > 1) or channels[channel]["active"]:
await cleanup(channel)
cmd, *args = content[1 if content[0] == "!" else 0:].split(" ")
try:
await globals()["cmd_" + cmd](message, *args)
except KeyError:
# await client.send_message(channel, "Command not found")
print("Command not found: " + cmd)
pass
@client.event
async def on_ready():
print("Logged in as {} ({})".format(client.user.name, client.user.id))
if client.user.bot:
print(discord.utils.oauth_url(client.user.id, permissions=discord.Permissions(67497024)))
if __name__ == "__main__":
with open(".bottoken") as f:
client.run(f.read().strip())
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment