Пример #1
0
class Bot:

    def __init__(self, config):
        self.config = config
        self.irc = Irc(config)
        self.game = Game()

    def run(self):
        last_start = time.time()

        while True:
            new_messages = self.irc.recv_messages(1024)
            
            if new_messages:
                for message in new_messages:
                    button = message['message'].lower()
                    username = message['username']

                    if not self.game.is_valid_button(button):
                        continue

                    if self.config['start_throttle']['enabled'] and button == 'start':
                        if time.time() - last_start < self.config['start_throttle']['time']:
                            continue

                    pbutton(username, button)
                    self.game.push_button(button)

                    if button == 'start':
                        last_start = time.time()
Пример #2
0
class Bot:
    def __init__(self):
        self.config = config
        self.irc = Irc(config)
        self.game = Game()
        self.stats = Stats()
        if self.config['features']['gui_stats']:
            self.GUI = GUI(self)

    def run(self):
        throttle_timers = {
            button: 0
            for button in config['throttled_buttons'].keys()
        }

        while True:
            new_messages = self.irc.recv_messages(1024)

            if not new_messages:
                continue

            for message in new_messages:
                button = message['message'].lower()
                username = message['username'].lower()

                if not self.game.is_valid_button(button):
                    continue

                if button in self.config['throttled_buttons']:
                    if (time.time() - throttle_timers[button] <
                            self.config['throttled_buttons'][button]):
                        continue
                    throttle_timers[button] = time.time()

                if not self.game.is_political(button):
                    if (self.config['features']['play_game'] and not button
                            in self.config['misc']['blocked_buttons']):
                        self.game.push_button(button)

                self.stats.tally_message(username, message['message'])

            if self.config['features']['stats_on']:
                if self.config['features']['gui_stats']:
                    self.GUI.run()
                if self.config['features']['console_stats']:
                    pframe(self.stats)

            elif self.config['features']['pbutton_on']:
                pbutton(self.stats.message_buffer)
Пример #3
0
class Bot:

    def __init__(self):
        self.config = config
        self.irc = Irc(config)
        self.game = Game()
        self.stats = Stats()
        if self.config['features']['gui_stats']:
            self.GUI = GUI(self)

    def run(self):
        throttle_timers = {button:0 for button in config['throttled_buttons'].keys()}

        while True:
            new_messages = self.irc.recv_messages(1024)
            
            if not new_messages:
                continue
            
            for message in new_messages: 
                button = message['message'].lower()
                username = message['username'].lower()
                
                if not self.game.is_valid_button(button):
                    continue
                
                if button in self.config['throttled_buttons']:
                    if (time.time() - throttle_timers[button] <
                            self.config['throttled_buttons'][button]):
                        continue
                    throttle_timers[button] = time.time()
                    
                if not self.game.is_political(button):
                    if (self.config['features']['play_game'] and
                            not button in self.config['misc']['blocked_buttons']):
                        self.game.push_button(button)
                
                self.stats.tally_message(username, message['message'])
            
            if self.config['features']['stats_on']:
                if self.config['features']['gui_stats']:
                    self.GUI.run()
                if self.config['features']['console_stats']:
                    pframe(self.stats)
                    
            elif self.config['features']['pbutton_on']:
                pbutton(self.stats.message_buffer)
Пример #4
0
class Bot:
    def __init__(self):
        self.config = config
        self.irc = Irc(config)
        self.game = Game()
        self.message_buffer = [{
            'username': '',
            'button': ''
        }] * self.config['misc']['chat_height']

    def set_message_buffer(self, message):
        self.message_buffer.insert(self.config['misc']['chat_height'] - 1,
                                   message)
        self.message_buffer.pop(0)

    def run(self):
        throttle_timers = {
            button: 0
            for button in config['throttled_buttons'].keys()
        }

        while True:
            new_messages = self.irc.recv_messages(1024)

            if not new_messages:
                continue

            for message in new_messages:
                button = message['message'].lower()
                username = message['username'].lower()

                if not self.game.is_valid_button(button):
                    continue

                if button in self.config['throttled_buttons']:
                    if time.time() - throttle_timers[button] < self.config[
                            'throttled_buttons'][button]:
                        continue

                    throttle_timers[button] = time.time()

                self.set_message_buffer({
                    'username': username,
                    'button': button
                })
                pbutton(self.message_buffer)
                self.game.push_button(button)
Пример #5
0
class Bot:

    def __init__(self):
        self.config = config
        self.irc = Irc(config)
        self.game = Game()

        self.message_buffer = [{'username': '', 'button': ''}] * 10


    def set_message_buffer(self, message):
        chat_height = 10
        self.message_buffer.insert(chat_height - 1, message)
        self.message_buffer.pop(0)


    def run(self):
        last_start = time.time()

        while True:
            new_messages = self.irc.recv_messages(1024)
            
            if not new_messages:
                continue

            for message in new_messages: 
                button = message['message'].lower()
                username = message['username'].lower()

                if not self.game.is_valid_button(button):
                    continue

                print button

                if self.config['start_throttle']['enabled'] and button == 'start':
                    if time.time() - last_start < self.config['start_throttle']['time']:
                        continue

                if button == 'start':
                    last_start = time.time()

                self.set_message_buffer({'username': username, 'button': button})
                pbutton(self.message_buffer)
                self.game.push_button(button)
Пример #6
0
class Bot:

    def __init__(self):
        self.config = config
        self.irc = Irc(config)
        self.game = Game()

        self.message_buffer = [{'username': '', 'button': ''}] * self.config['misc']['chat_height']


    def set_message_buffer(self, message):
        self.message_buffer.insert(self.config['misc']['chat_height'] - 1, message)
        self.message_buffer.pop(0)


    def run(self):
        throttle_timers = {button:0 for button in config['throttled_buttons'].keys()}

        while True:
            new_messages = self.irc.recv_messages(1024)
            
            if not new_messages:
                continue

            for message in new_messages: 
                button = message['message'].lower()
                username = message['username'].lower()

                if not self.game.is_valid_button(button):
                    continue

                if button in self.config['throttled_buttons']:
                    if time.time() - throttle_timers[button] < self.config['throttled_buttons'][button]:
                        continue

                    throttle_timers[button] = time.time()
         

                self.set_message_buffer({'username': username, 'button': button})
                pbutton(self.message_buffer)
                self.game.push_button(button)
