Solved Permissions set, command works, but is red w/o tab complete Please Help!

Discussion in 'Spigot Plugin Development' started by Th3_DoC, Feb 8, 2020.

  1. The title is fairly explanatory I've tried multiple attempts at getting this to work with hours of research -.- i've tried delaying the check and reversing the roles even.....as it seems to set the permissions on the second WorldChangeEvent instead of the first but then never unsets...Though the gamemode changes just fine! I figured permissions would be straight forward following bukkits guide! I must be missing something, joys of being new to the bukkit/java world :) Any help is much appreciated thanks guys.

    Here is the EventHandler:
    Code (Text):

    @EventHandler
    public void worldChange(PlayerChangedWorldEvent e) {
        p = e.getPlayer();
        uuid = p.getUniqueId().toString();
        PermissionAttachment attachment = p.addAttachment(main);
        perms.put(uuid, attachment);
        PermissionAttachment perm = perms.get(uuid);

        if(p.getWorld().getName().equals(main.getConfig().get("CreativeWorld"))) {
            p.setGameMode(GameMode.CREATIVE);
            perm.setPermission(mcc.gameMode(), true);
            perm.setPermission(mcc.effect(), true);
            perm.setPermission(mcc.clear(), true);
            perm.setPermission(mcc.fill(), true);
        }
        else {
            p.setGameMode(GameMode.SURVIVAL);
            perm.unsetPermission(mcc.gameMode());
            perm.unsetPermission(mcc.effect());
            perm.unsetPermission(mcc.clear());
            perm.unsetPermission(mcc.fill());
        }
    }
     
    and here is the hashmap i save the attachment to:
    Code (Text):

    private HashMap<String, PermissionAttachment> perms = new HashMap<String, PermissionAttachment>();//HASHMAP OBVIOUSLY
    private MinecraftCommands mcc = new MinecraftCommands();//CUSTOM STRING CLASS CONTAINING PERM INFO
     
    Also here is the full class if that helps any:
    Code (Text):

    package me.th3doc.creativetp;

    import me.th3doc.creativetp.commands.MinecraftCommands;
    import me.th3doc.creativetp.playerconfigs.LocationManager;
    import org.bukkit.Bukkit;
    import org.bukkit.GameMode;
    import org.bukkit.entity.Entity;
    import org.bukkit.entity.Player;
    import org.bukkit.event.EventHandler;
    import org.bukkit.event.Listener;
    import org.bukkit.event.entity.EntityDamageEvent;
    import org.bukkit.event.player.PlayerChangedWorldEvent;
    import org.bukkit.event.player.PlayerMoveEvent;
    import org.bukkit.permissions.PermissionAttachment;

    import java.util.HashMap;

    public class Events implements Listener {
        private HashMap<String, PermissionAttachment> perms = new HashMap<String, PermissionAttachment>();
        private MinecraftCommands mcc = new MinecraftCommands();
        private Main main;
        private LocationManager locManager;
        private String uuid;
        private Player p;

        public Events(Main main) {
            this.main = main;
        }

        @EventHandler
        public void onMove(PlayerMoveEvent e) {
            p = e.getPlayer();
            uuid = p.getUniqueId().toString();
            locManager = new LocationManager(main, uuid);
            HashMap<String, Integer> tpMap = locManager.getTpMap();
            if(tpMap.get(uuid) != null) {
                int taskId = locManager.getTpMap().get(p.getUniqueId().toString());
                Bukkit.getServer().getScheduler().cancelTask(taskId);
                locManager.getTpMap().remove(uuid);
                p.sendMessage("Cancelling TP, Player Moved");
            }
        }

        @EventHandler
        public void onDamaged(EntityDamageEvent e) {
            Entity ent = e.getEntity();

            if(ent instanceof Player) {
                p = (Player)ent;
                uuid = p.getUniqueId().toString();
                locManager = new LocationManager(main, uuid);
                HashMap<String, Integer> tpMap = locManager.getTpMap();
                if(tpMap.get(uuid) != null) {
                    int taskId = locManager.getTpMap().get(p.getUniqueId().toString());
                    Bukkit.getServer().getScheduler().cancelTask(taskId);
                    locManager.getTpMap().remove(uuid);
                    p.sendMessage("Cancelling TP, Player Is Taking Damage");
                }
            }
        }

        @EventHandler
        public void worldChange(PlayerChangedWorldEvent e) {
            p = e.getPlayer();
            uuid = p.getUniqueId().toString();
            PermissionAttachment attachment = p.addAttachment(main);
            perms.put(uuid, attachment);
            PermissionAttachment perm = perms.get(uuid);

            if(p.getWorld().getName().equals(main.getConfig().get("CreativeWorld"))) {
                p.setGameMode(GameMode.CREATIVE);
                perm.setPermission(mcc.gameMode(), true);
                perm.setPermission(mcc.effect(), true);
                perm.setPermission(mcc.clear(), true);
                perm.setPermission(mcc.fill(), true);
            }
            else {
                p.setGameMode(GameMode.SURVIVAL);
                perm.unsetPermission(mcc.gameMode());
                perm.unsetPermission(mcc.effect());
                perm.unsetPermission(mcc.clear());
                perm.unsetPermission(mcc.fill());
            }
        }
    }
     
     
    #1 Th3_DoC, Feb 8, 2020
    Last edited: Feb 8, 2020
  2. If you put the same key to the HashMap the old key's value will be overwritten.
    So you need to check every PlayerChangedWorldEvent if perms contains this uuid and then get the attachment


    Code (Java):
     @EventHandler
        public void worldChange(PlayerChangedWorldEvent e) {
            p = e.getPlayer();
            uuid = p.getUniqueId().toString();
            PermissionAttachment attachment = null;
            if(perms.containsKey(uuid)){
              attachment = perms.get(uuid);
            }
            else {
              attachment = p.addAttachment(main);
              perms.put(uuid, attachment);
            }
            //PermissionAttachment perm = perms.get(uuid);
            //perm is a same variable as attachment, why not use attachment?
     
  3. I wanna say you need to be getting the players permissions and then change the attachment that holds the permission instead of creating a new attachment.
     
  4. Hours later and a bald scalp i am back for more! It seems as though the permissions were setting true/false, but not providing tab complete until minecraft noticed on the next world switch, however by then the commands permissions were no longer available. I did clean up my code to get rid of any potential bugs thanks for pointing those out! Definitely a few obvious ones i can't believe i missed lol joys of no sleep research haha.

    Here is my new code....

    Code (Text):

    //Will Save to config and add check for existing so it saves perms based on world location, though for
    now this will suffice to test my current issues.
    @EventHandler
    public void onPlayerJoin(PlayerJoinEvent e) {
        p = e.getPlayer();
        uuid = p.getUniqueId().toString();
        PermissionAttachment attachment = p.addAttachment(main);
        perm.setPermAttachment(uuid, attachment);
    }

    @EventHandler
    public void worldChange(PlayerChangedWorldEvent e) {
        p = e.getPlayer();
        uuid = p.getUniqueId().toString();
        PermissionAttachment perms = perm.getPermAttachment(uuid);

        if(p.getWorld().getName().equals(main.getConfig().get("CreativeWorld"))) {
            p.setGameMode(GameMode.CREATIVE);
            perms.setPermission(mcc.gameMode(), true);
            p.sendMessage("Gamemode = " + p.hasPermission(mcc.gameMode()));//debug
            perms.setPermission(mcc.effect(), true);
            p.sendMessage("Effect = " + p.hasPermission(mcc.effect()));//debug
            perms.setPermission(mcc.clear(), true);
            p.sendMessage("Clear = " + p.hasPermission(mcc.clear()));//debug
            perms.setPermission(mcc.fill(), true);
            p.sendMessage("Fill = " + p.hasPermission(mcc.fill()));//debug
        }
        else {
            p.setGameMode(GameMode.SURVIVAL);
            perms.unsetPermission(mcc.gameMode());
            p.sendMessage(String.valueOf(p.hasPermission(mcc.gameMode())));//debug
            perms.unsetPermission(mcc.effect());
            p.sendMessage(String.valueOf(p.hasPermission(mcc.effect())));//debug
            perms.unsetPermission(mcc.clear());
            p.sendMessage(String.valueOf(p.hasPermission(mcc.clear())));//debug
            perms.unsetPermission(mcc.fill());
            p.sendMessage(String.valueOf(p.hasPermission(mcc.fill())));//debug
        }
    }
     
    I am still not able to sort this out i can have the permissions but no tab complete...or i can have the tab complete and no permissions !!! I know this is possible...and i know i'm just around the corner from the next issue...compatibility with overridden commands from other plugins like essentialsX for example >.> thanks for any help in this matter!

    P.S. I've been leaning on the idea of CommandMap....but it seems i would still need to have my own classes and essentially Override the commands which is not what i want...i want default minecraft commands....even if say essentialsX is running on the server.
     
    #4 Th3_DoC, Feb 9, 2020
    Last edited: Feb 9, 2020
  5. Sadly I've already tried calling this after setting nodes to true :'(


    Code (Text):
    p.recalculatePermissions();
    I also tried
    Code (Text):
    p.getEffectivePermissions();
    @md_5 Can you shed any light on this for me? i'm stuck i've tried everything i can think off i feel like theres a much simpler way seeing as MC is giving me the tab completion when i do the next world change, though there is now no permission to use it. Here's my most recent attempt at using Permission & CommandMap Class's
    Code (Text):

    Permission effect = new Permission(mcc.effect());
    perms.setPermission(effect, true);
    SimpleCommandMap map = new SimpleCommandMap(main.getServer());
    map.tabComplete(p, "effect");
     
    Hoping i'm heading in the right direction thanks for your time.

    UPDATE:
    I've attempted to set permissions true with luckPerms permission manager and i get the same effects ! However with permission "minecraft.command" this is not the case luckPerms will give me access to the tab completes, where as my plugin will not...

    EDIT: So i feel stupid but 11 Days later i stumbled upon player.updateCommands() this is what i was looking for should anyone ever have issues and find this thread :)
     
    #6 Th3_DoC, Feb 9, 2020
    Last edited: Feb 21, 2020
    • Useful Useful x 2