Yaribz / SPADS

SpringRTS Perl Autohost for Dedicated Server
GNU General Public License v3.0
15 stars 13 forks source link

Inconsistent vote permissions behavior in boss mode. #61

Closed Beherith closed 1 year ago

Beherith commented 1 year ago

BAR uses two sets of command files, both start with importing the entire {commands.conf}

https://github.com/beyond-all-reason/spads_config_bar/blob/main/etc/commands_default.conf commands_default.conf is used by the global default preset [team], thus I assume it is also picked up for the presets [ffa], [coop], [duel] and [tourney] as well. This uses the usual regular command permissions.

[kick]
battle,pv,game:player:|100:0
::|100:

https://github.com/beyond-all-reason/spads_config_bar/blob/main/etc/commands_custom.conf commands_custom.conf is used only in the global preset [custom], and is intended to make sure that non-bossed players cannot vote out the boss, and cant vote for kick or other commands, so their votelevel is set to 0.

[kick]
battle,pv,game:player:|100:10
::|100:

Expected behavior:

[custom] !kick commands from the boss should not trigger a vote.

[all others] !kick commands from the boss should not trigger a vote.

Observed behavior

[team] Boss saying !kick triggers a vote

[ffa] Boss saying !kick triggers a vote

[coop] Boss saying !kick triggers a vote

[duel] Boss saying !kick triggers a vote

[tourney] Boss saying !kick triggers a vote

[custom] Boss saying !kick does not trigger a vote

Yaribz commented 1 year ago

I'm not sure I understand the issue, the observed behavior is the correct one according to the configuration...

[kick]
battle,pv,game:player:|100:0
::|100:

The 0 at the end of the second line above means any player can vote for the command, even when boss mode is enabled.

Beherith commented 1 year ago

@Beherith this is your job you idiot

Beherith commented 1 year ago

Ok, I finally understood my own problem (based on user feedback). What users seem to want is:

  1. Boss can kick anyone without vote.
  2. Players can call a vote kick

Is this possible?

Yaribz commented 1 year ago

This is not possible without a plugin, because: 1) the entire "boss" logic is based on the fact that the boss mode doesn't change the access rights of the bossed users, it only reduces the access rights of the non-bossed users. 2) in SPADS, access rights to start a vote for a command = access rights to participate in an existing vote for this command.

So, if a non-bossed user has sufficient rights to start a vote, he also has sufficient rights to participate to an existing vote for this command and thus prevents a bossed user to be able to call the command directly...

However, a plugin to alter this behavior would be very easy to do, using the changeUserAccessLevel customization callback to increase the access level of bossed users.

Yaribz commented 1 year ago

In order to make it even easier, I extended SPADS plugin API with a new accessor getBosses. This accessor retrieves the hash (dictionnary in Python) of current bosses in battle (if the hash is empty, the boss mode is disabled).

I noticed your BarManager plugin was relying on postSpadsCommand to detect when !boss commands are called to determine current boss. This new accessor should make it much easier and less error prone.

Here is an example of PrivilegedBoss Python plugin to increase the access level of bossed users to a configurabe privilegedBossLevel value:

import perl
spads=perl.PrivilegedBoss

pluginVersion='0.1'
requiredSpadsVersion='0.13.11'

globalPluginParams = {'privilegedBossLevel' : ['integer']}
presetPluginParams = None

def getVersion(pluginObject):
    return pluginVersion

def getRequiredSpadsVersion(pluginName):
    return requiredSpadsVersion

def getParams(pluginName):
    return [globalPluginParams,presetPluginParams]

class PrivilegedBoss:

    def __init__(self,context):
        pluginConf = spads.getPluginConf()
        setattr(self,'privilegedBossLevel',int(pluginConf['privilegedBossLevel']))
        spads.slog("Plugin loaded (version %s)" % pluginVersion,3)

    def changeUserAccessLevel(self,userName,userData,isAuthenticated,currentAccessLevel):
        bosses = spads.getBosses()
        if userName in bosses:
            privilegedBossLevel = getattr(self,'privilegedBossLevel')
            if int(currentAccessLevel) < privilegedBossLevel:
                return privilegedBossLevel
        return
Beherith commented 1 year ago

Ahaa, thank you, this will be very useful :)