Пример #7
0
class Bot:

    def __init__(self):
        self.config = config
        self.irc = Irc(config)

    def run(self):
        throttle_timers = {button: 0 for button
                           in config['throttled_buttons'].keys()}

        i = 0
        while True:
            t1 = datetime.datetime.now()
            i += 1
            new_messages = self.irc.recv_messages(1024)
            if not new_messages:
                continue
            text_list = []
            for message in new_messages:
                button = message['message'].lower()
                username = message['username'].lower()
                d_time = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
                if button in self.config['throttled_buttons']:
                    if (time.time() - throttle_timers[button]
                            < self.config['throttled_buttons'][button]):
                        continue

                    throttle_timers[button] = time.time()
                print d_time, username, button
                if i == 1000:
                    output = open(t1.strftime("%Y%m%d%H%M%S") + ".log", "wb")
                    for post in text_list:
                        output.write("%s <%s> %s \n"
                                     % (post[0], post[1], post[2]))
                    i = 0
                    text_list = []
                    output.close()
Пример #8
0
class Bot:
    voteLength = 5  #Number of votes to show
    bufferLength = 5  #Number of recent commands to show
    commandDisplayLength = 21  #max number of characters visible on command screen

    def __init__(self):
        self.config = config
        self.irc = Irc(config)
        self.game = Game()
        self.extConfig = configparser.ConfigParser()
        self.message_buffer = deque(
            ' ', self.bufferLength
        )  #deque happens to be marginally more convenient for this
        self.curQueue = comQueue(
        )  #Based on Queue object, and therefore threadsafe
        self.daQueue = demAnQueue(
        )  #Based on deque object, and therefore threadsafe
        self.queueStatus = "Nominal"
        self.lastButton = ""
        self.voteCount = {}
        self.lastPushed = ""
        self.voteItems = self.voteCount.items(
        )  #Dynamically changing list in python 3 that keeps up with voteCount
        self.democracy = False  #Anarchy is default on.
        self.game.democracy = self.democracy  #Command processor needs this information due to slightly different processing in democracy vs. anarchy
        self.lastConfigTime = time.time()  #Timer on config file updates
        self.configUpdateFreq = 60  #config file updates every 60 seconds

        ###DEFAULT VALUES (should be overwritten by readConfigText() at the end###
        self.botConfig = {'votetime': 20, 'checktime': 0.1, 'votethresh': 75}
        ###END DEFAULT VALUES###

        self.readConfigText(
        )  #read in config file (after all possible object initializations)
        self.daQueue.updateQueue(
        )  #It's poor form that I have to do this, but it's cleanest

    def readConfigText(
        self
    ):  #the operations performed are threadsafe (attributes changed are either only ever changed here, or changed in one atomic operation)
        try:
            self.extConfig.read(
                self.config['configPath']
            )  #Note that nothing from extConfig is directly accessed by any other function. This function is paranoid about it anyway...
        except:
            return  #In case of read fail of some sort. In principle, this should throw a warning, but for the stream I don't want errors going to stdout, and it will not matter unless I try to edit the .ini and it somehow causes a permanent failure of the read (i.e. I messed up the formatting). By design, the stream will continue to run based on the old configuration; hopefully I will notice that the changes are not taking effect. Best practice would be to output the causative error to a log file; that can be implemented later if necessary

        tempkeymap = dict(self.extConfig['Keymap'])
        for sub in tempkeymap.keys():
            tempkeymap[sub] = int(tempkeymap[sub],
                                  16)  #convert from the hex to integer
        self.game.keymap = tempkeymap  #Note that the operations above are performed separately before being placed in the self object; this is for threadsafeness. This is an atomic operation.

        self.game.macros = dict(
            self.extConfig['Macros']
        )  #this is okay because it doesn't get changed after this. This is an atomic operation.

        tempbotconfig = self.extConfig['Bot']
        self.botConfig = self.configInferType(
            tempbotconfig
        )  #Note that the operations above are performed separately before being placed in the self object; this is for threadsafeness. This is an atomic operation.

        tempgameconfig = self.extConfig['Game']
        self.game.gameConfig = self.configInferType(
            tempgameconfig
        )  #Note that the operations above are performed separately before being placed in the self object; this is for threadsafeness. This is an atomic operation.

        tempdemanqueueconfig = self.extConfig['demAnQueue']
        self.daQueue.demAnQueueConfig = self.configInferType(
            tempdemanqueueconfig
        )  #Note that the operations above are performed separately before being placed in the self object; this is for threadsafeness. This is an atomic operation.

    def configInferType(
        self, inconfig
    ):  #convenience function for type conversion based on first character of variable name
        #indict is the source ConfigParser object, outdict is the output dictionary which will get keys that are stripped of the first character, which signals type
        outdict = {}
        for sub in inconfig.keys():
            if sub.startswith(
                    'f'
            ):  #Personal Note: I finally understand why the civ 5 XML files are the way there are....
                outdict[sub[1:]] = inconfig.getfloat(
                    sub)  #in python, dictionaries are a mutable type
            elif sub.startswith('i'):
                outdict[sub[1:]] = inconfig.getint(sub)
            elif sub.startswith('b'):
                outdict[sub[1:]] = inconfig.getboolean(sub)
        return outdict

    def update_message_buffer(self, message):
        self.message_buffer.appendleft(
            message
        )  #deque maximum length now takes care of the below functionality
        #if len(self.message_buffer)>self.bufferLength:
        #self.message_buffer.pop(0)

    def update_message(self, timeleft):
        system('cls')
        demvoteper = round(
            self.daQueue.demVotePerc
        )  #minimizing the number of times this attribute gets read, in case it changes midway
        if self.democracy:
            votes = self.sortVote(
            )  #It's inefficient to do this every time, yes, but the alternative is to implement a custom sorted value hashmap, and I hope that's not necessary...
            print('\n\n')
            print('Democracy: ' + str(demvoteper) + '%\nAnarchy: ' +
                  str(100 - demvoteper) + '%\n\nDemocracy!\nTime Remaining: ' +
                  str(int(timeleft)) + ' s\nLast Pushed: ' + self.lastPushed +
                  '\n')
            if votes:
                print('Top Votes:\n')
                for y in votes[0:min(len(votes), self.voteLength
                                     )]:  #show at most 5 votes
                    print(str(y[1]) + " " + y[0])
                print('\n')
            for y in self.message_buffer:
                print(y)
        else:
            print('\n\n')
            print('Democracy: ' + str(demvoteper) + '%\nAnarchy: ' +
                  str(100 - demvoteper) + '%\n\nAnarchy!\n')
            for y in self.message_buffer:
                print(y)

    def commandQueue(self):
        while True:
            #update config file if necessary...see readConfigText regarding threadsafeness
            if time.time() - self.lastConfigTime > self.configUpdateFreq:
                self.readConfigText()  #Only place this should ever get called
                self.lastConfigTime = time.time()
            #Toggles Anarchy/Democracy state
            self.daQueue.updateQueue()
            demvoteper = self.daQueue.demVotePerc  #minimizing the number of times this attribute gets read (though it should only ever get changed by updateQueue() anyway
            if self.democracy and demvoteper < 100 - self.botConfig[
                    'votethresh']:  #Note that the attribute changes here are all atomic operations and threadsafe
                self.democracy = False
                self.game.democracy = False
            elif not self.democracy and demvoteper > self.botConfig[
                    'votethresh']:
                self.democracy = True
                self.game.democracy = True
            if self.democracy:  #this is Democracy
                lastvotetime = time.time()
                self.queueStatus = "Adding Votes"
                while time.time() - lastvotetime < self.botConfig[
                        'votetime']:  #collect commands for votetime seconds
                    self.daQueue.updateQueue()
                    self.update_message(self.botConfig['votetime'] -
                                        time.time() + lastvotetime)
                    comList, userList = self.curQueue.getCom()
                    self.lastButton = comList
                    timetaken = time.time()
                    index = 0
                    for button in comList:
                        username = userList[index]
                        index += 1
                        self.queueStatus = "Adding Votes"

                        self.addVote(button)
                        userLength = self.commandDisplayLength - len(
                            button) - 2
                        printusername = username
                        if len(username) > userLength:
                            printusername = username[0:userLength - 3] + '...'
                        self.update_message_buffer(printusername + ': ' +
                                                   button)
                        #pbutton(self.message_buffer)
                    if time.time() - timetaken < self.botConfig[
                            'checktime']:  #don't check more frequently than once every 0.1
                        self.queueStatus = "Sleeping"
                        time.sleep(self.botConfig['checktime'])
                self.queueStatus = "Running Command"
                vote = self.topVote(
                )  #running the command after votetime seconds
                if vote:
                    self.lastPushed = vote
                    words = vote.split(
                        "+"
                    )  #input-time check should have already made sure it's a valid command
                    for y in words:
                        try:
                            self.game.push_button(y)
                        except:
                            time.sleep(
                                0.01
                            )  #this is just to fill this catch block. It's bad, yes.
                        time.sleep(.15)
                    self.clearVote()
                self.update_message(0)
            else:  #this is Anarchy
                self.queueStatus = "Pushing buttons"
                self.update_message(0)
                comList, userList = self.curQueue.getCom()
                self.lastButton = comList
                timetaken = time.time()
                index = 0
                for button in comList:
                    username = userList[index]
                    index += 1
                    words = button.split(
                        "+"
                    )  #input-time check should have already made sure it's a valid command

                    for y in words:
                        if y in self.config['throttled_buttons']:
                            if time.time() - throttle_timers[y] < self.config[
                                    'throttled_buttons'][y]:
                                continue

                            throttle_timers[y] = time.time()
                        try:  #Just in case of weird edge case
                            self.game.push_button(y)
                        except:
                            time.sleep(
                                0.01
                            )  #this is just to fill this catch block. It's bad, yes.
                        time.sleep(
                            .05)  #Anarchy is a bit more jumpy than Democracy
                    userLength = self.commandDisplayLength - len(button) - 2
                    printusername = username
                    if len(username) > userLength:
                        printusername = username[0:userLength - 3] + '...'
                    self.update_message_buffer(printusername + ': ' + button)
                if time.time() - timetaken < self.botConfig[
                        'checktime']:  #don't check more frequently than once every 0.1
                    self.queueStatus = "Sleeping"
                    time.sleep(self.botConfig['checktime'])

    def addVote(self, vote):
        if vote in self.voteCount:
            self.voteCount[vote] = self.voteCount[vote] + 1
        else:
            self.voteCount[vote] = 1

    def topVote(self):  #Gets top vote, applying rng to choose among ties
        top = [
            k for k, v in self.voteItems if v == max(self.voteCount.values())
        ]
        if not top:
            return None
        return random.choice(top)

    def sortVote(self):
        sortedItems = sorted(
            self.voteItems, key=lambda tup: tup[1],
            reverse=True)  #sort using the values, biggest to smallest
        return sortedItems

    def clearVote(self):
        self.voteCount.clear()

    def run(self):
        #print("New Version!")
        throttle_timers = {
            button: 0
            for button in config['throttled_buttons'].keys()
        }
        t = threading.Thread(target=self.commandQueue, args=())
        t.daemon = True
        t.start()

        while True:  #For threadsafeness see discussion at the top of this file
            #print(self.queueStatus)
            #print(self.lastButton)
            #print(self.curQueue.getStatus())
            #print("Checking for new messages")
            new_messages = self.irc.recv_messages(1024)

            if not new_messages:
                continue

            for message in new_messages:
                button = message['message'].lower()
                username = message['username'].lower()
                words = button.split(" ")  #basic input cleanup
                button = words[0]

                #Anarchy/Democracy vote
                if button == 'democracy':
                    self.daQueue.addVote(
                        1)  #No update to try to make this as fast as possible
                elif button == 'anarchy':
                    self.daQueue.addVote(0)

                if not self.game.is_valid_command(button):
                    continue
                #print("Adding command")
                self.curQueue.addCom([button, username])
