1.17.x Command to toggle hashmap state isn't working

Discussion in 'Spigot Plugin Development' started by Staraptor0, Jun 18, 2021.

  1. I was trying to setup this little manhunt plugin for me and my friends but when i type the command "/manhunt" theres no errors in the console and the plugin shows as green /plugins, although nothing seems to happen. I even made sure the command was registered in plugin.yml

    plugin.yml
    name: ManHunt
    main: enable
    version: 1.0.0
    commands:
    manhunt:
    usage: /manhunt
    description: Toggles between Hunter and Runner
    author: Nvenc

    Code (Java):

    //enable.class

    import org.bukkit.Bukkit;
    import org.bukkit.plugin.java.JavaPlugin;
    public class enable extends JavaPlugin {
        public void onEnable() {
            Bukkit.getServer().getPluginManager().registerEvents(new listener1(), this);
            this.getCommand("manhunt").setExecutor(new commandClass());
        }
        public void onDisable() {
            Bukkit.getServer().getPluginManager().disablePlugin(this);
        }
    }
    //listener1.class

    import org.bukkit.ChatColor;
    import org.bukkit.Material;
    import org.bukkit.entity.Player;
    import org.bukkit.event.EventHandler;
    import org.bukkit.event.Listener;
    import org.bukkit.event.player.PlayerJoinEvent;
    import org.bukkit.event.player.PlayerMoveEvent;
    import org.bukkit.inventory.ItemStack;

    import java.util.HashMap;

    public class listener1 implements Listener {
        Player hunted;
        @EventHandler
        public void onJoin(PlayerJoinEvent event) {
            event.getPlayer().sendMessage(ChatColor.GREEN + "Man Hunt v1.0.0");
        }
        @EventHandler
        public void onMove (PlayerMoveEvent move) {
            if (hunted != null) {
                move.getPlayer().setCompassTarget(hunted.getLocation());
            }
        }
        public static HashMap<Player, Boolean> isHunter = new HashMap<>();
        public void togglePluginState(Player sending) {
            if (isHunter.containsKey(sending)) {
                if (isHunter.get(sending)) {
                    isHunter.put(sending, false);
                    sending.sendMessage(ChatColor.LIGHT_PURPLE + "Run For your Life!");
                    if (sending.getInventory().contains(Material.COMPASS)) {
                        sending.getInventory().remove(Material.COMPASS);
                        hunted = sending.getPlayer();
                } else {
                    isHunter.put(sending, true);
                    sending.sendMessage(ChatColor.DARK_RED + "You have picked Hunter");
                    if (!sending.getInventory().contains(Material.COMPASS)) {
                        sending.getInventory().setItemInMainHand(new ItemStack(Material.COMPASS));
                    }
                }
            } else {
                isHunter.put(sending, true);
                sending.sendMessage(ChatColor.DARK_RED + "You have picked Hunter");
                if (!sending.getInventory().contains(Material.COMPASS)) {
                    sending.getInventory().setItemInMainHand(new ItemStack(Material.COMPASS));
                    }
                }
            }
        }
    }

    //commandClass.class

    import org.bukkit.Material;
    import org.bukkit.command.Command;
    import org.bukkit.command.CommandExecutor;
    import org.bukkit.command.CommandSender;
    import org.bukkit.entity.Player;
    import org.bukkit.inventory.ItemStack;

    public class commandClass implements CommandExecutor {
        public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) {
            if (cmd.getName().equalsIgnoreCase("manhunt")) {
                if(!(sender instanceof Player)) return true;
                Player player = (Player) sender;
                listener1 toggleState = new listener1();
                toggleState.togglePluginState(player);
                return true;
            }
            return false;
        }
    }
     
     
  2. The command doesn't appear to give any feedback. If by nothing happening you mean it's not working make sure the command's executor is set on the onEnable method.
     
  3. the command executes and shows a dialogue in the console saying that it went through, however none of the hunter messages come up ingame. in the meantime i will try and rework the command executor.
     
  4. What exactly doesnt work? add some debug lines.
    Also you're trying to add a player to a map when they're already in it. Try using Map#replace(key, newValue)
     
  5. I don't immediately see what is wrong, I do see about 5 severe basic Java convention breaking messes.
    1. Class names should be UpperCamelCase, so start with a capital.
    2. Package naming exists for a reason, use it. Currently your main class isn't grouped in any package. Make sure put your classes inside a package with proper naming, namely something like me.staraptor0.manhunt, so it is both specific to you and includes the name of your project. It is also a good idea to give your main class a descriptive name, so call it Manhunt for example.
    3. There is zero need to disable your plugin in onDisable, that is done automatically
    4. Your command is actually creating a new listener each time?? If you are abusing static to store data like your map does, just make the method toggleStatePlugin static too, so it doesn't require an instance.
    5. On the topic of that, it would be far better to do the management of which player is hunted etc somewhere else (not in a listener), for example in a dedicated class (or in your main class). Then instead of abusing static for it, make it properly accessible via setters/getters.
    6. Your command class doesn't have to check for the command used. You only set it to be the executor of your manhunt command, so if the code inside that class is executed, the command will always be "/manhunt"

    I sincerely encourage you to learn a bit more about Java and especially OOP before starting with Spigot, it will help you create plugins of far higher quality.

    EDIT: Just noticed the lack of understanding about what static means and what the difference is between class and instance variables is actually breaking your code. Your hunted variable is part of the instance, meaning that every time you create a new listener you only set the hunted player for that instance (see problem 4), not for the one actually registered to listen to events. See point 5. Your map is static, so that is shared across a instances of your listener.
     
    #5 3ricL, Jun 18, 2021
    Last edited: Jun 18, 2021
    • Agree Agree x 2
  6. That is not necessary. Put will actually replace if it is already in there, so it can very well be used here.
     
    • Agree Agree x 2
  7. Strange. Throws errors when I try to.
     
  8. In your command code, you are creating a new instance of the listener. You need to store it as a global variable.
     
  9. I deleted the hashmap and im gonna store that information a different way. Also i refactored all the namespaces. I will post the final version when done in a few days :D keep this boi open