From 296d0cbdb2cceea190499ac7717ee005418ad5b6 Mon Sep 17 00:00:00 2001 From: Olof Larsson Date: Tue, 27 Aug 2013 10:56:11 +0200 Subject: [PATCH] Add in a system to detect if a PlayerDeathEvent is an invalid duplicate event. --- src/com/massivecraft/mcore/MCore.java | 2 +- .../massivecraft/mcore/util/PlayerUtil.java | 74 ++++++++++++++++--- 2 files changed, 65 insertions(+), 11 deletions(-) diff --git a/src/com/massivecraft/mcore/MCore.java b/src/com/massivecraft/mcore/MCore.java index caadb922..a5d1d0a2 100644 --- a/src/com/massivecraft/mcore/MCore.java +++ b/src/com/massivecraft/mcore/MCore.java @@ -135,7 +135,6 @@ public class MCore extends MPlugin //db = MStore.getDb(ConfServer.dburi); // Setup PlayerUtil and it's events - new PlayerUtil(this); SenderIdMixinDefault.get().setup(); // Register events @@ -144,6 +143,7 @@ public class MCore extends MPlugin TeleportMixinCauseEngine.get().setup(); EngineWorldNameSet.get().setup(); EngineOfflineCase.get().setup(); + PlayerUtil.get().setup(); // Schedule the collection ticker. Bukkit.getScheduler().scheduleSyncRepeatingTask(this, this.collTickTask, 1, 1); diff --git a/src/com/massivecraft/mcore/util/PlayerUtil.java b/src/com/massivecraft/mcore/util/PlayerUtil.java index 51fe9b18..7202fa83 100644 --- a/src/com/massivecraft/mcore/util/PlayerUtil.java +++ b/src/com/massivecraft/mcore/util/PlayerUtil.java @@ -1,5 +1,7 @@ package com.massivecraft.mcore.util; +import java.util.HashMap; +import java.util.Map; import java.util.Set; import java.util.concurrent.ConcurrentSkipListSet; @@ -12,35 +14,87 @@ import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.Listener; +import org.bukkit.event.entity.PlayerDeathEvent; import org.bukkit.event.player.PlayerJoinEvent; import org.bukkit.event.player.PlayerQuitEvent; -import org.bukkit.plugin.Plugin; import com.massivecraft.mcore.MCore; public class PlayerUtil implements Listener { + // -------------------------------------------- // + // INSTANCE & CONSTRUCT + // -------------------------------------------- // + + private static PlayerUtil i = new PlayerUtil(); + public static PlayerUtil get() { return i; } + // -------------------------------------------- // // FIELDS // -------------------------------------------- // - protected static Set joinedPlayerNames = new ConcurrentSkipListSet(String.CASE_INSENSITIVE_ORDER); + private static Set joinedPlayerNames = new ConcurrentSkipListSet(String.CASE_INSENSITIVE_ORDER); + + private static Map lowercaseToDeath = new HashMap(); // -------------------------------------------- // - // CONSTRUCTOR AND EVENT LISTENER + // SETUP // -------------------------------------------- // - public PlayerUtil(Plugin plugin) + public void setup() { - Bukkit.getPluginManager().registerEvents(this, plugin); - joinedPlayerNames.clear(); for (Player player : Bukkit.getOnlinePlayers()) { joinedPlayerNames.add(player.getName()); } + + Bukkit.getPluginManager().registerEvents(this, MCore.get()); } + // -------------------------------------------- // + // IS DUPLICATE DEATH EVENT + // -------------------------------------------- // + // Some times when players die the PlayerDeathEvent is fired twice. + // We want to ignore the extra calls. + + public static boolean isDuplicateDeathEvent(PlayerDeathEvent event) + { + // Prepare the lowercase name ... + final String lowercase = event.getEntity().getName().toLowerCase(); + + // ... take a look at the currently stored event ... + PlayerDeathEvent current = lowercaseToDeath.get(lowercase); + + if (current != null) return !current.equals(event); + + // ... otherwise store ... + lowercaseToDeath.put(lowercase, event); + + // ... schedule removal ... + Bukkit.getScheduler().scheduleSyncDelayedTask(MCore.get(), new Runnable() + { + @Override + public void run() + { + lowercaseToDeath.remove(lowercase); + } + }); + + // ... and return the fact that it was not a duplicate. + return false; + } + + @EventHandler(priority = EventPriority.LOWEST) + public void isDuplicateDeathEventLowest(PlayerDeathEvent event) + { + isDuplicateDeathEvent(event); + } + + // -------------------------------------------- // + // IS JOINED + // -------------------------------------------- // + @EventHandler(priority = EventPriority.MONITOR) public void joinMonitor(PlayerJoinEvent event) { @@ -62,16 +116,16 @@ public class PlayerUtil implements Listener joinedPlayerNames.remove(playerName); } - // -------------------------------------------- // - // PUBLIC METHODS - // -------------------------------------------- // - public static boolean isJoined(Player player) { if (player == null) throw new NullPointerException("player was null"); return joinedPlayerNames.contains(player.getName()); } + // -------------------------------------------- // + // PACKET + // -------------------------------------------- // + /** * Updates the players food and health information. */