import os import ast import time from datetime import datetime, timedelta import asyncio import sgfengine import discord from discord.ext import commands # We don't use fancy slash commands here. It seems there is this library for python but it looks a bit more involved. # https://pypi.org/project/discord-py-slash-command/ intents = discord.Intents.default() #intents.message_content = True bot = commands.Bot(command_prefix='$', help_command=None, intents=intents) # People who can start and resign games :O admins=[] awesome_server_id= permitted_channel_id= player_id= 0 start_time = 0 with open("token.txt") as f: token = f.readlines()[0] # Get your own token and put it in token.txt @bot.command() async def help(ctx): if ctx.guild.id != awesome_server_id or ctx.channel.id != permitted_channel_id: return await ctx.send( '$help : shows this help\n\n'+ '$play : play a move. For example, `$play Q16`. Passing is not implemented!\n'+ '$edit : if you make a mistake in your move\n\n'+ '$sgf: get the sgf file of the game\n'+ '$board: shows the current board\n'+ '$newgame : starts a game in this channel (admin only!)\n'+ '$resign : resigns the game in this channel. It returns its sgf file (admin only!)' ) # ctx has guild, message, author, send, and channel (?) @bot.command() async def play(ctx, arg): if ctx.guild.id != awesome_server_id or ctx.channel.id != permitted_channel_id: return channel_id= ctx.channel.id user = ctx.author guild= ctx.guild global player_id global start_time if not os.path.exists(str(channel_id)+".sgf"): await ctx.send("No active game in this channel!") return if (player_id == user.id): await ctx.send("No two consecutive moves by the same player!") return elapsed_time = time.time() - start_time if elapsed_time < 1: await ctx.send("One second per move!") return legal_moves=[chr(col+ord('A')-1)+str(row) for col in range(1,21) if col!=9 for row in range(1,20)] legal_moves+=[chr(col+ord('a')-1)+str(row) for col in range(1,21) if col!=9 for row in range(1,20)] if arg not in legal_moves: await ctx.send("I don't understand the move! Please input it in the format `$play Q16`") return try: sgfengine.play_move(str(channel_id), arg, user.display_name) except ValueError as e: await ctx.send(str(e)) return player_id=user.id start_time = time.time() file = discord.File(str(ctx.channel.id)+".png") await ctx.send(file=file) @bot.command() async def edit(ctx, arg): if ctx.guild.id != awesome_server_id or ctx.channel.id != permitted_channel_id: return channel_id= ctx.channel.id user = ctx.author guild= ctx.guild global player_id if (player_id == user.id): await ctx.send("Not the player that made the mistake!") return if not os.path.exists(str(channel_id)+".sgf"): await ctx.send("No active game in this channel!") return colour= sgfengine.next_colour(str(channel_id)) legal_moves=[chr(col+ord('A')-1)+str(row) for col in range(1,21) if col!=9 for row in range(1,20)] legal_moves+=[chr(col+ord('a')-1)+str(row) for col in range(1,21) if col!=9 for row in range(1,20)] if arg not in legal_moves: await ctx.send("I don't understand the move! Please input it in the format `$play Q16`") return try: sgfengine.play_move(str(channel_id), arg, user.display_name, True) except ValueError as e: await ctx.send(str(e)) return file = discord.File(str(ctx.channel.id)+".png") await ctx.send(file=file) @bot.command() async def board(ctx): if ctx.guild.id != awesome_server_id or ctx.channel.id != permitted_channel_id: return channel_id= ctx.channel.id user = ctx.author guild= ctx.guild if not os.path.exists(str(channel_id)+".sgf"): await ctx.send("No active game in this channel!") return os.system("/home/nik/.cargo/bin/sgf-render -f png --style fancy --label-sides nesw -o "+str(channel_id)+".png -n last "+str(channel_id)+".sgf") file = discord.File(str(ctx.channel.id)+".png") await ctx.send(file=file) @bot.command() async def sgf(ctx): if ctx.guild.id != awesome_server_id or ctx.channel.id != permitted_channel_id: return file = discord.File(str(ctx.channel.id)+".sgf") await ctx.send(file=file) @bot.command() async def newgame(ctx, handicap=0, komi=6.5): if ctx.guild.id != awesome_server_id or ctx.channel.id != permitted_channel_id: return channel_id= ctx.channel.id user = ctx.author if user.id not in admins: await ctx.send("You don't have permissions for this!") return sgfengine.new_game(str(channel_id), handicap, komi) os.system("/home/nik/.cargo/bin/sgf-render -f png --style fancy --label-sides nesw -o "+str(channel_id)+".png -n last "+str(channel_id)+".sgf") file = discord.File(str(channel_id)+".png") await ctx.send(file=file, content="A new game has started! Play with `$play `") @bot.command() async def resign(ctx, arg): if ctx.guild.id != awesome_server_id or ctx.channel.id != permitted_channel_id: return channel_id= ctx.channel.id user = ctx.author if user.id not in admins: await ctx.send("You don't have permissions for this!") return if arg not in ["W","B"]: await ctx.send("Unrecognized colour! Please try `$resign ` to resign as Black/White") return now=datetime.now() file_name= "rengo_"+now.strftime("%Y_%m_%d_%H_%M_%S_")+ctx.channel.name+".sgf" sgfengine.resign(str(channel_id), arg, file_name) file = discord.File(file_name) await ctx.send(file=file, content=("Black" if arg=="W" else "White")+" wins!") print("Running") bot.run(token)