Пример #9
0
class Bot:

    def __init__(self):
        self.config = config
        self.irc = Irc(config)
        self.game = Game()
        self.botOn = True
        self.message_buffer = [{'username': '', 'button': ''}] * self.config['misc']['chat_height']

    def set_message_buffer(self, message):
        self.message_buffer.insert(self.config['misc']['chat_height'] - 1, message)
        self.message_buffer.pop(0)

    def run(self):
        throttle_timers = {button:0 for button in config['throttled_buttons'].keys()}

        while True:
            new_messages = self.irc.recv_messages(1024)
            
            if not new_messages:
                continue

            for message in new_messages: 
                button = message['message'].lower()
                username = message['username'].lower()

                #Turns off the bot with one of your commands
                if username == 'YOUR USERNAME GOES HERE':
                    if button == 'YOUR INPUT SHUTOFF MESSAGE HERE':
                        self.botOn = False

                #Turns on the bot with one of your commands
                if username == 'YOUR USERNAME GOES HERE':
                    if button == 'YOUR INPUT TURNON MESSAGE HERE':
                        self.botOn = True

                #Helper for writing actionable data to csv
                if button in self.game.keymap.keys():
                    actionable = 1
                else:
                    actionable = 0

                #Helper for writing is Bot Active data to csv
                if self.botOn == True:
                    chatActionsOn = 1
                else:
                    chatActionsOn = 0

                #Creates an array of data to write to csv
                chat_data_array = [username, time.time(), button, actionable , chatActionsOn]
                
                #Writes a message to the csv that tracks chat data
                with open('chat_data.csv', 'a+') as chatData:
                    writer = csv.writer(chatData)
                    writer.writerow(chat_data_array)

                #If the Bot is on, then it outputs the appropriate action.
                #If the Bot is off, continues to gen the input feed but does not execute an action
                if self.botOn == True:
                    if not self.game.is_valid_button(button):
                        continue

                    if button in self.config['throttled_buttons']:
                        if time.time() - throttle_timers[button] < self.config['throttled_buttons'][button]:
                            continue

                        throttle_timers[button] = time.time()
                    

                    self.set_message_buffer({'username': username, 'button': button})
                    pbutton(self.message_buffer) #This is a console output function. It outputs the log of inputs from chat
                    self.game.push_button(button)
                else:
                    self.set_message_buffer({'username': username, 'button': button})
                    pbutton(self.message_buffer)
                    
