ServerPlugin Icon Menu

Dieses Thema im Forum "Programmierung" wurde erstellt von squiby, 26. März 2013.

  1. squiby
    Offline

    squiby

    Registriert seit:
    23. November 2012
    Beiträge:
    8
    Ort:
    Österreich
    Problem: IconMenu.OptionClickEvent wird pro Klick 2x gecalled. Das Problem liegt irgendwo in der API, nur meldet sich deren Entwickler nicht, weshalb ich hier nochmal nachfrage.

    Hier die benutzte API:
    Code (Text):
    1. public class IconMenu implements Listener {
    2.     private String name;
    3.     private int size;
    4.     private OptionClickEventHandler handler;
    5.     private Plugin plugin;
    6.  
    7.     private String[] optionNames;
    8.     private ItemStack[] optionIcons;
    9.  
    10.     public IconMenu(String name, int size, OptionClickEventHandler handler, Plugin plugin) {
    11.         this.name = name;
    12.         this.size = size;
    13.         this.handler = handler;
    14.         this.plugin = plugin;
    15.         this.optionNames = new String[size];
    16.         this.optionIcons = new ItemStack[size];
    17.         plugin.getServer().getPluginManager().registerEvents(this, plugin);
    18.     }
    19.  
    20.     public IconMenu setOption(int position, ItemStack icon, String name, String... info) {
    21.         optionNames[position] = name;
    22.         optionIcons[position] = setItemNameAndLore(icon, name, info);
    23.         return this;
    24.     }
    25.  
    26.     public void open(Player player) throws Exception {
    27.         Inventory inventory = Bukkit.createInventory(player, size, name);
    28.         if (optionIcons == null)
    29.             throw new Exception("Null!");
    30.        
    31.         for (int i = 0; i < optionIcons.length; i++) {
    32.            inventory.setItem(i, optionIcons[i]);          
    33.         }
    34.         player.openInventory(inventory);
    35.     }
    36.  
    37.     public void destroy() {
    38.         HandlerList.unregisterAll(this);
    39.         handler = null;
    40.         plugin = null;
    41.         optionNames = null;
    42.         optionIcons = null;
    43.     }
    44.  
    45.     @EventHandler(priority = EventPriority.MONITOR)
    46.     void onInventoryClick(InventoryClickEvent event) {
    47.         if (event.getInventory().getTitle().equals(name)) {
    48.             event.setCancelled(true);
    49.             int slot = event.getRawSlot();
    50.             if (slot >= 0 && slot < size && optionNames[slot] != null) {
    51.                 Plugin plugin = this.plugin;
    52.                 OptionClickEvent e = new OptionClickEvent((Player) event.getWhoClicked(), slot, optionNames[slot]);
    53.                 handler.onOptionClick(e);
    54.                 if (e.willClose()) {
    55.                     final Player p = (Player) event.getWhoClicked();
    56.                     Bukkit.getScheduler().scheduleSyncDelayedTask(plugin, new Runnable() {
    57.                         public void run() {
    58.                             p.closeInventory();
    59.                         }
    60.                     }, 1);
    61.                 }
    62.                 if (e.willDestroy()) {
    63.                     destroy();
    64.                 }
    65.             }
    66.         }
    67.     }
    68.  
    69.     public interface OptionClickEventHandler {
    70.         public void onOptionClick(OptionClickEvent event);
    71.     }
    72.  
    73.     public class OptionClickEvent {
    74.         private Player player;
    75.         private int position;
    76.         private String name;
    77.         private boolean close;
    78.         private boolean destroy;
    79.  
    80.         public OptionClickEvent(Player player, int position, String name) {
    81.             this.player = player;
    82.             this.position = position;
    83.             this.name = name;
    84.             this.close = true;
    85.             this.destroy = false;
    86.         }
    87.  
    88.         public Player getPlayer() {
    89.             return player;
    90.         }
    91.  
    92.         public int getPosition() {
    93.             return position;
    94.         }
    95.  
    96.         public String getName() {
    97.             return name;
    98.         }
    99.  
    100.         public boolean willClose() {
    101.             return close;
    102.         }
    103.  
    104.         public boolean willDestroy() {
    105.             return destroy;
    106.         }
    107.  
    108.         public void setWillClose(boolean close) {
    109.             this.close = close;
    110.         }
    111.  
    112.         public void setWillDestroy(boolean destroy) {
    113.             this.destroy = destroy;
    114.         }
    115.     }
    116.  
    117.     private ItemStack setItemNameAndLore(ItemStack item, String name, String[] lore) {
    118.         ItemMeta im = item.getItemMeta();
    119.         im.setDisplayName(name);
    120.         im.setLore(Arrays.asList(lore));
    121.         item.setItemMeta(im);
    122.         return item;
    123.     }
    124.    
    125. }
    Hier das Objekt in der Main:

    Code (Text):
    1.     private IconMenu CreateIconMenu()
    2.     {
    3.         IconMenu menu = new IconMenu("Navi", 9, new IconMenu.OptionClickEventHandler() {
    4.             @Override
    5.  
    6.            //Dieser Part wird 2x ausgeführt!
    7.  
    8.             public void onOptionClick(IconMenu.OptionClickEvent event) {
    9.                 Player p = (Player) event.getPlayer();
    10.                
    11.                 if(event.getName().equals(...
    12.                
    13.                 event.setWillClose(true);
    14.             }
    15.         }, (Plugin) this)
    16.         .setOption(...
    17.        
    18.         return menu;
    19.     }
     
    #1
  2. games6471
    Offline

    games6471

    Also ich hab mir mal die Mühe gemacht und die gleiche API vom Entwickler genommen und ausprobiert. Ich habe keine Probleme, dass irgendetwas doppelt ausgeführt wird. Vllt gibt es irgendein Logik-Fehler bei deinem Plugin, da man aber nur ein kleinen Teil sieht, kann man dir hier nicht viel weiterhelfen.
     
    #2
  3. squiby
    Offline

    squiby

    Registriert seit:
    23. November 2012
    Beiträge:
    8
    Ort:
    Österreich
  4. games6471
    Offline

    games6471

    Bin zwar grad nur mobile Online. Ich hab aber schon beim ersten Blick gesehen, dass du das Even 2x anmeldest. Einmal wird es in der Api angemeldet und danach nochmals von dir selber.
     
    #4
  5. squiby
    Offline

    squiby

    Registriert seit:
    23. November 2012
    Beiträge:
    8
    Ort:
    Österreich
    Hier?
    Code (Text):
    1.     public interface OptionClickEventHandler {
    2.         public void onOptionClick(OptionClickEvent event);
    3.     }
    Wie schreibe ich es am bestem um?
     
    #5
  6. games6471
    Offline

    games6471

    Nein hier:

    Code (Text):
    1.     public void onEnable() {
    2.         PluginManager pm = Bukkit.getPluginManager();
    3.         this.im = this.CreateIconMenu();
    4.         this.il = new IconListener(this.im);
    5.        
    6.         Bukkit.getWorlds().get(0).setGameRuleValue("keepInventory", "true");
    7.        
    8.         [COLOR="#FF0000"]pm.registerEvents(this.im, this);[/COLOR]
    9.         pm.registerEvents(this.il, this);
    10.     }
    und hier:


    Code (Text):
    1.     public IconMenu(String name, int size, OptionClickEventHandler handler, Plugin plugin) {
    2.         this.name = name;
    3.         this.size = size;
    4.         this.handler = handler;
    5.         this.plugin = plugin;
    6.         this.optionNames = new String[size];
    7.         this.optionIcons = new ItemStack[size];
    8.         [COLOR="#FF0000"]plugin.getServer().getPluginManager().registerEvents(this, plugin);[/COLOR]
    9.     }
     
    #6
  7. squiby
    Offline

    squiby

    Registriert seit:
    23. November 2012
    Beiträge:
    8
    Ort:
    Österreich
    Danke, vollkommen überlesen!
     
    #7
  8. squiby
    Offline

    squiby

    Registriert seit:
    23. November 2012
    Beiträge:
    8
    Ort:
    Österreich
    Problem 2.0

    Hier wieder die relevanten Teile:
    IconMain: http://pastie.org/private/dsoxwzbpkmqoqtqaci7uiq
    IconMenu: http://pastie.org/private/ndk4wm2coihxt9cqesjaoa
    IconListener: http://pastie.org/private/0xjt6rvdumfnkvderdk8aq

    Folgendes Problem: Das Ganze funktioniert gut, solange man nicht auf ein Item außerhalb des Iconmenüs klickt, während es geöffnet ist. Der Vorgang sollte ja normal gecancelled werden, nur leider wird danach das Event scheinbar nicht mehr ausgelöst (mit Nachrichten getestet). Wäre cool, wenn jemand einen schnellen Blick drauf werfen könnte!
     
    #8
  9. squiby
    Offline

    squiby

    Registriert seit:
    23. November 2012
    Beiträge:
    8
    Ort:
    Österreich
    Update: Kleinigkeit vergessen (Events neu initialisieren nach .unregisterAll(this)) und schon stecke ich wieder bei meinem eigentlichen Problem fest: Beim Öffnen des Menüs (Interaktion mit der Uhr in der Hand) reseted sich das komplette Inventar. Alle aufgenommenen Items gehen verloren und Verschobene werden wieder in ihren vorigen Slot gesetzt. Blöcke, die im 2x2-Feld gecrafted wurden, verschwinden beim Setzen und die Ressourcen erscheinen wieder im Inventar. Das tritt auf, sobald der Spieler auf ein Icon klickt, welches IHN TELEPORTIERT. Nachrichten versenden, etc. funktioniert einwandfrei. Sobald, ich z.B. p.teleport(world.getSpawnLocation()) einfüge, beginnt das Inventar sich selbst zurückzusetzen.

    IconMain: http://pastie.org/private/kfim55lkyvv2xnenkj4ja#33
    IconMenu: http://pastie.org/private/5mkjagv2ao4wbvqowlog
     
    #9