You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在specqueue.py中正确调用auto_rebalance.py的函数并传参?

问题描述

我需要在specqueue.py的team_placement方法调用player.put(team)时,将handle_team_switch_attempt(self, player, old_team, new_team)的参数传递给auto_rebalance.py中的同名方法。之前尝试在player.put(team)后执行self.plugins['auto_rebalance'].handle_team_switch_attempt(self, player, old, new),但该方法无效。

相关代码

auto_rebalance.py

def handle_team_switch_attempt(self, player, old, new):
    """
    Handles the case where a player switches from spectators to "red", "blue", or "any" team, and
    the resulting teams would be suboptimal balanced.
    :param: player: the player that attempted the switch
    :param: old: the old team of the switching player
    :param: new: the new team that switching player would be put onto
    :return: minqlx.RET_NONE if the team switch should be allowed or minqlx.RET_STOP_EVENT if the switch should not
    be allowed, and we put the player on a better-suited team.
    """
    if not self.game:
        return minqlx.RET_NONE

    if self.last_new_player_id == player.steam_id and new in ["spectator", "free"]:
        self.last_new_player_id = None

    if self.game.state != "in_progress":
        return minqlx.RET_NONE

    if old not in ["spectator", "free"] or new not in ['red', 'blue', 'any']:
        return minqlx.RET_NONE

    if "balance" not in self.plugins:
        Plugin.msg("^1balance^7 plugin not loaded, ^1auto rebalance^7 not possible.")
        return minqlx.RET_NONE

    gametype = self.game.type_short
    if gametype not in SUPPORTED_GAMETYPES:
        return minqlx.RET_NONE

    teams = self.teams()
    if len(teams["red"]) == len(teams["blue"]):
        self.last_new_player_id = player.steam_id
        return minqlx.RET_NONE

    if not self.last_new_player_id:
        return minqlx.RET_NONE

    last_new_player = Plugin.player(self.last_new_player_id)
    if not last_new_player:
        self.last_new_player_id = None
        return minqlx.RET_NONE

    other_than_last_players_team = self.other_team(last_new_player.team)
    new_player_team = teams[other_than_last_players_team].copy() + [player]
    proposed_diff = self.calculate_player_average_difference(gametype,
                                                             teams[last_new_player.team].copy(),
                                                             new_player_team)

    alternative_team_a = [player for player in teams[last_new_player.team] if player != last_new_player] + \
                         [player]
    alternative_team_b = teams[other_than_last_players_team].copy() + [last_new_player]
    alternative_diff = self.calculate_player_average_difference(gametype,
                                                                alternative_team_a,
                                                                alternative_team_b)

    self.last_new_player_id = None
    if proposed_diff > alternative_diff:
        last_new_player.tell(f"{last_new_player.clean_name}, you have been moved to "
                             f"{self.format_team(other_than_last_players_team)} to maintain team balance.")
        last_new_player.put(other_than_last_players_team)
        if new in [last_new_player.team]:
            return minqlx.RET_NONE
        if new not in ["any"]:
            player.tell(f"{player.clean_name}, you have been moved to {self.format_team(last_new_player.team)} "
                        f"to maintain team balance.")
        player.put(last_new_player.team)
        return minqlx.RET_STOP_ALL

specqueue.py

def handle_team_switch_attempt(self, player, old_team, new_team):
    if self.q_game_info[0] in SUPPORTED_GAMETYPES and new_team != "spectator" and old_team == "spectator":
        teams = self.teams()
        at_max_players = False
        join_locked = False
        self.remove_from_afk(player)
        if self.q_game_info[0] in TEAM_BASED_GAMETYPES:
            if len(teams["red"]) + len(teams["blue"]) >= self.get_max_players():
                at_max_players = True
            join_locked = self.free_locked
        elif self.q_game_info[0] in NONTEAM_BASED_GAMETYPES:
            if len(self.teams()["free"]) >= self.get_max_players():
                at_max_players = True
            join_locked = self.red_locked or self.blue_locked
        if self._queue or join_locked or self.game.state in ["in_progress", "countdown"] or\
                at_max_players:
            self.add_to_queue(player)
            self.remove_from_spec(player)
            self.check_for_opening(0.2)
            self.update_queue_tags()
            return minqlx.RET_STP_ALL

def team_placement(self, player, team, add_queue=False):
    if ENABLE_LOG:
        self.queue_log.info("specqueue team placement: {} put on team {}".format(player, team))
    try:
        player.put(team)
        if add_queue:
            self.add_to_queue_pos(player, 0)
    except Exception as e:
        if ENABLE_LOG:
            self.queue_log.info("specqueue team placement Exception: {}".format([e]))
解决方案

你之前的调用错误在于传递了specqueue的self给auto_rebalance的方法,而且没有正确获取玩家的旧团队信息,修正步骤如下:

  1. 记录玩家旧团队
    在调用player.put(team)前,先获取玩家当前所在的团队(即切换前的旧团队):
old_team = player.team
  1. 正确调用auto_rebalance的方法
    auto_rebalance的handle_team_switch_attempt方法需要传入它自身的实例作为第一个参数,而非specqueue的self。先获取插件实例,再调用方法:
auto_rebalance = self.plugins.get('auto_rebalance')
if auto_rebalance:
    auto_rebalance.handle_team_switch_attempt(auto_rebalance, player, old_team, team)
  1. 修改后的team_placement方法
    完整修改后的代码如下:
def team_placement(self, player, team, add_queue=False):
    if ENABLE_LOG:
        self.queue_log.info("specqueue team placement: {} put on team {}".format(player, team))
    try:
        old_team = player.team  # 记录切换前的旧团队
        player.put(team)
        # 调用auto_rebalance的团队切换处理方法
        auto_rebalance = self.plugins.get('auto_rebalance')
        if auto_rebalance:
            auto_rebalance.handle_team_switch_attempt(auto_rebalance, player, old_team, team)
        if add_queue:
            self.add_to_queue_pos(player, 0)
    except Exception as e:
        if ENABLE_LOG:
            self.queue_log.info("specqueue team placement Exception: {}".format([e]))
  1. 注意事项
  • 确保auto_rebalance插件已正确加载,避免因实例不存在导致调用失败;
  • 检查传递的old_team和team是否为合法值(如spectator、red、blue等),符合auto_rebalance方法的参数校验要求。

内容的提问来源于stack exchange,提问作者David Houk

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 11:45:35