Пример #10
0
class Bot:
    voteLength=5 #Number of votes to show
    bufferLength=5 #Number of recent commands to show
    commandDisplayLength=21 #max number of characters visible on command screen

    def __init__(self):
        self.config = config
        self.irc = Irc(config)
        self.game = Game()
        self.extConfig=configparser.ConfigParser()
        self.message_buffer = deque(' ',self.bufferLength) #deque happens to be marginally more convenient for this
        self.curQueue=comQueue() #Based on Queue object, and therefore threadsafe
        self.daQueue=demAnQueue() #Based on deque object, and therefore threadsafe
        self.queueStatus="Nominal"
        self.lastButton=""
        self.voteCount={}
        self.lastPushed=""
        self.voteItems=self.voteCount.items() #Dynamically changing list in python 3 that keeps up with voteCount
        self.democracy=False #Anarchy is default on.
        self.game.democracy=self.democracy #Command processor needs this information due to slightly different processing in democracy vs. anarchy
        self.lastConfigTime=time.time() #Timer on config file updates
        self.configUpdateFreq=60 #config file updates every 60 seconds
        
        ###DEFAULT VALUES (should be overwritten by readConfigText() at the end###
        self.botConfig={'votetime':20,
            'checktime':0.1,
            'votethresh':75}
        ###END DEFAULT VALUES###
        
        self.readConfigText() #read in config file (after all possible object initializations)
        self.daQueue.updateQueue() #It's poor form that I have to do this, but it's cleanest
        
    def readConfigText(self): #the operations performed are threadsafe (attributes changed are either only ever changed here, or changed in one atomic operation)
        try:
            self.extConfig.read(self.config['configPath']) #Note that nothing from extConfig is directly accessed by any other function. This function is paranoid about it anyway...
        except:
            return #In case of read fail of some sort. In principle, this should throw a warning, but for the stream I don't want errors going to stdout, and it will not matter unless I try to edit the .ini and it somehow causes a permanent failure of the read (i.e. I messed up the formatting). By design, the stream will continue to run based on the old configuration; hopefully I will notice that the changes are not taking effect. Best practice would be to output the causative error to a log file; that can be implemented later if necessary
            
        tempkeymap=dict(self.extConfig['Keymap'])
        for sub in tempkeymap.keys():
            tempkeymap[sub] = int(tempkeymap[sub],16) #convert from the hex to integer
        self.game.keymap=tempkeymap #Note that the operations above are performed separately before being placed in the self object; this is for threadsafeness. This is an atomic operation.
        
        self.game.macros=dict(self.extConfig['Macros']) #this is okay because it doesn't get changed after this. This is an atomic operation.
        
        tempbotconfig=self.extConfig['Bot']
        self.botConfig=self.configInferType(tempbotconfig) #Note that the operations above are performed separately before being placed in the self object; this is for threadsafeness. This is an atomic operation.
        
        tempgameconfig=self.extConfig['Game']
        self.game.gameConfig=self.configInferType(tempgameconfig) #Note that the operations above are performed separately before being placed in the self object; this is for threadsafeness. This is an atomic operation.
        
        tempdemanqueueconfig=self.extConfig['demAnQueue']
        self.daQueue.demAnQueueConfig=self.configInferType(tempdemanqueueconfig)  #Note that the operations above are performed separately before being placed in the self object; this is for threadsafeness. This is an atomic operation.
        
    def configInferType(self,inconfig): #convenience function for type conversion based on first character of variable name
        #indict is the source ConfigParser object, outdict is the output dictionary which will get keys that are stripped of the first character, which signals type
        outdict={}
        for sub in inconfig.keys():
            if sub.startswith('f'): #Personal Note: I finally understand why the civ 5 XML files are the way there are....
                outdict[sub[1:]]=inconfig.getfloat(sub) #in python, dictionaries are a mutable type
            elif sub.startswith('i'):
                outdict[sub[1:]]=inconfig.getint(sub)
            elif sub.startswith('b'):
                outdict[sub[1:]]=inconfig.getboolean(sub)
        return outdict
            
    def update_message_buffer(self, message):
        self.message_buffer.appendleft(message) #deque maximum length now takes care of the below functionality
        #if len(self.message_buffer)>self.bufferLength:
            #self.message_buffer.pop(0)
        
    def update_message(self,timeleft):
        system('cls')
        demvoteper=round(self.daQueue.demVotePerc) #minimizing the number of times this attribute gets read, in case it changes midway
        if self.democracy:
            votes=self.sortVote() #It's inefficient to do this every time, yes, but the alternative is to implement a custom sorted value hashmap, and I hope that's not necessary...
            print ('\n\n')
            print ('Democracy: '+str(demvoteper)+'%\nAnarchy: '+str(100-demvoteper)+'%\n\nDemocracy!\nTime Remaining: '+str(int(timeleft))+' s\nLast Pushed: '+self.lastPushed+'\n')
            if votes:
                print ('Top Votes:\n')
                for y in votes[0:min(len(votes),self.voteLength)]: #show at most 5 votes
                    print (str(y[1])+" "+y[0])
                print ('\n')
            for y in self.message_buffer:
                print (y)
        else:
            print ('\n\n')
            print ('Democracy: '+str(demvoteper)+'%\nAnarchy: '+str(100-demvoteper)+'%\n\nAnarchy!\n')
            for y in self.message_buffer:
                print (y)
    
    def commandQueue(self):    
        while True:
            #update config file if necessary...see readConfigText regarding threadsafeness
            if time.time()-self.lastConfigTime>self.configUpdateFreq:
                self.readConfigText() #Only place this should ever get called
                self.lastConfigTime=time.time()
            #Toggles Anarchy/Democracy state
            self.daQueue.updateQueue()
            demvoteper=self.daQueue.demVotePerc #minimizing the number of times this attribute gets read (though it should only ever get changed by updateQueue() anyway
            if self.democracy and demvoteper<100-self.botConfig['votethresh']: #Note that the attribute changes here are all atomic operations and threadsafe
                self.democracy=False
                self.game.democracy=False
            elif not self.democracy and demvoteper>self.botConfig['votethresh']:
                self.democracy=True
                self.game.democracy=True
            if self.democracy: #this is Democracy
                lastvotetime=time.time()
                self.queueStatus="Adding Votes"
                while time.time()-lastvotetime<self.botConfig['votetime']: #collect commands for votetime seconds
                    self.daQueue.updateQueue()
                    self.update_message(self.botConfig['votetime']-time.time()+lastvotetime)
                    comList,userList=self.curQueue.getCom()
                    self.lastButton=comList
                    timetaken=time.time()
                    index=0;
                    for button in comList:
                        username=userList[index]
                        index +=1
                        self.queueStatus="Adding Votes"
                        
                        self.addVote(button)
                        userLength=self.commandDisplayLength-len(button)-2
                        printusername=username
                        if len(username)>userLength:
                            printusername=username[0:userLength-3]+'...'
                        self.update_message_buffer(printusername+': '+button)
                        #pbutton(self.message_buffer)
                    if time.time()-timetaken<self.botConfig['checktime']: #don't check more frequently than once every 0.1
                        self.queueStatus="Sleeping"
                        time.sleep(self.botConfig['checktime'])
                self.queueStatus="Running Command"
                vote=self.topVote() #running the command after votetime seconds
                if vote:
                    self.lastPushed=vote
                    words=vote.split("+") #input-time check should have already made sure it's a valid command
                    for y in words:
                        try:
                            self.game.push_button(y)
                        except:
                            time.sleep(0.01) #this is just to fill this catch block. It's bad, yes.
                        time.sleep(.15)
                    self.clearVote()
                self.update_message(0)
            else: #this is Anarchy
                self.queueStatus="Pushing buttons"
                self.update_message(0)
                comList,userList=self.curQueue.getCom()
                self.lastButton=comList
                timetaken=time.time()
                index=0;
                for button in comList:
                    username=userList[index]
                    index +=1
                    words=button.split("+") #input-time check should have already made sure it's a valid command
                    
                    for y in words:
                        if y in self.config['throttled_buttons']:
                            if time.time() - throttle_timers[y] < self.config['throttled_buttons'][y]:
                                continue

                            throttle_timers[y] = time.time()
                        try: #Just in case of weird edge case
                            self.game.push_button(y)
                        except:
                            time.sleep(0.01) #this is just to fill this catch block. It's bad, yes.
                        time.sleep(.05) #Anarchy is a bit more jumpy than Democracy
                    userLength=self.commandDisplayLength-len(button)-2
                    printusername=username
                    if len(username)>userLength:
                        printusername=username[0:userLength-3]+'...'
                    self.update_message_buffer(printusername+': '+button)
                if time.time()-timetaken<self.botConfig['checktime']: #don't check more frequently than once every 0.1
                    self.queueStatus="Sleeping"
                    time.sleep(self.botConfig['checktime'])
                    
    def addVote(self,vote):
        if vote in self.voteCount:
            self.voteCount[vote]=self.voteCount[vote]+1
        else:
            self.voteCount[vote]=1
            
    def topVote(self): #Gets top vote, applying rng to choose among ties
        top=[k for k,v in self.voteItems if v == max(self.voteCount.values())]
        if not top:
            return None
        return random.choice(top)
            
    def sortVote(self):
        sortedItems=sorted(self.voteItems,key=lambda tup: tup[1], reverse=True) #sort using the values, biggest to smallest
        return sortedItems
        
    def clearVote(self):
        self.voteCount.clear()
        
    def run(self):
        #print("New Version!")
        throttle_timers = {button:0 for button in config['throttled_buttons'].keys()}
        t=threading.Thread(target=self.commandQueue, args=()) 
        t.daemon=True
        t.start()
        
        while True: #For threadsafeness see discussion at the top of this file
            #print(self.queueStatus)
            #print(self.lastButton)
            #print(self.curQueue.getStatus())
            #print("Checking for new messages")
            new_messages = self.irc.recv_messages(1024)
            
            if not new_messages:
                continue

            for message in new_messages: 
                button = message['message'].lower()
                username = message['username'].lower()
                words = button.split(" ") #basic input cleanup
                button=words[0]
                
                #Anarchy/Democracy vote
                if button=='democracy':
                    self.daQueue.addVote(1) #No update to try to make this as fast as possible
                elif button=='anarchy':
                    self.daQueue.addVote(0)
                
                if not self.game.is_valid_command(button):
                    continue
                #print("Adding command")
                self.curQueue.addCom([button,username])
