Autorank

Autorank

380k Downloads

Multiple Groups Support

DeathStapler opened this issue ยท 18 comments

commented
Issue

When I tried the setup below and someone would rankup, they would lose the primary and secondary group and now only have the one that they ranked up to. So if a player was in the groups Member and L0, then ranked-up to L1, they would only be in the L1 group. The player loses the Member group.

Using

KCauldron: 1.7.10-1492.152
PermissionsEX: 1.22.9
AutoRank: 3.6-Dev-436

Setup

I have primary groups, let's say: Guest, Member, VIP, Admin, Owner

I also have secondary groups that simply add a suffix to their name in chat, let's say: L0, L1, L2, L3, L4, etc...

Each player would start with the default groups of Guest and L0. Over time a player might have:

Player Groups
SnubDub Guest, L1
LundGrund Member, L2
FethBeth VIP, L2
BossHoss Admin,L0
Config File
# This would be an example AdvancedConfig.yml
ranks:
    L0:
        requirements:
            time:
                value: 5d
        results:
            rank change: L0;L1
            message: 'Congratulations, you are now a Level 1.'
     L1:
        requirements:
            time:
                value: 10d
        results:
            rank change: L1;L2
            message: 'Congratulations, you are now a Level 2.'
     Guest:
        requirements:
            time:
                value: 3d
            exp:
                value: 20
        results:
            rank change: Guest;Member
            message: 'Congratulations, you are now a Member.'
     Member:
        requirements:
            time:
                value: 25d
            exp:
                value: 100
        results:
            rank change: Member;VIP
            message: 'Congratulations, you are now a VIP.'

I did change this value in Settings.yml:
use primary group for vault: false

commented

I also have this problem and i cannot figure out a way around it. I want to set subgroups for specific ranks and primary groups for all others.

There needs to be some kind of support for this.

commented

I believe this issue occurs when using default groups. So, in my case if a player is not explicitly in a group, they are by default in the Guest and L0 groups. I'm guessing default groups are implicitly defined by PermissionsEX.

So, when a player in the Guest group (by default) is ready to rankup to Member, AutoRank sees via the Vault API that this player is in the Guest group. Then AutoRank calls addGroup() then removeGroup() in the VaultPermissionsHandler--to rank them up to Member.

I believe, before the removeGroup() call is made, the default groups no longer apply and thus, the player is no longer in the default Guest and L0 groups. They now are explicitly in the Member group.

I'm not sure if there is a way that the Vault API can see if they are default group(s). But, if it can, then you could add those groups prior to replaceGroup().

Otherwise, groups would have to be explicitly defined for each user in PermissionsEX.

I hope that all makes sense.

commented

Could you try, instead of using a rank change, make use of a command result that adds the group to a player. Like this: pex user group add ? That way you avoid Autorank performing addGroup() and then removeGroup().

commented

I think that is working for me. A little crude, but I'm happy that it works.

Thanks.

commented

I'll make an option to disable the removeGroup() call, maybe that works?

commented

Could you try run build 437 to see if that changes things? (Revert back to the rank change result, I want to check if this does anything for you).

commented

This seems like a solution that could work. I can push a new build and let you test with it.The only thing is that this kind of 'algorithm' should only be used for PEX. Other permission plugins don't seem to have this problem.

commented

I see what you did. This causes a problem, when someone is assigned a group it is not removed for PermissionsEX. This would only really work if a player were assigned to a default group(s).

if (permission.getName().toLowerCase().contains("permissionsex")) {
    worked2 = true;  // <---The old group is not removed.  This is fine for a default group, but not an assigned group.
} else {
    worked2 = removeGroup(player, world, oldGroup);
}

The problem wasn't that it was removing a group, but that the default group(s) for PermissionsEX are implied. The player isn't really in the default group(s), so whether you remove them or not, it doesn't matter. Once they are actually assigned a group, whatever the default group(s) were, they do not apply--they are now only in the group you just assigned.

I wrote up some code that might work. I'm not too familiar with Java or bukkit plugins to setup a project and test this myself.

