Created
November 13, 2019 03:56
-
-
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
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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