Пример #11
0
class Bot:

    def __init__(self):
        self.config = config
        self.irc = Irc(config)
        self.game = Game()
        self.message_buffer = []
        self.scrolling_chat = []
        self.chat_buffer = []
        self.game_tracker = [0,0,0,0,0,0,0,0,0]
        self.windowSurface = pygame.display.set_mode((1300,800), 0, 32)
        self.BLACK = (0,0,0)
        self.WHITE = (255,255,255)
        self.start = time.clock()
        self.game_timer = 0
        self.old_time = 0;
        self.xwins = 0
        self.owins = 0
        self.cats_games = 0
        self.games = 0
        self.who_starts = 0
        self.whos_move = 0
        self.suspend = 0
        self.winner = False
        self.is_cats = False
        self.music = pygame.mixer.Sound('music_loop.wav')
        self.basicFont = pygame.font.SysFont(None, 36)
	
    def reset_message_buffer(self):
        self.message_buffer = []

    def draw_x1(self):
        pygame.draw.line(self.windowSurface, self.WHITE, (180,180), (266,266), 4)
        pygame.draw.line(self.windowSurface, self.WHITE, (180,266), (266,180), 4)
   
    def draw_x2(self):
        pygame.draw.line(self.windowSurface, self.WHITE, (334,180), (420,266), 4)
        pygame.draw.line(self.windowSurface, self.WHITE, (334,266), (420,180), 4)
		
    def draw_x3(self):
        pygame.draw.line(self.windowSurface, self.WHITE, (488,180), (574,266), 4)
        pygame.draw.line(self.windowSurface, self.WHITE, (488,266), (574,180), 4)
		
    def draw_x4(self):
        pygame.draw.line(self.windowSurface, self.WHITE, (180,334), (266,420), 4)
        pygame.draw.line(self.windowSurface, self.WHITE, (180,420), (266,334), 4)
		
    def draw_x5(self):    
        pygame.draw.line(self.windowSurface, self.WHITE, (334,334), (420,420), 4)
        pygame.draw.line(self.windowSurface, self.WHITE, (334,420), (420,334), 4)
		
    def draw_x6(self):
        pygame.draw.line(self.windowSurface, self.WHITE, (488,334), (574,420), 4)
        pygame.draw.line(self.windowSurface, self.WHITE, (488,420), (574,334), 4)
		
    def draw_x7(self):
        pygame.draw.line(self.windowSurface, self.WHITE, (180,488), (266,574), 4)
        pygame.draw.line(self.windowSurface, self.WHITE, (180,574), (266,488), 4)
		
    def draw_x8(self):
        pygame.draw.line(self.windowSurface, self.WHITE, (334,488), (420,574), 4)
        pygame.draw.line(self.windowSurface, self.WHITE, (334,574), (420,488), 4)
		
    def draw_x9(self):
        pygame.draw.line(self.windowSurface, self.WHITE, (488,488), (574,574), 4)
        pygame.draw.line(self.windowSurface, self.WHITE, (488,574), (574,488), 4)
		
    def draw_o1(self):
        pygame.draw.circle(self.windowSurface, self.WHITE,(223,223), 43, 4)
   
    def draw_o2(self):
        pygame.draw.circle(self.windowSurface, self.WHITE,(377,223), 43, 4)
		
    def draw_o3(self):
        pygame.draw.circle(self.windowSurface, self.WHITE,(531,223), 43, 4)
		
    def draw_o4(self):
        pygame.draw.circle(self.windowSurface, self.WHITE,(223,377), 43, 4)
		
    def draw_o5(self):
        pygame.draw.circle(self.windowSurface, self.WHITE,(377,377), 43, 4)
		
    def draw_o6(self):
        pygame.draw.circle(self.windowSurface, self.WHITE,(531,377), 43, 4)
		
    def draw_o7(self):
        pygame.draw.circle(self.windowSurface, self.WHITE,(223,531), 43, 4)
		
    def draw_o8(self):
        pygame.draw.circle(self.windowSurface, self.WHITE,(377,531), 43, 4)
		
    def draw_o9(self):
        pygame.draw.circle(self.windowSurface, self.WHITE,(531,531), 43, 4)
		
