def pick_default_next_map(self): selection = self.get_selection() maps_history = MapsHistory() config = VoteMapConfig() all_maps = ALL_MAPS if not config.get_votemap_allow_default_to_offsensive(): logger.debug( "Not allowing default to offensive, removing all offensive maps" ) selection = [m for m in selection if not "offensive" in m] all_maps = [m for m in ALL_MAPS if not "offensive" in m] if not maps_history: raise ValueError("Map history is empty") return { DefaultMethods.least_played_suggestions: partial(self.pick_least_played_map, selection), DefaultMethods.least_played_all_maps: partial(self.pick_least_played_map, all_maps), DefaultMethods.random_all_maps: lambda: random.choice( list(set(all_maps) - set([maps_history[0]["name"]]))), DefaultMethods.random_suggestions: lambda: random.choice( list(set(selection) - set([maps_history[0]["name"]]))), }[config.get_votemap_default_method()]()
def gen_selection(self): config = VoteMapConfig() logger.debug( f"""Generating new map selection for vote map with the following criteria: {ALL_MAPS} {config.get_votemap_number_of_options()=} {config.get_votemap_ratio_of_offensives_to_offer()=} {config.get_votemap_number_of_last_played_map_to_exclude()=} {config.get_votemap_consider_offensive_as_same_map()=} {config.get_votemap_allow_consecutive_offensives()=} {config.get_votemap_allow_consecutive_offensives_of_opposite_side()=} {config.get_votemap_default_method()=} """) selection = suggest_next_maps( MapsHistory(), ALL_MAPS, selection_size=config.get_votemap_number_of_options(), exclude_last_n=config. get_votemap_number_of_last_played_map_to_exclude(), offsensive_ratio=config.get_votemap_ratio_of_offensives_to_offer(), consider_offensive_as_same_map=config. get_votemap_consider_offensive_as_same_map(), allow_consecutive_offensive=config. get_votemap_allow_consecutive_offensives(), allow_consecutive_offensives_of_opposite_side=config. get_votemap_allow_consecutive_offensives_of_opposite_side(), current_map=self.get_current_map(), ) self.red.delete("MAP_SELECTION") self.red.lpush("MAP_SELECTION", *selection) logger.info("Saved new selection: %s", selection)
def on_map_change(old_map_info, new_map_info): config = VoteMapConfig() if config.get_vote_enabled(): votemap = VoteMap() votemap.gen_selection() votemap.clear_votes() votemap.apply_with_retry(nb_retry=4)
def count_vote(rcon: RecordedRcon, struct_log): config = VoteMapConfig() if not config.get_vote_enabled(): return v = VoteMap() if vote := v.is_vote(struct_log.get("sub_content")): logger.debug("Vote chat detected: %s", struct_log["message"]) map_name = v.register_vote(struct_log["player"], struct_log["timestamp_ms"] / 1000, vote) try: temporary_broadcast( rcon, config.get_votemap_thank_you_text().format( player_name=struct_log["player"], map_name=map_name), 5, ) except Exception: logger.warning("Unable to output thank you message") v.apply_with_retry(nb_retry=2)
def on_map_change(old_map: str, new_map: str): logger.info("Running on_map_change hooks with %s %s", old_map, new_map) try: config = VoteMapConfig() if config.get_vote_enabled(): votemap = VoteMap() votemap.gen_selection() votemap.clear_votes() votemap.apply_with_retry(nb_retry=4) #temporary_welcome_in( # "%s{votenextmap_vertical}" % config.get_votemap_instruction_text(), # seconds=60 * 20, # restore_after_seconds=60 * 5, #) except Exception: logger.exception("Unexpected error while running vote map") try: record_stats_worker(MapsHistory()[1]) except Exception: logger.exception("Unexpected error while running stats worker")
def apply_results(self): config = VoteMapConfig() votes = self.get_votes() first = Counter(votes.values()).most_common(1) if not first: next_map = self.pick_default_next_map() logger.warning( "No votes recorded, defaulting with %s using default winning map %s", config.get_votemap_default_method(), next_map, ) else: logger.info(f"{votes=}") next_map = first[0][0] if next_map not in ALL_MAPS: raise ValueError( f"{next_map=} is not part of the all map list {ALL_MAPS=}") if next_map not in (selection := self.get_selection()): raise ValueError( f"{next_map=} is not part of vote select {selection=}") logger.info(f"Winning map {next_map=}")
def scrolling_votemap(rcon, winning_maps, repeat=10): config = VoteMapConfig() vote_options = format_map_vote(rcon, "line", short_names=False) if not vote_options: return "" separator = ' *** ' options = separator.join([vote_options] * repeat) instructions = config.get_votemap_instruction_text().replace('\n', ' ') repeat_instructions = max( int(len(options) / (len(instructions) + len(separator))), 1) instructions = separator.join([instructions] * repeat_instructions) winning_maps = format_winning_map( rcon, winning_maps, display_count=0, default=config.get_votemap_no_vote_text()) repeat_winning_maps = max( int(len(options) / (len(winning_maps) + len(separator))), 1) winning_maps = separator.join([winning_maps] * repeat_winning_maps) return "{}\n{}\n{}".format(options, instructions, winning_maps)