#!/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())