#draws the tic tac toe board
    def draw_board(self):
        self.windowSurface.fill(self.BLACK)
        pygame.draw.line(self.windowSurface, self.WHITE, (300,150), (300,600), 4)
        pygame.draw.line(self.windowSurface, self.WHITE, (446,150), (446,600), 4)
        pygame.draw.line(self.windowSurface, self.WHITE, (150,296), (600,296), 4)
        pygame.draw.line(self.windowSurface, self.WHITE, (150,450), (600,450), 4)
 
    def draw_scores(self):
        xtext = self.basicFont.render("X WINS: %s" % str(self.xwins), True, self.WHITE, self.BLACK)
        xtextRect = xtext.get_rect()
        xtextRect = xtextRect.move(10,10)
        otext = self.basicFont.render("O WINS: %s" % str(self.owins), True, self.WHITE, self.BLACK)
        otextRect = otext.get_rect()
        otextRect = otextRect.move(250,10)
        catstext = self.basicFont.render("CATS GAMES: %s" % str(self.cats_games), True, self.WHITE, self.BLACK)
        catstextRect = catstext.get_rect()
        catstextRect = catstextRect.move(500,10)
        self.windowSurface.blit(xtext, xtextRect)
        self.windowSurface.blit(otext, otextRect)
        self.windowSurface.blit(catstext, catstextRect)
#draws the symbols 
    def draw_symbols(self):
        if self.game_tracker[0] == 1:
            self.draw_o1()
        if self.game_tracker[1] == 1:
            self.draw_o2()
        if self.game_tracker[2] == 1:
            self.draw_o3()
        if self.game_tracker[3] == 1:
            self.draw_o4()
        if self.game_tracker[4] == 1:
            self.draw_o5()
        if self.game_tracker[5] == 1:
            self.draw_o6()
        if self.game_tracker[6] == 1:
            self.draw_o7()
        if self.game_tracker[7] == 1:
            self.draw_o8()
        if self.game_tracker[8] == 1:
            self.draw_o9()
        if self.game_tracker[0] == 2:
            self.draw_x1()
        if self.game_tracker[1] == 2:
            self.draw_x2()
        if self.game_tracker[2] == 2:
            self.draw_x3()
        if self.game_tracker[3] == 2:
            self.draw_x4()
        if self.game_tracker[4] == 2:
            self.draw_x5()
        if self.game_tracker[5] == 2:
            self.draw_x6()
        if self.game_tracker[6] == 2:
            self.draw_x7()
        if self.game_tracker[7] == 2:
            self.draw_x8()
        if self.game_tracker[8] == 2:
            self.draw_x9()

    def get_scrolling_chat(self):
        if len(self.chat_buffer) > 0:
            if (len(self.scrolling_chat) + len(self.chat_buffer)) > 25:
                if len(self.chat_buffer) > 25:
                    self.scrolling_chat = self.chat_buffer[(len(self.chat_buffer)-25):]
                else:
                    del self.scrolling_chat[:len(self.chat_buffer)]
                    for item in self.chat_buffer:
                        self.scrolling_chat.append(item)
            else:
                for item in self.chat_buffer:
                    self.scrolling_chat.append(item)
        self.chat_buffer = []
            
    def draw_scrolling_chat(self):	
        counter = 0
        text = self.basicFont.render("CHAT COMMANDS", True, self.WHITE, self.BLACK)
        textRect = text.get_rect()
        textRect = textRect.move(870,10)
        self.windowSurface.blit(text, textRect)
        for item in self.scrolling_chat:
            text = self.basicFont.render(str(item), True, self.WHITE, self.BLACK)
            textRect = text.get_rect()
            textRect = textRect.move(870,(60+(25*counter)))
            self.windowSurface.blit(text, textRect)
            counter+=1
			
    def draw_game(self):
        self.draw_board()
        self.draw_symbols()
        self.draw_scores()
        self.draw_scrolling_chat()
        pygame.display.update()
	
    def reset_game(self):
        self.game_tracker = [0,0,0,0,0,0,0,0,0]
        self.game_timer = time.clock()
        self.old_time = 0
        self.suspend = 0
        self.who_starts += 1
        self.whos_move = self.who_starts%2
        self.winner = False
        self.is_cats = False
		
    def choose_random_move(self):
        templist = []
        counter = 0
        for move in self.game_tracker:
            if move == 0:
                templist.append(counter)
            counter+=1
        return choice(templist)

    def get_valid_moves(self):
        templist = []
        counter = 0
        for move in self.game_tracker:
            if move == 0:
                templist.append(counter+1)
            counter+=1
        return templist
		
        #TODO fix allows user selected move to overwrite filled in spaces.
    def choose_user_move(self):       
        valid_moves = self.get_valid_moves()
        print valid_moves
        templist = [0,0,0,0,0,0,0,0,0]
        for item in self.message_buffer:
            if int(item) in valid_moves:
                templist[int(item)-1]+=1
#        print templist
        max_votes = 0
        for item in templist:
            if item > max_votes:
                max_votes = item
#        print "max votes = %s" % max_votes
        moves_choices = []
        counter = 0
        for item in templist:
            if item == max_votes and max_votes>0:
                moves_choices.append(counter)
            counter+=1
        self.reset_message_buffer()
        print moves_choices
        if len(moves_choices) == 0:		
            return self.choose_random_move()
        else:
            return choice(moves_choices)
		
    def choose_move(self):
        if len(self.message_buffer) == 0:
            random_move = self.choose_random_move()
            print("random move")
            print random_move
            return random_move
        else:
            user_move = self.choose_user_move()
       #     print user_move
            return user_move
			
    def make_move(self):
        if self.winner == True or self.is_cats == True:
            self.games+=1
            self.reset_game()
        elif self.winner == False:
            count = 0
            for move in self.game_tracker:
                if move == 0:
                    count+=1
                    break
            if count > 0:
                self.game_tracker[self.choose_move()]=self.whos_move+1
                if calculate_win_condition(self.game_tracker):
                    self.winner = True
                    if self.whos_move == 0:
                        self.owins+=1
                    else:
                        self.xwins+=1
            elif calculate_win_condition(self.game_tracker):
                self.winner = True
                if self.whos_move == 0:
                    self.owins+=1
                else:
                    self.xwins+=1
            else:
                self.is_cats = True
                self.cats_games+=1
				
    def alternate_turn(self):
        if self.whos_move == 0:
            self.whos_move = 1
        else:
            self.whos_move = 0
    def run(self):
		# created by Aidan Thomson
        #throttle_timers = {button:0 for button in config['throttled_buttons'].keys()}
        #get new messages from chat. Store valid messages only in the message buffer list 
		#after 5-10 seconds calculate the move that was chosen. If no move was chosen automatically choose an open one.
		#update the board.
		#calculate an end game condition
		#
        self.reset_game()
        #self.music.play(-1)

        while True:
           # self.draw_game()
            timer = time.clock() - self.game_timer
            if((timer-self.old_time)>.90):
                self.old_time = timer
                timer = int(timer)
 #
                self.draw_game()
                # every 10 seconds make a move and check for a win
                if timer > 0 and timer%3 == 0:
                    self.make_move()
                    self.alternate_turn()
				
            new_messages = None
            new_messages = self.irc.recv_messages(1024)   
            if new_messages != None: 
                for message in new_messages: 		
                    button = message['message'].lower()
                    username = message['username'].lower()
               #     print username + " " + button
                    if self.game.is_valid_button(button): 
                #        print button
                        self.message_buffer.append(button)
                        self.chat_buffer.append(str(username + ': ' + button))
                self.get_scrolling_chat()
#                self.reset_message_buffer()
            
            for event in pygame.event.get():
                if event.type == QUIT:
                    pygame.quit()
                    sys.exit()
