• Es freut uns dass du in unser Minecraft Forum gefunden hast. Hier kannst du mit über 130.000 Minecraft Fans über Minecraft diskutieren, Fragen stellen und anderen helfen. In diesem Minecraft Forum kannst du auch nach Teammitgliedern, Administratoren, Moderatoren , Supporter oder Sponsoren suchen. Gerne kannst du im Offtopic Bereich unseres Minecraft Forums auch über nicht Minecraft spezifische Themen reden. Wir hoffen dir gefällt es in unserem Minecraft Forum!

Spigot PlayerCreatePortalEvent

xXSchrandXx

Kuhfänger
Mitglied seit
16 September 2012
Beiträge
98
Minecraft
xXSchrandXx
Hi,

ich suche eine Lösung um mein PlayerCreatePortalEvent zu callen (auch wenn e.getEntity() zu seien scheint).
Komischerweise ist e.getEntity() = null wenn ein Spieler das PortalCreateEvent triggert. Daher brauche ich Hilfe dabei zu testen ob PortalCreateEvent.getClickedBlock() in PlayerInteractEvent.e.getBlocks() vorhanden ist.

Im Spoiler ist der Code den ich bisher habe.

Vielen Dank schon mal für eure Hilfe :D

PlayerCreatePortalListener:
  @EventHandler
  public void onPortalCreate(PortalCreateEvent e) {
    if (e.getEntity() != null) {
      if (e.getEntity() instanceof Player) {
        Player p = (Player) e.getEntity();
        PlayerCreatePortalEvent pcpe = new PlayerCreatePortalEvent(e.getBlocks(), p, e.getReason());
        Bukkit.getPluginManager().callEvent(pcpe);
        e.setCancelled(pcpe.isCancelled());
        return;
      }
    }
  // Teste mit PlayerInteractEvent ob e.getEntity() wirklich null ist
  }
  @EventHandler
  public void onPlayerInteract(PlayerInteractEvent e) {
    if (e.getAction() == Action.RIGHT_CLICK_BLOCK) {
      if (((e.getMaterial() == Material.FIRE_CHARGE) || (e.getMaterial() == Material.FLINT_AND_STEEL)) && (e.getClickedBlock().getType() == Material.OBSIDIAN)) {
        
      }
    }
  }

Mit freundlichem Gruß

xXSchrandXx
 

Avankziar

Kuhfänger
Osterei Experte
Mitglied seit
12 Februar 2018
Beiträge
81
Alter
26
Minecraft
Avankziar

xXSchrandXx

Kuhfänger
Mitglied seit
16 September 2012
Beiträge
98
Minecraft
xXSchrandXx
Also laut https://hub.spigotmc.org/javadocs/bukkit/org/bukkit/event/world/PortalCreateEvent.html muss das Entity nicht unbedingt !=null sein. Dh. ich glaube, das Entity wird wahrscheinlich nur zurück gegeben, wenn es durch einen Feuerball (von einem bspw. Ghast) getriggert wird, auch dann nur der Feuerball zurückgegeben wird.

Du bist wahrscheinlich mit dem PlayerInteractEvent besser dran.
Damit ich nicht irgendwie testen muss, ob der Block wirklich in einem Portal liegt, hätte ich an sowas gedacht:
PlayerCreatePortalListener:
  private ConcurrentHashMap<Player, Block> blocks = new ConcurrentHashMap<Player, Block>();
  @EventHandler
  public void onPortalCreate(PortalCreateEvent e) {
    if (e.getEntity() != null) {
      if (e.getEntity() instanceof Player) {
        Player p = (Player) e.getEntity();
        PlayerCreatePortalEvent pcpe = new PlayerCreatePortalEvent(e.getBlocks(), p, e.getReason());
        Bukkit.getPluginManager().callEvent(pcpe);
        e.setCancelled(pcpe.isCancelled());
        return;
      }
    }
    if (e.getReason() == CreateReason.FIRE) {
      if (!blocks.isEmpty()) {
        for (Entry<Player, Block> pb : blocks.entrySet()) {
          for (BlockState bs : e.getBlocks()) {
            if (pb.getValue() == bs.getBlock()) {
              PlayerCreatePortalEvent pcpe = new PlayerCreatePortalEvent(e.getBlocks(), pb.getKey(), e.getReason());
              Bukkit.getPluginManager().callEvent(pcpe);
              e.setCancelled(pcpe.isCancelled());
            }
          }
        }
      }
    }
  }
  @SuppressWarnings("deprecation")
  @EventHandler
  public void onPlayerInteract(PlayerInteractEvent e) {
    if (e.getAction() == Action.RIGHT_CLICK_BLOCK) {
      if (((e.getMaterial() == Material.FIRE_CHARGE) || (e.getMaterial() == Material.FLINT_AND_STEEL)) && (e.getClickedBlock().getType() == Material.OBSIDIAN)) {
        if (blocks.get(e.getPlayer()) == null) {
          blocks.put(e.getPlayer(), e.getClickedBlock());
          Bukkit.getScheduler().scheduleAsyncDelayedTask(Main.getInstance(), new BukkitRunnable() {
            @Override
            public void run() {
              blocks.remove(e.getPlayer(), e.getClickedBlock());
            }
          }, 5 * 20);
        }
      }
    }
  }
