def load(self, steamid): try: with open("{}/{}_{}.{}".format(self.root, self.prefix, str(steamid), self.extension)) as file_to_read: player_dict = byteify(json.load(file_to_read)) player_object = Player(**player_dict) return player_object except Exception: raise KeyError
def __init__(self): self.width = 0 self.height = 0 self.cell = None self.players = [Player(), Player()] self.round = 0 self.initialized = False self._players_separated = False self.score = None self.search_depth = 0 self.best_moves = [] self.separated_score = None self.separated_search_depth = 0 self.separated_best_moves = [] self.hash = None self.children = None self._legal_moves = None self.legal_player = None self.adjacents = None
def load_all(self): # TODO: this need to be cached or whatever! all_players_dict = {} for root, dirs, files in os.walk(self.root): for filename in files: if filename.startswith(self.prefix) and filename.endswith(".{}".format(self.extension)): with open("{}/{}".format(self.root, filename)) as file_to_read: player_dict = byteify(json.load(file_to_read)) player_dict['health'] = 0 all_players_dict[player_dict['steamid']] = Player(**player_dict) return all_players_dict
def add_player_to_whitelist(self, command): try: player_object = self.bot.players.get(self.player_steamid) p = re.search( r"add\splayer\s(?P<steamid>([0-9]{17}))|(?P<entityid>[0-9]+)\sto whitelist", command) if p: steamid_to_whitelist = p.group("steamid") entityid_to_whitelist = p.group("entityid") if steamid_to_whitelist is None: steamid_to_whitelist = self.bot.players.entityid_to_steamid( entityid_to_whitelist) if steamid_to_whitelist is False: raise KeyError try: player_object_to_whitelist = self.bot.players.get( steamid_to_whitelist) except KeyError: player_dict = { 'steamid': steamid_to_whitelist, "name": 'unknown offline player' } player_object_to_whitelist = Player(**player_dict) if self.bot.whitelist.add(player_object, player_object_to_whitelist, save=True): self.tn.send_message_to_player( player_object_to_whitelist, "you have been whitelisted by {}".format( player_object.name), color=self.bot.chat_colors['alert']) else: self.tn.send_message_to_player( player_object, "could not find a player with steamid {}".format( steamid_to_whitelist), color=self.bot.chat_colors['warning']) self.tn.send_message_to_player( player_object, "you have whitelisted {}".format( player_object_to_whitelist.name), color=self.bot.chat_colors['success']) except Exception as e: logger.error(e) pass
def parse_settings(self, key, value): if key == "timebank": self.timebank = int(value) elif key == "time_per_move": self.time_per_move = int(value) elif key == "player_names": self.player_names = value.split(',') self.players = {name: Player(name) for name in self.player_names} elif key == "your_bot": self.me = self.players[value] self.opponent = self.players[[name for name in self.player_names if name != value][0]] elif key == "initial_stack": self.initial_stack = int(value) elif key == "initial_big_blind": self.initial_big_blind = int(value) elif key == "hands_per_blind_level": self.hands_per_blind_level = int(value)
def remove_player_from_whitelist(self, command): try: player_object = self.bot.players.get(self.player_steamid) p = re.search( r"remove\splayer\s(?P<steamid>([0-9]{17}))|(?P<entityid>[0-9]+)\sfrom whitelist", command) if p: steamid_to_dewhitelist = p.group("steamid") entityid_to_dewhitelist = p.group("entityid") if steamid_to_dewhitelist is None: steamid_to_dewhitelist = self.bot.players.entityid_to_steamid( entityid_to_dewhitelist) if steamid_to_dewhitelist is False: raise KeyError try: player_object_to_dewhitelist = self.bot.players.get( steamid_to_dewhitelist) except KeyError: player_dict = {'steamid': steamid_to_dewhitelist} player_object_to_dewhitelist = Player(**player_dict) if self.bot.whitelist.remove(player_object_to_dewhitelist): self.tn.send_message_to_player( player_object_to_dewhitelist, "you have been de-whitelisted by {}".format( player_object.name), color=self.bot.chat_colors['alert']) else: self.tn.send_message_to_player( player_object, "could not find a player with steamid '{}' on the whitelist" .format(steamid_to_dewhitelist), color=self.bot.chat_colors['warning']) return False self.tn.send_message_to_player( player_object, "you have de-whitelisted {}".format( player_object_to_dewhitelist.name), color=self.bot.chat_colors['success']) except Exception as e: logger.error(e) pass
def parse_settings(self, key, value): if key == "timebank": self.timebank = int(value) elif key == "time_per_move": self.time_per_move = int(value) elif key == "player_names": self.player_names = value.split(',') self.players = {name: Player(name) for name in self.player_names} elif key == "your_bot": self.me = self.players[value] self.opponent = self.players[[ name for name in self.player_names if name != value ][0]] elif key == "your_botid": self.me.id = value self.opponent.id = str(2 - (int(value) + 1)) elif key == "field_width": self.field.width = int(value) elif key == "field_height": self.field.height = int(value) elif key == "max_rounds": self.max_rounds = int(value) else: stderr.write('Cannot parse settings input with key {}'.format(key))
def run(self): self.is_active = True # this is set so the main loop can be started / stopped self.tn.togglechatcommandhide("/") listplayers_dict = {} list_players_timeout_start = 0 listplayers_interval = self.listplayers_interval while self.is_active: if timeout_occurred(listplayers_interval, list_players_timeout_start): # get all currently online players and store them in a dictionary last_listplayers_dict = listplayers_dict listplayers_dict = self.poll_players() if len( listplayers_dict ) == 0: # adjust poll frequency when the server is empty listplayers_interval = self.listplayers_interval_idle else: listplayers_interval = self.listplayers_interval list_players_timeout_start = time.time() # prune players not online anymore for player in set(self.players.players_dict) - set( listplayers_dict.keys()): del self.players.players_dict[player] # create new player entries / update existing ones for player_steamid, player_dict in listplayers_dict.iteritems( ): try: player_object = self.players.get(player_steamid) # player is already online and needs updating player_object.update(**player_dict) if last_listplayers_dict != listplayers_dict: # but only if they have changed at all! """ we only update this if things have changed since this poll is slow and might be out of date. Any teleport issued by the bot or a player would generate more accurate data If it HAS changed it is by all means current and can be used to update the object. """ self.players.upsert(player_object) except KeyError: # player has just come online try: player_object = self.players.load(player_steamid) # player has a file on disc, update database! player_object.update(**player_dict) self.players.upsert(player_object) except KeyError: # player is totally new, create file! player_object = Player(**player_dict) self.players.upsert(player_object, save=True) # there should be a valid object state here now ^^ """ handle player-threads """ for player_steamid, player_object in self.players.players_dict.iteritems( ): """ start player_observer_thread for each player not already being observed """ if player_steamid not in self.active_player_threads_dict: player_observer_thread_stop_flag = Event() player_observer_thread = PlayerObserver( player_observer_thread_stop_flag, self, str(player_steamid) ) # I'm passing the bot (self) into it to have easy access to it's variables player_observer_thread.name = player_steamid # nice to have for the logs player_observer_thread.isDaemon() player_observer_thread.trigger_action( player_object, "entered the stream") player_observer_thread.start() # self.players.upsert(player_object, save=True) self.active_player_threads_dict.update({ player_steamid: { "event": player_observer_thread_stop_flag, "thread": player_observer_thread } }) for player_steamid in set( self.active_player_threads_dict) - set( self.players.players_dict.keys()): """ prune all active_player_threads from players no longer online """ active_player_thread = self.active_player_threads_dict[ player_steamid] stop_flag = active_player_thread["thread"] stop_flag.stopped.set() del self.active_player_threads_dict[player_steamid] """ since telnet_lines can contain one or more actual telnet lines, we add them to a queue and pop one line at a time. I hope to minimize the risk of a clogged bot this way, it might result in laggy commands. I shall have to monitor that """ try: telnet_lines = self.tn.read_line() except Exception as e: logger.error(e) raise IOError self.telnet_lines_list = deque() if telnet_lines is not None: for line in telnet_lines: self.telnet_lines_list.append( line) # get the current global telnet-response try: telnet_line = self.telnet_lines_list.popleft() except IndexError: telnet_line = None if telnet_line is not None: m = re.search(self.match_types_system["telnet_commands"], telnet_line) if not m or m and m.group('telnet_command') != 'lp': if telnet_line != '': logger.debug(telnet_line) """ send telnet_line to player-thread check 'chat' telnet-line(s) for any known playername currently online """ for player_steamid, player_object in self.players.players_dict.iteritems( ): possible_action_for_player = re.search( player_object.name, telnet_line) if possible_action_for_player: if player_steamid in self.active_player_threads_dict: active_player_thread = self.active_player_threads_dict[ player_steamid] active_player_thread[ "thread"].trigger_action_by_telnet(telnet_line) """ work through triggers caused by telnet_activity """ # telnet_player_connected is the earliest usable player-data line available, perfect spot to fire off triggers for whitelist and blacklist and such m = re.search( self.match_types_system["telnet_player_connected"], telnet_line) if m: try: player_object = self.players.load(m.group("player_id")) except KeyError: player_dict = { 'entityid': int(m.group("entity_id")), 'steamid': m.group("player_id"), 'name': m.group("player_name"), 'ip': m.group("player_ip") } player_object = Player(**player_dict) logger.info( "found player '{}' in the stream, accessing matrix...". format(player_object.name)) command_queue = [] for observer in self.observers: if observer[ 0] == 'trigger': # we only want the triggers here observer_function_name = observer[2] observer_parameters = eval( observer[3] ) # yes. Eval. It's my own data, chill out! command_queue.append( [observer_function_name, observer_parameters]) for command in command_queue: try: command[0](*command[1]) except TypeError: command[0](command[1]) time.sleep(0.05) # to limit the speed a bit ^^
def ban_player(self, command): """Bans a player Keyword arguments: self -- the bot command -- the entire chatline (bot command) expected bot command: /ban player <steamid/entityid> for <ban_reason> example: /ban player 76561198040658370 for Being an asshat notes: both the ban-er and the ban-ee will be mentioned in the ban-message there is no timeframe, bans are permanent for now """ try: player_object = self.bot.players.get(self.player_steamid) p = re.search( r"ban\splayer\s(?P<steamid>([0-9]{17}))|(?P<entityid>[0-9]+)\sfor\s(?P<ban_reason>.+)", command) if p: steamid_to_ban = p.group("steamid") entityid_to_ban = p.group("entityid") if steamid_to_ban is None: steamid_to_ban = self.bot.players.entityid_to_steamid( entityid_to_ban) if steamid_to_ban is False: raise KeyError reason_for_ban = p.group("ban_reason") try: player_object_to_ban = self.bot.players.get(steamid_to_ban) except KeyError: player_dict = { 'steamid': steamid_to_ban, "name": 'unknown offline player' } player_object_to_ban = Player(**player_dict) if self.tn.ban( player_object_to_ban, "{} banned {} for {}".format(player_object.name, player_object_to_ban.name, reason_for_ban)): self.tn.send_message_to_player( player_object_to_ban, "you have been banned by {}".format(player_object.name), color=self.bot.chat_colors['alert']) self.tn.send_message_to_player( player_object, "you have banned player {}".format( player_object_to_ban.name), color=self.bot.chat_colors['success']) self.tn.say("{} has been banned by {} for '{}'!".format( player_object_to_ban.name, player_object.name, reason_for_ban), color=self.bot.chat_colors['success']) else: self.tn.send_message_to_player( player_object, "could not find a player with id {}".format( steamid_to_ban), color=self.bot.chat_colors['warning']) except Exception as e: logger.error(e) pass