Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- """ Bot to coordinate a TorD game
- written by Kitty for Ratz
- because apparently I have nothing better to do with my life than write
- code for free lmao <3
- """
- # importing other libraries is just this easy
- # random module is part of python, no need to worry about this
- from random import shuffle
- # discord.py: get it with > pip install --user discord
- import discord
- # STICK YOUR FUCKING BOT TOKEN HERE AND YOU'LL CUM, I PROMISE
- TOKEN = 'MjQyNDc2MjE1NTQwMTIxNjAw.XQf6jA.adpX0Rw_UoMPfcy1X_ZWFkaZGmo'
- # the first few functions are at the top because python style spec says that
- # functions that don't use 'self' shouldn't be in a class
- def newqueue(players):
- """grab the players in a queue and shuffle them"""
- # setting one variable to another in python *usually* creates a
- # reference, so we use the list's copy() function
- this = players.copy()
- # shuffle the list to randomize the player order
- shuffle(this)
- # and feed it back to whatever called this function
- return this
- # sidenote, you can use 'return' to end a function as well
- def runqueue(gamestate):
- """start the game or move the queue"""
- # check to see if we're starting a new game
- if not gamestate['lastplayer']:
- # there's no last player, so we need to start with a new queue,
- # then kick the first person into the last player slot
- gamestate['queue'] = newqueue(gamestate['players'])
- gamestate['lastplayer'] = gamestate['queue'].pop(0)
- # game should be ready to play at this point, so kick back
- return
- # pop out the first player in the queue to the lastplayer var
- gamestate['lastplayer'] = gamestate['queue'].pop(0)
- print(str(gamestate['lastplayer']).ljust(50, '_'))
- # check to see if there is anybody left in the queue
- # this should effectively never leave the queue empty
- # but stupidly might leave the person after the end of the queue unknown
- # until it is actually their turn
- if not gamestate['queue']:
- # if not, grab a new randomized queue
- gamestate['queue'] = newqueue(gamestate['players'])
- print(gamestate['queue'])
- class TordBot(discord.Client):
- """uhhhhhh hi guys im gay
- uh jk this is actually the class that wraps the discord.Client thing
- and makes the bot actually run lmao
- """
- def __init__(self, *args, **kwargs):
- """class initialization
- defines some variables that we're going to be using while the bot
- is running, and then kicks off discord.py's normal startup
- """
- # btw, class variables should ONLY be defined in __init__
- # they can be redefined elsewhere afterwards
- # gamestate: a dictionary of servers containing dictionaries of
- # channels containing game state information
- # when compared to your code, this piece right here makes it so that
- # the bot can be used on multiple servers and channels simultaneously
- self.gamestate = {}
- # prefix: well FUCK, I have no idea what this does, do you?
- self.prefix = '!'
- # kick off the initialization of the parent class
- super().__init__(*args, **kwargs)
- async def on_ready(self):
- """just a little thing to let us know the bot is ready"""
- # btw, print() just writes shit to the console, use it
- # like console.log() in js
- # ALSO SPEAKING OF JS, WE DON'T USE FUCKING SEMICOLONS
- # i mean you can but p much only if you're trying to put two commands
- # on the same line and that's against python style spec so fuck that
- print('Logged in as')
- print(self.user.name)
- print(self.user.id)
- print('------')
- def get_gamestate(self, channel):
- """grab the gamestate for the specific channel in question"""
- if channel.guild.id not in self.gamestate:
- self.gamestate[channel.guild.id] = {}
- if channel.id not in self.gamestate[channel.guild.id]:
- # at this point, we don't have a gamestate for the channel in
- # question, so we define its skeleton here
- self.gamestate[channel.guild.id][channel.id] = {
- 'players': [],
- 'queue': [],
- 'lastplayer': None,
- 'inprogress': False
- }
- return self.gamestate[channel.guild.id][channel.id]
- def endgame(self, channel):
- """end the game
- this is it's own function because there's more than one way the game
- could be ended
- """
- gamestate = self.get_gamestate(channel)
- gamestate['players'].clear()
- gamestate['queue'].clear()
- gamestate['lastplayer'] = None
- gamestate['inprogress'] = False
- async def on_message(self, msg):
- """handler for incoming messages"""
- # so it turns out python style also says things shouldn't get too big
- # fuck python style as far as that goes, turn off the linter warnings
- # pylint: disable=too-many-return-statements
- # pylint: disable=too-many-branches
- # pylint: disable=too-many-statements
- # split() will split a string by spaces by default, which we use here
- # to see if we've got the command we're looking for or not
- msgsplit = msg.content.split()
- # so a big concept of Python is that almost everything can be
- # interpreted as a boolean, and checking things this way is what
- # a lot of people would consider "pythonic"
- # `False` things would be things like an empty array or dict,
- # '', 0, and False, of course
- # We do this here to see if the msgsplit list is empty
- if not msgsplit:
- # no message, it's probably not for us
- return
- # so in the way that discord.py handles things, it gives us a
- # 'message' argument to the on_message() function. This is a class
- # object that contains all of the pertinent information associated
- # with the message.
- # Notable attributes include:
- # - message.author: a class object for the person that wrote it
- # - author.id: the id of the person
- # - author.name: the discord username of the person
- # - author.nick: the nickname of the user in the current server
- # - author.mention: a preformatted string to highlight the user
- # effectively translates to <@{author.id}>
- # - message.guild: the "server" where the message was posted
- # - guild.id: fuck why am i still awake, it's 8:34am
- # - message.channel: the channel the message was posted in
- # - channel.id: the snowflake of the channel
- # also, your code didn't have any references to it in your original so
- # I didn't put any in this script, but...
- # - message.mentions: an array of people who were highlighted in the
- # message received, you could use this for taking actions towards
- # a specified person
- if msgsplit[0] == self.prefix + 'j':
- gamestate = self.get_gamestate(msg.channel)
- # if gamestate['inprogress']:
- # await msg.channel.send(
- # 'Sorry, the game is already in progress!')
- # return
- if msg.author in gamestate['players']:
- # ok so this is the first message send in here
- # 'await' is a thing that has to do with asynchronous operation
- # don't worry about it too much, just know that it has to be
- # used pretty much before anything that is sent or received
- # from the server. more demanding and heavy bots would need it
- # a lot more but this bot is no big deal. also shit will break
- # if you don't use it where you need to. it'll probably just
- # not do whatever the command was supposed to do and complain
- # on the console but not actually completely stop or anything
- await msg.channel.send('You are already in queue, dafaq?')
- else:
- # holy FUCK is this easy or what? we literally fucking add
- # the person themself to the list. fucking miracles, man.
- # even better, this is a class object of the person, so we
- # get all of the goodies that go along with that
- gamestate['players'].append(msg.author)
- await msg.channel.send('You have been added to the queue.')
- elif msgsplit[0] == self.prefix + 'r':
- gamestate = self.get_gamestate(msg.channel)
- if msg.author in gamestate['players']:
- gamestate['players'].remove(msg.author)
- if msg.author in gamestate['queue']:
- gamestate['queue'].remove(msg.author)
- if len(gamestate['players']) < 2:
- final = gamestate['players'][0]
- nick = final.nick if final.nick else final.name
- await msg.channel.send(
- 'WOW ARE YOU SERIOUSLY GONNA LEAVE ' + nick.upper()
- + ' ALL BY THEMSELVES? YOU\'RE SUCH AN ASSHOLE.\n'
- 'Also, games over.')
- self.endgame(msg.channel)
- else:
- await msg.channel.send(
- 'You have been removed from the queue.')
- else:
- await msg.channel.send(
- 'How can I remove you from a queue you '
- 'were never a part of..?')
- elif msgsplit[0] == self.prefix + 'skip':
- gamestate = self.get_gamestate(msg.channel)
- if not gamestate['inprogress']:
- await msg.channel.send(
- 'Uh.. Who you trying to fuck over without a game starting?')
- return
- if not gamestate['queue']:
- await msg.channel.send(
- 'There should be people in queue before you try that.. \n'
- f'Should probly try `{self.prefix}n` first.')
- return
- #Figure out how the fuck to remove people... Fml
- #Tried These Two Options:
- #del gamestate['players'][0]
- #del gamestate['queue'][0]
- #gamestate['players'].remove(0)
- #gamestate['queue'].remove(0)
- gamestate['players'].pop(0)
- gamestate['queue'].pop(0)
- if len(gamestate['players']) < 2:
- final = gamestate['players'][0]
- nick = final.nick if final.nick else final.name
- await msg.channel.send(
- 'WOW YOU REMOVE THE LAST PERSON PLAYING WITH YOU, ' + nick.upper()
- + '? YOU\'RE SUCH AN ASSHOLE.\n'
- + 'Also, games over.')
- self.endgame(msg.channel)
- else:
- runqueue(gamestate)
- await msg.channel.send(
- 'The player has been removed from queue \n' +
- gamestate['lastplayer'].mention +
- 'is asking ' +
- gamestate['queue'][0].mention +
- ' Truth or Dare!?')
- elif msgsplit[0] == self.prefix + 'q':
- gamestate = self.get_gamestate(msg.channel)
- if not gamestate['inprogress']:
- await msg.channel.send(
- 'There isn\'t a game being played, you dumb dumb.')
- return
- if not gamestate['queue']:
- # "f-strings" allow you to use vars inside of strings
- await msg.channel.send(
- 'There is nobody in the queue, you dumb dumb. '
- f'Should probly try `{self.prefix}n`')
- return
- buffer = '**The currrent Queue Is:**\n'
- buffer += ''.ljust(53, '-') + '\n' # easy divider bars
- buffer += gamestate['lastplayer'].nick \
- if gamestate['lastplayer'].nick \
- else gamestate['lastplayer'].name
- buffer += '\n'
- for player in gamestate['queue']:
- # now this is a tricky little thing here that uses the person's
- # nickname in the server if they have one, otherwise just uses
- # their regular username
- buffer += player.nick if player.nick else player.name
- buffer += '\n'
- buffer += ''.ljust(53, '-') + '\n'
- buffer += '**Players Joined: **\n'
- buffer += ''.ljust(53, '-') + '\n'
- for player in gamestate['players']:
- buffer += player.nick if player.nick else player.name
- buffer += '\n'
- await msg.channel.send(buffer)
- elif msgsplit[0] == self.prefix + 'n':
- gamestate = self.get_gamestate(msg.channel)
- if not gamestate['inprogress']:
- await msg.channel.send(
- 'Please start the game by typing `' +
- self.prefix + 'start`')
- return
- # lmao get shit done hahahaha kill me
- runqueue(gamestate)
- # and the moment we've all been waiting for
- await msg.channel.send(
- gamestate['lastplayer'].mention +
- ' is asking ' +
- gamestate['queue'][0].mention +
- ' Truth or Dare!?')
- elif msgsplit[0] == self.prefix + 'start':
- gamestate = self.get_gamestate(msg.channel)
- if gamestate['inprogress']:
- await msg.channel.send(
- 'Are u fookin stoopid? ther\'s alredy a gayme her')
- return
- # you can't start with less than 2 players.
- # midgets count as a half a player, so you need at least 4 midgets.
- # 3 midgets would only be 1.5 players, and that's less than 2.
- if len(gamestate['players']) < 2:
- await msg.channel.send(
- 'You need at least 2 players to start a game\n'
- f'Please join with, `{self.prefix}j`')
- return
- gamestate['inprogress'] = True
- await msg.channel.send(
- '***WELCOME TO THE THUNDERDOME***\n'
- 'In this arena, literally every one of you are gas as fuck.\n'
- 'You must submit to whatever the other n-word tells you to do.'
- '\nMay Allah have mercy on your soul.'
- f'\nThe Game Has Now Started - `{self.prefix}n` to show who\'s asking who.')
- elif msgsplit[0] == self.prefix + 'end':
- gamestate = self.get_gamestate(msg.channel)
- if not gamestate['inprogress']:
- await msg.channel.send(
- 'There\'s no game being played here so maybe you should'
- 'end your life instead')
- return
- # clear out all of the crap and reinit gamestate
- self.endgame(msg.channel)
- await msg.channel.send(
- 'The game is over.')
- # more PROPER python shit, technically everything is a module
- # and no runtime code should be run outside of a function, so that
- # you can reuse the code elsewhere without it running by itself
- # "main" doesn't actually mean anything here, it could be named
- # anything else that you'd like
- def main():
- """RUN THE FOOKIN BOT ALREADY GODDAM"""
- bot = TordBot()
- bot.run(TOKEN)
- # on the other hand, __name__ here is a way of checking what module
- # we currently identify as, this would normally be the filename
- # (but without .py on the end of it) if being used as a module,
- # but if it is being run directly, then __name__ will be __main__
- # that said, if you're running this directly, actually run the bot here?
- if __name__ == '__main__':
- main()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement