def load_config(): config = get_config() config_file = "minqlx/config.cfg" if os.path.isfile(config_file): config.read(config_file) config["DEFAULT"] = { "PluginsFolder" : "minqlx/plugins", "CommandPrefix" : "!" } # Set default database if present. if "Database" in config["Core"]: db = config["Core"]["Database"] if db.lower() == "redis": minqlx.Plugin.database = minqlx.database.Redis # Set owner. # TODO: Convert regular SteamID format to 64-bit format automatically. if "Owner" in config["Core"]: try: global _owner _owner = int(config["Core"]["Owner"]) except ValueError: logger = minqlx.get_logger() logger.error("Failed to parse the Owner Steam ID. Make sure it's in SteamID64 format.") else: logger = minqlx.get_logger() logger.warning("Owner not set in the config. Consider setting it.") sys.path.append(os.path.dirname(config["Core"]["PluginsFolder"])) global _command_prefix _command_prefix = config["Core"]["CommandPrefix"].strip() return config else: raise(RuntimeError("Config file '{}' not found.".format(os.path.abspath(config_file))))
def handle_console_print(text: Optional[str]): # pylint: disable=inconsistent-return-statements """Called whenever the server prints something to the console and when rcon is used.""" if not text: return # noinspection PyBroadException try: # Log console output. Removes the need to have stdout logs in addition to minqlx.log. minqlx.get_logger().debug(text.rstrip("\n")) res = minqlx.EVENT_DISPATCHERS["console_print"].dispatch(text) if res is False: return False if _print_redirection: global _print_buffer # pylint: disable=global-statement _print_buffer += text # pylint: disable=undefined-variable if isinstance(res, str): return res return text except: # pylint: disable=bare-except minqlx.log_exception() return True
def dispatch(self, passed): # Check if there's a current vote in the first place. cs = minqlx.get_configstring(9) if not cs: minqlx.get_logger().warning("vote_ended went off without configstring 9.") return res = _re_vote.match(cs) vote = res.group("cmd") args = res.group("args") if res.group("args") else "" votes = (int(minqlx.get_configstring(10)), int(minqlx.get_configstring(11))) super().dispatch(votes, vote, args, passed)
def parse_variables(varstr: str, ordered: bool = False) -> Dict[Any, Any]: """ Parses strings of key-value pairs delimited by "\\" and puts them into a dictionary. :param: varstr: The string with variables. :type: varstr: str :param: ordered: Whether it should use :class:`collections.OrderedDict` or not. :type: ordered: bool :returns: dict -- A dictionary with the variables added as key-value pairs. """ res: Dict[Any, Any] if ordered: res = collections.OrderedDict() else: res = {} if not varstr.strip(): return res _vars = varstr.lstrip("\\").split("\\") try: for i in range(0, len(_vars), 2): res[_vars[i]] = _vars[i + 1] except IndexError: # Log and return incomplete dict. logger = minqlx.get_logger() logger.warning("Uneven number of keys and values: %s", varstr) return res
def handle_new_game(is_restart): # This is called early in the launch process, so it's a good place to initialize # minqlx stuff that needs QLDS to be initialized. global _first_game if _first_game: minqlx.late_init() _first_game = False # A good place to warn the owner if ZMQ stats are disabled. global _zmq_warning_issued if not bool(int(minqlx.get_cvar( "zmq_stats_enable"))) and not _zmq_warning_issued: logger = minqlx.get_logger() logger.warning( "Some events will not work because ZMQ stats is not enabled. " "Launch the server with \"zmq_stats_enable 1\"") _zmq_warning_issued = True minqlx.set_map_subtitles() if not is_restart: try: minqlx.EVENT_DISPATCHERS["map"].dispatch( minqlx.get_cvar("mapname"), minqlx.get_cvar("g_factory")) except: minqlx.log_exception() return True try: minqlx.EVENT_DISPATCHERS["new_game"].dispatch() except: minqlx.log_exception() return True
def handle_new_game(is_restart): # This is called early in the launch process, so it's a good place to initialize # minqlx stuff that needs QLDS to be initialized. global _first_game if _first_game: minqlx.late_init() _first_game = False # A good place to warn the owner if ZMQ stats are disabled. global _zmq_warning_issued if not bool(int(minqlx.get_cvar("zmq_stats_enable"))) and not _zmq_warning_issued: logger = minqlx.get_logger() logger.warning("Some events will not work because ZMQ stats is not enabled. " "Launch the server with \"zmq_stats_enable 1\"") _zmq_warning_issued = True minqlx.set_map_subtitles() if not is_restart: try: minqlx.EVENT_DISPATCHERS["map"].dispatch( minqlx.get_cvar("mapname"), minqlx.get_cvar("g_factory")) except: minqlx.log_exception() return True try: minqlx.EVENT_DISPATCHERS["new_game"].dispatch() except: minqlx.log_exception() return True
def parse_variables(varstr, ordered=False): """ Parses strings of key-value pairs delimited by "\\" and puts them into a dictionary. :param varstr: The string with variables. :type varstr: str :param ordered: Whether it should use :class:`collections.OrderedDict` or not. :type ordered: bool :returns: dict -- A dictionary with the variables added as key-value pairs. """ if ordered: res = collections.OrderedDict() else: res = {} if not varstr.strip(): return res vars = varstr.lstrip("\\").split("\\") try: for i in range(0, len(vars), 2): res[vars[i]] = vars[i + 1] except IndexError: # Log and return incomplete dict. logger = minqlx.get_logger() logger.warning("Uneven number of keys and values: {}".format(varstr)) return res
def dispatch(self, *args, **kwargs): """Calls all the handlers that have been registered when hooking this event. The recommended way to use this for events that inherit this class is to override the method with explicit arguments (as opposed to this one's) and call this method by using ``super().dispatch()``. Handlers have several options for return values that can affect the flow: - minqlx.RET_NONE or None -- Continue execution normally. - minqlx.RET_STOP -- Stop any further handlers from being called. - minqlx.RET_STOP_EVENT -- Let handlers process it, but stop the event at the engine-level. - minqlx.RET_STOP_ALL -- Stop handlers **and** the event. - Any other value -- Passed on to :func:`self.handle_return`, which will by default simply send a warning to the logger about an unknown value being returned. Can be overridden so that events can have their own special return values. :param: args: Any arguments. :param: kwargs: Any keyword arguments. """ # Allow subclasses of this to edit the arguments without having # to reimplement this method. Whenever an unknown return value # is returned, we pass it on to handle_return. self.args = args self.kwargs = kwargs logger = minqlx.get_logger() # Log the events as they come in. if self.name not in self.no_debug: dbgstr = f"{self.name}{args}" if len(dbgstr) > 100: dbgstr = dbgstr[0:99] + ")" logger.debug(dbgstr) plugins = self.plugins.copy() self.return_value = True for i in range(5): for plugin in plugins: for handler in plugins[plugin][i]: # noinspection PyBroadException try: res = handler(*self.args, **self.kwargs) if res == minqlx.RET_NONE or res is None: continue if res == minqlx.RET_STOP: return True if res == minqlx.RET_STOP_EVENT: self.return_value = False if res == minqlx.RET_STOP_ALL: return False # Got an unknown return value. return_handler = self.handle_return(handler, res) # pylint: disable=assignment-from-no-return if return_handler is not None: return return_handler except: # pylint: disable=bare-except minqlx.log_exception(plugin) continue return self.return_value
def dispatch(self, *args, **kwargs): """Calls all the handlers that have been registered when hooking this event. The recommended way to use this for events that inherit this class is to override the method with explicit arguments (as opposed to the this one's) and call this method by using ``super().dispatch()``. Handlers have several options for return values that can affect the flow: - minqlx.RET_NONE or None -- Continue execution normally. - minqlx.RET_STOP -- Stop any further handlers from being called. - minqlx.RET_STOP_EVENT -- Let handlers process it, but stop the event at the engine-level. - minqlx.RET_STOP_ALL -- Stop handlers **and** the event. - Any other value -- Passed on to :func:`self.handle_return`, which will by default simply send a warning to the logger about an unknown value being returned. Can be overridden so that events can have their own special return values. :param args: Any arguments. :param kwargs: Any keyword arguments. """ # Allow subclasses of this to edit the arguments without having # to reimplement this method. Whenever an unknown return value # is returned, we pass it on to handle_return. self.args = args self.kwargs = kwargs logger = minqlx.get_logger() # Log the events as they come in. if self.name not in self.no_debug: dbgstr = "{}{}".format(self.name, args) if len(dbgstr) > 100: dbgstr = dbgstr[0:99] + ")" logger.debug(dbgstr) plugins = self.plugins.copy() self.return_value = True for i in range(5): for plugin in plugins: for handler in plugins[plugin][i]: try: res = handler(*self.args, **self.kwargs) if res == minqlx.RET_NONE or res is None: continue elif res == minqlx.RET_STOP: return True elif res == minqlx.RET_STOP_EVENT: self.return_value = False elif res == minqlx.RET_STOP_ALL: return False else: # Got an unknown return value. return_handler = self.handle_return(handler, res) if return_handler is not None: return return_handler except: minqlx.log_exception(plugin) continue return self.return_value
def handle_set_configstring(index, value): """Called whenever the server tries to set a configstring. Can return False to stop the event. """ try: res = minqlx.EVENT_DISPATCHERS["set_configstring"].dispatch(index, value) if res == False: return False elif isinstance(res, str): value = res # GAME STATE CHANGES if index == 0: old_cs = minqlx.parse_variables(minqlx.get_configstring(index)) if not old_cs: return new_cs = minqlx.parse_variables(value) old_state = old_cs["g_gameState"] new_state = new_cs["g_gameState"] if old_state != new_state: if old_state == "PRE_GAME" and new_state == "IN_PROGRESS": minqlx.EVENT_DISPATCHERS["vote_ended"].cancel() # Cancel current vote if any. # minqlx.EVENT_DISPATCHERS["game_start"].dispatch() elif old_state == "PRE_GAME" and new_state == "COUNT_DOWN": minqlx.EVENT_DISPATCHERS["game_countdown"].dispatch() elif old_state == "COUNT_DOWN" and new_state == "IN_PROGRESS": minqlx.EVENT_DISPATCHERS["vote_ended"].cancel() # Cancel current vote if any. # minqlx.EVENT_DISPATCHERS["game_start"].dispatch() elif old_state == "IN_PROGRESS" and new_state == "PRE_GAME": pass elif old_state == "COUNT_DOWN" and new_state == "PRE_GAME": pass else: logger = minqlx.get_logger() logger.warning("UNKNOWN GAME STATES: {} - {}".format(old_state, new_state)) # ROUND COUNTDOWN AND START if index == 661: cvars = minqlx.parse_variables(value) if cvars: round_number = int(cvars["round"]) if round_number and "time" in cvars: if round_number == 1: # This is the case when the first countdown starts. minqlx.EVENT_DISPATCHERS["round_countdown"].dispatch(round_number) return minqlx.EVENT_DISPATCHERS["round_countdown"].dispatch(round_number) return elif round_number: minqlx.EVENT_DISPATCHERS["round_start"].dispatch(round_number) return return res except: minqlx.log_exception() return True
def owner(): """Returns the SteamID64 of the owner. This is set in the config.""" try: sid = int(minqlx.get_cvar("qlx_owner")) if sid == -1: raise RuntimeError return sid except: logger = minqlx.get_logger() logger.error("Failed to parse the Owner Steam ID. Make sure it's in SteamID64 format.")
def handle_return(self, handler, value): """Handle an unknown return value. If this returns anything but None, the it will stop execution of the event and pass the return value on to the C-level handlers. This method can be useful to override, because of the fact that you can edit the arguments that will be passed on to any handler after whatever handler returned *value* by editing *self.args*, *self.kwargs*. Furthermore, *self.return_value* is the return value that will be sent to the C-level handler if the event isn't stopped later along the road. """ logger = minqlx.get_logger() logger.warning("Handler '{}' returned unknown value '{}' for event '{}'" .format(handler.__name__, value, self.name))
def run(self): loop = asyncio.new_event_loop() logger = minqlx.get_logger("irc") asyncio.set_event_loop(loop) while not self.stop_event.is_set(): try: loop.run_until_complete(self.connect()) except Exception: minqlx.log_exception() # Disconnected. Try reconnecting in 30 seconds. logger.info("Disconnected from IRC. Reconnecting in 30 seconds...") time.sleep(30) loop.close()
def run(self): loop = asyncio.new_event_loop() logger = minqlx.get_logger("irc") asyncio.set_event_loop(loop) while not self.stop_event.is_set(): try: loop.run_until_complete(self.connect()) except Exception: minqlx.log_exception() # Disconnected. Try reconnecting in 30 seconds. logger.info("Disconnected from IRC. Reconnecting in 30 seconds...") minqlx.CHAT_CHANNEL.reply("Connection attempt to ^3CommLink^7 server failed, retrying in 30 seconds.") time.sleep(30) loop.close()
def handle_console_print(text): """Called whenever the server prints something to the console and when rcon is used.""" try: if not text: return # Log console output. Removes the need to have stdout logs in addition to minqlx.log. minqlx.get_logger().debug(text.rstrip("\n")) res = minqlx.EVENT_DISPATCHERS["console_print"].dispatch(text) if res is False: return False if _print_redirection: global _print_buffer _print_buffer += text if isinstance(res, str): return res return text except: minqlx.log_exception() return True
def handle_console_print(text): """Called whenever the server prints something to the console and when rcon is used.""" try: text = text.rstrip() if not text: return # Log console output. Removes the need to have stdout logs in addition to minqlx.log. minqlx.get_logger().debug(text) res = minqlx.EVENT_DISPATCHERS["console_print"].dispatch(text) if res == False: return False elif isinstance(res, str): text = res if _print_redirection: global _print_buffer _print_buffer += text return res except: minqlx.log_exception() return True
def handle_new_game(): # This is called early in the launch process, so it's a good place to warn # the owner if ZMQ stats are disabled. if not bool(int(minqlx.get_cvar("zmq_stats_enable"))) and not _zmq_warning_issued: global _zmq_warning_issued logger = minqlx.get_logger() logger.warning( "Some events will not work because ZMQ stats is not enabled. " 'Launch the server with "zmq_stats_enable 1"' ) _zmq_warning_issued = True try: minqlx.EVENT_DISPATCHERS["map"].dispatch(minqlx.get_cvar("mapname"), minqlx.get_cvar("g_factory")) except: minqlx.log_exception() return True
def owner() -> Optional[int]: # pylint: disable=inconsistent-return-statements """Returns the SteamID64 of the owner. This is set in the config.""" # noinspection PyBroadException try: owner_cvar = minqlx.get_cvar("qlx_owner") if owner_cvar is None: raise RuntimeError sid = int(owner_cvar) if sid == -1: raise RuntimeError return sid except: # pylint: disable=bare-except logger = minqlx.get_logger() logger.error( "Failed to parse the Owner Steam ID. Make sure it's in SteamID64 format." ) return None
def handle_new_game(): # This is called early in the launch process, so it's a good place to warn # the owner if ZMQ stats are disabled. if not bool(int( minqlx.get_cvar("zmq_stats_enable"))) and not _zmq_warning_issued: global _zmq_warning_issued logger = minqlx.get_logger() logger.warning( "Some events will not work because ZMQ stats is not enabled. " "Launch the server with \"zmq_stats_enable 1\"") _zmq_warning_issued = True try: minqlx.EVENT_DISPATCHERS["map"].dispatch(minqlx.get_cvar("mapname"), minqlx.get_cvar("g_factory")) except: minqlx.log_exception() return True
def state(self): """A string describing the state of the game. Possible values: - *warmup* -- The game has yet to start and is waiting for players to ready up. - *countdown* -- Players recently readied up, and it's counting down until the game starts. - *in_progress* -- The game is in progress. """ s = self["g_gameState"] if s == "PRE_GAME": return "warmup" elif s == "COUNT_DOWN": return "countdown" elif s == "IN_PROGRESS": return "in_progress" else: logger = minqlx.get_logger() logger.warning("Got unknown game state: {}".format(s)) return s
def handle_input(self, player, msg, channel): if not msg.strip(): return name = msg.strip().split(" ", 1)[0].lower() is_client_cmd = channel == "client_command" pass_through = True for priority_level in self._commands: for cmd in priority_level: if cmd.is_eligible_name(name) and cmd.is_eligible_channel( channel) and cmd.is_eligible_player( player, is_client_cmd): # Client commands will not pass through to the engine unless told to explicitly. # This is to avoid having to return RET_STOP_EVENT just to not get the "unknown cmd" msg. if is_client_cmd: pass_through = cmd.client_cmd_pass # Dispatch "command" and allow people to stop it from being executed. if minqlx.EVENT_DISPATCHERS["command"].dispatch( player, cmd, msg) == False: return True res = cmd.execute(player, msg, channel) if res == minqlx.RET_STOP: return elif res == minqlx.RET_STOP_EVENT: pass_through = False elif res == minqlx.RET_STOP_ALL: # C-level dispatchers expect False if it shouldn't go to the engine. return False elif res == minqlx.RET_USAGE and cmd.usage: channel.reply("^7Usage: ^6{} {}".format( name, cmd.usage)) elif res != None and res != minqlx.RET_NONE: logger = minqlx.get_logger(None) logger.warning( "Command '{}' with handler '{}' returned an unknown return value: {}" .format(cmd.name, cmd.handler.__name__, res)) return pass_through
def __init__(self): self.add_hook("new_game", self.handle_new_game) self.add_hook("game_end", self.handle_game_end) self.add_hook("player_loaded", self.handle_player_loaded) self.add_hook("player_disconnect", self.handle_player_disconnect) self.add_hook("team_switch", self.handle_team_switch) self.add_hook("team_switch_attempt", self.handle_team_switch_attempt) self.add_hook("set_configstring", self.handle_configstring, priority=minqlx.PRI_HIGH) self.add_hook("client_command", self.handle_client_command) self.add_hook("vote_ended", self.handle_vote_ended) self.add_hook("console_print", self.handle_console_print) self.add_command(("q", "queue"), self.cmd_lq) self.add_command("afk", self.cmd_afk) self.add_command("here", self.cmd_playing) self.add_command("qversion", self.cmd_qversion) self.add_command(("teamsize", "ts"), self.cmd_teamsize, priority=minqlx.PRI_HIGH) # Commands for debugging self.add_command("qpush", self.cmd_qpush, 5) self.add_command("qadd", self.cmd_qadd, 5, usage="<id>") self.add_command("qupd", self.cmd_qupd, 5) self.version = "1.0" self._queue = [] self._vip_queue = [] self._afk = [] self._tags = {} self.initialize() self.is_red_locked = False self.is_blue_locked = False self.is_push_pending = False self.is_endscreen = False ######## TODO: replace for something better, because ######## loading during the endgame screen might cause bugs self.set_cvar_once("qlx_queueSetAfkPermission", "2") self.set_cvar_once("qlx_queueAFKTag", "^3AFK") self.game_port = minqlx.get_cvar("net_port") self.jointimes = {} self._extended_vip = self.check_if_extended_vip() self.test_logger = minqlx.get_logger() self.qlogger = self._configure_logger()
def __init__(self): self.add_hook("new_game", self.handle_new_game) self.add_hook("game_end", self.handle_game_end) self.add_hook("player_loaded", self.handle_player_loaded) self.add_hook("player_disconnect", self.handle_player_disconnect) self.add_hook("team_switch", self.handle_team_switch) self.add_hook("team_switch_attempt", self.handle_team_switch_attempt) self.add_hook("set_configstring", self.handle_configstring, priority=minqlx.PRI_HIGH) self.add_hook("client_command", self.handle_client_command) self.add_hook("vote_ended", self.handle_vote_ended) self.add_hook("console_print", self.handle_console_print) self.add_command(("q", "queue"), self.cmd_lq) self.add_command("afk", self.cmd_afk) self.add_command("here", self.cmd_playing) self.add_command("qversion", self.cmd_qversion) self.add_command(("teamsize", "ts"), self.cmd_teamsize, priority=minqlx.PRI_HIGH) # Commands for debugging self.add_command("qpush", self.cmd_qpush, 5) self.add_command("qadd", self.cmd_qadd, 5, usage="<id>") self.add_command("qupd", self.cmd_qupd, 5) self.version = "2.7.3" self.plugin_updater_url = "https://raw.githubusercontent.com/Melodeiro/minqlx-plugins_mattiZed/master/queue.py" self._queue = [] self._afk = [] self._tags = {} self.initialize() self.is_red_locked = False self.is_blue_locked = False self.is_push_pending = False self.is_endscreen = self.game is None # game is None is between game_end (probably) and new_game self.set_cvar_once("qlx_queueSetAfkPermission", "2") self.set_cvar_once("qlx_queueAFKTag", "^3AFK") self.test_logger = minqlx.get_logger()
def handle_input(self, player, msg, channel): if not msg.strip(): return name = msg.split(" ", 1)[0].lower() is_client_cmd = channel == "client_command" pass_through = True for priority_level in self._commands: for cmd in priority_level: if cmd.is_eligible_name(name) and cmd.is_eligible_channel(channel) and cmd.is_eligible_player(player, is_client_cmd): # Client commands will not pass through to the engine unless told to explicitly. # This is to avoid having to return RET_STOP_EVENT just to not get the "unknown cmd" msg. if is_client_cmd: pass_through = cmd.client_cmd_pass # Dispatch "command" and allow people to stop it from being executed. if minqlx.EVENT_DISPATCHERS["command"].dispatch(player, cmd, msg) == False: return True res = cmd.execute(player, msg, channel) if res == minqlx.RET_STOP: return elif res == minqlx.RET_STOP_EVENT: pass_through = False elif res == minqlx.RET_STOP_ALL: # C-level dispatchers expect False if it shouldn't go to the engine. return False elif res == minqlx.RET_USAGE and cmd.usage: channel.reply("^7Usage: ^6{} {}".format(name, cmd.usage)) elif res != None and res != minqlx.RET_NONE: logger = minqlx.get_logger(None) logger.warning("Command '{}' with handler '{}' returned an unknown return value: {}" .format(cmd.name, cmd.handler.__name__, res)) return pass_through
def logger(self): """An instance of :class:`logging.Logger`, but initialized for this plugin.""" return minqlx.get_logger(self)
def execute(self, player: minqlx.Player, msg: str, channel: AbstractChannel) -> Optional[int]: logger = minqlx.get_logger(self.plugin) logger.debug("%s executed: %s @ %s -> %s", player.steam_id, self.name[0], self.plugin.name, channel) return self.handler(player, msg.split(), channel)
def execute(self, player, msg, channel): logger = minqlx.get_logger(self.plugin) logger.debug("{} executed: {} @ {} -> {}" .format(player.steam_id, self.name[0], self.plugin.name, channel)) return self.handler(player, msg.split(), channel)
def execute(self, player, msg, channel): logger = minqlx.get_logger(self.plugin) logger.debug("{} executed: {} @ {} -> {}".format( player.steam_id, self.name[0], self.plugin.name, channel)) return self.handler(player, msg.split(), channel)
def handle_set_configstring(index: int, value: str): # pylint: disable=inconsistent-return-statements """Called whenever the server tries to set a configstring. Can return False to stop the event. """ global _ad_round_number # pylint: disable=global-statement # noinspection PyBroadException try: res = minqlx.EVENT_DISPATCHERS["set_configstring"].dispatch( index, value) if res is False: return False if isinstance(res, str): value = res # VOTES if index == 9 and value: cmd = value.split() vote = cmd[0] if cmd else "" args = " ".join(cmd[1:]) if len(cmd) > 1 else "" minqlx.EVENT_DISPATCHERS["vote_started"].dispatch(vote, args) return # GAME STATE CHANGES if index == 0: old_cs = minqlx.parse_variables(minqlx.get_configstring(index)) if not old_cs: return new_cs = minqlx.parse_variables(value) old_state = old_cs["g_gameState"] new_state = new_cs["g_gameState"] if old_state != new_state: if old_state == "PRE_GAME" and new_state == "IN_PROGRESS": pass elif old_state == "PRE_GAME" and new_state == "COUNT_DOWN": _ad_round_number = 1 minqlx.EVENT_DISPATCHERS["game_countdown"].dispatch() elif old_state == "COUNT_DOWN" and new_state == "IN_PROGRESS": pass # minqlx.EVENT_DISPATCHERS["game_start"].dispatch() elif old_state == "IN_PROGRESS" and new_state == "PRE_GAME": pass elif old_state == "COUNT_DOWN" and new_state == "PRE_GAME": pass else: logger = minqlx.get_logger() logger.warning( f"UNKNOWN GAME STATES: {old_state} - {new_state}") # ROUND COUNTDOWN AND START elif index == 661: cvars = minqlx.parse_variables(value) if cvars: if "turn" in cvars: # it is A&D if int(cvars["state"]) == 0: return # round cvar appears only on round countdown # and first round is 0, not 1 try: round_number = int(cvars["round"]) * 2 + 1 + int( cvars["turn"]) _ad_round_number = round_number except KeyError: round_number = _ad_round_number else: # it is CA round_number = int(cvars["round"]) if round_number and "time" in cvars: minqlx.EVENT_DISPATCHERS["round_countdown"].dispatch( round_number) return if round_number: minqlx.EVENT_DISPATCHERS["round_start"].dispatch( round_number) return return res except: # pylint: disable=bare-except minqlx.log_exception() return True
def logger(self): return minqlx.get_logger(self.plugin)
def handle_set_configstring(index, value): """Called whenever the server tries to set a configstring. Can return False to stop the event. """ try: res = minqlx.EVENT_DISPATCHERS["set_configstring"].dispatch( index, value) if res == False: return False elif isinstance(res, str): value = res # GAME STATE CHANGES if index == 0: old_cs = minqlx.parse_variables(minqlx.get_configstring(index)) if not old_cs: return new_cs = minqlx.parse_variables(value) old_state = old_cs["g_gameState"] new_state = new_cs["g_gameState"] if old_state != new_state: if old_state == "PRE_GAME" and new_state == "IN_PROGRESS": minqlx.EVENT_DISPATCHERS["vote_ended"].cancel( ) # Cancel current vote if any. #minqlx.EVENT_DISPATCHERS["game_start"].dispatch() elif old_state == "PRE_GAME" and new_state == "COUNT_DOWN": minqlx.EVENT_DISPATCHERS["game_countdown"].dispatch() elif old_state == "COUNT_DOWN" and new_state == "IN_PROGRESS": minqlx.EVENT_DISPATCHERS["vote_ended"].cancel( ) # Cancel current vote if any. #minqlx.EVENT_DISPATCHERS["game_start"].dispatch() elif old_state == "IN_PROGRESS" and new_state == "PRE_GAME": pass elif old_state == "COUNT_DOWN" and new_state == "PRE_GAME": pass else: logger = minqlx.get_logger() logger.warning("UNKNOWN GAME STATES: {} - {}".format( old_state, new_state)) # ROUND COUNTDOWN AND START if index == 661: cvars = minqlx.parse_variables(value) if cvars: round_number = int(cvars["round"]) if round_number and "time" in cvars: if round_number == 1: # This is the case when the first countdown starts. minqlx.EVENT_DISPATCHERS["round_countdown"].dispatch( round_number) return minqlx.EVENT_DISPATCHERS["round_countdown"].dispatch( round_number) return elif round_number: minqlx.EVENT_DISPATCHERS["round_start"].dispatch( round_number) return return res except: minqlx.log_exception() return True