def current_vote_count(cls) -> Optional[Tuple[int, int]]: yes = minqlx.get_configstring(10) no = minqlx.get_configstring(11) if yes and no: return int(yes), int(no) return None
def handle_vote(self, player, yes): if not self.is_vote_active(): return if player in self.has_voted: ident = player.steam_id if (player.privileges != None or self.db.has_permission(ident, 3)): minqlx.force_vote(yes) if yes: word = "passed" else: word = "vetoed" self.msg("{}^7 {} the vote.".format(player.name, word)) return minqlx.RET_STOP_ALL self.has_voted.append(player) if (player.privileges != None): # at least give the impression that the QLDS admin/mod voted normally. if yes: yes_votes = int(minqlx.get_configstring(10)) yes_votes += 1 minqlx.set_configstring(10, str(yes_votes)) else: no_votes = int(minqlx.get_configstring(11)) no_votes += 1 minqlx.set_configstring(11, str(no_votes)) return minqlx.RET_STOP_ALL
def current_vote_count(cls): yes = minqlx.get_configstring(10) no = minqlx.get_configstring(11) if yes and no: return int(yes), int(no) else: return None
def cmd_clan(self, player, msg, channel): index = 529 + player.id tag_key = _tag_key.format(player.steam_id) if len(msg) < 2: if tag_key in self.db: del self.db[tag_key] cs = minqlx.parse_variables(minqlx.get_configstring(index), ordered=True) del cs["cn"] del cs["xcn"] new_cs = "".join(["\\{}\\{}".format(key, cs[key]) for key in cs]).lstrip("\\") minqlx.set_configstring(index, new_cs) player.tell("The clan tag has been cleared.") else: player.tell("Usage to set a clan tag: ^4{} <clan_tag>".format(msg[0])) return minqlx.RET_STOP_EVENT if len(self.clean_text(msg[1])) > 5: player.tell("The clan tag can only be at most 5 characters long, excluding colors.") return minqlx.RET_STOP_EVENT # If the player already has a clan, we need to edit the current # configstring. We can't just append cn and xcn. tag = self.clean_tag(msg[1]) cs = minqlx.parse_variables(minqlx.get_configstring(index), ordered=True) cs["xcn"] = tag cs["cn"] = tag new_cs = "".join(["\\{}\\{}".format(key, cs[key]) for key in cs]) minqlx.set_configstring(index, new_cs) self.db[tag_key] = tag self.msg("{} changed clan tag to {}".format(player, tag)) return minqlx.RET_STOP_EVENT
def cmd_clan(self, player, msg, channel): index = 529 + player.id tag_key = _tag_key.format(player.steam_id) if len(msg) < 2: if tag_key in self.db: del self.db[tag_key] cs = minqlx.parse_variables(minqlx.get_configstring(index), ordered=True) del cs["cn"] del cs["xcn"] new_cs = "".join(["\\{}\\{}".format(key, cs[key]) for key in cs]).lstrip("\\") minqlx.set_configstring(index, new_cs) player.tell("The clan tag has been cleared.") else: player.tell("Usage to set a clan tag: ^6{} <clan_tag>".format(msg[0])) return minqlx.RET_STOP_EVENT if len(self.clean_text(msg[1])) > 5: player.tell("The clan tag can only be at most 5 characters long, excluding colors.") return minqlx.RET_STOP_EVENT # If the player already has a clan, we need to edit the current # configstring. We can't just append cn and xcn. tag = self.clean_tag(msg[1]) cs = minqlx.parse_variables(minqlx.get_configstring(index), ordered=True) cs["xcn"] = tag cs["cn"] = tag new_cs = "".join(["\\{}\\{}".format(key, cs[key]) for key in cs]) minqlx.set_configstring(index, new_cs) self.db[tag_key] = tag self.msg("{} changed clan tag to {}".format(player, tag)) return minqlx.RET_STOP_EVENT
def set_map_subtitles(): cs = minqlx.get_configstring(678) if cs: cs += " - " minqlx.set_configstring(678, cs + "Running minqlx ^6{}^7 with plugins ^6{}^7." .format(minqlx.__version__, minqlx.__plugins_version__)) cs = minqlx.get_configstring(679) if cs: cs += " - " minqlx.set_configstring(679, cs + "Check ^6http://github.com/MinoMino/minqlx^7 for more details.")
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 cancel(self): # Check if there's a current vote in the first place. cs = minqlx.get_configstring(9) if not cs: 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))) # Return None if the vote's cancelled (like if the round starts before vote's over). super().trigger(votes, vote, args, None)
def set_map_subtitles(): cs = minqlx.get_configstring(678) if cs: cs += " - " minqlx.set_configstring( 678, cs + "Running minqlx ^6{}^7 with plugins ^6{}^7.".format( minqlx.__version__, minqlx.__plugins_version__)) cs = minqlx.get_configstring(679) if cs: cs += " - " minqlx.set_configstring( 679, cs + "Check ^6http://github.com/MinoMino/minqlx^7 for more details.")
def set_map_subtitles(): # We save the actual values before setting them so that we can retrieve them in Game. setattr(minqlx, "_map_title", minqlx.get_configstring(3)) setattr(minqlx, "_map_subtitle1", minqlx.get_configstring(678)) setattr(minqlx, "_map_subtitle2", minqlx.get_configstring(679)) cs = minqlx.get_configstring(678) if cs: cs += " - " minqlx.set_configstring(678, cs + "Running minqlx ^6{}^7 with plugins ^6{}^7." .format(minqlx.__version__, minqlx.__plugins_version__)) cs = minqlx.get_configstring(679) if cs: cs += " - " minqlx.set_configstring(679, cs + "Check ^6http://github.com/MinoMino/minqlx^7 for more details.")
def clan(self, tag): index = self.id + 529 cs = minqlx.parse_variables(minqlx.get_configstring(index), ordered=True) cs["xcn"] = tag cs["cn"] = tag new_cs = "".join(["\\{}\\{}".format(key, cs[key]) for key in cs]) minqlx.set_configstring(index, new_cs)
def __init__(self, cached=True): self.cached = cached self._valid = True cs = minqlx.get_configstring(0) if not cs: self._valid = False raise NonexistentGameError("Tried to instantiate a game while no game is active.")
def brand_map(self): if self.get_cvar("qlx_brandingPrependMapName", bool): minqlx.set_configstring(3, self.game.map_title + " " + (self.get_cvar("qlx_serverBrandName"))) else: minqlx.set_configstring(3, (self.get_cvar("qlx_serverBrandName"))) cs = self.game.map_subtitle1 if cs: cs += " - " minqlx.set_configstring(678, cs + (self.get_cvar("qlx_serverBrandTopField"))) cs = self.game.map_subtitle2 if cs: cs += " - " minqlx.set_configstring(679, cs + (self.get_cvar("qlx_serverBrandBottomField"))) if self.get_cvar("qlx_rainbowBrandName", bool): # Thanks Mino for this bit! def rotating_colors(): i = 0 while True: res = (i % 7) + 1 i += 1 yield res map_name = minqlx.get_configstring(3) r = rotating_colors() res = "" for i in range(len(map_name)): res += "^{}{}".format(next(r), map_name[i]) minqlx.set_configstring(3, res)
def __getitem__(self, key): cs = minqlx.get_configstring(0) if not cs: self._valid = False raise NonexistentGameError("Invalid game. Is the server loading a new map?") cvars = minqlx.parse_variables(cs) return cvars[key]
def clan(self): """The clan tag. Not actually supported by QL, but it used to be and fortunately the scoreboard still properly displays it if we manually set the configstring to use clan tags.""" try: return minqlx.parse_variables(minqlx.get_configstring(529 + self._id))["cn"] except KeyError: return ""
def __contains__(self, key: str) -> bool: cs = minqlx.get_configstring(0) if not cs: self._valid = False raise NonexistentGameError("Invalid game. Is the server loading a new map?") cvars = minqlx.parse_variables(cs) return key in cvars
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 __init__(self): self.add_hook("round_end", self.handle_round_end) self.add_hook("round_start", self.handle_round_start) self.add_hook("set_configstring", self.handle_set_configstring) self.add_hook("kamikaze_use", self.handle_kamikaze_use) self.add_hook("kamikaze_explode", self.handle_kamikaze_explode) # self.add_command("drop", self.cmd_drop_holdable) self.add_command("spawn_test", self.spawn_kamikaze, 2) # reload config string # it runs handle_set_configstring minqlx.set_configstring(CS_ITEMS, minqlx.get_configstring(CS_ITEMS)) self.enabled = False
def brand_map(self): if self.get_cvar("qlx_serverBrandName") == None: self.set_cvar("qlx_serverBrandName", self.game.map_title) if self.get_cvar("qlx_brandingPrependMapName", bool): topBranding = self.game.map_title + " " + self.get_cvar( "qlx_serverBrandName") else: topBranding = self.get_cvar("qlx_serverBrandName") if self.get_cvar("qlx_brandingAppendGameType", bool): minqlx.set_configstring(3, topBranding + " " + self.game.type) else: minqlx.set_configstring(3, topBranding) if self.get_cvar("qlx_serverBrandTopField") != None: cs = self.game.map_subtitle1 if cs: cs += " - " minqlx.set_configstring( 678, cs + (self.get_cvar("qlx_serverBrandTopField"))) if self.get_cvar("qlx_serverBrandBottomField") != None: cs = self.game.map_subtitle2 if cs: cs += " - " minqlx.set_configstring( 679, cs + (self.get_cvar("qlx_serverBrandBottomField"))) if self.get_cvar("qlx_rainbowBrandName", bool): # Thanks Mino for this bit! def rotating_colors(): i = 0 while True: res = (i % 7) + 1 i += 1 yield res map_name = self.clean_text(minqlx.get_configstring(3)) r = rotating_colors() res = "" for i in range(len(map_name)): res += "^{}{}".format(next(r), map_name[i]) minqlx.set_configstring(3, res)
def map_title(self): """The full name of the map. Ex.: ``Longest Yard``.""" return minqlx.get_configstring(3)
def blue_score(self): return int(minqlx.get_configstring(7))
def is_vote_active(cls): if minqlx.get_configstring(9): return True else: return False
def workshop_items(self): return [int(i) for i in minqlx.get_configstring(715).split()]
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 cmd_clan(self, player, msg, channel): index = 529 + player.id tag_key = _tag_key.format(player.steam_id) if len(msg) < 2: if tag_key in self.db: del self.db[tag_key] cs = minqlx.parse_variables(minqlx.get_configstring(index), ordered=True) del cs["cn"] del cs["xcn"] new_cs = "".join([ "\\{}\\{}".format(key, cs[key]) for key in cs ]).lstrip("\\") minqlx.set_configstring(index, new_cs) player.tell("^3The clan tag has been cleared.") else: player.tell( "^3Usage to set a clan tag: ^6{} <clan_tag>".format( msg[0])) return minqlx.RET_STOP_EVENT cleanTag = self.clean_text(msg[1]) if len(cleanTag) > 5: player.tell( "^3The clan tag can only be at most 5 characters long, excluding colors." ) return minqlx.RET_STOP_EVENT tag = self.clean_tag(msg[1]) #The clan tag being added is checked if the player is not in the clan members list. if player.steam_id not in self.clanTagMembers: colors = self.get_cvar("qlx_clanmembersTagColors", bool) case = self.get_cvar("qlx_clanmembersLetterCase", bool) #Checks the tag if tag enforcement is not color or case specific. if not colors and not case: tempList = [] for tags in self.clanTag: tempList.append(self.clean_text(tags).lower()) if cleanTag.lower() in tempList: player.tell( "^3You must be added to the clan members list to put that tag on in this server." ) return minqlx.RET_STOP_EVENT #Checks the tag if tag enforcement is not color specific but is case specific. elif not colors: tempList = [] for tags in self.clanTag: tempList.append(self.clean_text(tags)) if cleanTag in tempList: player.tell( "^3You must be added to the clan members list to put that tag on in this server." ) return minqlx.RET_STOP_EVENT #Checks the tag if tag enforcement is not case specific but is color specific. elif not case: tempList = [] for tags in self.clanTag: tempList.append(tags.lower()) if tag.lower() in tempList: player.tell( "^3You must be added to the clan members list to put that tag on in this server." ) return minqlx.RET_STOP_EVENT #Checks the tag if tag enforcement is case and color specific. elif cleanTag in self.clanTag or tag in self.clanTag: player.tell( "^3You must be added to the clan members list to put that tag on in this server." ) return minqlx.RET_STOP_EVENT # If the player already has a clan, we need to edit the current # configstring. We can't just append cn and xcn. cs = minqlx.parse_variables(minqlx.get_configstring(index), ordered=True) cs["xcn"] = tag cs["cn"] = tag new_cs = "".join(["\\{}\\{}".format(key, cs[key]) for key in cs]) minqlx.set_configstring(index, new_cs) self.db[tag_key] = tag self.msg("{} changed clan tag to {}".format(player, tag)) return minqlx.RET_STOP_EVENT
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 red_score(self): return int(minqlx.get_configstring(6))
def is_vote_active(cls) -> bool: return bool(minqlx.get_configstring(9))
def set_player_configstring(self, player, index, key, value): # will let you set a configstring on a per-player basis. original_configstring = minqlx.parse_variables(minqlx.get_configstring(index)) original_configstring[key] = value modified_configstring = (("\\") + ("\\".join("\\".join((k,str(v))) for k,v in sorted(original_configstring.items())))) minqlx.send_server_command(player.id, "cs {} {}".format(index, modified_configstring))
def cvars(self): """A dictionary of unprocessed cvars. Use attributes whenever possible, but since some cvars might not have attributes on this class, this could be useful. """ return minqlx.parse_variables(minqlx.get_configstring(0))
def reference_steamworks(item_id): new_ref = minqlx.get_configstring(715) + "{} ".format(item_id) minqlx.set_configstring(715, new_ref)
def steamworks_items(self): return minqlx.get_configstring(715).split()