Ich bitte aber um Verbesserungsvorschläge.
 

xXSchrandXx

Kuhfänger
Mitglied seit
16 September 2012
Beiträge
98
Minecraft
xXSchrandXx
denn == macht man nur bei primitiven Daten oder Enums, siehe https://www.geeksforgeeks.org/difference-equals-method-java/
Das wusste ich noch nicht, danke.

Aktueller Code:
Java:
  private ConcurrentHashMap<Player, Block> blocks = new ConcurrentHashMap<Player, Block>();
  @EventHandler
  public void onPortalCreate(PortalCreateEvent e) {
    if (e.getEntity() != null) {
      if (e.getEntity() instanceof Player) {
        Player p = (Player) e.getEntity();
        Main.Log(Level.INFO, "Calling PlayerCreatePortalEvent with " + p.getName() + ".");
        PlayerCreatePortalEvent pcpe = new PlayerCreatePortalEvent(e.getBlocks(), p, e.getReason());
        Bukkit.getPluginManager().callEvent(pcpe);
        Main.Log(Level.INFO, "PlayerCreatePortalEvent: " + pcpe.isCancelled());
        e.setCancelled(pcpe.isCancelled());
        return;
      }
    }
    Main.Log(Level.INFO, "Entity is null.");
    if (e.getReason() == CreateReason.FIRE) {
      Main.Log(Level.INFO, "CreateReason ist Fire.");
      if (!blocks.isEmpty()) {
        for (Entry<Player, Block> pb : blocks.entrySet()) {
          Main.Log(Level.INFO, pb.getValue().toString());
          for (BlockState bs : e.getBlocks()) {
            Main.Log(Level.INFO, "Testing Block...");
            Main.Log(Level.INFO, bs.getBlock().toString());
            if (sameBlocks(pb.getValue(), bs.getBlock())) {
              PlayerCreatePortalEvent pcpe = new PlayerCreatePortalEvent(e.getBlocks(), pb.getKey(), e.getReason());
              Main.Log(Level.INFO, "Calling PlayerCreatePortalEvent with " + pb.getKey().getName() + ".");
              Bukkit.getPluginManager().callEvent(pcpe);
              Main.Log(Level.INFO, "PlayerCreatePortalEvent: " + pcpe.isCancelled());
              e.setCancelled(pcpe.isCancelled());
              return;
            }
          }
        }
      }
    }
  }
  @SuppressWarnings("deprecation")
  @EventHandler
  public void onPlayerInteract(PlayerInteractEvent e) {
    if (e.getAction() == Action.RIGHT_CLICK_BLOCK) {
      if (((e.getMaterial() == Material.FIRE_CHARGE) || (e.getMaterial() == Material.FLINT_AND_STEEL)) && (e.getClickedBlock().getType() == Material.OBSIDIAN)) {
        if (blocks.get(e.getPlayer()) == null) {
          Main.Log(Level.INFO, "Add " + e.getPlayer().getName() + " with " + e.getClickedBlock().getType() + ".");
          blocks.put(e.getPlayer(), e.getClickedBlock());
          Bukkit.getScheduler().scheduleAsyncDelayedTask(Main.getInstance(), new BukkitRunnable() {
            @Override
            public void run() {
              Main.Log(Level.INFO, "Remove " + e.getPlayer().getName() + " with " + e.getClickedBlock().getType() + ".");
              blocks.remove(e.getPlayer(), e.getClickedBlock());
            }
          }, 5 * 20);
        }
        else {
          Main.Log(Level.INFO, e.getPlayer().getName() + " got skipped " + e.getClickedBlock().getType() + " because a task is already running.");
        }
      }
    }
  }
  public static boolean sameBlocks(Block block1, Block block2) {
    if (block1 == block2) {
      return true;
    }
    if (block1.equals(block2)) {
      return true;
    }
    if (block1.getLocation() == block2.getLocation()) {
      return true;
    }
    if (block1.getLocation().equals(block2.getLocation()))
    if (block1.getWorld().getName() == block2.getWorld().getName()) {
      if (block1.getX() == block2.getX()) {
        if (block1.getY() == block2.getY()) {
          if (block1. getZ() == block2.getZ()) {
            return true;
          }
        }
      }
    }
    if (block1.getBlockKey() == block2.getBlockKey()) {
      return true;
    }
    return false;
  }
 