Пример #12
0
class Bot:

    def __init__(self):
        self.config = config
        self.irc = Irc(config)

        self.message_buffer = [{'username': '', 'button': ''}] * 10


    def set_message_buffer(self, message):
        chat_height = 10
        self.message_buffer.insert(chat_height - 1, message)
        self.message_buffer.pop(0)

    def start_golden_timer(self, cc):
        has_alerted_golden = False
        has_alerted_reindeer = False
        while True:
            time.sleep(1)
            golden_life = cc.get_golden_life()
            reindeer_life = cc.get_reindeer_life()
            print str(golden_life) + str(has_alerted_golden)
            print str(reindeer_life) + str(has_alerted_reindeer)
            if golden_life == 0:
                has_alerted_golden = False
            elif golden_life > 0 and has_alerted_golden == False:
                self.irc.say('GOLDEN!!!')
                has_alerted_golden = True

            if reindeer_life == 0:
                has_alerted_reindeer = False
            elif reindeer_life > 0 and has_alerted_reindeer == False:
                self.irc.say('REINDEER!!!')
                has_alerted_reindeer = True

    def run(self, cc):
        self.game = Game(cc)
        last_start = time.time()

        
        reset_counter = 0
        reset_counter_max = self.config['reset_bar']['max']
        pledge_counter = 0
        pledge_counter_max = config['pledge_bar']['max']
        pop_counter = 0
        pop_counter_max = config['pop_bar']['max']
        next_golden = time.clock() + 5

        while True:
            new_messages = self.irc.recv_messages(1024)
            
            if not new_messages:
                continue

            for message in new_messages: 
                button = message['message'].lower()
                username = message['username'].lower()
                suffix = ''
                
                if button[:12] == 'info upgrade':
                    if len(button) > 12:
                        try:
                            upgrade_ind = int(button[12])-1
                        except:
                            upgrade_ind = -1
                    else:
                        upgrade_ind = 0
                    upgrade_name = self.game.cc.get_upgrade_name(upgrade_ind)
                    if upgrade_name == 'undefined':
                        self.irc.say('Invalid Upgrade')
                    else:
                        numdivs = 0
                        upgrade_price = self.game.cc.get_upgrade_price(upgrade_ind)
                        if upgrade_price > 1000000:
                            upgrade_price = float(upgrade_price) / 1000000
                            numdivs += 1
                            while upgrade_price > 1000:
                                upgrade_price = float(upgrade_price) / 1000
                                numdivs += 1
                        if numdivs == 0:
                            pricesuffix = ''
                        elif numdivs == 1:
                            pricesuffix = ' M'
                        elif numdivs == 2:
                            pricesuffix = ' B'
                        elif numdivs == 3:
                            pricesuffix = ' T'
                        elif numdivs == 4:
                            pricesuffix = ' Qa'
                        elif numdivs == 5:
                            pricesuffix = ' Qi'
                        elif numdivs == 6:
                            pricesuffix = ' Sx'
                        elif numdivs == 7:
                            pricesuffix = ' Sp'
                        elif numdivs == 8:
                            pricesuffix = ' O'
                        short_price = "%.3f%s" % (upgrade_price, pricesuffix)
                        self.irc.say('UPGRADE' + str(upgrade_ind+1) + ': ' + upgrade_name + ' (' + short_price + ')')
                elif button == '!commands':
                    self.irc.say('Clickclick..., Golden, Reindeer, Dungeon, Up, Down, Left, Right, Stay, Upgrade1 - Upgrade5, Info UpgradeX, NoPledge, Santa, Cursor, Grandma, Farm, Factory, Mine, Shipment, Lab, Portal, Time, Antimatter, Prism, View, Scrolldown, Scrollup, Expand, Collapse, Reset, Continue')
                elif self.game.is_valid_button(button):
                    if button == 'pop' and config['pop_bar']['enable']:
                        pop_counter += 1
                        if pop_counter >= pop_counter_max:
                            pop_counter = 0
                            self.game.push_button('unwrinkle')
                        set_pop_bar(pop_counter)
                    elif button == 'reset' or button == 'continue': 
                        if button == 'reset':
                            reset_counter += 5
                            if reset_counter >= reset_counter_max:
                                reset_counter = 0
                                self.game.push_button('reset')
                                pledge_counter = 0
                                set_pledge_bar(pledge_counter)
                        else:
                            reset_counter -= 5
                            if reset_counter < 0:
                                reset_counter = 0
                        suffix = '({0}/{1})'.format(reset_counter,reset_counter_max)
                    elif button[:7] == 'upgrade':
                        reset_counter -= 1
                        if reset_counter < 0:
                            reset_counter = 0
                        if len(button) == 7:
                            upgrade_ind = 0
                        else:
                            upgrade_ind = int(button[7])-1
                        name = self.game.cc.get_upgrade_name(upgrade_ind)
                        if config['pledge_bar']['enable'] and (name == 'Elder Pledge' or name == 'Elder Covenant' or name == 'Revoke Elder Covenant'):
                          # Throttle pledges if necessary
                          pledge_counter += 1
                          if pledge_counter >= pledge_counter_max:
                            self.game.push_button(button)
                            pledge_counter = 0
                          set_pledge_bar(pledge_counter)
                          button = 'pledge/cov'
                          suffix = '({0}/{1})'.format(pledge_counter,pledge_counter_max)
                        else:
                          self.game.push_button(button)
                    elif button == 'nopledge':
                        reset_counter -= 1
                        if reset_counter < 0:
                            reset_counter = 0
                        if pledge_counter > 0:
                            pledge_counter -= 1
                            set_pledge_bar(pledge_counter)
                        suffix = '({0}/{1})'.format(pledge_counter,pledge_counter_max)
                    else:
                        reset_counter -= 1
                        if reset_counter < 0:
                            reset_counter = 0
                        
                        print button

                        self.set_message_buffer({'username': username, 'button': button})

                        self.game.push_button(button)
                    command(username, button + suffix)
                    set_reset_bar(reset_counter)
                else:
                    numclicks = button.count("click")
                    if numclicks > 0:
                      if numclicks > 9:
                        numclicks = 9
                      reset_counter -= 1 #numclicks?
                      if reset_counter < 0:
                              reset_counter = 0
                      self.game.push_button("click%d" % numclicks)
                      command(username, "click(%d)" % numclicks)
                      set_reset_bar(reset_counter)