From 022e05ceaaa32122801ce71682d611ca3880a065 Mon Sep 17 00:00:00 2001 From: Olof Larsson Date: Fri, 22 Feb 2013 08:12:02 +0100 Subject: [PATCH] more mixin and loads of other stuff --- plugin.yml | 3 + src/com/massivecraft/mcore5/Conf.java | 1 + .../massivecraft/mcore5/InternalListener.java | 111 ++++-- src/com/massivecraft/mcore5/MCore.java | 89 ++++- src/com/massivecraft/mcore5/PS.java | 15 +- src/com/massivecraft/mcore5/Permission.java | 11 +- .../mcore5/cmd/BukkitGlueCommand.java | 26 ++ src/com/massivecraft/mcore5/cmd/MCommand.java | 14 +- .../mcore5/cmd/arg/ARMillisDiff.java | 36 ++ .../massivecraft/mcore5/cmd/arg/ARPlayer.java | 6 +- .../massivecraft/mcore5/cmd/arg/ARSender.java | 6 +- .../mcore5/cmd/arg/ARSenderId.java | 6 +- .../mcore5/cmd/arg/ARSenderIdAbstract.java | 10 +- .../cmd/arg/ARSenderIdAbstractPredsource.java | 24 +- .../massivecraft/mcore5/cmd/arg/ARWorld.java | 42 ++- .../mcore5/cmd/arg/ARWorldId.java | 60 +++ .../massivecraft/mcore5/event/MCoreEvent.java | 18 + .../mcore5/event/MCoreSenderEvent.java | 23 ++ .../event/MCoreSenderRegisterEvent.java | 25 ++ .../event/MCoreSenderUnregisterEvent.java | 25 ++ .../mcore5/mixin/DefaultDisplayNameMixin.java | 67 ---- .../mcore5/mixin/DefaultListNameMixin.java | 67 ---- .../mixin/DefaultPsTeleporterMixin.java | 37 -- .../mcore5/mixin/DefaultSenderIdMixin.java | 180 --------- .../mcore5/mixin/DisplayNameMixin.java | 8 +- .../mixin/DisplayNameMixinAbstract.java | 20 + .../mcore5/mixin/DisplayNameMixinDefault.java | 81 ++++ .../massivecraft/mcore5/mixin/KickMixin.java | 12 + .../mcore5/mixin/KickMixinAbstract.java | 18 + .../mcore5/mixin/KickMixinDefault.java | 39 ++ .../mcore5/mixin/ListNameMixin.java | 8 +- .../mcore5/mixin/ListNameMixinAbstract.java | 20 + .../mcore5/mixin/ListNameMixinDefault.java | 81 ++++ .../mcore5/mixin/MessageMixin.java | 24 ++ .../mcore5/mixin/MessageMixinAbstract.java | 76 ++++ .../mcore5/mixin/MessageMixinDefault.java | 55 +++ src/com/massivecraft/mcore5/mixin/Mixin.java | 356 ++++++++++++++++-- .../mcore5/mixin/PlayedMixin.java | 10 + .../mcore5/mixin/PlayedMixinAbstract.java | 19 + .../mcore5/mixin/PlayedMixinDefault.java | 56 +++ .../mcore5/mixin/PsTeleporterException.java | 31 -- .../mcore5/mixin/PsTeleporterMixin.java | 14 - .../mcore5/mixin/ScheduledTeleport.java | 118 ++++++ .../mixin/ScheduledTeleportListener.java | 51 +++ .../mcore5/mixin/SenderIdMixin.java | 11 +- .../mcore5/mixin/SenderIdMixinAbstract.java | 18 + .../mcore5/mixin/SenderIdMixinDefault.java | 232 ++++++++++++ .../mcore5/mixin/SenderPsMixin.java | 9 + .../mcore5/mixin/SenderPsMixinAbstract.java | 6 + .../mcore5/mixin/SenderPsMixinDefault.java | 34 ++ .../mcore5/mixin/TeleportMixin.java | 50 +++ .../mcore5/mixin/TeleportMixinAbstract.java | 154 ++++++++ .../mcore5/mixin/TeleportMixinDefault.java | 73 ++++ .../mcore5/mixin/TeleporterException.java | 31 ++ .../mcore5/mixin/VisibilityMixin.java | 16 + .../mcore5/mixin/VisibilityMixinAbstract.java | 6 + .../mcore5/mixin/VisibilityMixinDefault.java | 87 +++++ .../massivecraft/mcore5/mixin/WorldMixin.java | 33 ++ .../mcore5/mixin/WorldMixinAbstract.java | 40 ++ .../mcore5/mixin/WorldMixinDefault.java | 122 ++++++ .../mcore5/sender/BasicCommandSender.java | 20 + src/com/massivecraft/mcore5/store/Entity.java | 5 +- .../mcore5/store/MixinSenderIdSource.java | 26 -- .../massivecraft/mcore5/store/SenderColl.java | 16 +- .../mcore5/store/SenderEntity.java | 12 +- .../mcore5/store/SenderIdSource.java | 2 +- .../mcore5/store/SenderIdSourceCombined.java | 7 +- .../SenderIdSourceMixinAllPlayerIds.java | 30 ++ .../SenderIdSourceMixinAllSenderIds.java | 30 ++ src/com/massivecraft/mcore5/util/MUtil.java | 81 ++++ .../massivecraft/mcore5/util/PermUtil.java | 10 +- .../massivecraft/mcore5/util/SenderUtil.java | 158 ++------ .../mcore5/util/TimeDiffUtil.java | 191 ++++++++++ .../massivecraft/mcore5/util/TimeUnit.java | 138 +++++++ 74 files changed, 2909 insertions(+), 738 deletions(-) create mode 100644 src/com/massivecraft/mcore5/cmd/arg/ARMillisDiff.java create mode 100644 src/com/massivecraft/mcore5/cmd/arg/ARWorldId.java create mode 100644 src/com/massivecraft/mcore5/event/MCoreEvent.java create mode 100644 src/com/massivecraft/mcore5/event/MCoreSenderEvent.java create mode 100644 src/com/massivecraft/mcore5/event/MCoreSenderRegisterEvent.java create mode 100644 src/com/massivecraft/mcore5/event/MCoreSenderUnregisterEvent.java delete mode 100644 src/com/massivecraft/mcore5/mixin/DefaultDisplayNameMixin.java delete mode 100644 src/com/massivecraft/mcore5/mixin/DefaultListNameMixin.java delete mode 100644 src/com/massivecraft/mcore5/mixin/DefaultPsTeleporterMixin.java delete mode 100644 src/com/massivecraft/mcore5/mixin/DefaultSenderIdMixin.java create mode 100644 src/com/massivecraft/mcore5/mixin/DisplayNameMixinAbstract.java create mode 100644 src/com/massivecraft/mcore5/mixin/DisplayNameMixinDefault.java create mode 100644 src/com/massivecraft/mcore5/mixin/KickMixin.java create mode 100644 src/com/massivecraft/mcore5/mixin/KickMixinAbstract.java create mode 100644 src/com/massivecraft/mcore5/mixin/KickMixinDefault.java create mode 100644 src/com/massivecraft/mcore5/mixin/ListNameMixinAbstract.java create mode 100644 src/com/massivecraft/mcore5/mixin/ListNameMixinDefault.java create mode 100644 src/com/massivecraft/mcore5/mixin/MessageMixin.java create mode 100644 src/com/massivecraft/mcore5/mixin/MessageMixinAbstract.java create mode 100644 src/com/massivecraft/mcore5/mixin/MessageMixinDefault.java create mode 100644 src/com/massivecraft/mcore5/mixin/PlayedMixin.java create mode 100644 src/com/massivecraft/mcore5/mixin/PlayedMixinAbstract.java create mode 100644 src/com/massivecraft/mcore5/mixin/PlayedMixinDefault.java delete mode 100644 src/com/massivecraft/mcore5/mixin/PsTeleporterException.java delete mode 100644 src/com/massivecraft/mcore5/mixin/PsTeleporterMixin.java create mode 100644 src/com/massivecraft/mcore5/mixin/ScheduledTeleport.java create mode 100644 src/com/massivecraft/mcore5/mixin/ScheduledTeleportListener.java create mode 100644 src/com/massivecraft/mcore5/mixin/SenderIdMixinAbstract.java create mode 100644 src/com/massivecraft/mcore5/mixin/SenderIdMixinDefault.java create mode 100644 src/com/massivecraft/mcore5/mixin/SenderPsMixin.java create mode 100644 src/com/massivecraft/mcore5/mixin/SenderPsMixinAbstract.java create mode 100644 src/com/massivecraft/mcore5/mixin/SenderPsMixinDefault.java create mode 100644 src/com/massivecraft/mcore5/mixin/TeleportMixin.java create mode 100644 src/com/massivecraft/mcore5/mixin/TeleportMixinAbstract.java create mode 100644 src/com/massivecraft/mcore5/mixin/TeleportMixinDefault.java create mode 100644 src/com/massivecraft/mcore5/mixin/TeleporterException.java create mode 100644 src/com/massivecraft/mcore5/mixin/VisibilityMixin.java create mode 100644 src/com/massivecraft/mcore5/mixin/VisibilityMixinAbstract.java create mode 100644 src/com/massivecraft/mcore5/mixin/VisibilityMixinDefault.java create mode 100644 src/com/massivecraft/mcore5/mixin/WorldMixin.java create mode 100644 src/com/massivecraft/mcore5/mixin/WorldMixinAbstract.java create mode 100644 src/com/massivecraft/mcore5/mixin/WorldMixinDefault.java delete mode 100644 src/com/massivecraft/mcore5/store/MixinSenderIdSource.java create mode 100644 src/com/massivecraft/mcore5/store/SenderIdSourceMixinAllPlayerIds.java create mode 100644 src/com/massivecraft/mcore5/store/SenderIdSourceMixinAllSenderIds.java create mode 100644 src/com/massivecraft/mcore5/util/TimeDiffUtil.java create mode 100644 src/com/massivecraft/mcore5/util/TimeUnit.java diff --git a/plugin.yml b/plugin.yml index 72673297..e160d8fe 100644 --- a/plugin.yml +++ b/plugin.yml @@ -24,6 +24,8 @@ permissions: mcore.cmd.usys.aspect.use: {description: set multiverse for aspect, default: false} # mcore command mcore.cmd.mcore: {description: use the mcore command, default: false} +# misc + mcore.notpdelay: {description: teleport without delay, default: false} # -------------------------------------------- # # STAR NOTATION # -------------------------------------------- # @@ -66,6 +68,7 @@ permissions: default: false children: mcore.cmd.*: true + mcore.notpdelay: true # -------------------------------------------- # # KITS # -------------------------------------------- # diff --git a/src/com/massivecraft/mcore5/Conf.java b/src/com/massivecraft/mcore5/Conf.java index 526d14b6..c48f4eb3 100644 --- a/src/com/massivecraft/mcore5/Conf.java +++ b/src/com/massivecraft/mcore5/Conf.java @@ -21,6 +21,7 @@ public class Conf extends SimpleConfig CmdUsys.USYS, MUtil.list(CmdUsys.USYS), CmdMcore.MCORE, MUtil.list(CmdMcore.MCORE) ); + public static int tpdelay = 10; public static List getCmdAliases(String name) { diff --git a/src/com/massivecraft/mcore5/InternalListener.java b/src/com/massivecraft/mcore5/InternalListener.java index 7f6c5be4..2dfac133 100644 --- a/src/com/massivecraft/mcore5/InternalListener.java +++ b/src/com/massivecraft/mcore5/InternalListener.java @@ -2,8 +2,11 @@ package com.massivecraft.mcore5; import java.util.HashMap; import java.util.Map; +import java.util.Set; +import java.util.TreeSet; import org.bukkit.Bukkit; +import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; @@ -13,6 +16,7 @@ import org.bukkit.event.entity.EntityDamageEvent.DamageCause; import org.bukkit.event.player.PlayerKickEvent; import org.bukkit.event.player.PlayerLoginEvent; import org.bukkit.event.player.PlayerLoginEvent.Result; +import org.bukkit.event.player.PlayerChatTabCompleteEvent; import org.bukkit.event.player.PlayerQuitEvent; import org.bukkit.event.player.PlayerRespawnEvent; import org.bukkit.event.player.PlayerTeleportEvent; @@ -20,37 +24,60 @@ import org.bukkit.event.player.PlayerTeleportEvent; import com.massivecraft.mcore5.event.MCoreAfterPlayerRespawnEvent; import com.massivecraft.mcore5.event.MCoreAfterPlayerTeleportEvent; import com.massivecraft.mcore5.event.MCorePlayerLeaveEvent; +import com.massivecraft.mcore5.event.MCoreSenderRegisterEvent; +import com.massivecraft.mcore5.event.MCoreSenderUnregisterEvent; +import com.massivecraft.mcore5.mixin.Mixin; import com.massivecraft.mcore5.store.Coll; import com.massivecraft.mcore5.store.SenderColl; +import com.massivecraft.mcore5.util.SenderUtil; import com.massivecraft.mcore5.util.SmokeUtil; public class InternalListener implements Listener { - MCore p; + // -------------------------------------------- // + // INSTANCE & CONSTRUCT + // -------------------------------------------- // - public InternalListener(MCore p) + private static InternalListener i = new InternalListener(); + public static InternalListener get() { return i; } + + // -------------------------------------------- // + // REGISTER + // -------------------------------------------- // + + public void setup() { - this.p = p; MCorePlayerLeaveEvent.player2event.clear(); - Bukkit.getServer().getPluginManager().registerEvents(this, this.p); + Bukkit.getPluginManager().registerEvents(this, MCore.get()); } - /* - @EventHandler(priority = EventPriority.LOW) - public void onPlayerLogin(PlayerLoginEvent event) + // -------------------------------------------- // + // CHAT TAB COMPLETE + // -------------------------------------------- // + + @EventHandler(priority = EventPriority.LOW, ignoreCancelled = true) + public void chatTabComplete(PlayerChatTabCompleteEvent event) { - String id = event.getPlayer().getName(); + // So the player is watching ... + Player watcher = event.getPlayer(); - for (Persist instance : Persist.instances) + // Get the lowercased token + String tokenlc = event.getLastToken().toLowerCase(); + + // Create a case insensitive set to check for already added stuff + Set current = new TreeSet(String.CASE_INSENSITIVE_ORDER); + current.addAll(event.getTabCompletions()); + + // Add ids of all online senders that match and isn't added yet. + for (String senderId : Mixin.getOnlineSenderIds()) { - for (IClassManager manager : instance.getClassManagers().values()) - { - if (manager.idCanFix(Player.class) == false) continue; - if (manager.containsId(id)) continue; - manager.create(id); - } + if (!senderId.toLowerCase().startsWith(tokenlc)) continue; + if (current.contains(senderId)) continue; + if (!Mixin.isVisible(watcher, senderId)) continue; + + event.getTabCompletions().add(senderId); } - }*/ + } // -------------------------------------------- // // EXPLOSION FX @@ -75,32 +102,50 @@ public class InternalListener implements Listener // -------------------------------------------- // @EventHandler(priority = EventPriority.LOWEST) - public void playerReferencesLoginLowest(PlayerLoginEvent event) + public void senderReferencesLoginLowest(PlayerLoginEvent event) { - String id = event.getPlayer().getName(); - Player player = event.getPlayer(); + String id = SenderUtil.getSenderId(event.getPlayer()); + CommandSender sender = event.getPlayer(); - SenderColl.setSenderRefferences(id, player); + SenderColl.setSenderRefferences(id, sender); } @EventHandler(priority = EventPriority.MONITOR) - public void playerReferencesLoginMonitor(PlayerLoginEvent event) + public void senderReferencesLoginMonitor(PlayerLoginEvent event) { if (event.getResult() == Result.ALLOWED) return; - String id = event.getPlayer().getName(); - Player player = null; + String id = SenderUtil.getSenderId(event.getPlayer()); + CommandSender sender = null; - SenderColl.setSenderRefferences(id, player); + SenderColl.setSenderRefferences(id, sender); } @EventHandler(priority = EventPriority.MONITOR) - public void playerReferencesQuitMonitor(PlayerQuitEvent event) + public void senderReferencesQuitMonitor(PlayerQuitEvent event) { - String id = event.getPlayer().getName(); - Player player = null; + String id = SenderUtil.getSenderId(event.getPlayer()); + CommandSender sender = null; - SenderColl.setSenderRefferences(id, player); + SenderColl.setSenderRefferences(id, sender); + } + + @EventHandler(priority = EventPriority.MONITOR) + public void senderReferencesRegisterMonitor(MCoreSenderRegisterEvent event) + { + String id = SenderUtil.getSenderId(event.getSender()); + CommandSender sender = event.getSender(); + + SenderColl.setSenderRefferences(id, sender); + } + + @EventHandler(priority = EventPriority.MONITOR) + public void senderReferencesUnregisterMonitor(MCoreSenderUnregisterEvent event) + { + String id = SenderUtil.getSenderId(event.getSender()); + CommandSender sender = null; + + SenderColl.setSenderRefferences(id, sender); } // -------------------------------------------- // @@ -110,13 +155,13 @@ public class InternalListener implements Listener @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) public void after(PlayerTeleportEvent event) { - Bukkit.getScheduler().scheduleSyncDelayedTask(p, new MCoreAfterPlayerTeleportEvent(event), 0); + Bukkit.getScheduler().scheduleSyncDelayedTask(MCore.get(), new MCoreAfterPlayerTeleportEvent(event), 0); } @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) public void after(PlayerRespawnEvent event) { - Bukkit.getScheduler().scheduleSyncDelayedTask(p, new MCoreAfterPlayerRespawnEvent(event, event.getPlayer().getLocation()), 0); + Bukkit.getScheduler().scheduleSyncDelayedTask(MCore.get(), new MCoreAfterPlayerRespawnEvent(event, event.getPlayer().getLocation()), 0); } // -------------------------------------------- // @@ -182,17 +227,17 @@ public class InternalListener implements Listener // SYNC PLAYER ON LOGON AND LEAVE // -------------------------------------------- // - @EventHandler(priority = EventPriority.LOW, ignoreCancelled = true) + @EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true) public void syncOnPlayerLogin(PlayerLoginEvent event) { - //p.log("syncOnPlayerLogin", event.getPlayer().getName()); + MCore.get().log("LOWEST syncOnPlayerLogin", event.getPlayer().getName()); this.syncAllForPlayer(event.getPlayer()); } @EventHandler(priority = EventPriority.MONITOR) public void syncOnPlayerLeave(MCorePlayerLeaveEvent event) { - //p.log("syncOnPlayerLeave", event.getPlayer().getName()); + MCore.get().log("MONITOR syncOnPlayerLeave", event.getPlayer().getName()); this.syncAllForPlayer(event.getPlayer()); } diff --git a/src/com/massivecraft/mcore5/MCore.java b/src/com/massivecraft/mcore5/MCore.java index e0e2c34d..0a9bce5f 100644 --- a/src/com/massivecraft/mcore5/MCore.java +++ b/src/com/massivecraft/mcore5/MCore.java @@ -1,9 +1,12 @@ package com.massivecraft.mcore5; import java.lang.reflect.Modifier; +import java.util.Map; +import java.util.Map.Entry; import java.util.Random; import org.bukkit.Bukkit; +import org.bukkit.ChatColor; import org.bukkit.inventory.Inventory; import org.bukkit.inventory.ItemStack; @@ -12,7 +15,8 @@ import com.massivecraft.mcore5.adapter.ItemStackAdapter; import com.massivecraft.mcore5.adapter.MongoURIAdapter; import com.massivecraft.mcore5.adapter.PSAdapter; import com.massivecraft.mcore5.cmd.CmdMcore; -import com.massivecraft.mcore5.mixin.DefaultSenderIdMixin; +import com.massivecraft.mcore5.mixin.SenderIdMixinDefault; +import com.massivecraft.mcore5.mixin.ScheduledTeleportListener; import com.massivecraft.mcore5.store.Coll; import com.massivecraft.mcore5.store.Db; import com.massivecraft.mcore5.store.MStore; @@ -20,6 +24,8 @@ import com.massivecraft.mcore5.usys.AspectColl; import com.massivecraft.mcore5.usys.MultiverseColl; import com.massivecraft.mcore5.usys.cmd.CmdUsys; import com.massivecraft.mcore5.util.PlayerUtil; +import com.massivecraft.mcore5.util.TimeDiffUtil; +import com.massivecraft.mcore5.util.TimeUnit; import com.massivecraft.mcore5.xlib.gson.Gson; import com.massivecraft.mcore5.xlib.gson.GsonBuilder; import com.massivecraft.mcore5.xlib.mongodb.MongoURI; @@ -33,6 +39,14 @@ public class MCore extends MPlugin public final static String INSTANCE = "instance"; public final static String DEFAULT = "default"; + // -------------------------------------------- // + // INSTANCE & CONSTRUCT + // -------------------------------------------- // + + public static MCore p; + public static MCore get() { return p; } + public MCore() { p = this; } + // -------------------------------------------- // // STATIC // -------------------------------------------- // @@ -57,19 +71,13 @@ public class MCore extends MPlugin public static Db getDb() { return db; } // -------------------------------------------- // - // CONSTRUCT + // FIELDS // -------------------------------------------- // - public static MCore p; - public MCore() - { - p = this; - } + // Commands + public CmdUsys cmdUsys; + public CmdMcore cmdMcore; - // -------------------------------------------- // - // NON STATIC :) - // -------------------------------------------- // - private Runnable collTickTask = new Runnable() { public void run() @@ -81,9 +89,9 @@ public class MCore extends MPlugin } }; - public InternalListener internalListener; - public CmdUsys cmdUsys; - public CmdMcore cmdMcore; + // -------------------------------------------- // + // OVERRIDE + // -------------------------------------------- // @Override public void onEnable() @@ -101,11 +109,11 @@ public class MCore extends MPlugin // Setup PlayerUtil and it's events new PlayerUtil(this); - DefaultSenderIdMixin.get().register(); - DefaultSenderIdMixin.get().setup(); + SenderIdMixinDefault.get().setup(); // Register events - this.internalListener = new InternalListener(this); + InternalListener.get().setup(); + ScheduledTeleportListener.get().setup(); // Schedule the collection ticker. Bukkit.getScheduler().scheduleSyncRepeatingTask(this, this.collTickTask, 1, 1); @@ -121,7 +129,54 @@ public class MCore extends MPlugin this.cmdMcore = new CmdMcore(); this.cmdMcore.register(this, true); + /* + test(""); + test("+1day"); + test("1day"); + test("1 day"); + test("-1day"); + test("1week4d"); + test("+1week-4d"); + test("day"); + test("1month"); + test("1months"); + test("1months2ms"); + */ + this.postEnable(); } + public void test(String diffString) + { + log("==========================="); + log("Testing Diff String \""+diffString+"\":"); + + try + { + Map unitcounts = TimeDiffUtil.unitcounts(diffString); + for (Entry entry : unitcounts.entrySet()) + { + System.out.println(entry.getValue()+": "+entry.getKey()); + } + + System.out.println("---"); + + long millis = TimeDiffUtil.millis(unitcounts); + log("millis: "+millis); + + String verboose = ChatColor.stripColor(TimeDiffUtil.formatedVerboose(unitcounts)); + String minimal = ChatColor.stripColor(TimeDiffUtil.formatedMinimal(unitcounts)); + log("verboose: "+verboose); + log("minimal: "+minimal); + + long millisRec = TimeDiffUtil.millis(minimal); + log("millisRec: "+millisRec); + log("matches: "+(millis == millisRec)); + } + catch (Exception e) + { + e.printStackTrace(); + } + } + } diff --git a/src/com/massivecraft/mcore5/PS.java b/src/com/massivecraft/mcore5/PS.java index 9cc2fa9a..5e0877cf 100644 --- a/src/com/massivecraft/mcore5/PS.java +++ b/src/com/massivecraft/mcore5/PS.java @@ -15,10 +15,12 @@ import org.bukkit.Location; import org.bukkit.World; import org.bukkit.block.Block; import org.bukkit.entity.Entity; +import org.bukkit.entity.Player; import org.bukkit.util.Vector; +import com.massivecraft.mcore5.mixin.TeleportMixinDefault; import com.massivecraft.mcore5.mixin.Mixin; -import com.massivecraft.mcore5.mixin.PsTeleporterException; +import com.massivecraft.mcore5.mixin.TeleporterException; import com.massivecraft.mcore5.usys.Aspect; import com.massivecraft.mcore5.usys.Multiverse; import com.massivecraft.mcore5.util.MUtil; @@ -486,9 +488,16 @@ public class PS implements Cloneable, Serializable // WRITERS //----------------------------------------------// - public synchronized void write(Entity entity) throws PsTeleporterException + public synchronized void write(Entity entity) throws TeleporterException { - Mixin.teleport(entity, this); + if (entity instanceof Player) + { + Mixin.teleport((Player)entity, this); + } + else + { + TeleportMixinDefault.teleportEntity(entity, this); + } } //----------------------------------------------// diff --git a/src/com/massivecraft/mcore5/Permission.java b/src/com/massivecraft/mcore5/Permission.java index e977d35d..082e52bb 100644 --- a/src/com/massivecraft/mcore5/Permission.java +++ b/src/com/massivecraft/mcore5/Permission.java @@ -1,6 +1,6 @@ package com.massivecraft.mcore5; -import org.bukkit.command.CommandSender; +import org.bukkit.permissions.Permissible; import com.massivecraft.mcore5.util.PermUtil; @@ -22,6 +22,7 @@ public enum Permission CMD_USYS_ASPECT_SHOW("cmd.usys.aspect.show"), CMD_USYS_ASPECT_USE("cmd.usys.aspect.use"), CMD_MCORE("cmd.mcore"), + NOTPDELAY("notpdelay"), ; public final String node; @@ -31,13 +32,13 @@ public enum Permission this.node = "mcore."+permissionNode; } - public boolean has(CommandSender sender, boolean informSenderIfNot) + public boolean has(Permissible permissible, boolean informSenderIfNot) { - return PermUtil.has(sender, this.node, informSenderIfNot); + return PermUtil.has(permissible, this.node, informSenderIfNot); } - public boolean has(CommandSender sender) + public boolean has(Permissible permissible) { - return has(sender, false); + return has(permissible, false); } } diff --git a/src/com/massivecraft/mcore5/cmd/BukkitGlueCommand.java b/src/com/massivecraft/mcore5/cmd/BukkitGlueCommand.java index ca503edb..eddfbc2d 100644 --- a/src/com/massivecraft/mcore5/cmd/BukkitGlueCommand.java +++ b/src/com/massivecraft/mcore5/cmd/BukkitGlueCommand.java @@ -1,11 +1,15 @@ package com.massivecraft.mcore5.cmd; import java.util.ArrayList; +import java.util.List; +import java.util.Set; +import java.util.TreeSet; import org.bukkit.command.Command; import org.bukkit.command.CommandSender; import com.massivecraft.mcore5.MPlugin; +import com.massivecraft.mcore5.mixin.Mixin; import com.massivecraft.mcore5.util.Txt; public class BukkitGlueCommand extends Command @@ -27,4 +31,26 @@ public class BukkitGlueCommand extends Command this.mcommand.execute(sender, Txt.tokenizeArguments(Txt.implode(args, " "))); return true; } + + @Override + public List tabComplete(CommandSender sender, String alias, String[] args) throws IllegalArgumentException + { + List superRet = super.tabComplete(sender, alias, args); + if (args.length == 0) return superRet; + + Set ret = new TreeSet(String.CASE_INSENSITIVE_ORDER); + ret.addAll(superRet); + + String tokenlc = args[args.length - 1].toLowerCase(); + + // Add ids of all online senders that match and isn't added yet. + for (String senderId : Mixin.getOnlineSenderIds()) + { + if (!senderId.toLowerCase().startsWith(tokenlc)) continue; + if (!Mixin.isVisible(sender, senderId)) continue; + ret.add(senderId); + } + + return new ArrayList(ret); + } } diff --git a/src/com/massivecraft/mcore5/cmd/MCommand.java b/src/com/massivecraft/mcore5/cmd/MCommand.java index 1afd10bb..802be633 100644 --- a/src/com/massivecraft/mcore5/cmd/MCommand.java +++ b/src/com/massivecraft/mcore5/cmd/MCommand.java @@ -18,9 +18,9 @@ import com.massivecraft.mcore5.cmd.arg.ArgReader; import com.massivecraft.mcore5.cmd.arg.ArgResult; import com.massivecraft.mcore5.cmd.req.IReq; import com.massivecraft.mcore5.cmd.req.ReqHasPerm; +import com.massivecraft.mcore5.mixin.Mixin; import com.massivecraft.mcore5.util.BukkitCommandUtil; import com.massivecraft.mcore5.util.PermUtil; -import com.massivecraft.mcore5.util.SenderUtil; import com.massivecraft.mcore5.util.Txt; public abstract class MCommand @@ -411,34 +411,34 @@ public abstract class MCommand public boolean sendMessage(String message) { - return SenderUtil.sendMessage(this.sender, message); + return Mixin.message(this.sender, message); } public boolean sendMessage(String... messages) { - return SenderUtil.sendMessage(this.sender, messages); + return Mixin.message(this.sender, messages); } public boolean sendMessage(Collection messages) { - return SenderUtil.sendMessage(this.sender, messages); + return Mixin.message(this.sender, messages); } // CONVENIENCE MSG public boolean msg(String msg) { - return SenderUtil.msg(this.sender, msg); + return Mixin.msg(this.sender, msg); } public boolean msg(String msg, Object... args) { - return SenderUtil.msg(this.sender, msg, args); + return Mixin.msg(this.sender, msg, args); } public boolean msg(Collection msgs) { - return SenderUtil.msg(this.sender, msgs); + return Mixin.msg(this.sender, msgs); } // -------------------------------------------- // diff --git a/src/com/massivecraft/mcore5/cmd/arg/ARMillisDiff.java b/src/com/massivecraft/mcore5/cmd/arg/ARMillisDiff.java new file mode 100644 index 00000000..a34a89ba --- /dev/null +++ b/src/com/massivecraft/mcore5/cmd/arg/ARMillisDiff.java @@ -0,0 +1,36 @@ +package com.massivecraft.mcore5.cmd.arg; + +import org.bukkit.command.CommandSender; + +import com.massivecraft.mcore5.util.TimeDiffUtil; +import com.massivecraft.mcore5.util.Txt; + +public class ARMillisDiff implements ArgReader +{ + // -------------------------------------------- // + // OVERRIDE + // -------------------------------------------- // + + @Override + public ArgResult read(String arg, CommandSender sender) + { + ArgResult ret = new ArgResult(); + try + { + ret.setResult(TimeDiffUtil.millis(arg)); + } + catch (Exception e) + { + ret.setErrors(Txt.parse("")+e.getMessage()); + } + return ret; + } + + // -------------------------------------------- // + // INSTANCE + // -------------------------------------------- // + + private static ARMillisDiff i = new ARMillisDiff(); + public static ARMillisDiff get() { return i; } + +} diff --git a/src/com/massivecraft/mcore5/cmd/arg/ARPlayer.java b/src/com/massivecraft/mcore5/cmd/arg/ARPlayer.java index bf01517d..dc788b29 100644 --- a/src/com/massivecraft/mcore5/cmd/arg/ARPlayer.java +++ b/src/com/massivecraft/mcore5/cmd/arg/ARPlayer.java @@ -2,7 +2,7 @@ package com.massivecraft.mcore5.cmd.arg; import org.bukkit.entity.Player; -import com.massivecraft.mcore5.store.MixinSenderIdSource; +import com.massivecraft.mcore5.store.SenderIdSourceMixinAllSenderIds; import com.massivecraft.mcore5.store.SenderIdSource; import com.massivecraft.mcore5.util.SenderUtil; @@ -12,10 +12,10 @@ public class ARPlayer extends ARSenderIdAbstractPredsource // INSTANCE & CONSTRUCT // -------------------------------------------- // - private static final ARPlayer full = getFull(MixinSenderIdSource.get()); + private static final ARPlayer full = getFull(SenderIdSourceMixinAllSenderIds.get()); public static ARPlayer getFull() { return full; } - private static final ARPlayer start = getStart(MixinSenderIdSource.get()); + private static final ARPlayer start = getStart(SenderIdSourceMixinAllSenderIds.get()); public static ARPlayer getStart() { return start; } public static ARPlayer getFull(SenderIdSource source) diff --git a/src/com/massivecraft/mcore5/cmd/arg/ARSender.java b/src/com/massivecraft/mcore5/cmd/arg/ARSender.java index cb0cfc2d..c85c0035 100644 --- a/src/com/massivecraft/mcore5/cmd/arg/ARSender.java +++ b/src/com/massivecraft/mcore5/cmd/arg/ARSender.java @@ -2,7 +2,7 @@ package com.massivecraft.mcore5.cmd.arg; import org.bukkit.command.CommandSender; -import com.massivecraft.mcore5.store.MixinSenderIdSource; +import com.massivecraft.mcore5.store.SenderIdSourceMixinAllSenderIds; import com.massivecraft.mcore5.store.SenderIdSource; import com.massivecraft.mcore5.util.SenderUtil; @@ -12,10 +12,10 @@ public class ARSender extends ARSenderIdAbstractPredsource // INSTANCE & CONSTRUCT // -------------------------------------------- // - private static final ARSender full = getFull(MixinSenderIdSource.get()); + private static final ARSender full = getFull(SenderIdSourceMixinAllSenderIds.get()); public static ARSender getFull() { return full; } - private static final ARSender start = getStart(MixinSenderIdSource.get()); + private static final ARSender start = getStart(SenderIdSourceMixinAllSenderIds.get()); public static ARSender getStart() { return start; } public static ARSender getFull(SenderIdSource source) diff --git a/src/com/massivecraft/mcore5/cmd/arg/ARSenderId.java b/src/com/massivecraft/mcore5/cmd/arg/ARSenderId.java index ea1baddf..8b4277ed 100644 --- a/src/com/massivecraft/mcore5/cmd/arg/ARSenderId.java +++ b/src/com/massivecraft/mcore5/cmd/arg/ARSenderId.java @@ -1,6 +1,6 @@ package com.massivecraft.mcore5.cmd.arg; -import com.massivecraft.mcore5.store.MixinSenderIdSource; +import com.massivecraft.mcore5.store.SenderIdSourceMixinAllSenderIds; import com.massivecraft.mcore5.store.SenderIdSource; public class ARSenderId extends ARSenderIdAbstractPredsource @@ -9,10 +9,10 @@ public class ARSenderId extends ARSenderIdAbstractPredsource // INSTANCE & CONSTRUCT // -------------------------------------------- // - private static final ARSenderId full = getFull(MixinSenderIdSource.get()); + private static final ARSenderId full = getFull(SenderIdSourceMixinAllSenderIds.get()); public static ARSenderId getFull() { return full; } - private static final ARSenderId start = getStart(MixinSenderIdSource.get()); + private static final ARSenderId start = getStart(SenderIdSourceMixinAllSenderIds.get()); public static ARSenderId getStart() { return start; } public static ARSenderId getFull(SenderIdSource source) diff --git a/src/com/massivecraft/mcore5/cmd/arg/ARSenderIdAbstract.java b/src/com/massivecraft/mcore5/cmd/arg/ARSenderIdAbstract.java index 6344982b..8544dd81 100644 --- a/src/com/massivecraft/mcore5/cmd/arg/ARSenderIdAbstract.java +++ b/src/com/massivecraft/mcore5/cmd/arg/ARSenderIdAbstract.java @@ -13,6 +13,12 @@ public abstract class ARSenderIdAbstract implements ArgReader // ABSTRACT // -------------------------------------------- // + public final static int MAX_COUNT = 10; + + // -------------------------------------------- // + // ABSTRACT + // -------------------------------------------- // + public abstract String getTypename(); public abstract T getResultForSenderId(String senderId); @@ -51,10 +57,10 @@ public abstract class ARSenderIdAbstract implements ArgReader { // Ambigious! ret.getErrors().add("Online "+this.getTypename()+" matching \""+arg+"\" is ambigious."); - if (senderIds.size() > 10) + if (senderIds.size() >= MAX_COUNT) { // To many to list - ret.getErrors().add("Could be any of "+senderIds.size()+" possible alternatives."); + ret.getErrors().add("More than "+MAX_COUNT+" possible alternatives."); } else { diff --git a/src/com/massivecraft/mcore5/cmd/arg/ARSenderIdAbstractPredsource.java b/src/com/massivecraft/mcore5/cmd/arg/ARSenderIdAbstractPredsource.java index b6849d9b..819597f2 100644 --- a/src/com/massivecraft/mcore5/cmd/arg/ARSenderIdAbstractPredsource.java +++ b/src/com/massivecraft/mcore5/cmd/arg/ARSenderIdAbstractPredsource.java @@ -1,7 +1,7 @@ package com.massivecraft.mcore5.cmd.arg; import java.util.Collection; -import java.util.Iterator; +import java.util.TreeSet; import org.bukkit.command.CommandSender; @@ -41,18 +41,26 @@ public abstract class ARSenderIdAbstractPredsource extends ARSenderIdAbstract @Override public Collection getSenderIdsFor(String arg, CommandSender sender) { - Collection senderIds = this.source.getSenderIds(); arg = arg.toLowerCase(); - Iterator iter = senderIds.iterator(); - while(iter.hasNext()) + TreeSet ret = new TreeSet(String.CASE_INSENSITIVE_ORDER); + + for (Collection coll : this.source.getSenderIdCollections()) { - String senderId = iter.next(); - if (this.isSenderIdOk(senderId, arg, sender)) continue; - iter.remove(); + for (String senderId : coll) + { + if (this.isSenderIdOk(senderId, arg, sender)) + { + ret.add(senderId); + if (ret.size() >= MAX_COUNT) + { + return ret; + } + } + } } - return senderIds; + return ret; } protected boolean isSenderIdOk(String senderId, String arg, CommandSender sender) diff --git a/src/com/massivecraft/mcore5/cmd/arg/ARWorld.java b/src/com/massivecraft/mcore5/cmd/arg/ARWorld.java index 8026a763..e090702d 100644 --- a/src/com/massivecraft/mcore5/cmd/arg/ARWorld.java +++ b/src/com/massivecraft/mcore5/cmd/arg/ARWorld.java @@ -1,34 +1,35 @@ package com.massivecraft.mcore5.cmd.arg; -import java.util.ArrayList; -import java.util.List; - import org.bukkit.Bukkit; import org.bukkit.World; import org.bukkit.command.CommandSender; -public class ARWorld extends ARAbstractSelect +public class ARWorld implements ArgReader { @Override - public String typename() + public ArgResult read(String arg, CommandSender sender) { - return "world"; - } - - @Override - public World select(String arg, CommandSender sender) - { - return Bukkit.getWorld(arg); - } - - @Override - public List altNames(CommandSender sender) - { - List ret = new ArrayList(); - for (World world : Bukkit.getWorlds()) + ArgResult ret = new ArgResult(); + + ArgResult inner = ARWorldId.get().read(arg, sender); + if (inner.hasErrors()) { - ret.add(world.getName()); + ret.setErrors(inner.getErrors()); + return ret; } + + String worldId = inner.getResult(); + + World world = Bukkit.getWorld(worldId); + if (world == null) + { + ret.setErrors("The world could not be found."); + } + else + { + ret.setResult(world); + } + return ret; } @@ -39,4 +40,5 @@ public class ARWorld extends ARAbstractSelect private static ARWorld i = new ARWorld(); public static ARWorld get() { return i; } + } diff --git a/src/com/massivecraft/mcore5/cmd/arg/ARWorldId.java b/src/com/massivecraft/mcore5/cmd/arg/ARWorldId.java new file mode 100644 index 00000000..c587b165 --- /dev/null +++ b/src/com/massivecraft/mcore5/cmd/arg/ARWorldId.java @@ -0,0 +1,60 @@ +package com.massivecraft.mcore5.cmd.arg; + +import java.util.ArrayList; +import java.util.List; + +import org.bukkit.command.CommandSender; + +import com.massivecraft.mcore5.mixin.Mixin; + +public class ARWorldId extends ARAbstractSelect +{ + @Override + public String typename() + { + return "world"; + } + + @Override + public String select(String arg, CommandSender sender) + { + List visibleWorldIds = Mixin.getVisibleWorldIds(sender); + + for (String worldId : visibleWorldIds) + { + if (!Mixin.canSee(sender, worldId)) continue; + if (arg.equalsIgnoreCase(worldId)) return worldId; + } + + for (String worldId : visibleWorldIds) + { + if (!Mixin.canSee(sender, worldId)) continue; + for (String worldAlias : Mixin.getWorldAliases(worldId)) + { + if (arg.equalsIgnoreCase(worldAlias)) return worldId; + } + } + + return null; + } + + @Override + public List altNames(CommandSender sender) + { + List ret = new ArrayList(); + for (String worldId : Mixin.getWorldIds()) + { + if (!Mixin.canSee(sender, worldId)) continue; + ret.add(Mixin.getWorldDisplayName(worldId)); + } + return ret; + } + + // -------------------------------------------- // + // INSTANCE + // -------------------------------------------- // + + private static ARWorldId i = new ARWorldId(); + public static ARWorldId get() { return i; } + +} diff --git a/src/com/massivecraft/mcore5/event/MCoreEvent.java b/src/com/massivecraft/mcore5/event/MCoreEvent.java new file mode 100644 index 00000000..8b26ebb0 --- /dev/null +++ b/src/com/massivecraft/mcore5/event/MCoreEvent.java @@ -0,0 +1,18 @@ +package com.massivecraft.mcore5.event; + +import org.bukkit.Bukkit; +import org.bukkit.event.Event; + +public abstract class MCoreEvent extends Event implements Runnable +{ + // -------------------------------------------- // + // RUN + // -------------------------------------------- // + + @Override + public void run() + { + Bukkit.getPluginManager().callEvent(this); + } + +} diff --git a/src/com/massivecraft/mcore5/event/MCoreSenderEvent.java b/src/com/massivecraft/mcore5/event/MCoreSenderEvent.java new file mode 100644 index 00000000..8992e950 --- /dev/null +++ b/src/com/massivecraft/mcore5/event/MCoreSenderEvent.java @@ -0,0 +1,23 @@ +package com.massivecraft.mcore5.event; + +import org.bukkit.command.CommandSender; + +public abstract class MCoreSenderEvent extends MCoreEvent +{ + // -------------------------------------------- // + // FIELDS + // -------------------------------------------- // + + private final CommandSender sender; + public CommandSender getSender() { return this.sender; } + + // -------------------------------------------- // + // CONSTRUCT + // -------------------------------------------- // + + public MCoreSenderEvent(CommandSender sender) + { + this.sender = sender; + } + +} diff --git a/src/com/massivecraft/mcore5/event/MCoreSenderRegisterEvent.java b/src/com/massivecraft/mcore5/event/MCoreSenderRegisterEvent.java new file mode 100644 index 00000000..dea24004 --- /dev/null +++ b/src/com/massivecraft/mcore5/event/MCoreSenderRegisterEvent.java @@ -0,0 +1,25 @@ +package com.massivecraft.mcore5.event; + +import org.bukkit.command.CommandSender; +import org.bukkit.event.HandlerList; + +public class MCoreSenderRegisterEvent extends MCoreSenderEvent +{ + // -------------------------------------------- // + // REQUIRED EVENT CODE + // -------------------------------------------- // + + private static final HandlerList handlers = new HandlerList(); + @Override public HandlerList getHandlers() { return handlers; } + public static HandlerList getHandlerList() { return handlers; } + + // -------------------------------------------- // + // CONSTRUCT + // -------------------------------------------- // + + public MCoreSenderRegisterEvent(CommandSender sender) + { + super(sender); + } + +} diff --git a/src/com/massivecraft/mcore5/event/MCoreSenderUnregisterEvent.java b/src/com/massivecraft/mcore5/event/MCoreSenderUnregisterEvent.java new file mode 100644 index 00000000..94fe7782 --- /dev/null +++ b/src/com/massivecraft/mcore5/event/MCoreSenderUnregisterEvent.java @@ -0,0 +1,25 @@ +package com.massivecraft.mcore5.event; + +import org.bukkit.command.CommandSender; +import org.bukkit.event.HandlerList; + +public class MCoreSenderUnregisterEvent extends MCoreSenderEvent +{ + // -------------------------------------------- // + // REQUIRED EVENT CODE + // -------------------------------------------- // + + private static final HandlerList handlers = new HandlerList(); + @Override public HandlerList getHandlers() { return handlers; } + public static HandlerList getHandlerList() { return handlers; } + + // -------------------------------------------- // + // CONSTRUCT + // -------------------------------------------- // + + public MCoreSenderUnregisterEvent(CommandSender sender) + { + super(sender); + } + +} diff --git a/src/com/massivecraft/mcore5/mixin/DefaultDisplayNameMixin.java b/src/com/massivecraft/mcore5/mixin/DefaultDisplayNameMixin.java deleted file mode 100644 index 7770499a..00000000 --- a/src/com/massivecraft/mcore5/mixin/DefaultDisplayNameMixin.java +++ /dev/null @@ -1,67 +0,0 @@ -package com.massivecraft.mcore5.mixin; - -import java.util.Map; -import java.util.TreeMap; - -import org.bukkit.Bukkit; -import org.bukkit.command.CommandSender; -import org.bukkit.entity.Player; - -import com.massivecraft.mcore5.util.SenderUtil; - -public class DefaultDisplayNameMixin implements DisplayNameMixin -{ - // -------------------------------------------- // - // INSTANCE & CONSTRUCT - // -------------------------------------------- // - - private static DefaultDisplayNameMixin i = new DefaultDisplayNameMixin(); - public static DefaultDisplayNameMixin get() { return i; } - - // -------------------------------------------- // - // FIELDS - // -------------------------------------------- // - - protected Map idToDisplayName = new TreeMap(String.CASE_INSENSITIVE_ORDER); - - // -------------------------------------------- // - // OVERRIDE - // -------------------------------------------- // - - @Override - public String get(String senderId) - { - if (senderId == null) return null; - - String ret = this.idToDisplayName.get(senderId); - if (ret != null) return ret; - - Player player = Bukkit.getPlayerExact(senderId); - if (player != null) return player.getDisplayName(); - - return Mixin.tryFix(senderId); - } - - @Override - public void set(String senderId, String displayName) - { - this.idToDisplayName.put(senderId, displayName); - - Player player = Bukkit.getPlayerExact(senderId); - if (player == null) return; - player.setDisplayName(displayName); - } - - @Override - public String get(CommandSender sender) - { - return this.get(SenderUtil.getSenderId(sender)); - } - - @Override - public void set(CommandSender sender, String displayName) - { - this.set(SenderUtil.getSenderId(sender), displayName); - } - -} \ No newline at end of file diff --git a/src/com/massivecraft/mcore5/mixin/DefaultListNameMixin.java b/src/com/massivecraft/mcore5/mixin/DefaultListNameMixin.java deleted file mode 100644 index b0a61e49..00000000 --- a/src/com/massivecraft/mcore5/mixin/DefaultListNameMixin.java +++ /dev/null @@ -1,67 +0,0 @@ -package com.massivecraft.mcore5.mixin; - -import java.util.Map; -import java.util.TreeMap; - -import org.bukkit.Bukkit; -import org.bukkit.command.CommandSender; -import org.bukkit.entity.Player; - -import com.massivecraft.mcore5.util.SenderUtil; - -public class DefaultListNameMixin implements ListNameMixin -{ - // -------------------------------------------- // - // INSTANCE & CONSTRUCT - // -------------------------------------------- // - - private static DefaultListNameMixin i = new DefaultListNameMixin(); - public static DefaultListNameMixin get() { return i; } - - // -------------------------------------------- // - // FIELDS - // -------------------------------------------- // - - protected Map idToListName = new TreeMap(String.CASE_INSENSITIVE_ORDER); - - // -------------------------------------------- // - // OVERRIDE - // -------------------------------------------- // - - @Override - public String get(String senderId) - { - if (senderId == null) return null; - - String ret = this.idToListName.get(senderId); - if (ret != null) return ret; - - Player player = Bukkit.getPlayerExact(senderId); - if (player != null) return player.getDisplayName(); - - return Mixin.tryFix(senderId); - } - - @Override - public void set(String senderId, String listName) - { - this.idToListName.put(senderId, listName); - - Player player = Bukkit.getPlayerExact(senderId); - if (player == null) return; - player.setDisplayName(listName); - } - - @Override - public String get(CommandSender sender) - { - return this.get(SenderUtil.getSenderId(sender)); - } - - @Override - public void set(CommandSender sender, String listName) - { - this.set(SenderUtil.getSenderId(sender), listName); - } - -} \ No newline at end of file diff --git a/src/com/massivecraft/mcore5/mixin/DefaultPsTeleporterMixin.java b/src/com/massivecraft/mcore5/mixin/DefaultPsTeleporterMixin.java deleted file mode 100644 index fdf4cd08..00000000 --- a/src/com/massivecraft/mcore5/mixin/DefaultPsTeleporterMixin.java +++ /dev/null @@ -1,37 +0,0 @@ -package com.massivecraft.mcore5.mixin; - -import org.bukkit.Location; -import org.bukkit.entity.Entity; -import org.bukkit.util.Vector; - -import com.massivecraft.mcore5.PS; -import com.massivecraft.mcore5.util.Txt; - -public class DefaultPsTeleporterMixin implements PsTeleporterMixin -{ - // -------------------------------------------- // - // INSTANCE & CONSTRUCT - // -------------------------------------------- // - - private static DefaultPsTeleporterMixin i = new DefaultPsTeleporterMixin(); - public static DefaultPsTeleporterMixin get() { return i; } - - // -------------------------------------------- // - // OVERRIDE - // -------------------------------------------- // - - @Override - public void teleport(Entity entity, PS ps) throws PsTeleporterException - { - Location location = ps.calcLocation(); - if (location == null) throw new PsTeleporterException(Txt.parse("Could not calculate the location")); - - entity.teleport(location); - - Vector velocity = ps.getVelocity(); - if (velocity == null) return; - - entity.setVelocity(velocity); - } - -} \ No newline at end of file diff --git a/src/com/massivecraft/mcore5/mixin/DefaultSenderIdMixin.java b/src/com/massivecraft/mcore5/mixin/DefaultSenderIdMixin.java deleted file mode 100644 index 048f4adf..00000000 --- a/src/com/massivecraft/mcore5/mixin/DefaultSenderIdMixin.java +++ /dev/null @@ -1,180 +0,0 @@ -package com.massivecraft.mcore5.mixin; - -import java.io.File; -import java.util.Map; -import java.util.Set; -import java.util.TreeSet; -import java.util.concurrent.ConcurrentSkipListMap; - -import org.bukkit.Bukkit; -import org.bukkit.command.CommandSender; -import org.bukkit.entity.Player; -import org.bukkit.event.EventHandler; -import org.bukkit.event.EventPriority; -import org.bukkit.event.HandlerList; -import org.bukkit.event.Listener; -import org.bukkit.event.player.PlayerLoginEvent; - -import com.massivecraft.mcore5.MCore; -import com.massivecraft.mcore5.util.MUtil; -import com.massivecraft.mcore5.util.SenderUtil; - -public class DefaultSenderIdMixin implements SenderIdMixin, Listener -{ - // -------------------------------------------- // - // INSTANCE & CONSTRUCT - // -------------------------------------------- // - - private static DefaultSenderIdMixin i = new DefaultSenderIdMixin(); - public static DefaultSenderIdMixin get() { return i; } - - // -------------------------------------------- // - // REGISTER & UNREGISTER - // -------------------------------------------- // - - public void register() - { - Bukkit.getServer().getPluginManager().registerEvents(this, MCore.p); - } - - public void unregister() - { - HandlerList.unregisterAll(this); - } - - // -------------------------------------------- // - // SETUP - // -------------------------------------------- // - - public void setup() - { - for (String playerName : MUtil.getPlayerDirectoryNames()) - { - this.idToCorrectId.put(playerName, playerName); - } - } - - // -------------------------------------------- // - // FIELDS - // -------------------------------------------- // - - // This map will contain all players that ever were on the server. - // It will however not contain any senders registered through SenderUtil. - protected Map idToCorrectId = new ConcurrentSkipListMap(String.CASE_INSENSITIVE_ORDER); - - // -------------------------------------------- // - // LISTENER - // -------------------------------------------- // - - @EventHandler(priority = EventPriority.LOWEST) - public void onPlayerLogin(PlayerLoginEvent event) - { - String id = event.getPlayer().getName(); - idToCorrectId.put(id, id); - } - - // -------------------------------------------- // - // OVERRIDE: FIX - // -------------------------------------------- // - - @Override - public String reqFix(String senderId) - { - if (!SenderUtil.isPlayerId(senderId)) return senderId; - return this.idToCorrectId.get(senderId); - } - - @Override - public String tryFix(String senderId) - { - String ret = this.reqFix(senderId); - if (ret != null) return ret; - return senderId; - } - - @Override - public boolean canFix(String senderId) - { - return this.reqFix(senderId) != null; - } - - // -------------------------------------------- // - // OVERRIDE: SIMPLES - // -------------------------------------------- // - - @Override - public boolean isOnline(String senderId) - { - if (senderId == null) return false; - if (SenderUtil.isPlayerId(senderId)) - { - Player player = Bukkit.getPlayerExact(senderId); - return player != null; - } - else - { - // Non-players must be registered for us to consider them online. - CommandSender sender = SenderUtil.getSender(senderId); - return sender != null; - } - } - - @Override - public boolean isOffline(String senderId) - { - return !this.isOnline(senderId); - } - - @Override - public boolean hasBeenOnline(String senderId) - { - CommandSender sender = SenderUtil.getSender(senderId); - if (sender != null) return true; - return this.idToCorrectId.containsKey(senderId); - } - - @Override - public Long getLastOnline(String senderId) - { - if (this.isOnline(senderId)) return System.currentTimeMillis(); - - String playerNameCC = this.reqFix(senderId); - if (playerNameCC == null) return null; - - File playerFile = new File(MUtil.getPlayerDirectory(), playerNameCC+".dat"); - return playerFile.lastModified(); - } - - // -------------------------------------------- // - // OVERRIDE: SETS - // -------------------------------------------- // - - @Override - public Set getAllSenderIds() - { - Set ret = new TreeSet(String.CASE_INSENSITIVE_ORDER); - ret.addAll(SenderUtil.getIdToSender().keySet()); - ret.addAll(this.idToCorrectId.keySet()); - return ret; - } - - @Override - public Set getOnlineSenderIds() - { - Set ret = new TreeSet(String.CASE_INSENSITIVE_ORDER); - ret.addAll(SenderUtil.getIdToSender().keySet()); - for (Player player : Bukkit.getOnlinePlayers()) - { - ret.add(player.getName()); - } - return ret; - } - - @Override - public Set getOfflineSenderIds() - { - Set ret = this.getAllSenderIds(); - ret.removeAll(this.getOnlineSenderIds()); - return ret; - } -} \ No newline at end of file diff --git a/src/com/massivecraft/mcore5/mixin/DisplayNameMixin.java b/src/com/massivecraft/mcore5/mixin/DisplayNameMixin.java index de41a048..652d677b 100644 --- a/src/com/massivecraft/mcore5/mixin/DisplayNameMixin.java +++ b/src/com/massivecraft/mcore5/mixin/DisplayNameMixin.java @@ -4,8 +4,8 @@ import org.bukkit.command.CommandSender; public interface DisplayNameMixin { - public String get(String senderId); - public void set(String senderId, String displayName); - public String get(CommandSender sender); - public void set(CommandSender sender, String displayName); + public String getDisplayName(String senderId); + public void setDisplayName(String senderId, String displayName); + public String getDisplayName(CommandSender sender); + public void setDisplayName(CommandSender sender, String displayName); } diff --git a/src/com/massivecraft/mcore5/mixin/DisplayNameMixinAbstract.java b/src/com/massivecraft/mcore5/mixin/DisplayNameMixinAbstract.java new file mode 100644 index 00000000..24f1ef29 --- /dev/null +++ b/src/com/massivecraft/mcore5/mixin/DisplayNameMixinAbstract.java @@ -0,0 +1,20 @@ +package com.massivecraft.mcore5.mixin; + +import org.bukkit.command.CommandSender; + +import com.massivecraft.mcore5.util.SenderUtil; + +public abstract class DisplayNameMixinAbstract implements DisplayNameMixin +{ + @Override + public String getDisplayName(CommandSender sender) + { + return this.getDisplayName(SenderUtil.getSenderId(sender)); + } + + @Override + public void setDisplayName(CommandSender sender, String displayName) + { + this.setDisplayName(SenderUtil.getSenderId(sender), displayName); + } +} \ No newline at end of file diff --git a/src/com/massivecraft/mcore5/mixin/DisplayNameMixinDefault.java b/src/com/massivecraft/mcore5/mixin/DisplayNameMixinDefault.java new file mode 100644 index 00000000..4d364fda --- /dev/null +++ b/src/com/massivecraft/mcore5/mixin/DisplayNameMixinDefault.java @@ -0,0 +1,81 @@ +package com.massivecraft.mcore5.mixin; + +import java.util.Map; +import java.util.TreeMap; + +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.entity.Player; + +public class DisplayNameMixinDefault extends DisplayNameMixinAbstract +{ + public final static ChatColor DEFAULT_COLOR = ChatColor.WHITE; + + // -------------------------------------------- // + // INSTANCE & CONSTRUCT + // -------------------------------------------- // + + private static DisplayNameMixinDefault i = new DisplayNameMixinDefault(); + public static DisplayNameMixinDefault get() { return i; } + + // -------------------------------------------- // + // FIELDS + // -------------------------------------------- // + + protected Map idToDisplayName = new TreeMap(String.CASE_INSENSITIVE_ORDER); + + // -------------------------------------------- // + // OVERRIDE + // -------------------------------------------- // + + @Override + public String getDisplayName(String senderId) + { + if (senderId == null) return null; + + // Try Our Map + String ret = this.idToDisplayName.get(senderId); + + // Try Bukkit + if (ret == null) + { + Player player = Bukkit.getPlayerExact(senderId); + if (player != null) + { + ret = player.getDisplayName(); + } + } + + // Try Fixed Id + if (ret == null) + { + ret = Mixin.tryFix(senderId); + } + + // Ensure Colored + if (ChatColor.stripColor(ret).equals(ret)) + { + ret = DEFAULT_COLOR.toString()+ret; + } + + return ret; + } + + @Override + public void setDisplayName(String senderId, String displayName) + { + if (displayName == null) + { + this.idToDisplayName.remove(senderId); + } + else + { + this.idToDisplayName.put(senderId, displayName); + } + + Player player = Bukkit.getPlayerExact(senderId); + if (player == null) return; + player.setDisplayName(this.getDisplayName(senderId)); + } + +} \ No newline at end of file diff --git a/src/com/massivecraft/mcore5/mixin/KickMixin.java b/src/com/massivecraft/mcore5/mixin/KickMixin.java new file mode 100644 index 00000000..89961d92 --- /dev/null +++ b/src/com/massivecraft/mcore5/mixin/KickMixin.java @@ -0,0 +1,12 @@ +package com.massivecraft.mcore5.mixin; + +import org.bukkit.command.CommandSender; + +public interface KickMixin +{ + public boolean kick(CommandSender sender); + public boolean kick(String senderId); + + public boolean kick(CommandSender sender, String message); + public boolean kick(String senderId, String message); +} diff --git a/src/com/massivecraft/mcore5/mixin/KickMixinAbstract.java b/src/com/massivecraft/mcore5/mixin/KickMixinAbstract.java new file mode 100644 index 00000000..d6bcda18 --- /dev/null +++ b/src/com/massivecraft/mcore5/mixin/KickMixinAbstract.java @@ -0,0 +1,18 @@ +package com.massivecraft.mcore5.mixin; + +import org.bukkit.command.CommandSender; + +public abstract class KickMixinAbstract implements KickMixin +{ + @Override + public boolean kick(CommandSender sender) + { + return this.kick(sender, null); + } + + @Override + public boolean kick(String senderId) + { + return this.kick(senderId, null); + } +} diff --git a/src/com/massivecraft/mcore5/mixin/KickMixinDefault.java b/src/com/massivecraft/mcore5/mixin/KickMixinDefault.java new file mode 100644 index 00000000..6454271b --- /dev/null +++ b/src/com/massivecraft/mcore5/mixin/KickMixinDefault.java @@ -0,0 +1,39 @@ +package com.massivecraft.mcore5.mixin; + +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +import com.massivecraft.mcore5.util.SenderUtil; + +public class KickMixinDefault extends KickMixinAbstract +{ + // -------------------------------------------- // + // INSTANCE & CONSTRUCT + // -------------------------------------------- // + + private static KickMixinDefault i = new KickMixinDefault(); + public static KickMixinDefault get() { return i; } + + // -------------------------------------------- // + // OVERRIDE + // -------------------------------------------- // + + @Override + public boolean kick(CommandSender sender, String message) + { + Player player = SenderUtil.getAsPlayer(sender); + if (player == null) return false; + player.kickPlayer(message); + return true; + } + + @Override + public boolean kick(String senderId, String message) + { + Player player = SenderUtil.getPlayer(senderId); + if (player == null) return false; + player.kickPlayer(message); + return true; + } + +} \ No newline at end of file diff --git a/src/com/massivecraft/mcore5/mixin/ListNameMixin.java b/src/com/massivecraft/mcore5/mixin/ListNameMixin.java index 5671f85d..807a04f9 100644 --- a/src/com/massivecraft/mcore5/mixin/ListNameMixin.java +++ b/src/com/massivecraft/mcore5/mixin/ListNameMixin.java @@ -4,8 +4,8 @@ import org.bukkit.command.CommandSender; public interface ListNameMixin { - public String get(String senderId); - public void set(String senderId, String listName); - public String get(CommandSender sender); - public void set(CommandSender sender, String listName); + public String getListName(String senderId); + public void setListName(String senderId, String listName); + public String getListName(CommandSender sender); + public void setListName(CommandSender sender, String listName); } diff --git a/src/com/massivecraft/mcore5/mixin/ListNameMixinAbstract.java b/src/com/massivecraft/mcore5/mixin/ListNameMixinAbstract.java new file mode 100644 index 00000000..4626e186 --- /dev/null +++ b/src/com/massivecraft/mcore5/mixin/ListNameMixinAbstract.java @@ -0,0 +1,20 @@ +package com.massivecraft.mcore5.mixin; + +import org.bukkit.command.CommandSender; + +import com.massivecraft.mcore5.util.SenderUtil; + +public abstract class ListNameMixinAbstract implements ListNameMixin +{ + @Override + public String getListName(CommandSender sender) + { + return this.getListName(SenderUtil.getSenderId(sender)); + } + + @Override + public void setListName(CommandSender sender, String listName) + { + this.setListName(SenderUtil.getSenderId(sender), listName); + } +} \ No newline at end of file diff --git a/src/com/massivecraft/mcore5/mixin/ListNameMixinDefault.java b/src/com/massivecraft/mcore5/mixin/ListNameMixinDefault.java new file mode 100644 index 00000000..59a6593c --- /dev/null +++ b/src/com/massivecraft/mcore5/mixin/ListNameMixinDefault.java @@ -0,0 +1,81 @@ +package com.massivecraft.mcore5.mixin; + +import java.util.Map; +import java.util.TreeMap; + +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.entity.Player; + +public class ListNameMixinDefault extends ListNameMixinAbstract +{ + public final static ChatColor DEFAULT_COLOR = ChatColor.WHITE; + + // -------------------------------------------- // + // INSTANCE & CONSTRUCT + // -------------------------------------------- // + + private static ListNameMixinDefault i = new ListNameMixinDefault(); + public static ListNameMixinDefault get() { return i; } + + // -------------------------------------------- // + // FIELDS + // -------------------------------------------- // + + protected Map idToListName = new TreeMap(String.CASE_INSENSITIVE_ORDER); + + // -------------------------------------------- // + // OVERRIDE + // -------------------------------------------- // + + @Override + public String getListName(String senderId) + { + if (senderId == null) return null; + + // Try Our Map + String ret = this.idToListName.get(senderId); + + // Try Bukkit + if (ret == null) + { + Player player = Bukkit.getPlayerExact(senderId); + if (player != null) + { + ret = player.getPlayerListName(); + } + } + + // Try Fixed Id + if (ret == null) + { + ret = Mixin.tryFix(senderId); + } + + // Ensure Colored + if (ChatColor.stripColor(ret).equals(ret)) + { + ret = DEFAULT_COLOR.toString()+ret; + } + + return ret; + } + + @Override + public void setListName(String senderId, String listName) + { + if (listName == null) + { + this.idToListName.remove(senderId); + } + else + { + this.idToListName.put(senderId, listName); + } + + Player player = Bukkit.getPlayerExact(senderId); + if (player == null) return; + player.setPlayerListName(this.getListName(senderId)); + } + +} \ No newline at end of file diff --git a/src/com/massivecraft/mcore5/mixin/MessageMixin.java b/src/com/massivecraft/mcore5/mixin/MessageMixin.java new file mode 100644 index 00000000..8029551d --- /dev/null +++ b/src/com/massivecraft/mcore5/mixin/MessageMixin.java @@ -0,0 +1,24 @@ +package com.massivecraft.mcore5.mixin; + +import java.util.Collection; + +import org.bukkit.command.CommandSender; + +public interface MessageMixin +{ + public boolean message(CommandSender sender, String message); + public boolean message(CommandSender sender, Collection messages); + public boolean message(CommandSender sender, String... messages); + + public boolean message(String senderId, String message); + public boolean message(String senderId, Collection messages); + public boolean message(String senderId, String... messages); + + public boolean msg(CommandSender sender, String msg); + public boolean msg(CommandSender sender, String msg, Object... args); + public boolean msg(CommandSender sender, Collection msgs); + + public boolean msg(String senderId, String msg); + public boolean msg(String senderId, String msg, Object... args); + public boolean msg(String senderId, Collection msgs); +} diff --git a/src/com/massivecraft/mcore5/mixin/MessageMixinAbstract.java b/src/com/massivecraft/mcore5/mixin/MessageMixinAbstract.java new file mode 100644 index 00000000..5f31708d --- /dev/null +++ b/src/com/massivecraft/mcore5/mixin/MessageMixinAbstract.java @@ -0,0 +1,76 @@ +package com.massivecraft.mcore5.mixin; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.List; + +import org.bukkit.command.CommandSender; + +import com.massivecraft.mcore5.util.Txt; + +public abstract class MessageMixinAbstract implements MessageMixin +{ + @Override + public boolean message(CommandSender sender, String... messages) + { + Collection coll = new ArrayList(Arrays.asList(messages)); + return this.message(sender, coll); + } + + @Override + public boolean message(String senderId, String... messages) + { + Collection coll = new ArrayList(Arrays.asList(messages)); + return this.message(senderId, coll); + } + + @Override + public boolean msg(CommandSender sender, String msg) + { + return this.message(sender, Txt.parse(msg)); + } + + @Override + public boolean msg(CommandSender sender, String msg, Object... args) + { + return this.message(sender, Txt.parse(msg, args)); + } + + @Override + public boolean msg(CommandSender sender, Collection msgs) + { + List messages = new ArrayList(); + for (String msg : msgs) + { + String message = Txt.parse(msg); + messages.add(message); + } + return this.message(sender, messages); + } + + @Override + public boolean msg(String senderId, String msg) + { + return this.message(senderId, Txt.parse(msg)); + } + + @Override + public boolean msg(String senderId, String msg, Object... args) + { + return this.message(senderId, Txt.parse(msg, args)); + } + + @Override + public boolean msg(String senderId, Collection msgs) + { + List messages = new ArrayList(); + for (String msg : msgs) + { + String message = Txt.parse(msg); + messages.add(message); + } + return this.message(senderId, messages); + } + +} diff --git a/src/com/massivecraft/mcore5/mixin/MessageMixinDefault.java b/src/com/massivecraft/mcore5/mixin/MessageMixinDefault.java new file mode 100644 index 00000000..95a5cdbf --- /dev/null +++ b/src/com/massivecraft/mcore5/mixin/MessageMixinDefault.java @@ -0,0 +1,55 @@ +package com.massivecraft.mcore5.mixin; + +import java.util.Collection; + +import org.bukkit.command.CommandSender; + +import com.massivecraft.mcore5.util.SenderUtil; + +public class MessageMixinDefault extends MessageMixinAbstract +{ + // -------------------------------------------- // + // INSTANCE & CONSTRUCT + // -------------------------------------------- // + + private static MessageMixinDefault i = new MessageMixinDefault(); + public static MessageMixinDefault get() { return i; } + + // -------------------------------------------- // + // OVERRIDE + // -------------------------------------------- // + + @Override + public boolean message(CommandSender sender, String message) + { + if (sender == null) return false; + if (message == null) return false; + sender.sendMessage(message); + return true; + } + + @Override + public boolean message(CommandSender sender, Collection messages) + { + if (sender == null) return false; + if (messages == null) return false; + for (String message : messages) + { + sender.sendMessage(message); + } + return true; + } + + @Override + public boolean message(String senderId, String message) + { + return this.message(SenderUtil.getSender(senderId), message); + } + + @Override + public boolean message(String senderId, Collection messages) + { + return this.message(SenderUtil.getSender(senderId), messages); + } + +} diff --git a/src/com/massivecraft/mcore5/mixin/Mixin.java b/src/com/massivecraft/mcore5/mixin/Mixin.java index 0d9dcab4..5dc416dd 100644 --- a/src/com/massivecraft/mcore5/mixin/Mixin.java +++ b/src/com/massivecraft/mcore5/mixin/Mixin.java @@ -1,9 +1,13 @@ package com.massivecraft.mcore5.mixin; +import java.util.Collection; +import java.util.List; import java.util.Set; +import org.bukkit.ChatColor; import org.bukkit.command.CommandSender; -import org.bukkit.entity.Entity; +import org.bukkit.entity.Player; +import org.bukkit.permissions.Permissible; import com.massivecraft.mcore5.PS; @@ -13,29 +17,98 @@ public class Mixin // GET/SET MIXINS // -------------------------------------------- // - private static PsTeleporterMixin psTeleporterMixin = DefaultPsTeleporterMixin.get(); - public static PsTeleporterMixin getPsTeleporterMixin() { return psTeleporterMixin; } - public static void setPsTeleporterMixin(PsTeleporterMixin val) { psTeleporterMixin = val; } + private static WorldMixin worldMixin = WorldMixinDefault.get(); + public static WorldMixin getWorldMixin() { return worldMixin; } + public static void setWorldMixin(WorldMixin val) { worldMixin = val; } - private static DisplayNameMixin displayNameMixin = DefaultDisplayNameMixin.get(); + private static DisplayNameMixin displayNameMixin = DisplayNameMixinDefault.get(); public static DisplayNameMixin getDisplayNameMixin() { return displayNameMixin; } public static void setDisplayNameMixin(DisplayNameMixin val) { displayNameMixin = val; } - private static ListNameMixin listNameMixin = DefaultListNameMixin.get(); + private static ListNameMixin listNameMixin = ListNameMixinDefault.get(); public static ListNameMixin getListNameMixin() { return listNameMixin; } public static void setListNameMixin(ListNameMixin val) { listNameMixin = val; } - private static SenderIdMixin senderIdMixin = DefaultSenderIdMixin.get(); + private static SenderPsMixin senderPsMixin = SenderPsMixinDefault.get(); + public static SenderPsMixin getSenderPsMixin() { return senderPsMixin; } + public static void setSenderPsMixin(SenderPsMixin val) { senderPsMixin = val; } + + private static PlayedMixin playedMixin = PlayedMixinDefault.get(); + public static PlayedMixin getPlayedMixin() { return playedMixin; } + public static void setPlayedMixin(PlayedMixin val) { playedMixin = val; } + + private static VisibilityMixin visibilityMixin = VisibilityMixinDefault.get(); + public static VisibilityMixin getVisibilityMixin() { return visibilityMixin; } + public static void setVisibilityMixin(VisibilityMixin val) { visibilityMixin = val; } + + private static SenderIdMixin senderIdMixin = SenderIdMixinDefault.get(); public static SenderIdMixin getSenderIdMixin() { return senderIdMixin; } public static void setSenderIdMixin(SenderIdMixin val) { senderIdMixin = val; } + private static TeleportMixin teleportMixin = TeleportMixinDefault.get(); + public static TeleportMixin getTeleportMixin() { return teleportMixin; } + public static void setTeleportMixin(TeleportMixin val) { teleportMixin = val; } + + private static MessageMixin messageMixin = MessageMixinDefault.get(); + public static MessageMixin getMessageMixin() { return messageMixin; } + public static void setMessageMixin(MessageMixin val) { messageMixin = val; } + + private static KickMixin kickMixin = KickMixinDefault.get(); + public static KickMixin getKickMixin() { return kickMixin; } + public static void setKickMixin(KickMixin val) { kickMixin = val; } + // -------------------------------------------- // - // STATIC EXPOSE: PS TELEPORTER + // STATIC EXPOSE: WORLD // -------------------------------------------- // - public static void teleport(Entity entity, PS ps) throws PsTeleporterException + public static boolean canSee(Permissible permissible, String worldId) { - getPsTeleporterMixin().teleport(entity, ps); + return getWorldMixin().canSee(permissible, worldId); + } + + public static List getWorldIds() + { + return getWorldMixin().getWorldIds(); + } + + public static List getVisibleWorldIds(Permissible permissible) + { + return getWorldMixin().getVisibleWorldIds(permissible); + } + + public static ChatColor getWorldColor(String worldId) + { + return getWorldMixin().getWorldColor(worldId); + } + + public static List getWorldAliases(String worldId) + { + return getWorldAliases(worldId); + } + + public static String getWorldAliasOrId(String worldId) + { + return getWorldMixin().getWorldAliasOrId(worldId); + } + + public static String getWorldDisplayName(String worldId) + { + return getWorldMixin().getWorldDisplayName(worldId); + } + + public static PS getWorldSpawnPs(String worldId) + { + return getWorldMixin().getWorldSpawnPs(worldId); + } + + public static void setWorldSpawnPs(String worldId, PS spawnPs) + { + getWorldMixin().setWorldSpawnPs(worldId, spawnPs); + } + + public static boolean trySetWorldSpawnWp(CommandSender sender, String worldId, PS spawnPs, boolean verbooseChange, boolean verbooseSame) + { + return getWorldMixin().trySetWorldSpawnWp(sender, worldId, spawnPs, verbooseChange, verbooseSame); } // -------------------------------------------- // @@ -44,22 +117,22 @@ public class Mixin public static String getDisplayName(String senderId) { - return getDisplayNameMixin().get(senderId); + return getDisplayNameMixin().getDisplayName(senderId); } public static void setDisplayName(String senderId, String displayName) { - getDisplayNameMixin().set(senderId, displayName); + getDisplayNameMixin().setDisplayName(senderId, displayName); } public static String getDisplayName(CommandSender sender) { - return getDisplayNameMixin().get(sender); + return getDisplayNameMixin().getDisplayName(sender); } public static void setDisplayName(CommandSender sender, String displayName) { - getDisplayNameMixin().set(sender, displayName); + getDisplayNameMixin().setDisplayName(sender, displayName); } // -------------------------------------------- // @@ -68,22 +141,99 @@ public class Mixin public static String getListName(String senderId) { - return getListNameMixin().get(senderId); + return getListNameMixin().getListName(senderId); } public static void setListName(String senderId, String listName) { - getListNameMixin().set(senderId, listName); + getListNameMixin().setListName(senderId, listName); } public static String getListName(CommandSender sender) { - return getListNameMixin().get(sender); + return getListNameMixin().getListName(sender); } public static void setListName(CommandSender sender, String listName) { - getListNameMixin().set(sender, listName); + getListNameMixin().setListName(sender, listName); + } + + // -------------------------------------------- // + // STATIC EXPOSE: SENDER PS + // -------------------------------------------- // + + public static PS getSenderPs(String senderId) + { + return getSenderPsMixin().getSenderPs(senderId); + } + + public static void setSenderPs(String senderId, PS ps) + { + getSenderPsMixin().setSenderPs(senderId, ps); + } + + // -------------------------------------------- // + // STATIC EXPOSE: PLAYED + // -------------------------------------------- // + + public static boolean isOnline(String senderId) + { + return getPlayedMixin().isOnline(senderId); + } + public static boolean isOffline(String senderId) + { + return getPlayedMixin().isOffline(senderId); + } + public static Long getLastPlayed(String senderId) + { + return getPlayedMixin().getLastPlayed(senderId); + } + public static Long getFirstPlayed(String senderId) + { + return getPlayedMixin().getFirstPlayed(senderId); + } + public static boolean hasPlayedBefore(String senderId) + { + return getPlayedMixin().hasPlayedBefore(senderId); + } + + // -------------------------------------------- // + // STATIC EXPOSE: VISIBILITY + // -------------------------------------------- // + + public static boolean isVisible(String watcherId, String watcheeId) + { + return getVisibilityMixin().isVisible(watcherId, watcheeId); + } + public static boolean isVisible(CommandSender watcher, String watcheeId) + { + return getVisibilityMixin().isVisible(watcher, watcheeId); + } + public static boolean isVisible(String watcherId, CommandSender watchee) + { + return getVisibilityMixin().isVisible(watcherId, watchee); + } + public static boolean isVisible(CommandSender watcher, CommandSender watchee) + { + return getVisibilityMixin().isVisible(watcher, watchee); + } + + public static void setVisible(String watcherId, String watcheeId, boolean visible) + { + getVisibilityMixin().setVisible(watcherId, watcheeId, visible); + } + public static void setVisible(CommandSender watcher, String watcheeId, boolean visible) + { + getVisibilityMixin().setVisible(watcher, watcheeId, visible); + } + public static void setVisible(String watcherId, CommandSender watchee, boolean visible) + { + getVisibilityMixin().setVisible(watcherId, watchee, visible); + } + public static void setVisible(CommandSender watcher, CommandSender watchee, boolean visible) + { + getVisibilityMixin().setVisible(watcher, watchee, visible); } // -------------------------------------------- // @@ -103,23 +253,6 @@ public class Mixin return getSenderIdMixin().canFix(senderId); } - public static boolean isOnline(String senderId) - { - return getSenderIdMixin().isOnline(senderId); - } - public static boolean isOffline(String senderId) - { - return getSenderIdMixin().isOffline(senderId); - } - public static boolean hasBeenOnline(String senderId) - { - return getSenderIdMixin().hasBeenOnline(senderId); - } - public static Long getLastOnline(String senderId) - { - return getSenderIdMixin().getLastOnline(senderId); - } - public static Set getAllSenderIds() { return getSenderIdMixin().getAllSenderIds(); @@ -133,4 +266,157 @@ public class Mixin return getSenderIdMixin().getOfflineSenderIds(); } + public static Set getAllPlayerIds() + { + return getSenderIdMixin().getAllPlayerIds(); + } + public static Set getOnlinePlayerIds() + { + return getSenderIdMixin().getOnlinePlayerIds(); + } + public static Set getOfflinePlayerIds() + { + return getSenderIdMixin().getOfflinePlayerIds(); + } + + // -------------------------------------------- // + // STATIC EXPOSE: TELEPORTER + // -------------------------------------------- // + + public static void teleport(Player teleportee, PS destinationPs) throws TeleporterException + { + getTeleportMixin().teleport(teleportee, destinationPs); + } + public static void teleport(Player teleportee, PS destinationPs, String destinationDesc) throws TeleporterException + { + getTeleportMixin().teleport(teleportee, destinationPs, destinationDesc); + } + public static void teleport(Player teleportee, PS destinationPs, String destinationDesc, Permissible delayPermissible) throws TeleporterException + { + getTeleportMixin().teleport(teleportee, destinationPs, destinationDesc, delayPermissible); + } + public static void teleport(Player teleportee, PS destinationPs, String destinationDesc, Permissible delayPermissible, CommandSender otherSender, String otherPerm) throws TeleporterException + { + getTeleportMixin().teleport(teleportee, destinationPs, destinationDesc, delayPermissible, otherSender, otherPerm); + } + public static void teleport(Player teleportee, PS destinationPs, String destinationDesc, CommandSender otherSender, String otherPerm) throws TeleporterException + { + getTeleportMixin().teleport(teleportee, destinationPs, destinationDesc, otherSender, otherPerm); + } + public static void teleport(Player teleportee, PS destinationPs, String destinationDesc, int delaySeconds, CommandSender otherSender, String otherPerm) throws TeleporterException + { + getTeleportMixin().teleport(teleportee, destinationPs, destinationDesc, delaySeconds, otherSender, otherPerm); + } + public static void teleport(Player teleportee, PS destinationPs, String destinationDesc, int delaySeconds) throws TeleporterException + { + getTeleportMixin().teleport(teleportee, destinationPs, destinationDesc, delaySeconds); + } + + public static void teleport(String teleporteeId, PS destinationPs) throws TeleporterException + { + getTeleportMixin().teleport(teleporteeId, destinationPs); + } + public static void teleport(String teleporteeId, PS destinationPs, String destinationDesc) throws TeleporterException + { + getTeleportMixin().teleport(teleporteeId, destinationPs, destinationDesc); + } + public static void teleport(String teleporteeId, PS destinationPs, String destinationDesc, Permissible delayPermissible) throws TeleporterException + { + getTeleportMixin().teleport(teleporteeId, destinationPs, destinationDesc, delayPermissible); + } + public static void teleport(String teleporteeId, PS destinationPs, String destinationDesc, Permissible delayPermissible, CommandSender otherSender, String otherPerm) throws TeleporterException + { + getTeleportMixin().teleport(teleporteeId, destinationPs, destinationDesc, delayPermissible, otherSender, otherPerm); + } + public static void teleport(String teleporteeId, PS destinationPs, String destinationDesc, CommandSender otherSender, String otherPerm) throws TeleporterException + { + getTeleportMixin().teleport(teleporteeId, destinationPs, destinationDesc, otherSender, otherPerm); + } + public static void teleport(String teleporteeId, PS destinationPs, String destinationDesc, int delaySeconds, CommandSender otherSender, String otherPerm) throws TeleporterException + { + getTeleportMixin().teleport(teleporteeId, destinationPs, destinationDesc, delaySeconds, otherSender, otherPerm); + } + public static void teleport(String teleporteeId, PS destinationPs, String destinationDesc, int delaySeconds) throws TeleporterException + { + getTeleportMixin().teleport(teleporteeId, destinationPs, destinationDesc, delaySeconds); + } + + // -------------------------------------------- // + // STATIC EXPOSE: MESSAGE + // -------------------------------------------- // + + public static boolean message(CommandSender sender, String message) + { + return getMessageMixin().message(sender, message); + } + public static boolean message(CommandSender sender, Collection messages) + { + return getMessageMixin().message(sender, messages); + } + public static boolean message(CommandSender sender, String... messages) + { + return getMessageMixin().message(sender, messages); + } + + public static boolean message(String senderId, String message) + { + return getMessageMixin().message(senderId, message); + } + public static boolean message(String senderId, Collection messages) + { + return getMessageMixin().message(senderId, messages); + } + public static boolean message(String senderId, String... messages) + { + return getMessageMixin().message(senderId, messages); + } + + public static boolean msg(CommandSender sender, String msg) + { + return getMessageMixin().msg(sender, msg); + } + public static boolean msg(CommandSender sender, String msg, Object... args) + { + return getMessageMixin().msg(sender, msg, args); + } + public static boolean msg(CommandSender sender, Collection msgs) + { + return getMessageMixin().msg(sender, msgs); + } + + public static boolean msg(String senderId, String msg) + { + return getMessageMixin().msg(senderId, msg); + } + public static boolean msg(String senderId, String msg, Object... args) + { + return getMessageMixin().msg(senderId, msg, args); + } + public static boolean msg(String senderId, Collection msgs) + { + return getMessageMixin().msg(senderId, msgs); + } + + // -------------------------------------------- // + // STATIC EXPOSE: KICK + // -------------------------------------------- // + + public static boolean kick(CommandSender sender) + { + return getKickMixin().kick(sender); + } + public static boolean kick(String senderId) + { + return getKickMixin().kick(senderId); + } + + public static boolean kick(CommandSender sender, String message) + { + return getKickMixin().kick(sender, message); + } + public static boolean kick(String senderId, String message) + { + return getKickMixin().kick(senderId, message); + } + } diff --git a/src/com/massivecraft/mcore5/mixin/PlayedMixin.java b/src/com/massivecraft/mcore5/mixin/PlayedMixin.java new file mode 100644 index 00000000..a26c3a11 --- /dev/null +++ b/src/com/massivecraft/mcore5/mixin/PlayedMixin.java @@ -0,0 +1,10 @@ +package com.massivecraft.mcore5.mixin; + +public interface PlayedMixin +{ + public boolean isOnline(String senderId); + public boolean isOffline(String senderId); + public Long getFirstPlayed(String senderId); + public Long getLastPlayed(String senderId); + public boolean hasPlayedBefore(String senderId); +} diff --git a/src/com/massivecraft/mcore5/mixin/PlayedMixinAbstract.java b/src/com/massivecraft/mcore5/mixin/PlayedMixinAbstract.java new file mode 100644 index 00000000..b00a8092 --- /dev/null +++ b/src/com/massivecraft/mcore5/mixin/PlayedMixinAbstract.java @@ -0,0 +1,19 @@ +package com.massivecraft.mcore5.mixin; + +public abstract class PlayedMixinAbstract implements PlayedMixin +{ + + @Override + public boolean isOffline(String senderId) + { + return !this.isOnline(senderId); + } + + @Override + public boolean hasPlayedBefore(String senderId) + { + Long firstPlayed = this.getFirstPlayed(senderId); + return firstPlayed != null && firstPlayed != 0; + } + +} diff --git a/src/com/massivecraft/mcore5/mixin/PlayedMixinDefault.java b/src/com/massivecraft/mcore5/mixin/PlayedMixinDefault.java new file mode 100644 index 00000000..dc3dae7c --- /dev/null +++ b/src/com/massivecraft/mcore5/mixin/PlayedMixinDefault.java @@ -0,0 +1,56 @@ +package com.massivecraft.mcore5.mixin; + +import java.io.File; + +import org.bukkit.Bukkit; +import org.bukkit.OfflinePlayer; +import org.bukkit.command.CommandSender; + +import com.massivecraft.mcore5.util.MUtil; +import com.massivecraft.mcore5.util.SenderUtil; + +public class PlayedMixinDefault extends PlayedMixinAbstract +{ + // -------------------------------------------- // + // INSTANCE & CONSTRUCT + // -------------------------------------------- // + + private static PlayedMixinDefault i = new PlayedMixinDefault(); + public static PlayedMixinDefault get() { return i; } + + // -------------------------------------------- // + // OVERRIDE + // -------------------------------------------- // + + @Override + public boolean isOnline(String senderId) + { + if (senderId == null) return false; + CommandSender sender = SenderUtil.getSender(senderId); + return sender != null; + } + + @Override + public Long getFirstPlayed(String senderId) + { + OfflinePlayer offlinePlayer = Bukkit.getOfflinePlayer(senderId); + Long ret = offlinePlayer.getFirstPlayed(); + if (ret == 0) ret = null; + return ret; + } + + @Override + public Long getLastPlayed(String senderId) + { + if (this.isOnline(senderId)) return System.currentTimeMillis(); + + String playerNameCC = Mixin.reqFix(senderId); + if (playerNameCC == null) return null; + + File playerFile = new File(MUtil.getPlayerDirectory(), playerNameCC+".dat"); + long lastModified = playerFile.lastModified(); + if (lastModified == 0) return null; + return lastModified; + } + +} \ No newline at end of file diff --git a/src/com/massivecraft/mcore5/mixin/PsTeleporterException.java b/src/com/massivecraft/mcore5/mixin/PsTeleporterException.java deleted file mode 100644 index 71934b8e..00000000 --- a/src/com/massivecraft/mcore5/mixin/PsTeleporterException.java +++ /dev/null @@ -1,31 +0,0 @@ -package com.massivecraft.mcore5.mixin; - -public class PsTeleporterException extends Exception -{ - private static final long serialVersionUID = 1L; - - public PsTeleporterException() - { - super(); - } - - public PsTeleporterException(String message) - { - super(message); - } - - public PsTeleporterException(String message, Throwable cause) - { - super(message, cause); - } - - public PsTeleporterException(Throwable cause) - { - super(cause); - } - - protected PsTeleporterException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) - { - super(message, cause, enableSuppression, writableStackTrace); - } -} diff --git a/src/com/massivecraft/mcore5/mixin/PsTeleporterMixin.java b/src/com/massivecraft/mcore5/mixin/PsTeleporterMixin.java deleted file mode 100644 index e2b68ca2..00000000 --- a/src/com/massivecraft/mcore5/mixin/PsTeleporterMixin.java +++ /dev/null @@ -1,14 +0,0 @@ -package com.massivecraft.mcore5.mixin; - -import org.bukkit.entity.Entity; - -import com.massivecraft.mcore5.PS; - -public interface PsTeleporterMixin -{ - /** - * @param entity The entity to be teleported - * @param ps The target PhysicalState - */ - public void teleport(Entity entity, PS ps) throws PsTeleporterException; -} diff --git a/src/com/massivecraft/mcore5/mixin/ScheduledTeleport.java b/src/com/massivecraft/mcore5/mixin/ScheduledTeleport.java new file mode 100644 index 00000000..707b3e31 --- /dev/null +++ b/src/com/massivecraft/mcore5/mixin/ScheduledTeleport.java @@ -0,0 +1,118 @@ +package com.massivecraft.mcore5.mixin; + +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; + +import com.massivecraft.mcore5.MCore; +import com.massivecraft.mcore5.PS; + +public class ScheduledTeleport implements Runnable +{ + // -------------------------------------------- // + // CONSTANTS + // -------------------------------------------- // + + public final static transient int NON_SCHEDULED_TASK_ID = -1; + + // -------------------------------------------- // + // STATIC INDEX + // -------------------------------------------- // + + public static Map teleporteeToScheduledTeleport = new ConcurrentHashMap(); + + public static void schedule(ScheduledTeleport scheduledTeleport) + { + if (isScheduled(scheduledTeleport)) return; + Bukkit.getScheduler().scheduleSyncDelayedTask(MCore.get(), scheduledTeleport, scheduledTeleport.getDelaySeconds()*20); + } + + public static boolean isScheduled(ScheduledTeleport scheduledTeleport) + { + return teleporteeToScheduledTeleport.containsKey(scheduledTeleport.getTeleportee()); + } + + // -------------------------------------------- // + // FIELDS & RAW-DATA ACCESS + // -------------------------------------------- // + + private final Player teleportee; + public Player getTeleportee() { return this.teleportee; } + + private final PS destinationPs; + public PS getDestinationPs() { return this.destinationPs; } + + private final String destinationDesc; + public String getDestinationDesc() { return this.destinationDesc; } + + private final int delaySeconds; + public int getDelaySeconds() { return this.delaySeconds; } + + private int taskId; + public int getTaskId() { return this.taskId; } + + // -------------------------------------------- // + // CONSTRUCT + // -------------------------------------------- // + + public ScheduledTeleport(Player teleportee, PS destinationPs, String destinationDesc, int delaySeconds) + { + this.teleportee = teleportee; + this.destinationPs = destinationPs; + this.destinationDesc = destinationDesc; + this.delaySeconds = delaySeconds; + this.taskId = NON_SCHEDULED_TASK_ID; + } + + // -------------------------------------------- // + // SCHEDULING + // -------------------------------------------- // + + public boolean isScheduled() + { + return this.taskId != NON_SCHEDULED_TASK_ID; + } + + public ScheduledTeleport schedule() + { + ScheduledTeleport old = teleporteeToScheduledTeleport.get(this.getTeleportee()); + if (old != null) old.unschedule(); + + teleporteeToScheduledTeleport.put(this.getTeleportee(), this); + + this.taskId = Bukkit.getScheduler().scheduleSyncDelayedTask(MCore.get(), this, this.getDelaySeconds()*20); + + return old; + } + + public boolean unschedule() + { + Bukkit.getScheduler().cancelTask(this.getTaskId()); + + this.taskId = NON_SCHEDULED_TASK_ID; + + return teleporteeToScheduledTeleport.remove(this.getTeleportee()) != null; + } + + // -------------------------------------------- // + // OVERRIDE + // -------------------------------------------- // + + @Override + public void run() + { + this.unschedule(); + if (!teleportee.isOnline()) return; + try + { + Mixin.teleport(this.teleportee, this.destinationPs, this.destinationDesc); + } + catch (TeleporterException e) + { + this.teleportee.sendMessage(e.getMessage()); + } + } + +} diff --git a/src/com/massivecraft/mcore5/mixin/ScheduledTeleportListener.java b/src/com/massivecraft/mcore5/mixin/ScheduledTeleportListener.java new file mode 100644 index 00000000..9815a1d9 --- /dev/null +++ b/src/com/massivecraft/mcore5/mixin/ScheduledTeleportListener.java @@ -0,0 +1,51 @@ +package com.massivecraft.mcore5.mixin; + +import org.bukkit.Bukkit; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.player.PlayerMoveEvent; + +import com.massivecraft.mcore5.MCore; +import com.massivecraft.mcore5.util.MUtil; + +public class ScheduledTeleportListener implements Listener +{ + // -------------------------------------------- // + // INSTANCE & CONSTRUCT + // -------------------------------------------- // + + private static ScheduledTeleportListener i = new ScheduledTeleportListener(); + public static ScheduledTeleportListener get() { return i; } + + // -------------------------------------------- // + // SETUP + // -------------------------------------------- // + + public void setup() + { + Bukkit.getPluginManager().registerEvents(this, MCore.get()); + } + + // -------------------------------------------- // + // LISTENER + // -------------------------------------------- // + + @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) + public void onPlayerMoved(PlayerMoveEvent event) + { + // If the player moved from one block to another ... + if (MUtil.isSameBlock(event.getFrom(), event.getTo())) return; + + // ... and there is a ScheduledTeleport ... + ScheduledTeleport scheduledTeleport = ScheduledTeleport.teleporteeToScheduledTeleport.get(event.getPlayer()); + if (scheduledTeleport == null) return; + + // ... unschedule it ... + scheduledTeleport.unschedule(); + + // ... and inform the teleportee. + Mixin.msg(scheduledTeleport.getTeleportee(), "Cancelled teleport to "+scheduledTeleport.getDestinationDesc()+"."); + } + +} diff --git a/src/com/massivecraft/mcore5/mixin/SenderIdMixin.java b/src/com/massivecraft/mcore5/mixin/SenderIdMixin.java index 043b9721..c49cefd6 100644 --- a/src/com/massivecraft/mcore5/mixin/SenderIdMixin.java +++ b/src/com/massivecraft/mcore5/mixin/SenderIdMixin.java @@ -10,14 +10,13 @@ public interface SenderIdMixin public String tryFix(String senderId); public boolean canFix(String senderId); - public boolean isOnline(String senderId); - public boolean isOffline(String senderId); - public boolean hasBeenOnline(String senderId); - public Long getLastOnline(String senderId); - - // All of these are static snapshots that are alterable and won't change over time. + // These may be unmodifiable. Don't expect them to be changeable. public Set getAllSenderIds(); public Set getOnlineSenderIds(); public Set getOfflineSenderIds(); + public Set getAllPlayerIds(); + public Set getOnlinePlayerIds(); + public Set getOfflinePlayerIds(); + } diff --git a/src/com/massivecraft/mcore5/mixin/SenderIdMixinAbstract.java b/src/com/massivecraft/mcore5/mixin/SenderIdMixinAbstract.java new file mode 100644 index 00000000..46531778 --- /dev/null +++ b/src/com/massivecraft/mcore5/mixin/SenderIdMixinAbstract.java @@ -0,0 +1,18 @@ +package com.massivecraft.mcore5.mixin; + +public abstract class SenderIdMixinAbstract implements SenderIdMixin +{ + @Override + public String tryFix(String senderId) + { + String ret = this.reqFix(senderId); + if (ret != null) return ret; + return senderId; + } + + @Override + public boolean canFix(String senderId) + { + return this.reqFix(senderId) != null; + } +} \ No newline at end of file diff --git a/src/com/massivecraft/mcore5/mixin/SenderIdMixinDefault.java b/src/com/massivecraft/mcore5/mixin/SenderIdMixinDefault.java new file mode 100644 index 00000000..147e305b --- /dev/null +++ b/src/com/massivecraft/mcore5/mixin/SenderIdMixinDefault.java @@ -0,0 +1,232 @@ +package com.massivecraft.mcore5.mixin; + +import java.util.Collections; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.ConcurrentSkipListMap; +import java.util.concurrent.ConcurrentSkipListSet; + +import org.bukkit.Bukkit; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.player.PlayerJoinEvent; +import org.bukkit.event.player.PlayerLoginEvent; + +import com.massivecraft.mcore5.MCore; +import com.massivecraft.mcore5.event.MCorePlayerLeaveEvent; +import com.massivecraft.mcore5.event.MCoreSenderRegisterEvent; +import com.massivecraft.mcore5.event.MCoreSenderUnregisterEvent; +import com.massivecraft.mcore5.util.MUtil; +import com.massivecraft.mcore5.util.SenderUtil; +import com.massivecraft.mcore5.util.Txt; + +public class SenderIdMixinDefault extends SenderIdMixinAbstract implements Listener +{ + // -------------------------------------------- // + // INSTANCE & CONSTRUCT + // -------------------------------------------- // + + private static SenderIdMixinDefault i = new SenderIdMixinDefault(); + public static SenderIdMixinDefault get() { return i; } + + // -------------------------------------------- // + // SETUP + // -------------------------------------------- // + + public void setup() + { + long start = System.currentTimeMillis(); + + // Create new empty sets + this.allSenderIds = new ConcurrentSkipListMap(String.CASE_INSENSITIVE_ORDER); + this.onlineSenderIds = new ConcurrentSkipListSet(String.CASE_INSENSITIVE_ORDER); + this.offlineSenderIds = new ConcurrentSkipListSet(String.CASE_INSENSITIVE_ORDER); + + this.allPlayerIds = new ConcurrentSkipListSet(String.CASE_INSENSITIVE_ORDER); + this.onlinePlayerIds = new ConcurrentSkipListSet(String.CASE_INSENSITIVE_ORDER); + this.offlinePlayerIds = new ConcurrentSkipListSet(String.CASE_INSENSITIVE_ORDER); + + // Add online players + for (Player player : Bukkit.getOnlinePlayers()) + { + String id = player.getName(); + + this.allSenderIds.put(id, id); + this.allPlayerIds.add(id); + + this.onlineSenderIds.add(id); + this.onlinePlayerIds.add(id); + } + + // Add offline players + for (String id : MUtil.getPlayerDirectoryNames()) + { + // Check if this player was added already since it's online + if (this.onlinePlayerIds.contains(id)) continue; + + this.allSenderIds.put(id, id); + this.allPlayerIds.add(id); + + this.offlineSenderIds.add(id); + this.offlinePlayerIds.add(id); + } + + // Add command senders + for (String id : SenderUtil.getIdToSender().keySet()) + { + this.allSenderIds.put(id, id); + this.onlineSenderIds.add(id); + } + + Bukkit.getServer().getPluginManager().registerEvents(this, MCore.p); + + long end = System.currentTimeMillis(); + MCore.get().log(Txt.parse("Setup of SenderIdMixinDefault took %dms.", end-start)); + } + + // -------------------------------------------- // + // FIELDS + // -------------------------------------------- // + + // The first field is a map since we use it for the "try" methods. + protected Map allSenderIds; + protected Set onlineSenderIds; + protected Set offlineSenderIds; + + protected Set allPlayerIds; + protected Set onlinePlayerIds; + protected Set offlinePlayerIds; + + // -------------------------------------------- // + // UTIL + // -------------------------------------------- // + + protected void onOnlineChanged(CommandSender sender, boolean isOnline) + { + boolean isPlayer = SenderUtil.isPlayer(sender); + String id = SenderUtil.getSenderId(sender); + + this.allSenderIds.put(id, id); + if (isPlayer) + { + this.allPlayerIds.add(id); + } + + if (isOnline) + { + this.onlineSenderIds.add(id); + this.offlineSenderIds.remove(id); + if (isPlayer) + { + this.onlinePlayerIds.add(id); + this.offlinePlayerIds.remove(id); + } + } + else + { + this.offlineSenderIds.add(id); + this.onlineSenderIds.remove(id); + if (isPlayer) + { + this.offlinePlayerIds.add(id); + this.onlinePlayerIds.remove(id); + } + } + } + + // -------------------------------------------- // + // LISTENER + // -------------------------------------------- // + + // We don't care if it's cancelled or not. + // We just wan't to make sure this id is known of and can be "fixed" asap. + // Online or not? We just use the mixin to get the actuall value. + @EventHandler(priority = EventPriority.LOWEST) + public void playerLoginLowest(PlayerLoginEvent event) + { + boolean isOnline = Mixin.isOnline(SenderUtil.getSenderId(event.getPlayer())); + this.onOnlineChanged(event.getPlayer(), isOnline); + } + + // Can't be cancelled + @EventHandler(priority = EventPriority.LOWEST) + public void playerJoinLowest(PlayerJoinEvent event) + { + this.onOnlineChanged(event.getPlayer(), true); + } + + // Can't be cancelled + @EventHandler(priority = EventPriority.LOWEST) + public void senderRegisterLowest(MCoreSenderRegisterEvent event) + { + this.onOnlineChanged(event.getSender(), true); + } + + // Can't be cancelled + @EventHandler(priority = EventPriority.MONITOR) + public void playerLeaveMonitor(MCorePlayerLeaveEvent event) + { + this.onOnlineChanged(event.getPlayer(), false); + } + + // Can't be cancelled + @EventHandler(priority = EventPriority.MONITOR) + public void senderUnregisterLowest(MCoreSenderUnregisterEvent event) + { + this.onOnlineChanged(event.getSender(), false); + } + + // -------------------------------------------- // + // OVERRIDE: FIX + // -------------------------------------------- // + + @Override + public String reqFix(String senderId) + { + return this.allSenderIds.get(senderId); + } + + // -------------------------------------------- // + // OVERRIDE: SETS + // -------------------------------------------- // + + @Override + public Set getAllSenderIds() + { + return Collections.unmodifiableSet(this.allSenderIds.keySet()); + } + + @Override + public Set getOnlineSenderIds() + { + return Collections.unmodifiableSet(this.onlineSenderIds); + } + + @Override + public Set getOfflineSenderIds() + { + return Collections.unmodifiableSet(this.offlineSenderIds); + } + + @Override + public Set getAllPlayerIds() + { + return Collections.unmodifiableSet(this.allPlayerIds); + } + + @Override + public Set getOnlinePlayerIds() + { + return Collections.unmodifiableSet(this.onlinePlayerIds); + } + + @Override + public Set getOfflinePlayerIds() + { + return Collections.unmodifiableSet(this.offlinePlayerIds); + } + +} \ No newline at end of file diff --git a/src/com/massivecraft/mcore5/mixin/SenderPsMixin.java b/src/com/massivecraft/mcore5/mixin/SenderPsMixin.java new file mode 100644 index 00000000..a14100b4 --- /dev/null +++ b/src/com/massivecraft/mcore5/mixin/SenderPsMixin.java @@ -0,0 +1,9 @@ +package com.massivecraft.mcore5.mixin; + +import com.massivecraft.mcore5.PS; + +public interface SenderPsMixin +{ + public PS getSenderPs(String senderId); + public void setSenderPs(String senderId, PS ps); +} diff --git a/src/com/massivecraft/mcore5/mixin/SenderPsMixinAbstract.java b/src/com/massivecraft/mcore5/mixin/SenderPsMixinAbstract.java new file mode 100644 index 00000000..4769e983 --- /dev/null +++ b/src/com/massivecraft/mcore5/mixin/SenderPsMixinAbstract.java @@ -0,0 +1,6 @@ +package com.massivecraft.mcore5.mixin; + +public abstract class SenderPsMixinAbstract implements SenderPsMixin +{ + +} diff --git a/src/com/massivecraft/mcore5/mixin/SenderPsMixinDefault.java b/src/com/massivecraft/mcore5/mixin/SenderPsMixinDefault.java new file mode 100644 index 00000000..7972343f --- /dev/null +++ b/src/com/massivecraft/mcore5/mixin/SenderPsMixinDefault.java @@ -0,0 +1,34 @@ +package com.massivecraft.mcore5.mixin; + +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; + +import com.massivecraft.mcore5.PS; + +public class SenderPsMixinDefault extends SenderPsMixinAbstract +{ + // -------------------------------------------- // + // INSTANCE & CONSTRUCT + // -------------------------------------------- // + + private static SenderPsMixinDefault i = new SenderPsMixinDefault(); + public static SenderPsMixinDefault get() { return i; } + + // -------------------------------------------- // + // OVERRIDE + // -------------------------------------------- // + + @Override + public PS getSenderPs(String senderId) + { + Player player = Bukkit.getPlayerExact(senderId); + if (player == null) return null; + return new PS(player.getLocation()); + } + + @Override + public void setSenderPs(String senderId, PS ps) + { + // Bukkit does not support setting the physical state for offline players for now. + } +} diff --git a/src/com/massivecraft/mcore5/mixin/TeleportMixin.java b/src/com/massivecraft/mcore5/mixin/TeleportMixin.java new file mode 100644 index 00000000..1fb86bfd --- /dev/null +++ b/src/com/massivecraft/mcore5/mixin/TeleportMixin.java @@ -0,0 +1,50 @@ +package com.massivecraft.mcore5.mixin; + +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.bukkit.permissions.Permissible; + +import com.massivecraft.mcore5.PS; + +public interface TeleportMixin +{ + // -------------------------------------------- // + // MESSAGING + // -------------------------------------------- // + + public void sendPreTeleportMessage(Player teleportee, String destinationDesc, int delaySeconds); + + // -------------------------------------------- // + // PLAYER + // -------------------------------------------- // + + public void teleport(Player teleportee, PS destinationPs) throws TeleporterException; + + public void teleport(Player teleportee, PS destinationPs, String destinationDesc) throws TeleporterException; + + public void teleport(Player teleportee, PS destinationPs, String destinationDesc, Permissible delayPermissible) throws TeleporterException; + public void teleport(Player teleportee, PS destinationPs, String destinationDesc, Permissible delayPermissible, CommandSender otherSender, String otherPerm) throws TeleporterException; + + public void teleport(Player teleportee, PS destinationPs, String destinationDesc, CommandSender otherSender, String otherPerm) throws TeleporterException; + + public void teleport(Player teleportee, PS destinationPs, String destinationDesc, int delaySeconds, CommandSender otherSender, String otherPerm) throws TeleporterException; + + public void teleport(Player teleportee, PS destinationPs, String destinationDesc, int delaySeconds) throws TeleporterException; + + // -------------------------------------------- // + // PLAYER ID + // -------------------------------------------- // + + public void teleport(String teleporteeId, PS destinationPs) throws TeleporterException; + + public void teleport(String teleporteeId, PS destinationPs, String destinationDesc) throws TeleporterException; + + public void teleport(String teleporteeId, PS destinationPs, String destinationDesc, Permissible delayPermissible) throws TeleporterException; + public void teleport(String teleporteeId, PS destinationPs, String destinationDesc, Permissible delayPermissible, CommandSender otherSender, String otherPerm) throws TeleporterException; + + public void teleport(String teleporteeId, PS destinationPs, String destinationDesc, CommandSender otherSender, String otherPerm) throws TeleporterException; + + public void teleport(String teleporteeId, PS destinationPs, String destinationDesc, int delaySeconds, CommandSender otherSender, String otherPerm) throws TeleporterException; + + public void teleport(String teleporteeId, PS destinationPs, String destinationDesc, int delaySeconds) throws TeleporterException; +} diff --git a/src/com/massivecraft/mcore5/mixin/TeleportMixinAbstract.java b/src/com/massivecraft/mcore5/mixin/TeleportMixinAbstract.java new file mode 100644 index 00000000..b44342b1 --- /dev/null +++ b/src/com/massivecraft/mcore5/mixin/TeleportMixinAbstract.java @@ -0,0 +1,154 @@ +package com.massivecraft.mcore5.mixin; + +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.bukkit.permissions.Permissible; + +import com.massivecraft.mcore5.Conf; +import com.massivecraft.mcore5.PS; +import com.massivecraft.mcore5.Permission; +import com.massivecraft.mcore5.util.PermUtil; +import com.massivecraft.mcore5.util.SenderUtil; +import com.massivecraft.mcore5.util.Txt; + +public abstract class TeleportMixinAbstract implements TeleportMixin +{ + // -------------------------------------------- // + // OVERRIDE + // -------------------------------------------- // + + @Override + public void sendPreTeleportMessage(Player teleportee, String destinationDesc, int delaySeconds) + { + if (delaySeconds > 0) + { + if (destinationDesc != null) + { + Mixin.msg(teleportee, "Teleporting to "+destinationDesc+" in "+delaySeconds+"s unless you move."); + } + else + { + Mixin.msg(teleportee, "Teleporting in "+delaySeconds+"s unless you move."); + } + } + else + { + if (destinationDesc != null) + { + Mixin.msg(teleportee, "Teleporting to "+destinationDesc+"."); + } + } + } + + @Override + public void teleport(Player teleportee, PS destinationPs) throws TeleporterException + { + this.teleport(teleportee, destinationPs, null); + } + + @Override + public void teleport(Player teleportee, PS destinationPs, String destinationDesc) throws TeleporterException + { + this.teleport(teleportee, destinationPs, destinationDesc, 0); + } + + @Override + public void teleport(Player teleportee, PS destinationPs, String destinationDesc, Permissible delayPermissible) throws TeleporterException + { + int delaySeconds = decideDelaySeconds(delayPermissible); + this.teleport(teleportee, destinationPs, destinationDesc, delaySeconds); + } + + @Override + public void teleport(Player teleportee, PS destinationPs, String destinationDesc, Permissible delayPermissible, CommandSender otherSender, String otherPerm) throws TeleporterException + { + int delaySeconds = decideDelaySeconds(delayPermissible); + this.teleport(teleportee, destinationPs, destinationDesc, delaySeconds, otherSender, otherPerm); + } + + @Override + public void teleport(Player teleportee, PS destinationPs, String destinationDesc, CommandSender otherSender, String otherPerm) throws TeleporterException + { + this.teleport(teleportee, destinationPs, destinationDesc, 0, otherSender, otherPerm); + } + + @Override + public void teleport(Player teleportee, PS destinationPs, String destinationDesc, int delaySeconds, CommandSender otherSender, String otherPerm) throws TeleporterException + { + otherPermCheck(SenderUtil.getSenderId(teleportee), otherSender, otherPerm); + this.teleport(teleportee, destinationPs, destinationDesc, delaySeconds); + } + + // ---- + + @Override + public void teleport(String teleporteeId, PS destinationPs) throws TeleporterException + { + this.teleport(teleporteeId, destinationPs, null); + } + + @Override + public void teleport(String teleporteeId, PS destinationPs, String destinationDesc) throws TeleporterException + { + this.teleport(teleporteeId, destinationPs, destinationDesc, 0); + } + + @Override + public void teleport(String teleporteeId, PS destinationPs, String destinationDesc, Permissible delayPermissible) throws TeleporterException + { + int delaySeconds = decideDelaySeconds(delayPermissible); + this.teleport(teleporteeId, destinationPs, destinationDesc, delaySeconds); + } + + @Override + public void teleport(String teleporteeId, PS destinationPs, String destinationDesc, Permissible delayPermissible, CommandSender otherSender, String otherPerm) throws TeleporterException + { + int delaySeconds = decideDelaySeconds(delayPermissible); + this.teleport(teleporteeId, destinationPs, destinationDesc, delaySeconds, otherSender, otherPerm); + } + + @Override + public void teleport(String teleporteeId, PS destinationPs, String destinationDesc, CommandSender otherSender, String otherPerm) throws TeleporterException + { + this.teleport(teleporteeId, destinationPs, destinationDesc, 0, otherSender, otherPerm); + } + + @Override + public void teleport(String teleporteeId, PS destinationPs, String destinationDesc, int delaySeconds, CommandSender otherSender, String otherPerm) throws TeleporterException + { + otherPermCheck(teleporteeId, otherSender, otherPerm); + this.teleport(teleporteeId, destinationPs, destinationDesc, delaySeconds); + } + + // -------------------------------------------- // + // UTIL + // -------------------------------------------- // + + public static int decideDelaySeconds(Permissible delayPermissible) + { + int ret = Conf.tpdelay; + if (Permission.NOTPDELAY.has(delayPermissible, false)) + { + ret = 0; + } + ret = Math.max(ret, 0); + return ret; + } + + public static void otherPermCheck(String teleporteeId, CommandSender otherSender, String otherPerm) throws TeleporterException + { + String otherSenderId = SenderUtil.getSenderId(otherSender); + if (otherSenderId.equalsIgnoreCase(teleporteeId)) return; + if (PermUtil.has(otherSender, otherPerm, false)) return; + throw new TeleporterException(PermUtil.getForbiddenMessage(otherPerm)); + } + + public static void validateTeleporteeId(String teleporteeId) throws TeleporterException + { + if (!SenderUtil.isPlayerId(teleporteeId)) throw new TeleporterException(Txt.parse("%s is not a player.", Mixin.getDisplayName(teleporteeId))); + if (Mixin.isOffline(teleporteeId)) throw new TeleporterException(Txt.parse("%s is offline.", Mixin.getDisplayName(teleporteeId))); + } + + + +} diff --git a/src/com/massivecraft/mcore5/mixin/TeleportMixinDefault.java b/src/com/massivecraft/mcore5/mixin/TeleportMixinDefault.java new file mode 100644 index 00000000..34d8da0c --- /dev/null +++ b/src/com/massivecraft/mcore5/mixin/TeleportMixinDefault.java @@ -0,0 +1,73 @@ +package com.massivecraft.mcore5.mixin; + +import org.bukkit.Location; +import org.bukkit.entity.Entity; +import org.bukkit.entity.Player; +import org.bukkit.util.Vector; + +import com.massivecraft.mcore5.PS; +import com.massivecraft.mcore5.util.SenderUtil; +import com.massivecraft.mcore5.util.Txt; + +public class TeleportMixinDefault extends TeleportMixinAbstract +{ + // -------------------------------------------- // + // INSTANCE & CONSTRUCT + // -------------------------------------------- // + + private static TeleportMixinDefault i = new TeleportMixinDefault(); + public static TeleportMixinDefault get() { return i; } + + // -------------------------------------------- // + // CORE LOGIC + // -------------------------------------------- // + + public static void teleportEntity(Entity entity, PS ps) throws TeleporterException + { + // Use a local clone of the ps to avoid altering original + ps = ps.clone(); + + // Ensure the ps has a world name + if (ps.getWorldName() == null) + { + ps.setWorldName(entity.getWorld().getName()); + } + + Location location = ps.calcLocation(); + if (location == null) throw new TeleporterException(Txt.parse("Could not calculate the location.")); + + entity.teleport(location); + + Vector velocity = ps.getVelocity(); + if (velocity == null) return; + + entity.setVelocity(velocity); + } + + // -------------------------------------------- // + // OVERRIDE + // -------------------------------------------- // + + @Override + public void teleport(Player teleportee, PS destinationPs, String destinationDesc, int delaySeconds) throws TeleporterException + { + this.sendPreTeleportMessage(teleportee, destinationDesc, delaySeconds); + if (delaySeconds > 0) + { + new ScheduledTeleport(teleportee, destinationPs, destinationDesc, delaySeconds).schedule(); + } + else + { + teleportEntity(teleportee, destinationPs); + } + } + + @Override + public void teleport(String teleporteeId, PS destinationPs, String destinationDesc, int delaySeconds) throws TeleporterException + { + validateTeleporteeId(teleporteeId); + Player teleportee = SenderUtil.getPlayer(teleporteeId); + this.teleport(teleportee, destinationPs, destinationDesc, delaySeconds); + } + +} \ No newline at end of file diff --git a/src/com/massivecraft/mcore5/mixin/TeleporterException.java b/src/com/massivecraft/mcore5/mixin/TeleporterException.java new file mode 100644 index 00000000..c3321e1d --- /dev/null +++ b/src/com/massivecraft/mcore5/mixin/TeleporterException.java @@ -0,0 +1,31 @@ +package com.massivecraft.mcore5.mixin; + +public class TeleporterException extends Exception +{ + private static final long serialVersionUID = 1L; + + public TeleporterException() + { + super(); + } + + public TeleporterException(String message) + { + super(message); + } + + public TeleporterException(String message, Throwable cause) + { + super(message, cause); + } + + public TeleporterException(Throwable cause) + { + super(cause); + } + + protected TeleporterException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) + { + super(message, cause, enableSuppression, writableStackTrace); + } +} diff --git a/src/com/massivecraft/mcore5/mixin/VisibilityMixin.java b/src/com/massivecraft/mcore5/mixin/VisibilityMixin.java new file mode 100644 index 00000000..276f9602 --- /dev/null +++ b/src/com/massivecraft/mcore5/mixin/VisibilityMixin.java @@ -0,0 +1,16 @@ +package com.massivecraft.mcore5.mixin; + +import org.bukkit.command.CommandSender; + +public interface VisibilityMixin +{ + public boolean isVisible(String watcherId, String watcheeId); + public boolean isVisible(CommandSender watcher, String watcheeId); + public boolean isVisible(String watcherId, CommandSender watchee); + public boolean isVisible(CommandSender watcher, CommandSender watchee); + + public void setVisible(String watcherId, String watcheeId, boolean visible); + public void setVisible(CommandSender watcher, String watcheeId, boolean visible); + public void setVisible(String watcherId, CommandSender watchee, boolean visible); + public void setVisible(CommandSender watcher, CommandSender watchee, boolean visible); +} diff --git a/src/com/massivecraft/mcore5/mixin/VisibilityMixinAbstract.java b/src/com/massivecraft/mcore5/mixin/VisibilityMixinAbstract.java new file mode 100644 index 00000000..e7dcd923 --- /dev/null +++ b/src/com/massivecraft/mcore5/mixin/VisibilityMixinAbstract.java @@ -0,0 +1,6 @@ +package com.massivecraft.mcore5.mixin; + +public abstract class VisibilityMixinAbstract implements VisibilityMixin +{ + +} diff --git a/src/com/massivecraft/mcore5/mixin/VisibilityMixinDefault.java b/src/com/massivecraft/mcore5/mixin/VisibilityMixinDefault.java new file mode 100644 index 00000000..8652f26b --- /dev/null +++ b/src/com/massivecraft/mcore5/mixin/VisibilityMixinDefault.java @@ -0,0 +1,87 @@ +package com.massivecraft.mcore5.mixin; + +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +import com.massivecraft.mcore5.util.SenderUtil; + +public class VisibilityMixinDefault extends VisibilityMixinAbstract +{ + // -------------------------------------------- // + // INSTANCE & CONSTRUCT + // -------------------------------------------- // + + private static VisibilityMixinDefault i = new VisibilityMixinDefault(); + public static VisibilityMixinDefault get() { return i; } + + // -------------------------------------------- // + // OVERRIDE + // -------------------------------------------- // + + @Override + public boolean isVisible(String watcherId, String watcheeId) + { + return this.isVisible(SenderUtil.getSender(watcherId), SenderUtil.getSender(watcheeId)); + } + + @Override + public boolean isVisible(CommandSender watcher, String watcheeId) + { + return this.isVisible(watcher, SenderUtil.getSender(watcheeId)); + } + + @Override + public boolean isVisible(String watcherId, CommandSender watchee) + { + return this.isVisible(SenderUtil.getSender(watcherId), watchee); + } + + @Override + public boolean isVisible(CommandSender watcher, CommandSender watchee) + { + Player pwatcher = SenderUtil.getAsPlayer(watcher); + Player pwatchee = SenderUtil.getAsPlayer(watchee); + + if (pwatcher == null) return true; + if (pwatchee == null) return true; + + return pwatcher.canSee(pwatchee); + } + + @Override + public void setVisible(String watcherId, String watcheeId, boolean visible) + { + this.setVisible(SenderUtil.getSender(watcherId), SenderUtil.getSender(watcheeId), visible); + } + + @Override + public void setVisible(CommandSender watcher, String watcheeId, boolean visible) + { + this.setVisible(watcher, SenderUtil.getSender(watcheeId), visible); + } + + @Override + public void setVisible(String watcherId, CommandSender watchee, boolean visible) + { + this.setVisible(SenderUtil.getSender(watcherId), watchee, visible); + } + + @Override + public void setVisible(CommandSender watcher, CommandSender watchee, boolean visible) + { + Player pwatcher = SenderUtil.getAsPlayer(watcher); + Player pwatchee = SenderUtil.getAsPlayer(watchee); + + if (pwatcher == null) return; + if (pwatchee == null) return; + + if (visible) + { + pwatcher.showPlayer(pwatchee); + } + else + { + pwatcher.hidePlayer(pwatchee); + } + } +} diff --git a/src/com/massivecraft/mcore5/mixin/WorldMixin.java b/src/com/massivecraft/mcore5/mixin/WorldMixin.java new file mode 100644 index 00000000..ccf30ddd --- /dev/null +++ b/src/com/massivecraft/mcore5/mixin/WorldMixin.java @@ -0,0 +1,33 @@ +package com.massivecraft.mcore5.mixin; + +import java.util.List; + +import org.bukkit.ChatColor; +import org.bukkit.command.CommandSender; +import org.bukkit.permissions.Permissible; + +import com.massivecraft.mcore5.PS; + +public interface WorldMixin +{ + public boolean canSee(Permissible permissible, String worldId); + + public List getWorldIds(); + + public List getVisibleWorldIds(Permissible permissible); + + public ChatColor getWorldColor(String worldId); + + public List getWorldAliases(String worldId); + + public String getWorldAliasOrId(String worldId); + + public String getWorldDisplayName(String worldId); + + public PS getWorldSpawnPs(String worldId); + + public void setWorldSpawnPs(String worldId, PS spawnPs); + + public boolean trySetWorldSpawnWp(CommandSender sender, String worldId, PS spawnPs, boolean verbooseChange, boolean verbooseSame); + +} diff --git a/src/com/massivecraft/mcore5/mixin/WorldMixinAbstract.java b/src/com/massivecraft/mcore5/mixin/WorldMixinAbstract.java new file mode 100644 index 00000000..b16d13be --- /dev/null +++ b/src/com/massivecraft/mcore5/mixin/WorldMixinAbstract.java @@ -0,0 +1,40 @@ +package com.massivecraft.mcore5.mixin; + +import java.util.ArrayList; +import java.util.List; + +import org.bukkit.permissions.Permissible; + +public abstract class WorldMixinAbstract implements WorldMixin +{ + // -------------------------------------------- // + // OVERRIDE + // -------------------------------------------- // + + @Override + public List getVisibleWorldIds(Permissible permissible) + { + List ret = new ArrayList(); + for (String worldId : this.getWorldIds()) + { + if (!this.canSee(permissible, worldId)) continue; + ret.add(worldId); + } + return ret; + } + + @Override + public String getWorldAliasOrId(String worldId) + { + List aliases = this.getWorldAliases(worldId); + if (aliases.size() > 0) return aliases.get(0); + return worldId; + } + + @Override + public String getWorldDisplayName(String worldId) + { + return this.getWorldColor(worldId).toString()+this.getWorldAliasOrId(worldId); + } + +} \ No newline at end of file diff --git a/src/com/massivecraft/mcore5/mixin/WorldMixinDefault.java b/src/com/massivecraft/mcore5/mixin/WorldMixinDefault.java new file mode 100644 index 00000000..f842d83e --- /dev/null +++ b/src/com/massivecraft/mcore5/mixin/WorldMixinDefault.java @@ -0,0 +1,122 @@ +package com.massivecraft.mcore5.mixin; + +import java.util.ArrayList; +import java.util.List; + +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.Location; +import org.bukkit.World; +import org.bukkit.command.CommandSender; +import org.bukkit.permissions.Permissible; + +import com.massivecraft.mcore5.PS; +import com.massivecraft.mcore5.util.MUtil; + +public class WorldMixinDefault extends WorldMixinAbstract +{ + // -------------------------------------------- // + // INSTANCE & CONSTRUCT + // -------------------------------------------- // + + private static WorldMixinDefault i = new WorldMixinDefault(); + public static WorldMixinDefault get() { return i; } + + // -------------------------------------------- // + // OVERRIDE + // -------------------------------------------- // + + @Override + public boolean canSee(Permissible permissible, String worldId) + { + return true; + } + + @Override + public List getWorldIds() + { + List ret = new ArrayList(); + for (World world : Bukkit.getWorlds()) + { + ret.add(world.getName()); + } + return ret; + } + + @Override + public ChatColor getWorldColor(String worldId) + { + return ChatColor.WHITE; + } + + @Override + public List getWorldAliases(String worldId) + { + return new ArrayList(); + } + + @Override + public PS getWorldSpawnPs(String worldId) + { + World world = Bukkit.getWorld(worldId); + if (world == null) return null; + return new PS(world.getSpawnLocation()); + } + + @Override + public void setWorldSpawnPs(String worldId, PS spawnPs) + { + World world = Bukkit.getWorld(worldId); + if (world == null) return; + + spawnPs = spawnPs.clone(); + spawnPs.setWorldName(worldId); + Location location = spawnPs.calcLocation(); + if (location == null) return; + + world.setSpawnLocation(location.getBlockX(), location.getBlockY(), location.getBlockZ()); + } + + @Override + public boolean trySetWorldSpawnWp(CommandSender sender, String worldId, PS goal, boolean verbooseChange, boolean verbooseSame) + { + World world = Bukkit.getWorld(worldId); + if (world == null) + { + if (verbooseChange || verbooseSame) + { + Mixin.msg(sender, "Unknown world %s.", worldId); + } + return false; + } + + // Pre Calculations + String worldDisplayName = Mixin.getWorldDisplayName(worldId); + PS current = this.getWorldSpawnPs(worldId); + String currentFormatted = current.getShortDesc(); + String goalFormatted = goal.getShortDesc(); + + // No change? + if (MUtil.equals(goal, current)) + { + if (verbooseSame) + { + Mixin.msg(sender, "Spawn location is already %s for %s.", currentFormatted, worldDisplayName); + } + return true; + } + + // Report + if (verbooseChange) + { + Mixin.msg(sender, "Changing spawn location from %s to %s for %s.", currentFormatted, goalFormatted, worldDisplayName); + } + + // Set it + this.setWorldSpawnPs(worldId, goal); + + // Return + return true; + } + +} \ No newline at end of file diff --git a/src/com/massivecraft/mcore5/sender/BasicCommandSender.java b/src/com/massivecraft/mcore5/sender/BasicCommandSender.java index 2e91722a..a3f92cac 100644 --- a/src/com/massivecraft/mcore5/sender/BasicCommandSender.java +++ b/src/com/massivecraft/mcore5/sender/BasicCommandSender.java @@ -5,6 +5,7 @@ import org.bukkit.Server; import org.bukkit.command.CommandSender; import org.bukkit.permissions.PermissibleBase; +import com.massivecraft.mcore5.MCore; import com.massivecraft.mcore5.util.SenderUtil; public class BasicCommandSender extends PermissibleBase implements CommandSender @@ -55,6 +56,24 @@ public class BasicCommandSender extends PermissibleBase implements CommandSender } public boolean register() + { + final BasicCommandSender ME = this; + + // register later + Bukkit.getScheduler().scheduleSyncDelayedTask(MCore.get(), new Runnable() + { + @Override + public void run() + { + ME.registerImmediately(); + } + }); + + // and register now + return this.registerImmediately(); + } + + public boolean registerImmediately() { return SenderUtil.register(this); } @@ -63,4 +82,5 @@ public class BasicCommandSender extends PermissibleBase implements CommandSender { return SenderUtil.unregister(this); } + } diff --git a/src/com/massivecraft/mcore5/store/Entity.java b/src/com/massivecraft/mcore5/store/Entity.java index 75691d0d..f2b26952 100644 --- a/src/com/massivecraft/mcore5/store/Entity.java +++ b/src/com/massivecraft/mcore5/store/Entity.java @@ -46,10 +46,7 @@ public abstract class Entity, L extends Comparable coll = this.getColl(); - if (coll == null) return false; - - return coll.getAll().contains(this); + return this.getColl() != null; } public boolean detached() diff --git a/src/com/massivecraft/mcore5/store/MixinSenderIdSource.java b/src/com/massivecraft/mcore5/store/MixinSenderIdSource.java deleted file mode 100644 index 972c8061..00000000 --- a/src/com/massivecraft/mcore5/store/MixinSenderIdSource.java +++ /dev/null @@ -1,26 +0,0 @@ -package com.massivecraft.mcore5.store; - -import java.util.Collection; - -import com.massivecraft.mcore5.mixin.Mixin; - -public class MixinSenderIdSource implements SenderIdSource -{ - // -------------------------------------------- // - // INSTANCE & CONSTRUCT - // -------------------------------------------- // - - private static MixinSenderIdSource i = new MixinSenderIdSource(); - public static MixinSenderIdSource get() { return i; } - - // -------------------------------------------- // - // OVERRIDE - // -------------------------------------------- // - - @Override - public Collection getSenderIds() - { - return Mixin.getAllSenderIds(); - } - -} diff --git a/src/com/massivecraft/mcore5/store/SenderColl.java b/src/com/massivecraft/mcore5/store/SenderColl.java index d1eb03f0..5d566693 100644 --- a/src/com/massivecraft/mcore5/store/SenderColl.java +++ b/src/com/massivecraft/mcore5/store/SenderColl.java @@ -1,8 +1,9 @@ package com.massivecraft.mcore5.store; +import java.util.ArrayList; import java.util.Collection; import java.util.Comparator; -import java.util.TreeSet; +import java.util.List; import org.bukkit.command.CommandSender; @@ -31,7 +32,7 @@ public class SenderColl> extends Coll imple protected boolean lowercasing; public boolean isLowercasing() { return this.lowercasing; } - protected final SenderIdSource mixinedIdSource = new SenderIdSourceCombined(this, MixinSenderIdSource.get()); + protected final SenderIdSource mixinedIdSource = new SenderIdSourceCombined(this, SenderIdSourceMixinAllSenderIds.get()); public SenderIdSource getMixinedIdSource() { return this.mixinedIdSource; } // -------------------------------------------- // @@ -63,9 +64,9 @@ public class SenderColl> extends Coll imple // EXTRAS // -------------------------------------------- // - public TreeSet getFixedIds() + public List getFixedIds() { - TreeSet ret = new TreeSet(String.CASE_INSENSITIVE_ORDER); + List ret = new ArrayList(); for (String senderId : this.getIds()) { ret.add(Mixin.tryFix(senderId)); @@ -74,11 +75,14 @@ public class SenderColl> extends Coll imple } @Override - public Collection getSenderIds() + public Collection> getSenderIdCollections() { - return this.getFixedIds(); + List> ret = new ArrayList>(); + ret.add(this.getFixedIds()); + return ret; } + @Override public String fixId(Object oid) { diff --git a/src/com/massivecraft/mcore5/store/SenderEntity.java b/src/com/massivecraft/mcore5/store/SenderEntity.java index 1c0d5c5f..2c3df29b 100644 --- a/src/com/massivecraft/mcore5/store/SenderEntity.java +++ b/src/com/massivecraft/mcore5/store/SenderEntity.java @@ -161,34 +161,34 @@ public abstract class SenderEntity> extends Entity messages) { - return SenderUtil.sendMessage(this.getId(), messages); + return Mixin.message(this.getId(), messages); } // CONVENIENCE MSG public boolean msg(String msg) { - return SenderUtil.msg(this.getId(), msg); + return Mixin.msg(this.getId(), msg); } public boolean msg(String msg, Object... args) { - return SenderUtil.msg(this.getId(), msg, args); + return Mixin.msg(this.getId(), msg, args); } public boolean msg(Collection msgs) { - return SenderUtil.msg(this.getId(), msgs); + return Mixin.msg(this.getId(), msgs); } // CONVENIENCE GAME-MODE diff --git a/src/com/massivecraft/mcore5/store/SenderIdSource.java b/src/com/massivecraft/mcore5/store/SenderIdSource.java index 936a8812..dd29b019 100644 --- a/src/com/massivecraft/mcore5/store/SenderIdSource.java +++ b/src/com/massivecraft/mcore5/store/SenderIdSource.java @@ -4,5 +4,5 @@ import java.util.Collection; public interface SenderIdSource { - public Collection getSenderIds(); + public Collection> getSenderIdCollections(); } diff --git a/src/com/massivecraft/mcore5/store/SenderIdSourceCombined.java b/src/com/massivecraft/mcore5/store/SenderIdSourceCombined.java index 4912701a..02038d69 100644 --- a/src/com/massivecraft/mcore5/store/SenderIdSourceCombined.java +++ b/src/com/massivecraft/mcore5/store/SenderIdSourceCombined.java @@ -4,7 +4,6 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.List; -import java.util.TreeSet; public class SenderIdSourceCombined implements SenderIdSource { @@ -33,12 +32,12 @@ public class SenderIdSourceCombined implements SenderIdSource // -------------------------------------------- // @Override - public Collection getSenderIds() + public Collection> getSenderIdCollections() { - TreeSet ret = new TreeSet(String.CASE_INSENSITIVE_ORDER); + List> ret = new ArrayList>(); for (SenderIdSource source : this.sources) { - ret.addAll(source.getSenderIds()); + ret.addAll(source.getSenderIdCollections()); } return ret; } diff --git a/src/com/massivecraft/mcore5/store/SenderIdSourceMixinAllPlayerIds.java b/src/com/massivecraft/mcore5/store/SenderIdSourceMixinAllPlayerIds.java new file mode 100644 index 00000000..dba71a9a --- /dev/null +++ b/src/com/massivecraft/mcore5/store/SenderIdSourceMixinAllPlayerIds.java @@ -0,0 +1,30 @@ +package com.massivecraft.mcore5.store; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +import com.massivecraft.mcore5.mixin.Mixin; + +public class SenderIdSourceMixinAllPlayerIds implements SenderIdSource +{ + // -------------------------------------------- // + // INSTANCE & CONSTRUCT + // -------------------------------------------- // + + private static SenderIdSourceMixinAllPlayerIds i = new SenderIdSourceMixinAllPlayerIds(); + public static SenderIdSourceMixinAllPlayerIds get() { return i; } + + // -------------------------------------------- // + // OVERRIDE + // -------------------------------------------- // + + @Override + public Collection> getSenderIdCollections() + { + List> ret = new ArrayList>(); + ret.add(Mixin.getAllPlayerIds()); + return ret; + } + +} diff --git a/src/com/massivecraft/mcore5/store/SenderIdSourceMixinAllSenderIds.java b/src/com/massivecraft/mcore5/store/SenderIdSourceMixinAllSenderIds.java new file mode 100644 index 00000000..97213915 --- /dev/null +++ b/src/com/massivecraft/mcore5/store/SenderIdSourceMixinAllSenderIds.java @@ -0,0 +1,30 @@ +package com.massivecraft.mcore5.store; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +import com.massivecraft.mcore5.mixin.Mixin; + +public class SenderIdSourceMixinAllSenderIds implements SenderIdSource +{ + // -------------------------------------------- // + // INSTANCE & CONSTRUCT + // -------------------------------------------- // + + private static SenderIdSourceMixinAllSenderIds i = new SenderIdSourceMixinAllSenderIds(); + public static SenderIdSourceMixinAllSenderIds get() { return i; } + + // -------------------------------------------- // + // OVERRIDE + // -------------------------------------------- // + + @Override + public Collection> getSenderIdCollections() + { + List> ret = new ArrayList>(); + ret.add(Mixin.getAllSenderIds()); + return ret; + } + +} diff --git a/src/com/massivecraft/mcore5/util/MUtil.java b/src/com/massivecraft/mcore5/util/MUtil.java index 44d78fe1..25504ac1 100644 --- a/src/com/massivecraft/mcore5/util/MUtil.java +++ b/src/com/massivecraft/mcore5/util/MUtil.java @@ -21,8 +21,10 @@ import java.util.TreeSet; import net.minecraft.server.v1_4_R1.DedicatedServer; import org.bukkit.Bukkit; +import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.World; +import org.bukkit.block.BlockFace; import org.bukkit.command.CommandSender; import org.bukkit.craftbukkit.v1_4_R1.CraftServer; import org.bukkit.entity.Entity; @@ -101,6 +103,85 @@ public class MUtil return ret; } + // -------------------------------------------- // + // PICK + // -------------------------------------------- // + + public static T regexPickFirstVal(String input, Map regex2val) + { + if (regex2val == null) return null; + T ret = null; + + for (Entry entry : regex2val.entrySet()) + { + ret = entry.getValue(); + if (input == null) continue; + String regex = entry.getKey(); + if (Pattern.matches(regex, input)) break; + } + + return ret; + } + + public static T equalsPickFirstVal(E input, Map thing2val) + { + if (thing2val == null) return null; + T ret = null; + + for (Entry entry : thing2val.entrySet()) + { + ret = entry.getValue(); + if (input == null) continue; + E thing = entry.getKey(); + if (MUtil.equals(input, thing)) break; + } + + return ret; + } + + // -------------------------------------------- // + // BLOCK COMPARISON BY LOCATIONS + // -------------------------------------------- // + + public static boolean isSameBlock(Location one, Location two) + { + if (one.getBlockX() != two.getBlockX()) return false; + if (one.getBlockZ() != two.getBlockZ()) return false; + if (one.getBlockY() != two.getBlockY()) return false; + return one.getWorld().equals(two.getWorld()); + } + + // -------------------------------------------- // + // FACE AND YAW + // -------------------------------------------- // + + public static Float getYaw(BlockFace face) + { + switch (face) + { + case NORTH: return 0f; + case EAST: return 90f; + case SOUTH: return 180f; + case WEST: return 270f; + case UP: return null; + case DOWN: return null; + case NORTH_EAST: return 45f; + case NORTH_WEST: return 315f; + case SOUTH_EAST: return 135f; + case SOUTH_WEST: return 225f; + case WEST_NORTH_WEST: return 292.5f; + case NORTH_NORTH_WEST: return 337.5f; + case NORTH_NORTH_EAST: return 22.5f; + case EAST_NORTH_EAST: return 67.5f; + case EAST_SOUTH_EAST: return 112.5f; + case SOUTH_SOUTH_EAST: return 157.5f; + case SOUTH_SOUTH_WEST: return 202.5f; + case WEST_SOUTH_WEST: return 247.5f; + case SELF: return null; + } + return null; + } + // -------------------------------------------- // // MATERIAL FACTS // -------------------------------------------- // diff --git a/src/com/massivecraft/mcore5/util/PermUtil.java b/src/com/massivecraft/mcore5/util/PermUtil.java index c4f29f2f..d091bfa2 100644 --- a/src/com/massivecraft/mcore5/util/PermUtil.java +++ b/src/com/massivecraft/mcore5/util/PermUtil.java @@ -32,17 +32,17 @@ public class PermUtil { return has(permissable, permission.getName(), verbose); } - public static boolean has(Permissible permissable, String perm, boolean verbose) + public static boolean has(Permissible permissible, String perm, boolean verbose) { - if (has(permissable, perm)) + if (has(permissible, perm)) { return true; } - else if (verbose && permissable != null) + else if (verbose && permissible != null) { - if (permissable instanceof CommandSender) + if (permissible instanceof CommandSender) { - CommandSender sender = (CommandSender)permissable; + CommandSender sender = (CommandSender)permissible; sender.sendMessage(getForbiddenMessage(perm)); } } diff --git a/src/com/massivecraft/mcore5/util/SenderUtil.java b/src/com/massivecraft/mcore5/util/SenderUtil.java index 233ed185..dd3a0902 100644 --- a/src/com/massivecraft/mcore5/util/SenderUtil.java +++ b/src/com/massivecraft/mcore5/util/SenderUtil.java @@ -2,7 +2,6 @@ package com.massivecraft.mcore5.util; import java.util.ArrayList; import java.util.Arrays; -import java.util.Collection; import java.util.Collections; import java.util.List; import java.util.Map; @@ -12,7 +11,6 @@ import java.util.TreeMap; import net.minecraft.server.v1_4_R1.MinecraftServer; import org.bukkit.Bukkit; -import org.bukkit.ChatColor; import org.bukkit.GameMode; import org.bukkit.Server; import org.bukkit.command.BlockCommandSender; @@ -22,33 +20,18 @@ import org.bukkit.command.RemoteConsoleCommandSender; import org.bukkit.craftbukkit.v1_4_R1.CraftServer; import org.bukkit.entity.Player; -import com.massivecraft.mcore5.mixin.Mixin; +import com.massivecraft.mcore5.MCore; +import com.massivecraft.mcore5.event.MCoreSenderRegisterEvent; +import com.massivecraft.mcore5.event.MCoreSenderUnregisterEvent; import com.massivecraft.mcore5.sender.FakeBlockCommandSender; -import com.massivecraft.mcore5.store.SenderColl; /** - * This Util was created to fill out the void between the Player interface and other CommandSenders. - * - * +++ The ID +++ * We add an ID <--> CommandSender lookup feature. * Each player has an id which is the name of the player. Players are retrievable by id using Bukkit.getPlayerExact(). * Other command senders have no true id. We make it so they have. * Non-player-sender-ids always start with and ampersand (@). This is to avoid clashes with regular player names. * The id is simply "@"+CommandSender.getName() with exception for the block command sender which we call "@block". * Non standard CommandSenders must be manually registered to the util using the register method. - * - * +++ The DisplayName and ListName +++ - * CommandSenders can have DisplayName and ListName just like normal Player. - * - * +++ Online/Offline +++ - * Players may be Online/Offline. We allow CommandSenders to be Online/Offline as well. - * This is simply done by stating that everything non-player in online all the time. - * The ConsoleCommandSender is for example always online and never offline. - * - * +++ Easy sendMessage and dispatchCommand +++ - * This feature isn't new "fake fields" like the ones above. - * Its a suite of useful utility methods for sending messages and dispatching commands as a certain sender. - * */ public class SenderUtil { @@ -80,16 +63,19 @@ public class SenderUtil { if (sender == null) return false; String id = getSenderId(sender); - CommandSender current = idToSender.get(id); - if (current != null) return current == sender; idToSender.put(id, sender); - SenderColl.setSenderRefferences(id, sender); + new MCoreSenderRegisterEvent(sender).run(); return true; } public static synchronized boolean unregister(CommandSender sender) { - return idToSender.remove(getSenderId(sender)) != null; + boolean ret = (idToSender.remove(getSenderId(sender)) != null); + if (ret) + { + new MCoreSenderUnregisterEvent(sender).run(); + } + return ret; } public static Map getIdToSender() @@ -99,20 +85,17 @@ public class SenderUtil static { - // Register - register(getConsole()); - register(getRcon()); - register(getBlock()); - - // Display Name - Mixin.setDisplayName(ID_CONSOLE, ChatColor.RED.toString()+ID_CONSOLE.toUpperCase()); - Mixin.setDisplayName(ID_RCON, ChatColor.RED.toString()+ID_RCON.toUpperCase()); - Mixin.setDisplayName(ID_BLOCK, ChatColor.RED.toString()+ID_BLOCK.toUpperCase()); - - // List Name - Mixin.setListName(ID_CONSOLE, ChatColor.RED.toString()+ID_CONSOLE.toUpperCase()); - Mixin.setListName(ID_RCON, ChatColor.RED.toString()+ID_RCON.toUpperCase()); - Mixin.setListName(ID_BLOCK, ChatColor.RED.toString()+ID_BLOCK.toUpperCase()); + // Since the console and rcon does not exist we schedule the register for these senders. + Bukkit.getScheduler().scheduleSyncDelayedTask(MCore.get(), new Runnable() + { + @Override + public void run() + { + register(getConsole()); + register(getRcon()); + register(getBlock()); + } + }); } // -------------------------------------------- // @@ -349,105 +332,6 @@ public class SenderUtil return ret; } - // -------------------------------------------- // - // CONVENIENCE CMD - // -------------------------------------------- // - - public static boolean cmd(CommandSender sender, String cmd) - { - return Bukkit.dispatchCommand(sender, cmd); - } - - // -------------------------------------------- // - // CONVENIENCE SEND MESSAGE - // -------------------------------------------- // - - // sender - - public static boolean sendMessage(CommandSender sender, String message) - { - if (sender == null) return false; - sender.sendMessage(message); - return true; - } - - public static boolean sendMessage(CommandSender sender, String... messages) - { - if (sender == null) return false; - sender.sendMessage(messages); - return true; - } - - public static boolean sendMessage(CommandSender sender, Collection messages) - { - if (sender == null) return false; - for (String message : messages) - { - sender.sendMessage(message); - } - return true; - } - - // senderId - - public static boolean sendMessage(String senderId, String message) - { - return sendMessage(getSender(senderId), message); - } - - public static boolean sendMessage(String senderId, String... messages) - { - return sendMessage(getSender(senderId), messages); - } - - public static boolean sendMessage(String senderId, Collection messages) - { - return sendMessage(getSender(senderId), messages); - } - - // -------------------------------------------- // - // CONVENIENCE MSG - // -------------------------------------------- // - - // sender - - public static boolean msg(CommandSender sender, String msg) - { - return sendMessage(sender, Txt.parse(msg)); - } - - public static boolean msg(CommandSender sender, String msg, Object... args) - { - return sendMessage(sender, Txt.parse(msg, args)); - } - - public static boolean msg(CommandSender sender, Collection msgs) - { - if (sender == null) return false; - for (String msg : msgs) - { - msg(sender, msg); - } - return true; - } - - // senderId - - public static boolean msg(String senderId, String msg) - { - return msg(getSender(senderId), msg); - } - - public static boolean msg(String senderId, String msg, Object... args) - { - return msg(getSender(senderId), msg, args); - } - - public static boolean msg(String senderId, Collection msgs) - { - return msg(getSender(senderId), msgs); - } - // -------------------------------------------- // // CONVENIENCE GAME-MODE // -------------------------------------------- // diff --git a/src/com/massivecraft/mcore5/util/TimeDiffUtil.java b/src/com/massivecraft/mcore5/util/TimeDiffUtil.java new file mode 100644 index 00000000..eb5b5bd4 --- /dev/null +++ b/src/com/massivecraft/mcore5/util/TimeDiffUtil.java @@ -0,0 +1,191 @@ +package com.massivecraft.mcore5.util; + +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.TreeSet; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class TimeDiffUtil +{ + // -------------------------------------------- // + // CONSTANTS + // -------------------------------------------- // + + public final static Pattern patternFull = Pattern.compile("^(?:([^a-zA-Z]+)([a-zA-Z]*))+$"); + public final static Pattern patternPart = Pattern.compile("([^a-zA-Z]+)([a-zA-Z]*)"); + + // -------------------------------------------- // + // MILLIS + // -------------------------------------------- // + + public static long millis(TimeUnit timeUnit, long count) + { + return timeUnit.millis*count; + } + + public static long millis(TimeUnit timeUnit) + { + return millis(timeUnit, 1); + } + + public static long millis(Map unitcounts, long count) + { + long ret = 0; + for (Entry entry : unitcounts.entrySet()) + { + ret += millis(entry.getKey(), entry.getValue()*count); + } + return ret; + } + + public static long millis(Map unitcounts) + { + return millis(unitcounts, 1); + } + + public static long millis(String formated, long count) throws Exception + { + Map unitcount = unitcounts(formated); + return millis(unitcount, count); + } + + public static long millis(String formated) throws Exception + { + return millis(formated, 1); + } + + // -------------------------------------------- // + // UNITCOUNT + // -------------------------------------------- // + + public static LinkedHashMap unitcounts(String formated) throws Exception + { + if (formated == null) throw new NullPointerException("The string can't be null."); + + Matcher matcherFull = patternFull.matcher(formated); + if (!matcherFull.matches()) throw new NullPointerException("Invalid time diff format."); + + LinkedHashMap ret = new LinkedHashMap(); + + Matcher matcherPart = patternPart.matcher(formated); + while (matcherPart.find()) + { + // Parse the count + String countString = matcherPart.group(1); + String countStringFixed = countString.replaceAll("[\\+\\s]", ""); + long count = 0; + try + { + count = Long.parseLong(countStringFixed); + } + catch (Exception e) + { + throw new Exception("\""+countString+"\" is not a valid integer."); + } + + // Parse the time unit + String unitString = matcherPart.group(2); + TimeUnit unit = TimeUnit.get(unitString); + if (unit == null) + { + throw new Exception("\""+unit+"\" is not a valid time unit."); + } + + // Add to the return map + if (ret.put(unit, count) != null) + { + throw new Exception("Multiple "+unit.singularName+" entries is not allowed."); + } + } + + return ret; + } + + public static LinkedHashMap unitcounts(long millis, TreeSet units) + { + // Create non-negative millis decumulator + long millisLeft = Math.abs(millis); + + LinkedHashMap ret = new LinkedHashMap(); + + for (TimeUnit unit : units) + { + long count = (long) Math.floor(millisLeft / unit.millis); + if (count < 1) continue; + millisLeft -= unit.millis*count; + ret.put(unit, count); + } + + return ret; + } + + public static LinkedHashMap unitcounts(long millis) + { + return unitcounts(millis, TimeUnit.getAll()); + } + + // -------------------------------------------- // + // FORMAT + // -------------------------------------------- // + + public static final String FORMAT_ENTRY_VERBOOSE = Txt.parse("%1$d%3$s"); + public static final String FORMAT_COMMA_VERBOOSE = "%s, "; + public static final String FORMAT_AND_VERBOOSE = " %sand "; + + public static final String FORMAT_ENTRY_MINIMAL = Txt.parse("%1$d%2$s"); + public static final String FORMAT_COMMA_MINIMAL = "%s"; + public static final String FORMAT_AND_MINIMAL = "%s"; + + public static String formated(TimeUnit unit, long count, String formatEntry) + { + return String.format(formatEntry, count, unit.getUnitString(count), unit.getNameString(count)); + } + + public static String formated(Map unitcounts, String entryFormat, String commaFormat, String andFormat, String color) + { + String comma = String.format(commaFormat, Txt.parse(color)); + String and = String.format(andFormat, Txt.parse(color)); + + List parts = new ArrayList(); + for (Entry entry : unitcounts.entrySet()) + { + parts.add(formated(entry.getKey(), entry.getValue(), entryFormat)); + } + return Txt.implodeCommaAnd(parts, comma, and); + } + + public static String formatedVerboose(TimeUnit unit, long count) + { + return formated(unit, count, FORMAT_ENTRY_VERBOOSE); + } + + public static String formatedVerboose(Map unitcounts, String color) + { + return formated(unitcounts, FORMAT_ENTRY_VERBOOSE, FORMAT_COMMA_VERBOOSE, FORMAT_AND_VERBOOSE, color); + } + + public static String formatedVerboose(Map unitcounts) + { + return formatedVerboose(unitcounts, ""); + } + + public static String formatedMinimal(TimeUnit unit, long count) + { + return formated(unit, count, FORMAT_ENTRY_MINIMAL); + } + + public static String formatedMinimal(Map unitcounts, String color) + { + return formated(unitcounts, FORMAT_ENTRY_MINIMAL, FORMAT_COMMA_MINIMAL, FORMAT_AND_MINIMAL, color); + } + + public static String formatedMinimal(Map unitcounts) + { + return formatedMinimal(unitcounts, ""); + } + +} diff --git a/src/com/massivecraft/mcore5/util/TimeUnit.java b/src/com/massivecraft/mcore5/util/TimeUnit.java new file mode 100644 index 00000000..48f86a26 --- /dev/null +++ b/src/com/massivecraft/mcore5/util/TimeUnit.java @@ -0,0 +1,138 @@ +package com.massivecraft.mcore5.util; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.TreeSet; + +public class TimeUnit implements Comparable +{ + // -------------------------------------------- // + // CONSTANTS + // -------------------------------------------- // + + public static final long MILLIS_PER_MILLISECOND = 1L; + public static final long MILLIS_PER_SECOND = 1000L * MILLIS_PER_MILLISECOND; + public static final long MILLIS_PER_MINUTE = 60L * MILLIS_PER_SECOND; + public static final long MILLIS_PER_HOUR = 60L * MILLIS_PER_MINUTE; + public static final long MILLIS_PER_DAY = 24L * MILLIS_PER_HOUR; + public static final long MILLIS_PER_WEEK = 7L * MILLIS_PER_DAY; + public static final long MILLIS_PER_MONTH = 31L * MILLIS_PER_DAY; + public static final long MILLIS_PER_MONTHUP = 32L * MILLIS_PER_DAY; + public static final long MILLIS_PER_YEAR = 365L * MILLIS_PER_DAY; + + public static final TimeUnit YEAR = new TimeUnit(MILLIS_PER_YEAR, "year", "years", "year", "years", "y", "year", "years"); + public static final TimeUnit MONTH = new TimeUnit(MILLIS_PER_MONTH, "month", "months", "month", "months", "month", "months"); + public static final TimeUnit WEEK = new TimeUnit(MILLIS_PER_WEEK, "week", "weeks", "week", "weeks", "w", "week", "weeks"); + public static final TimeUnit DAY = new TimeUnit(MILLIS_PER_DAY, "day", "days", "day", "days", "d", "day", "days"); + public static final TimeUnit HOUR = new TimeUnit(MILLIS_PER_HOUR, "hour", "hours", "h", "h", "h", "hs", "hour", "hours"); + public static final TimeUnit MINUTE = new TimeUnit(MILLIS_PER_MINUTE, "minute", "minutes", "min", "min", "m", "min", "mins", "minute", "minutes"); + public static final TimeUnit SECOND = new TimeUnit(MILLIS_PER_SECOND, "second", "seconds", "s", "s", "s", "sec", "secs", "second", "seconds"); + public static final TimeUnit MILLISECOND = new TimeUnit(MILLIS_PER_MILLISECOND, "millisecond", "milliseconds", "ms", "ms", "millis", "millisec", "millisecs", "millisecond", "milliseconds", "ms", "msec", "msecs", "msecond", "mseconds"); + + // -------------------------------------------- // + // REGISTRY + // -------------------------------------------- // + + private static final TreeSet all = new TreeSet(); + public static TreeSet getAll() { return new TreeSet(all); } + + public static TimeUnit get(String timeUnitString) + { + if (timeUnitString == null) return null; + String timeUnitStringLowerCase = timeUnitString.toLowerCase(); + for(TimeUnit timeUnit : all) + { + for (String alias : timeUnit.aliases) + { + if (alias.equals(timeUnitStringLowerCase)) + { + return timeUnit; + } + } + } + return null; + } + + public static boolean register(TimeUnit timeUnit) + { + return all.add(timeUnit); + } + + static + { + register(YEAR); + register(MONTH); + register(WEEK); + register(DAY); + register(HOUR); + register(MINUTE); + register(SECOND); + register(MILLISECOND); + } + + // -------------------------------------------- // + // FIELDS + // -------------------------------------------- // + + public final long millis; + public final String singularName; + public final String pluralName; + public final String singularUnit; + public final String pluralUnit; + public final Collection aliases; + + // -------------------------------------------- // + // CONSTRUCT + // -------------------------------------------- // + + private TimeUnit(long millis, String singularName, String pluralName, String singularUnit, String pluralUnit, String... aliases) + { + this.millis = millis; + this.singularName = singularName; + this.pluralName = pluralName; + this.singularUnit = singularUnit; + this.pluralUnit = pluralUnit; + this.aliases = new ArrayList(Arrays.asList(aliases)); + } + + // -------------------------------------------- // + // UTIL + // -------------------------------------------- // + + public String getUnitString(long amount) + { + if (amount == 1) return this.singularUnit; + return this.pluralUnit; + } + + public String getNameString(long amount) + { + if (amount == 1) return this.singularName; + return this.pluralName; + } + + // -------------------------------------------- // + // BASIC + // -------------------------------------------- // + + @Override + public String toString() + { + return this.singularName; + } + + @Override + public int compareTo(TimeUnit that) + { + return Long.valueOf(this.millis).compareTo(that.millis) * -1; + } + + @Override + public final boolean equals(Object other) + { + if (! (other instanceof TimeUnit)) return false; + return this.millis == ((TimeUnit)other).millis; + } + +}