LinuxServer

Redstoneengineer
Mitglied seit
17 September 2016
Beiträge
35
Hey,

das passt jetzt möglicherweise nicht zum Thema, aber ich verstehe nicht warum du dort eine ConcurrentHashMap nutzt. Zudem ist dein Code ziemlich rechts.

Mit freundlichen Grüßen
 

Kroseida

Kuhfänger
Mitglied seit
28 September 2015
Beiträge
83
Alter
21
Minecraft
Kroseida
Probier mal das :p
Kein Zeite gehabt das jetzt zu testen, sollte aber klappen.

Java:
    private final Map<Block, Player> interactions = new HashMap<Block, Player>();
    private final Map<Player, Block> reverseInteractions = new HashMap<Player, Block>();

    @EventHandler
    public void onPortalCreate(PortalCreateEvent event) {
        for (BlockState block : event.getBlocks()) {
            Player player = interactions.getOrDefault(block.getBlock(), null);
            if(validateAndCall(player, block.getBlock())) {
                return;
            }
        }
        for (BlockState block : event.getBlocks()) {
            Player player = interactions.getOrDefault(block.getBlock().getLocation().add(0, -1, 0).getBlock(), null);
            if(validateAndCall(player, block.getBlock())) {
                return;
            }
        }
    }
   
    private boolean validateAndCall(Player player, Block block) {
        if (player != null) {
            interactions.remove(block);
            reverseInteractions.remove(player);
            this.playerSpawnNetherPortalEvent(player, block);
            return true;
        }
        return false;
    }
   
    @EventHandler
    public void onPlayerInteract(PlayerInteractEvent event) {
        if (event.getAction() != Action.RIGHT_CLICK_BLOCK) {
            return;
        }
        if (event.getItem() == null) {
            return;
        }
        if (event.getClickedBlock() == null) {
            return;
        }
        if (event.getClickedBlock().getType() != Material.OBSIDIAN)  {
            return;
        }
        if (event.getItem().getType() != Material.FLINT_AND_STEEL && event.getItem().getType() != Material.FIRE_CHARGE)  {
            return;
        }
        Block block = reverseInteractions.getOrDefault(event.getPlayer(), null);
        if (block != null) {
            interactions.remove(block);
            reverseInteractions.remove(event.getPlayer());
        }
        interactions.put(event.getClickedBlock(), event.getPlayer());
        reverseInteractions.put(event.getPlayer(), event.getClickedBlock());
    }

    private void playerSpawnNetherPortalEvent(Player player, Block block) {
        // YYEEEEEY?
        player.sendMessage("You spawned a Nether portal!");
    }
 

xXSchrandXx

Kuhfänger
Mitglied seit
16 September 2012
Beiträge
98
Minecraft
xXSchrandXx
Hey,

das passt jetzt möglicherweise nicht zum Thema, aber ich verstehe nicht warum du dort eine ConcurrentHashMap nutzt. Zudem ist dein Code ziemlich rechts.

Mit freundlichen Grüßen
Ich hab vor einiger Zeit so einen Beitrag gelesen.
Daher benutze ich fast nur noch ConcurrentHashMaps...
Ob es wirklich was bringt, weiß ich jedoch noch nicht.
 
Allgemein
Hilfe Benutzer
    Matthias Matthias: Guten Morgen
    Oben