Solved Passing a Player Temporarily Between Classes

Discussion in 'Plugin Development' started by AppleBabies, Feb 3, 2016.

Thread Status:
Not open for further replies.
  1. Offline

    AppleBabies

    Hello all! Tis' been a while. Maybe that's a good thing...hehe.

    I am stumped with this one. This has been in my thoughts for many days. So here's my predicament:

    • I have a command that goes "/mban <playername>" and opens up a GUI.
    • I want to take that player name and make sure it transfers between classes and also the original sender's name
    So I want to basically store those objects but have the sender's name own the player name object. That way when they close the inventory I can remove them and then it removes the player name they typed, and also so when they click an icon it does the same.

    Any help would be appreciated!
     
  2. Offline

    Xerox262

    If it's a ban plugin then you need to use offline player, if they're banned and can't join you can't get a player object from them.

    Pass the offline player and sender's name, then save the offlineplayer to the sender's name in a hashmap.

    There's probably a better way to do what you're trying to do, can you explain your plan and we'll tell you if there is?
     
  3. Offline

    AppleBabies

    @Xerox262 Well, allow me to explain this a bit better.

    So the icons when clicked will run a command called "ee mb ban <name>". But there are different menus in the GUI for chat offenses, gameplay offenses, and general offenses. So I just need the player name to be temporarily stored and passed between the GUIs.
     
  4. Offline

    Zombie_Striker

    @AppleBabies
    • Create a Hashmap that stores the "Clicker", and a class that will contain the player.
    • When a player first clicks who they want to ban, create the class and store them into the hashmap.
    • When the player clicks GUI2, use the hashmap to get the class and do what you need
     
  5. Offline

    AppleBabies

    @Zombie_Striker
    So something like this may work?
    Code:
    public Map<String,Class<?> > playerMap= new HashMap<String,Class<T>>();
    
    playerMap.put(e.getWhoClicked.getName(), this);
     
  6. Offline

    Zombie_Striker

    @AppleBabies
    No, you should have a separate class specifically built for storing data about the player (I only suggest making and storing a new class because you can also store more data if you need). What you should have should be:
    Code:
    Map<String/UUID, PlayerStorer> playermap = new HashMap<>();
    
    playerMap.put(player.getUUID() , new PlayerStorer(banned player's name/uuid))
    
    
    
    //.... New class
    public class PlayerStorer{
    
    privateUUID/String bannedPlayer;
    
    public String/UUID getBannedPlayer(){
      return bannedPlayer;
    }
    
    }
    
    
    
    //Wherever you want to get that banned player
    Player bannedPlayer = Bukkit.getServer().getOnline/OfflinePlayer( playerMap.get( Sender's UUID/Name).getBannedPlayer() )
     
  7. Offline

    AppleBabies

    How does this line work with the PlayerStorer? It tells me that PlayerStorer cannot be parsed to a String.
     
  8. Change your Map value.
     
  9. Offline

    AppleBabies

    @MaTaMoR_ I do not understand. My map values are all associated with a string. I don't see where PlayerStorer could be assigned one.
     
  10. If you wanna use PlayerStorer you will have to change your Map value to PlayerStorer
     
  11. Offline

    Xerox262

    There's absolutely no reason to make a player storer class, you can just store both UUIDs then use Bukkit.getOfflinePlayer(UUID); to get everything about a player including name.

    Change
    Code:
    public Map<String,Class<?>> playerMap=new HashMap<String,Class<T>>();
    To
    Code:
    public Map<UUID,UUID> playerMap = new HashMap<UUID, UUID>();
     
  12. Im just help him with this :
     
  13. Offline

    Flaps

    Use a PlayerWrapper and a Set that stores the object. Grab the PlayerWrapper and through the wrapper you can access it's variables, etc.
     
  14. Offline

    Xerox262

    @Flaps Again, there's no need for him to make a wrapper, since all he is trying to get can be achieved through the OfflinePlayer class.

    @MaTaMoR_ Sorry if it sounded different, I was just trying to tell him he does not need to make a class when he can use OfflinePlayer.
     
  15. Offline

    Flaps

    A wrapper allows you to store more variables that in the end can cause no harm. For example, storing a ban reason, a ban duration, etc.
     
  16. Offline

    Xerox262

    But you're assuming he is not using the default ban storage, or that he doesn't already have a way of storing it.
     
  17. Offline

    Flaps

    I'm not, I'm simply stating that a wrapper can serve many purposes that may be plausible to use in a plugin of this nature.
     
  18. Offline

    AppleBabies

    Alrighty, this is getting a LITTLE off topic...but now, I have a problem with a command. Every time it is run it sends a null pointer exception, and it basically says the sender is null:
    Code:
    @SuppressWarnings("deprecation")
        public boolean onCommand(CommandSender sender, Command cmd, String commandLabel,
                String[] args) {
           
                if(commandLabel.equalsIgnoreCase("mban")){
                   
                        Player p = (Player) sender;
                        p.sendMessage("Works!");
                        Main.getInstance().menu.show(p); //Here
                       
                        Main.getInstance().playermap.put(p.getName(), new PlayerStorer(Bukkit.getPlayerExact(args[1]).getName()) //And here);
                        return true;
                           
                }
           
            return false;
        }
    And @Flaps I find @Zombie_Striker's suggestion of making a class quite neat and tidy.
     
  19. Offline

    mythbusterma

    @AppleBabies

    I don't think the Bukkit API permits the sender to be null. And if that were the case, the error would be on line 7 of your snippet, as 'null' cannot be cast to other classes.

    It's probably that public member you should've encapsulated that is null (menu).
     
    AppleBabies likes this.
  20. Offline

    Xerox262

    No matter if you use the wrapper class or not you will have to move to OfflinePlayers for storage if you want to use player's that aren't online, or if they log off from the time between the inventory opening and the item in the inventory being clicked, although a punishment system seems useless to me if the player can grief or what ever and then simply log off before being punished. Player's return null if not online, so you would get a NPE for example the one you're getting on line 11 of what you posted.
     
  21. Offline

    AppleBabies

    @mythbusterma Probably, although I see no place where it could throw a null at me in my Menu class...
    Code:
    import java.util.Arrays;
    
    import org.bukkit.Bukkit;
    import org.bukkit.ChatColor;
    import org.bukkit.Material;
    import org.bukkit.Sound;
    import org.bukkit.entity.Player;
    import org.bukkit.event.EventHandler;
    import org.bukkit.event.Listener;
    import org.bukkit.event.inventory.InventoryClickEvent;
    import org.bukkit.inventory.Inventory;
    import org.bukkit.inventory.ItemStack;
    import org.bukkit.inventory.meta.ItemMeta;
    import org.bukkit.plugin.Plugin;
    public class MainMenu implements Listener {
       
           
            private Inventory inv;
            private ItemStack head, client, chat, gameplay, perm;
          
            public MainMenu(Plugin p) {
                   
                    inv = Bukkit.getServer().createInventory(null, 54, "Ban Manager");
               
                    head = headStack("Player name");
                       
                    inv.setItem(13, head);
            }
           
            private ItemStack headStack(String name){
               
                ItemStack head = new ItemStack(Material.SKULL);
                  ItemMeta im = head.getItemMeta();
                  im.setDisplayName(name);
                  im.setLore(Arrays.asList("Lore", ""));
                  head.setItemMeta(im);
                return head;
               
            }
           
          
           
            public void show(Player p) {
                    p.openInventory(inv);
            }
           
           
          
            @SuppressWarnings("deprecation")
            @EventHandler
            public void onInventoryClick(InventoryClickEvent e) {
                Player p = (Player) e.getWhoClicked();
                    if (!e.getInventory().getName().equalsIgnoreCase(inv.getName())) return;
                    if (e.getCurrentItem().getItemMeta() == null) return;
               
                    if (e.getCurrentItem().getItemMeta().getDisplayName().contains("Player name")) {
                        e.setCancelled(true);
                        e.getWhoClicked().closeInventory();
                        Player bannedPlayer = (Player) Bukkit.getServer().getOfflinePlayer(Main.getInstance().playermap.get(e.getWhoClicked()).getBannedPlayer());
                        Main.getInstance().playermap.remove(e.getWhoClicked());
                              p.sendMessage(bannedPlayer.getName());
                              p.playSound(p.getLocation(), Sound.NOTE_BASS_GUITAR, 1, 10);
                              MessageManager.getInstance().noRandomMsg(e.getWhoClicked());
                
                }
                   
            }
        }
    
    And @Xerox262 I'm not doing the ban handling myself...don't know why people aren't understanding that. I am simply trying to organize a way to use an existing ban plugin in a GUI.
     
  22. Offline

    mythbusterma

    @AppleBabies

    Err the 'Main' class, not the 'MainMenu' class.
     
  23. Offline

    AppleBabies

    @mythbusterma Ah, my mistake :p
    Code:
    import java.util.HashMap;
    import java.util.Map;
    
    import org.bukkit.Bukkit;
    import org.bukkit.plugin.java.JavaPlugin;
    
    public class Main extends JavaPlugin {
       
        public MainMenu menu;
        private static Main instance;
        public Map<String, PlayerStorer> playermap = new HashMap<>();
       
        public void onEnable(){
            menu = new MainMenu(this);
            Bukkit.getServer().getPluginManager().registerEvents(menu, this);
            getCommand("mban").setExecutor(new MBan());
        }
       
        public static Main getInstance(){
            return instance;
        }
       
        public void onDisable(){
           
        }
       
    }
    
     
  24. Offline

    Xerox262

    When I said storage, I meant in your Hashmaps/Player wrapper class, also read my previous posts, I already said that you were probably not managing the storage yourself.

    Your error is instance, you never set it.

    Wait, why even do this
    Code:
    new PlayerStorer(Bukkit.getPlayerExact(args[1]).getName()//And here
    If args[1] is going to contain the name why not just directly use it? You wont need OfflinePlayer in that case.
     
    Last edited: Feb 4, 2016
  25. Offline

    AppleBabies

    @Xerox262
    :p
    EDIT: WAIT. Ignore me. Hold on...
     
  26. Offline

    Xerox262

    @AppleBabies You never set it, you only created it.

    But again, like I said, Bukkit.getPlayer(); and Bukkit.getPlayerExact(); will both return null unless the player is online, you can just pass the args[1] to the Player wrapper to fix this, however if the player leaves out a letter or misses a capital it will not save for the correct player, unless the plugin you're hooking into fixes it for you.

    Wait a minute, you said you wanted it to be

    /mban <playername>

    So why are you using args[1]?
     
    Last edited: Feb 4, 2016
  27. Offline

    AppleBabies

    @Xerox262 That did it XD Sorry. Kinda foolish-ish XD
     
Thread Status:
Not open for further replies.

Share This Page