@Override
public boolean replaceGroup(final Player player, String world,
        final String oldGroup, final String newGroup) {
    String[] groupsBeforeAdd = null;
    String[] groupsAfterAdd = null;

    // Temporary fix for bPermissions
    if (world == null
            && permission.getName().toLowerCase().contains("bpermissions")) {
        world = player.getWorld().getName();
    }
    /*System.out.print("Group To: " + newGroup);
    System.out.print("Group From: " + oldGroup);
    System.out.print("World: " + world);
    System.out.print("Player: " + player);*/

    // Let get the player groups before we change them.
    groupsBeforeAdd = getPlayerGroups(player);

    /* Is there some way output the array groupsBeforeAdd if Debug is enabled? */

    final boolean worked1 = addGroup(player, world, newGroup);

    // Was the group added successfully?
    if (worked1) {
        groupsAfterAdd = getPlayerGroups(player);

        /* Is there some way output the array groupsAfterAdd if Debug is enabled? */

        if (permission.getName().toLowerCase().contains("permissionsex")) {
            // Normally the player should have one more group at this point.
            if (groupsAfterAdd.length > (groupsBeforeAdd.length + 1)) {
                // We have one more groups than before.  Great.  Let's remove oldGroup.
                worked2 = removeGroup(player, world, oldGroup);

            // Otherwise, let's see if we have just one group.  This is an indication that the
            // PermissionsEX player had more than one default group set.  Those are now gone 
            // and we are left with just the newGroup.
            } else if (groupsAfterAdd.length == 1) {
                // We have just one group.  Let's add any that are missing.
                for (String group : groupsBefore) {
                    // Let's not re-add the oldGroup
                    if (!group.equals(oldGroup)) {
                        // Should we check it if succeeds?
                        addGroup(player, world, group);
                    }
                }
                worked2 = true;
            } else {
                //  Not sure what situation would lead us here, so we'll just assume everything is good.
                worked2 = true;
            }
        } else {
            worked2 = removeGroup(player, world, oldGroup);
        }
    }

    //System.out.print("Worked1: " + worked1);
    //System.out.print("Worked2: " + worked2);

    //System.out.print("In group: " + permission.playerInGroup(world, player.getName(), newGroup));
    return worked1 && worked2;
}
commented

I believe it is starting to come together. It seems to handle the default groups correctly. A player that starts in the default groups (Guest and L0), which then ranks up from Guest to Member and still retains the L0 group. This was not happening before.

But, when the player ranks up from L0 to L1, he still retains the L0 group.

I think I see what I did wrong.

if (groupsAfterAdd.length > (groupsBeforeAdd.length + 1)) {

should be

if (groupsAfterAdd.length == (groupsBeforeAdd.length + 1)) {
commented

When the player ranks up from L0 to L1, does he rank up to L1 AND he keeps L0? Or does he only get L0?

commented

He keeps the L0.

I think that is because of my logic. It wasn't ever doing the removeGroup() call. because I was looking for groupsAfter > groupsBefore+1. This would be true only if we added two or more groups. We only add one, so this will never be true.

// This is never called to remove the oldGroup
worked2 = removeGroup(player, world, oldGroup);
commented

We can also make it use >= instead of ==. This could prevent any errors, when for some reason more than 1 group was added. Unfortunately I can't access my pc this weekend, so it'll be somewhere on sunday that I can push the new build.

commented

I tried to clone your repository and get it built using spigot-1.8.8.jar to do some testing. I don't think I had all the dependencies from other libraries. Not too familiar with how that all works.

Guess I'll wait until Sunday to see if it works.

commented

I've updated the code, with your excellent suggestions. See if it works for you (438).

commented

I managed to get it built with the change I mentioned above and the issue with default groups appears to be resolved. I'll try to test other scenarios to see if I can break it.

commented

Good to hear that you got it working yourself and that the issue seems to be fixed. Keep me posted with updates if you have any!

commented

I added the new fix, but one of the repo's of dependencies seems down so my build server can't build it. Tomorrow morning it will be ready for a build.

commented

Closed due to inactivity.