diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 00000000..e933d3b4 Binary files /dev/null and b/.DS_Store differ diff --git a/pom.xml b/pom.xml new file mode 100644 index 00000000..e4b26005 --- /dev/null +++ b/pom.xml @@ -0,0 +1,44 @@ + + 4.0.0 + com.sekwah.advancedportals + Advanced-Portals + + ${basedir}/core/ + + + ${basedir}/Resources + + + + + + + + 1.0.0-snapshot + + UTF-8 + 1.7 + 1.7 + + + + + + + + + \ No newline at end of file diff --git a/src/com/sekwah/advancedportals/core/AdvancedPortalsCore.java b/src/com/sekwah/advancedportals/core/AdvancedPortalsCore.java new file mode 100644 index 00000000..636c75fc --- /dev/null +++ b/src/com/sekwah/advancedportals/core/AdvancedPortalsCore.java @@ -0,0 +1,39 @@ +package com.sekwah.advancedportals.core; + +import com.sekwah.advancedportals.core.util.DataStorage; +import com.sekwah.advancedportals.core.util.InfoLogger; + +public class AdvancedPortalsCore { + + private static AdvancedPortalsCore instance; + private static CoreConnector coreConnector; + private static DataStorage dataStorage; + private static InfoLogger infoLogger; + + public AdvancedPortalsCore(CoreConnector coreConnector, DataStorage dataStorage, InfoLogger infoLogger) { + this.dataStorage = dataStorage; + this.infoLogger = infoLogger; + this.instance = this; + this.coreConnector = coreConnector; + } + + private static AdvancedPortalsCore getInstance() { + return instance; + } + + public static DataStorage getDataStorage() { + return dataStorage; + } + + public static InfoLogger getInfoLogger() { + return infoLogger; + } + + public static CoreConnector getCoreConnector() { + return coreConnector; + } + + public interface CoreConnector { + DataStorage getDataStorage(); + } +} diff --git a/src/com/sekwah/advancedportals/core/api/commands/SubCommand.java b/src/com/sekwah/advancedportals/core/api/commands/SubCommand.java new file mode 100644 index 00000000..61c9a136 --- /dev/null +++ b/src/com/sekwah/advancedportals/core/api/commands/SubCommand.java @@ -0,0 +1,35 @@ +package com.sekwah.advancedportals.core.api.commands; + +import org.bukkit.command.CommandSender; + +import java.util.List; + +/** + * Subcommand that can be registered to parts. + * + * @author sekwah41 + */ +public interface SubCommand { + + /** + * @param sender + * @param args arguments including the subcommand that has been specified. + * @return if the command has worked (if false it will just display a message from the command suggesting to check help) + */ + boolean onCommand(CommandSender sender, String[] args); + + /** + * + * + * @param sender + * @param args arguments including the subcommand that has been specified. + * @return tab completion for the subcommand + */ + List onTabComplete(CommandSender sender, String[] args); + + /** + * @return the string to show on the above help menu. (describing the subcommand) + */ + String getHelpText(); + +} diff --git a/src/com/sekwah/advancedportals/core/api/destination/Destination.java b/src/com/sekwah/advancedportals/core/api/destination/Destination.java new file mode 100644 index 00000000..cbad38c7 --- /dev/null +++ b/src/com/sekwah/advancedportals/core/api/destination/Destination.java @@ -0,0 +1,13 @@ +package com.sekwah.advancedportals.core.api.destination; + +/** + * Possibly look at adding the ability to add some tags to destinations such as permissions. Would make it easier + * to add permissions to block access to certain areas and such. Could be a different permission system or just + * it takes the tags on the destination and automatically applies them when a portal wants to warp to there. + * (Of course it would not work cross server unless the data was communicated and checked first however that + * could effect performance and would definitely effect speed) + * + * @author sekwah41 + */ +public class Destination { +} diff --git a/src/com/sekwah/advancedportals/core/api/effect/TestEffect.java b/src/com/sekwah/advancedportals/core/api/effect/TestEffect.java new file mode 100644 index 00000000..397aac84 --- /dev/null +++ b/src/com/sekwah/advancedportals/core/api/effect/TestEffect.java @@ -0,0 +1,21 @@ +package com.sekwah.advancedportals.core.api.effect; + +import com.sekwah.advancedportals.core.api.portal.Portal; +import org.bukkit.Location; +import org.bukkit.entity.Player; + +/** + * @author sekwah41 + */ +public class TestEffect implements WarpEffect { + + @Override + public void onWarp(Player player, Location loc, Action action, Portal portal) { + + } + + @Override + public Type getType() { + return null; + } +} diff --git a/src/com/sekwah/advancedportals/core/api/effect/WarpEffect.java b/src/com/sekwah/advancedportals/core/api/effect/WarpEffect.java new file mode 100644 index 00000000..7ddcd8ef --- /dev/null +++ b/src/com/sekwah/advancedportals/core/api/effect/WarpEffect.java @@ -0,0 +1,32 @@ +package com.sekwah.advancedportals.core.api.effect; + +import com.sekwah.advancedportals.core.api.portal.Portal; +import org.bukkit.Location; +import org.bukkit.entity.Player; + +/** + * Effects to be registered to the list. + *

+ * Fires once at each end. + *

+ * Can be a Visual effect or a Sound. Just register to the correct one + * + * @author sekwah41 + */ +public interface WarpEffect { + + void onWarp(Player player, Location loc, Action action, Portal portal); + + Type getType(); + + enum Action { + ENTER, + EXIT; + } + + enum Type { + SOUND, + VISUAL; + } + +} diff --git a/src/com/sekwah/advancedportals/core/api/events/PortalEditEvent.java b/src/com/sekwah/advancedportals/core/api/events/PortalEditEvent.java new file mode 100644 index 00000000..c795bc18 --- /dev/null +++ b/src/com/sekwah/advancedportals/core/api/events/PortalEditEvent.java @@ -0,0 +1,21 @@ +package com.sekwah.advancedportals.core.api.events; + +/** + * Activated when something about the event is edited. + * + * @author sekwah41 + */ +public class PortalEditEvent { + + public class TagChange { + + } + + public class Renamed { + + } + + public class Moved { + + } +} diff --git a/src/com/sekwah/advancedportals/core/api/events/PortalsLoadedEvent.java b/src/com/sekwah/advancedportals/core/api/events/PortalsLoadedEvent.java new file mode 100644 index 00000000..1fb73a62 --- /dev/null +++ b/src/com/sekwah/advancedportals/core/api/events/PortalsLoadedEvent.java @@ -0,0 +1,16 @@ +package com.sekwah.advancedportals.core.api.events; + +import org.bukkit.event.Event; +import org.bukkit.event.HandlerList; + +/** + * Triggered once all the portals are loaded + * + * @author sekwah41 + */ +public class PortalsLoadedEvent extends Event { + @Override + public HandlerList getHandlers() { + return null; + } +} diff --git a/src/com/sekwah/advancedportals/core/api/events/WarpEvent.java b/src/com/sekwah/advancedportals/core/api/events/WarpEvent.java new file mode 100644 index 00000000..ada9ca33 --- /dev/null +++ b/src/com/sekwah/advancedportals/core/api/events/WarpEvent.java @@ -0,0 +1,76 @@ +package com.sekwah.advancedportals.bukkit.api.events; + +import com.sekwah.advancedportals.bukkit.portals.AdvancedPortal; +import org.bukkit.entity.Player; +import org.bukkit.event.Cancellable; +import org.bukkit.event.Event; +import org.bukkit.event.HandlerList; + +/** + * Trigered whenever a player activates the warp after the tags are handled. + */ +public class WarpEvent extends Event implements Cancellable { + + private static HandlerList handlers = new HandlerList(); + + private boolean cancelled = false; + + private final Player player; + + @SuppressWarnings("unused") + private final AdvancedPortal portalData; + + private boolean hasWarped = false; + + /*public WarpEvent(Player player, AdvancedPortal portalData) { + this.player = player; + this.portalData = portalData; + }*/ + + public static HandlerList getHandlerList() { + return handlers; + } + + /** + * Returns if the event has been cancelled + * + * @return cancelled + */ + public boolean isCancelled() { + return cancelled; + } + + public void setCancelled(boolean cancel) { + cancelled = cancel; + } + + /*public AdvancedPortal getPortalData() { + return portalData; + }*/ + + /** + * This will return true if another plugin has warped the player(and set this to true) + * + * @return hasWarped + */ + public boolean getHasWarped() { + return hasWarped; + } + + /** + * If the + * + * @param warped + */ + public void setHasWarped(boolean warped) { + this.hasWarped = warped; + } + + public Player getPlayer() { + return player; + } + + public HandlerList getHandlers() { + return handlers; + } +} diff --git a/src/com/sekwah/advancedportals/core/api/managers/DestinationManager.java b/src/com/sekwah/advancedportals/core/api/managers/DestinationManager.java new file mode 100644 index 00000000..c60339ad --- /dev/null +++ b/src/com/sekwah/advancedportals/core/api/managers/DestinationManager.java @@ -0,0 +1,7 @@ +package com.sekwah.advancedportals.core.api.managers; + +/** + * @author sekwah41 + */ +public class DestinationManager { +} diff --git a/src/com/sekwah/advancedportals/core/api/managers/PortalManager.java b/src/com/sekwah/advancedportals/core/api/managers/PortalManager.java new file mode 100644 index 00000000..17606182 --- /dev/null +++ b/src/com/sekwah/advancedportals/core/api/managers/PortalManager.java @@ -0,0 +1,50 @@ +package com.sekwah.advancedportals.core.api.managers; + +import com.sekwah.advancedportals.core.api.portal.Portal; +import org.bukkit.entity.Player; + +import java.util.HashMap; + +/** + * When a player leaves the server any data stored on them is removed to free memory. + * + * @author sekwah41 + */ +public class PortalManager { + + /** + * Cooldown time for players to try entering portals. + */ + private static final int COOLDOWN = 0; + + private static PortalManager instance = new PortalManager(); + /** + * Store data of when the player last entered the portal + */ + private HashMap lastAttempt = new HashMap(); + /** + * Tracks what portal a player has selected + */ + private HashMap selectedPortal = new HashMap(); + + public PortalManager() { + this.loadPortals(); + } + + /** + * A player has left the server + * + * @param player + */ + public static void playerLeave(Player player) { + instance.lastAttempt.remove(player); + instance.selectedPortal.remove(player); + } + + /** + * Load the default data into the portals. + */ + private void loadPortals() { + + } +} diff --git a/src/com/sekwah/advancedportals/core/api/portal/Portal.java b/src/com/sekwah/advancedportals/core/api/portal/Portal.java new file mode 100644 index 00000000..5919a911 --- /dev/null +++ b/src/com/sekwah/advancedportals/core/api/portal/Portal.java @@ -0,0 +1,7 @@ +package com.sekwah.advancedportals.core.api.portal; + +/** + * @author sekwah41 + */ +public class Portal { +} diff --git a/src/com/sekwah/advancedportals/core/api/portal/PortalTag.java b/src/com/sekwah/advancedportals/core/api/portal/PortalTag.java new file mode 100644 index 00000000..9868a5a2 --- /dev/null +++ b/src/com/sekwah/advancedportals/core/api/portal/PortalTag.java @@ -0,0 +1,16 @@ +package com.sekwah.advancedportals.core.api.portal; + +public class PortalTag { + + public final String NAME; + public final String VALUE; + //public final int type; + + public PortalTag(String argName, String value/*, int type*/) { + this.NAME = argName; + this.VALUE = value; + // may be used if values need to be 100% not string + //this.type = type; + } + +} diff --git a/src/com/sekwah/advancedportals/core/api/registry/DestinationSubCommandRegistry.java b/src/com/sekwah/advancedportals/core/api/registry/DestinationSubCommandRegistry.java new file mode 100644 index 00000000..8546a2f1 --- /dev/null +++ b/src/com/sekwah/advancedportals/core/api/registry/DestinationSubCommandRegistry.java @@ -0,0 +1,9 @@ +package com.sekwah.advancedportals.core.api.registry; + +/** + * Designed to let addons add new command sections to access, edit or add new functonality. + * + * @author sekwah41 + */ +public class DestinationSubCommandRegistry extends SubCommandRegistry { +} diff --git a/src/com/sekwah/advancedportals/core/api/registry/PortalSubCommandRegistry.java b/src/com/sekwah/advancedportals/core/api/registry/PortalSubCommandRegistry.java new file mode 100644 index 00000000..f379f7a6 --- /dev/null +++ b/src/com/sekwah/advancedportals/core/api/registry/PortalSubCommandRegistry.java @@ -0,0 +1,11 @@ +package com.sekwah.advancedportals.core.api.registry; + +/** + * Designed to let addons add new command sections to access, edit or add new functonality. + * + * @author sekwah41 + */ +public class PortalSubCommandRegistry extends SubCommandRegistry { + + +} diff --git a/src/com/sekwah/advancedportals/core/api/registry/SubCommandRegistry.java b/src/com/sekwah/advancedportals/core/api/registry/SubCommandRegistry.java new file mode 100644 index 00000000..b0205aee --- /dev/null +++ b/src/com/sekwah/advancedportals/core/api/registry/SubCommandRegistry.java @@ -0,0 +1,84 @@ +package com.sekwah.advancedportals.core.api.registry; + +import com.sekwah.advancedportals.core.AdvancedPortalsCore; +import com.sekwah.advancedportals.core.api.commands.SubCommand; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + +/** + * Do not register to here. Register to the sprcific subcommand registry classes. + *

+ * Designed to let addons add new command sections to access, edit or add new functonality. + * + * @author sekwah41 + */ +public class SubCommandRegistry { + + private Map subCommandMap = new HashMap<>(); + + private static final SubCommandRegistry instance = new SubCommandRegistry(); + + /** + * List of subcommand names which should be in order alphabetically + */ + private ArrayList subCommands = new ArrayList<>(); + + /** + * @param arg argument needed to activate + * @param subCommand + * @return if the subcommand is registered or not + */ + public static boolean registerSubCommand(String arg, SubCommand subCommand) { + + if (subCommand == null) { + AdvancedPortalsCore.getInfoLogger().logWarning("The subcommand '" + arg + "' cannot be null."); + return false; + } + + if(!instance.subCommandMap.containsKey(arg)){ + AdvancedPortalsCore.getInfoLogger().logWarning("The subcommand '" + arg + "' already exists."); + return false; + } + + instance.subCommandMap.put(arg.toLowerCase(), subCommand); + + instance.subCommands.add(arg.toLowerCase()); + + Collections.sort(instance.subCommands); + + return true; + } + + /** + * @return a list of arguments of registered subcommands + */ + public static ArrayList getSubCommands(){ + return instance.subCommands; + } + + /** + * I may be wrong but for larger lists containsKey is faster with a hashmap than arraylist. + * + * Though im not sure at what size it becomes more efficient. + * @param arg + * @return if the argument is registered + */ + public static boolean isArgRegistered(String arg){ + return instance.subCommandMap.containsKey(arg.toLowerCase()); + } + + /** + * Gets the subcommand corresponding to the string argument + * @param arg + * @return the subcommand linked to the arg + */ + public static SubCommand getSubCommand(String arg){ + if(instance.subCommandMap.containsKey(arg.toLowerCase())){ + return instance.subCommandMap.get(arg.toLowerCase()); + } + return null; + } +} diff --git a/src/com/sekwah/advancedportals/core/api/registry/TagRegistry.java b/src/com/sekwah/advancedportals/core/api/registry/TagRegistry.java new file mode 100644 index 00000000..6079cf45 --- /dev/null +++ b/src/com/sekwah/advancedportals/core/api/registry/TagRegistry.java @@ -0,0 +1,123 @@ +package com.sekwah.advancedportals.api.registry; + +import com.sekwah.advancedportals.api.warphandler.TagHandler; +import com.sekwah.advancedportals.core.AdvancedPortalsCore; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + +/** + * Allows a portal to register a tag and add a handler. If a plugin wants to add functionality + * to someone elses tag then they should use the events. + * + * @author sekwah41 + */ +public class TagRegistry { + + // TODO the event can be used for general data detection and management, but use a TagHandler to make it so they can register + // the individual class to handle. + private static TagRegistry instance = new TagRegistry(); + + /** + * List of tag names which should be in order alphabetically + */ + private ArrayList tags = new ArrayList(); + /** + * Description of tags for help commands + */ + private Map tagDesc = new HashMap(); + private Map activationHandlers = new HashMap(); + private Map creationHandlers = new HashMap(); + private Map statusHandlers = new HashMap(); + + /** + * + * @param tag + * @param desc + * @param tagHandler + * @return if the tag was registered + */ + public static boolean registerTag(String tag, String desc, TagHandler tagHandler) { + if (registerTag(tag, tagHandler)) { + instance.tagDesc.put(tag, desc); + } + return false; + } + + + /** + * It is reccomended that you use the taghandlers to add tag functionality. However + * if needed such as extra data for a tag then this is here. + * + * @param tag + * @return if the tag was registered + */ + public static boolean registerTag(String tag) { + if (tag.contains(" ")) { + AdvancedPortalsCore.getInfoLogger().logWarning("The tag '" + + tag + "' is invalid as it contains spaces."); + return false; + } + if (instance.tags.contains(tag)) { + AdvancedPortalsCore.getInfoLogger().logWarning("The tag " + + tag + " has already been registered."); + return false; + } + instance.tags.add(tag); + Collections.sort(instance.tags); + return true; + } + + /** + * Same as registerTag(String tag) but allows a description to be added. + * + * @param tag Tag to be used on command line + * @param desc + * @return if the tag was registered + */ + public static boolean registerTag(String tag, String desc) { + if (registerTag(tag)) { + instance.tagDesc.put(tag, desc); + return true; + } + return false; + } + + public static boolean isTagRegistered(String tag){ + return instance.tagDesc.containsKey(tag); + } + + /** + * @return if the tag has been registered or if it already exists. + */ + public static boolean registerTag(String tag, TagHandler tagHandler) { + + if (tag == null) { + AdvancedPortalsCore.getInfoLogger().logWarning("A tag cannot be null."); + return false; + } + + if (!registerTag(tag)) { + return false; + } + + if (tagHandler != null && !(tagHandler instanceof TagHandler.Activation) && !(tagHandler instanceof TagHandler.TagStatus) && + !(tagHandler instanceof TagHandler.Creation)) { + AdvancedPortalsCore.getInfoLogger().logWarning("Error with tag: " + tag + ". A tag handler must implement one of the handlers. Not just extend."); + if (tagHandler instanceof TagHandler.Activation) { + instance.activationHandlers.put(tag, (TagHandler.Activation) tagHandler); + } + if (tagHandler instanceof TagHandler.TagStatus) { + instance.statusHandlers.put(tag, (TagHandler.TagStatus) tagHandler); + } + if (tagHandler instanceof TagHandler.Creation) { + instance.creationHandlers.put(tag, (TagHandler.Creation) tagHandler); + } + } + return true; + } + + +} diff --git a/src/com/sekwah/advancedportals/core/api/registry/WarpEffectRegistry.java b/src/com/sekwah/advancedportals/core/api/registry/WarpEffectRegistry.java new file mode 100644 index 00000000..f32b62d9 --- /dev/null +++ b/src/com/sekwah/advancedportals/core/api/registry/WarpEffectRegistry.java @@ -0,0 +1,76 @@ +package com.sekwah.advancedportals.core.api.registry; + +import com.sekwah.advancedportals.core.AdvancedPortalsCore; +import com.sekwah.advancedportals.core.api.effect.WarpEffect; + +import java.util.HashMap; +import java.util.Map; + +/** + * @author sekwah41 + */ +public class WarpEffectRegistry { + + + private Map visualEffects = new HashMap(); + + private Map soundEffects = new HashMap(); + + private static final WarpEffectRegistry instance = new WarpEffectRegistry(); + + /** + * Register a new warp effect. + * + * @param name + * @param effect + * @return if the effect was registered + */ + public static boolean registerEffect(String name, WarpEffect effect) { + if(name == null){ + return false; + } + Map list = null; + switch (effect.getType()){ + case SOUND: + list = instance.soundEffects; + break; + case VISUAL: + list = instance.visualEffects; + break; + default: + AdvancedPortalsCore.getInfoLogger().logWarning(effect.getType().toString() + + " effect type not recognised"); + return false; + } + if(list.containsKey(name)){ + return false; + } + list.put(name, effect); + return true; + } + + public static WarpEffect getEffect(String name, WarpEffect.Type type){ + Map list = null; + switch (type){ + case SOUND: + list = instance.soundEffects; + break; + case VISUAL: + list = instance.visualEffects; + break; + default: + AdvancedPortalsCore.getInfoLogger().logWarning(type.toString() + + " effect type not recognised"); + return null; + } + if(list.containsKey(name)) { + return list.get(name); + } + else{ + AdvancedPortalsCore.getInfoLogger().logWarning("No effect of type:" + + type.toString() + " was registered with the name: " + name); + return null; + } + } + +} diff --git a/src/com/sekwah/advancedportals/core/api/warphandler/ActivationData.java b/src/com/sekwah/advancedportals/core/api/warphandler/ActivationData.java new file mode 100644 index 00000000..9dad3933 --- /dev/null +++ b/src/com/sekwah/advancedportals/core/api/warphandler/ActivationData.java @@ -0,0 +1,60 @@ +package com.sekwah.advancedportals.bukkit.api.warphandler; + +import com.sekwah.advancedportals.bukkit.portals.Portal; + +public class ActivationData { + + private boolean warpAllowed = true; + + private WarpedStatus warpStatus = WarpedStatus.INACTIVE; + + private final Portal activePortal; + + /*public ActivationData(Portal portal){ + this.activePortal = portal; + } +*/ + public WarpedStatus getWarped() { + return this.warpStatus; + } + + public void setWarpStatus(WarpedStatus warped){ + if(this.warpStatus == WarpedStatus.WARPED || this.warpStatus == WarpedStatus.INACTIVE){ + return; + } + this.warpStatus = warped; + } + + /** + * In case you need to set the status back down a step for whatever reason. However it is not recommended. + * + * @param warped + */ + public void setWarpStatusAbsolute(WarpedStatus warped) { + this.warpStatus = warped; + } + + public boolean getAllowed() { + return this.warpAllowed; + } + + public void setAllowed(boolean allowed) { + this.warpAllowed = allowed; + } + + public enum WarpedStatus { + /** + * Player has moved or something major has happened. (only one of these should activate) + */ + WARPED, + /** + * Shows that the portal has been activated even if a major function is not performed. + */ + ACTIVATED, + /** + * Nothing has activated on the portal. + */ + INACTIVE + } + +} diff --git a/src/com/sekwah/advancedportals/core/api/warphandler/TagHandler.java b/src/com/sekwah/advancedportals/core/api/warphandler/TagHandler.java new file mode 100644 index 00000000..c7a04b96 --- /dev/null +++ b/src/com/sekwah/advancedportals/core/api/warphandler/TagHandler.java @@ -0,0 +1,96 @@ +package com.sekwah.advancedportals.bukkit.api.warphandler; + +import org.bukkit.entity.Player; + +public class TagHandler { + + /** + * When the user wants to activate the tag, not all will support this of course. its just a _ before or after the tag + * to specify + */ + public enum ActivatePref{ + BEFORE, + AFTER, + DEFAULT; + } + + public interface Creation { + + /** + * Example if the player does not have access to use a tag on the portal. + * + * @param player if null the portal has been created by the server or a plugin + * @param activeData + * @param argData + * @return if the portal can be created. + */ + boolean portalCreated(@Nullable Player player, ActivationData activeData, String argData); + + /** + * Example if the player does not have access to remove the portal. + * + * @param player if null the portal has been destroyed by the server or a plugin + * @param activeData + * @param argData + * @return if the portal can be destroyed. + */ + boolean portalDestroyed(@Nullable Player player, ActivationData activeData, String argData); + + } + + public interface Activation { + + /** + * Activates before the main part of portal activation. + * + * @param player + * @param activeData + * @param argData + */ + void portalPreActivated(Player player, ActivationData activeData, String argData); + + /** + * Activates after portal activation + * + * @param player + * @param activeData + * @param argData + */ + void portalPostActivated(Player player, ActivationData activeData, String argData); + + /** + * Activates if the portal is allowed from pre + * + * @param player + * @param activeData + * @param argData + */ + void portalActivated(Player player, ActivationData activeData, String argData); + + } + + public interface TagStatus { + + /** + * If the user has access to add the tag + * + * @param player + * @param activeData + * @param argData + * @return if the tag will be added. + */ + boolean tagAdded(@Nullable Player player, ActivationData activeData, String argData); + + /** + * If the user has access to remove the tag + * + * @param player + * @param activeData + * @param argData + * @return if the tag will be removed. + */ + boolean tagRemoved(Player player, ActivationData activeData, String argData); + + } + +} diff --git a/src/com/sekwah/advancedportals/core/util/DataStorage.java b/src/com/sekwah/advancedportals/core/util/DataStorage.java new file mode 100644 index 00000000..2ab7434f --- /dev/null +++ b/src/com/sekwah/advancedportals/core/util/DataStorage.java @@ -0,0 +1,97 @@ +package com.sekwah.advancedportals.core.util; + +import com.sekwah.advancedportals.core.AdvancedPortalsCore; + +import java.io.*; + +public abstract class DataStorage { + + protected File dataFolder; + + /** + * Copies the default file, defaults to true to keep true to the name + * + * @param fileLoc + * @return + */ + public boolean copyDefaultFile(String fileLoc) { + return this.copyDefaultFile(fileLoc, true); + } + + public void copyDefaultFiles(boolean override, String... fileLocs) { + for (String fileLoc : fileLocs) { + this.copyDefaultFile(fileLoc, override); + } + } + + /** + * Copies the specified file out of the plugin and into the plugins folder. + * + * @param fileLoc + * @return if the file is copied, will be false if override is false and the file already existed. + */ + public boolean copyDefaultFile(String fileLoc, boolean overwrite) { + File outFile = new File(this.dataFolder, fileLoc); + if (!outFile.exists()) { + outFile.getParentFile().mkdirs(); + } + if (!outFile.exists() || overwrite) { + try { + InputStream inputStream = DataStorage.class.getClassLoader().getResourceAsStream(fileLoc); + FileOutputStream outStream = new FileOutputStream(outFile); + + byte[] buf = new byte[1024]; + int len; + while ((len = inputStream.read(buf)) > 0) { + outStream.write(buf, 0, len); + } + inputStream.close(); + outStream.close(); + } catch (NullPointerException e) { + e.printStackTrace(); + AdvancedPortalsCore.getInfoLogger().logWarning("Could not load " + fileLoc + ". The file does" + + "not exist or there has been an error reading the file."); + return false; + } catch (FileNotFoundException e) { + e.printStackTrace(); + AdvancedPortalsCore.getInfoLogger().logWarning("Could not create " + fileLoc); + } catch (IOException e) { + e.printStackTrace(); + AdvancedPortalsCore.getInfoLogger().logWarning("File error reading " + fileLoc); + } + } + return true; + } + + /** + * A method to try to grab the files from the plugin and if its in the plugin folder load from there instead. + *

+ * TODO add loading from the plugin folder first rather than straight from the plugin. + * + * @param lang + * @param location + * @return + */ + public InputStream loadResource(Lang lang, String location) { + File inFile = new File(dataFolder, location); + if (inFile.exists() && !inFile.isDirectory()) { + try { + return new FileInputStream(inFile); + } catch (FileNotFoundException e) { + e.printStackTrace(); + return null; + } + } else { + try { + copyDefaultFile(location, false); + return lang.getClass().getClassLoader().getResourceAsStream(location); + } catch (NullPointerException e) { + e.printStackTrace(); + AdvancedPortalsCore.getInfoLogger().logWarning("Could not load " + location + ". The file does" + + "not exist or there has been an error reading the file."); + return null; + } + } + } + +} diff --git a/src/com/sekwah/advancedportals/core/util/InfoLogger.java b/src/com/sekwah/advancedportals/core/util/InfoLogger.java new file mode 100644 index 00000000..5289cb7e --- /dev/null +++ b/src/com/sekwah/advancedportals/core/util/InfoLogger.java @@ -0,0 +1,5 @@ +package com.sekwah.advancedportals.core.util; + +public abstract class InfoLogger { + public abstract void logWarning(String s); +} diff --git a/src/com/sekwah/advancedportals/core/util/Lang.java b/src/com/sekwah/advancedportals/core/util/Lang.java new file mode 100644 index 00000000..c480d499 --- /dev/null +++ b/src/com/sekwah/advancedportals/core/util/Lang.java @@ -0,0 +1,113 @@ +package com.sekwah.advancedportals.core.util; + +import com.google.common.collect.Maps; +import com.sekwah.advancedportals.core.AdvancedPortalsCore; + +import java.io.IOException; +import java.io.InputStream; +import java.util.Map; +import java.util.Scanner; + +/** + * @author sekwah41 + *

+ * The language translation file for the game. Will always load english first + * so that if the translations are missing any then they are still readable and can then be translated. + * (Its better than a raw translate string) + *

+ * TODO add a loaddefault where it only loads from the plugins version of the data rather than paying attention to any + * possible changed versions in the lang folder. + */ +public class Lang { + + private static final Lang instance = new Lang(); + private final Map languageMap = Maps.newHashMap(); + private final String DEFAULT_LANG = "en_GB"; + + public Lang() { + injectTranslations(this, DEFAULT_LANG); + } + + public static void loadLanguage(String fileName) { + instance.injectTranslations(instance, fileName); + } + + public static String translate(String s) { + if (instance.languageMap.containsKey(s)) { + return instance.languageMap.get(s); + } else { + return s; + } + } + + public static String translateInsertVariables(String s, String... args) { + String translation = instance.translate(s); + for (int i = 1; i <= args.length; i++) { + translation = translation.replaceAll("%" + i + "$s", args[i]); + } + return translation; + } + + public static String translateInsertVariablesColor(String s, String... args) { + String translation = instance.translateColor(s); + for (int i = 1; i <= args.length; i++) { + translation = translation.replaceAll("%" + i + "$s", args[i]); + } + return translation; + } + + public static String translateColor(String s) { + String translation = instance.translate(s); + translation = translation.replaceAll("\\\\u00A7", "\u00A7"); + return translation; + } + + private void injectTranslations(Lang lang, String fileName) { + try { + //URL url = lang.getClass().getClassLoader().getResource("lang/" + fileName + ".lang"); + //System.out.println(url); + //Map newLangMap = lang.parseLang(url.openStream()); + InputStream stream = AdvancedPortalsCore.getDataStorage().loadResource(lang, "lang/" + fileName + ".lang"); + if (stream != null) { + Map newLangMap = lang.parseLang(stream); + if (newLangMap != null) { + lang.languageMap.putAll(newLangMap); + } + } + } catch (NullPointerException e) { + e.printStackTrace(); + AdvancedPortalsCore.getInfoLogger().logWarning("Could not load " + fileName + ".lang The file does" + + "not exist or there has been an error reading the file. Canceled loading language file."); + } + } + + private Map parseLang(InputStream inputStream) { + Scanner scanner = new Scanner(inputStream, "UTF-8"); + String line = getNextLine(scanner); + Map newMap = Maps.newHashMap(); + while (scanner != null && line != null) { + //System.out.println(line); + if (!line.startsWith("#") && line.indexOf('=') > -1) { + int split = line.indexOf('='); + String key = line.substring(0, split); + String value = line.substring(split + 1, line.length()); + newMap.put(key, value); + } + line = getNextLine(scanner); + // TODO add split code at the first = and also conversion of strings/codes which are constants like colors. + } + try { + inputStream.close(); + } catch (IOException e) { + e.printStackTrace(); + } + return newMap; + } + + private String getNextLine(Scanner scanner) { + if (scanner.hasNextLine()) { + return scanner.nextLine(); + } + return null; + } +} diff --git a/src/main/java/com/sekwah/advancedportals/bukkit/api/events/WarpEvent.java b/src/main/java/com/sekwah/advancedportals/bukkit/api/events/WarpEvent.java index f09164f5..ada9ca33 100644 --- a/src/main/java/com/sekwah/advancedportals/bukkit/api/events/WarpEvent.java +++ b/src/main/java/com/sekwah/advancedportals/bukkit/api/events/WarpEvent.java @@ -6,13 +6,12 @@ import org.bukkit.event.Cancellable; import org.bukkit.event.Event; import org.bukkit.event.HandlerList; -public final class WarpEvent extends Event implements Cancellable { +/** + * Trigered whenever a player activates the warp after the tags are handled. + */ +public class WarpEvent extends Event implements Cancellable { - /** - * Use listeners so you can add new triggers easier and also other plugins can listen for the event - * and add their own triggers - */ - private static final HandlerList handlers = new HandlerList(); + private static HandlerList handlers = new HandlerList(); private boolean cancelled = false; @@ -23,10 +22,10 @@ public final class WarpEvent extends Event implements Cancellable { private boolean hasWarped = false; - public WarpEvent(Player player, AdvancedPortal portalData) { + /*public WarpEvent(Player player, AdvancedPortal portalData) { this.player = player; this.portalData = portalData; - } + }*/ public static HandlerList getHandlerList() { return handlers; @@ -45,9 +44,9 @@ public final class WarpEvent extends Event implements Cancellable { cancelled = cancel; } - public AdvancedPortal getPortalData() { + /*public AdvancedPortal getPortalData() { return portalData; - } + }*/ /** * This will return true if another plugin has warped the player(and set this to true) @@ -63,7 +62,6 @@ public final class WarpEvent extends Event implements Cancellable { * * @param warped */ - @SuppressWarnings("unused") public void setHasWarped(boolean warped) { this.hasWarped = warped; } diff --git a/src/main/java/com/sekwah/advancedportals/bukkit/api/warphandler/ActivationData.java b/src/main/java/com/sekwah/advancedportals/bukkit/api/warphandler/ActivationData.java index 039bb078..9dad3933 100644 --- a/src/main/java/com/sekwah/advancedportals/bukkit/api/warphandler/ActivationData.java +++ b/src/main/java/com/sekwah/advancedportals/bukkit/api/warphandler/ActivationData.java @@ -10,11 +10,11 @@ public class ActivationData { private final Portal activePortal; - public ActivationData(Portal portal){ + /*public ActivationData(Portal portal){ this.activePortal = portal; } - - public WarpedStatus getWarped(){ +*/ + public WarpedStatus getWarped() { return this.warpStatus; } @@ -27,21 +27,22 @@ public class ActivationData { /** * In case you need to set the status back down a step for whatever reason. However it is not recommended. + * * @param warped */ - public void setWarpStatusAbsolute(WarpedStatus warped){ + public void setWarpStatusAbsolute(WarpedStatus warped) { this.warpStatus = warped; } - public boolean getAllowed(){ + public boolean getAllowed() { return this.warpAllowed; } - public void setAllowed(boolean allowed){ + public void setAllowed(boolean allowed) { this.warpAllowed = allowed; } - public enum WarpedStatus{ + public enum WarpedStatus { /** * Player has moved or something major has happened. (only one of these should activate) */ diff --git a/src/main/java/com/sekwah/advancedportals/bukkit/api/warphandler/TagHandler.java b/src/main/java/com/sekwah/advancedportals/bukkit/api/warphandler/TagHandler.java index 28f1b862..c7a04b96 100644 --- a/src/main/java/com/sekwah/advancedportals/bukkit/api/warphandler/TagHandler.java +++ b/src/main/java/com/sekwah/advancedportals/bukkit/api/warphandler/TagHandler.java @@ -4,32 +4,45 @@ import org.bukkit.entity.Player; public class TagHandler { - public interface Creation{ + /** + * When the user wants to activate the tag, not all will support this of course. its just a _ before or after the tag + * to specify + */ + public enum ActivatePref{ + BEFORE, + AFTER, + DEFAULT; + } + + public interface Creation { /** * Example if the player does not have access to use a tag on the portal. - * @param player + * + * @param player if null the portal has been created by the server or a plugin * @param activeData * @param argData * @return if the portal can be created. */ - boolean portalCreated(Player player, ActivationData activeData, String argData); + boolean portalCreated(@Nullable Player player, ActivationData activeData, String argData); /** * Example if the player does not have access to remove the portal. - * @param player + * + * @param player if null the portal has been destroyed by the server or a plugin * @param activeData * @param argData * @return if the portal can be destroyed. */ - boolean portalDestroyed(Player player, ActivationData activeData, String argData); + boolean portalDestroyed(@Nullable Player player, ActivationData activeData, String argData); } - public interface Activation{ + public interface Activation { /** * Activates before the main part of portal activation. + * * @param player * @param activeData * @param argData @@ -38,6 +51,7 @@ public class TagHandler { /** * Activates after portal activation + * * @param player * @param activeData * @param argData @@ -46,6 +60,7 @@ public class TagHandler { /** * Activates if the portal is allowed from pre + * * @param player * @param activeData * @param argData @@ -54,19 +69,21 @@ public class TagHandler { } - public interface TagStatus{ + public interface TagStatus { /** * If the user has access to add the tag + * * @param player * @param activeData * @param argData * @return if the tag will be added. */ - boolean tagAdded(Player player, ActivationData activeData, String argData); + boolean tagAdded(@Nullable Player player, ActivationData activeData, String argData); /** * If the user has access to remove the tag + * * @param player * @param activeData * @param argData