diff --git a/BuildConfigUpdater/BuildConfigUpdater.iml b/BuildConfigUpdater/BuildConfigUpdater.iml index 04dfdc0..c77ce8b 100644 --- a/BuildConfigUpdater/BuildConfigUpdater.iml +++ b/BuildConfigUpdater/BuildConfigUpdater.iml @@ -19,6 +19,11 @@ + + + + + diff --git a/ButtonCore/src/main/java/buttondevteam/core/MainPlugin.java b/ButtonCore/src/main/java/buttondevteam/core/MainPlugin.java index dfb50ba..5fd411e 100755 --- a/ButtonCore/src/main/java/buttondevteam/core/MainPlugin.java +++ b/ButtonCore/src/main/java/buttondevteam/core/MainPlugin.java @@ -101,7 +101,8 @@ public class MainPlugin extends ButtonPlugin { Component.registerComponent(this, new ChannelComponent()); Component.registerComponent(this, new RandomTPComponent()); Component.registerComponent(this, new MemberComponent()); - Component.registerComponent(this, new SpawnComponent()); + if (Bukkit.getPluginManager().isPluginEnabled("Multiverse-Core")) + Component.registerComponent(this, new SpawnComponent()); if (Bukkit.getPluginManager().isPluginEnabled("Towny")) //It fails to load the component class otherwise Component.registerComponent(this, new TownyComponent()); if (Bukkit.getPluginManager().isPluginEnabled("Votifier") && economy != null) diff --git a/ButtonCore/src/main/java/buttondevteam/core/component/members/MemberComponent.java b/ButtonCore/src/main/java/buttondevteam/core/component/members/MemberComponent.java index 5ea098a..735cf40 100644 --- a/ButtonCore/src/main/java/buttondevteam/core/component/members/MemberComponent.java +++ b/ButtonCore/src/main/java/buttondevteam/core/component/members/MemberComponent.java @@ -2,6 +2,7 @@ package buttondevteam.core.component.members; import buttondevteam.core.MainPlugin; import buttondevteam.lib.architecture.Component; +import buttondevteam.lib.architecture.ComponentMetadata; import buttondevteam.lib.architecture.ConfigData; import org.bukkit.Statistic; import org.bukkit.event.EventHandler; @@ -18,6 +19,7 @@ import static buttondevteam.core.MainPlugin.permission; /** * Allows giving a 'member' group over some time elapsed OR played. */ +@ComponentMetadata(enabledByDefault = false) public class MemberComponent extends Component implements Listener { /** * The permission group to give to the player diff --git a/ButtonCore/src/main/java/buttondevteam/core/component/randomtp/RandomTPComponent.java b/ButtonCore/src/main/java/buttondevteam/core/component/randomtp/RandomTPComponent.java index a31bef9..19ef768 100644 --- a/ButtonCore/src/main/java/buttondevteam/core/component/randomtp/RandomTPComponent.java +++ b/ButtonCore/src/main/java/buttondevteam/core/component/randomtp/RandomTPComponent.java @@ -2,12 +2,14 @@ package buttondevteam.core.component.randomtp; import buttondevteam.core.MainPlugin; import buttondevteam.lib.architecture.Component; +import buttondevteam.lib.architecture.ComponentMetadata; /** * Teleport player to random location within world border. * Every five players teleport to the same general area, and then a new general area is randomly selected for the next five players. * Author: github.com/iiegit */ +@ComponentMetadata(enabledByDefault = false) public class RandomTPComponent extends Component { @Override protected void enable() { diff --git a/ButtonCore/src/main/java/buttondevteam/core/component/towny/TownyComponent.java b/ButtonCore/src/main/java/buttondevteam/core/component/towny/TownyComponent.java index 3d8966d..a6fdda4 100644 --- a/ButtonCore/src/main/java/buttondevteam/core/component/towny/TownyComponent.java +++ b/ButtonCore/src/main/java/buttondevteam/core/component/towny/TownyComponent.java @@ -31,7 +31,9 @@ public class TownyComponent extends Component { */ public static void renameInTowny(String oldName, String newName) { if (!ComponentManager.isEnabled(TownyComponent.class)) - return; TownyUniverse tu = Towny.getPlugin(Towny.class).getTownyUniverse(); + return; + Bukkit.getLogger().info("Renaming" + oldName + " in Towny to " + newName); + TownyUniverse tu = Towny.getPlugin(Towny.class).getTownyUniverse(); Resident resident = tu.getResidentMap().get(oldName.toLowerCase()); //The map keys are lowercase if (resident == null) { Bukkit.getLogger().warning("Resident not found - couldn't rename in Towny."); @@ -42,6 +44,7 @@ public class TownyComponent extends Component { } else try { tu.getDataSource().renamePlayer(resident, newName); //Fixed in Towny 0.91.1.2 + Bukkit.getLogger().info("Renaming done."); } catch (AlreadyRegisteredException e) { TBMCCoreAPI.SendException("Failed to rename resident, there's already one with this name.", e); } catch (NotRegisteredException e) { diff --git a/ButtonCore/src/main/java/buttondevteam/core/component/updater/PluginUpdaterComponent.java b/ButtonCore/src/main/java/buttondevteam/core/component/updater/PluginUpdaterComponent.java index 3ea44c8..68a0002 100644 --- a/ButtonCore/src/main/java/buttondevteam/core/component/updater/PluginUpdaterComponent.java +++ b/ButtonCore/src/main/java/buttondevteam/core/component/updater/PluginUpdaterComponent.java @@ -2,11 +2,13 @@ package buttondevteam.core.component.updater; import buttondevteam.core.MainPlugin; import buttondevteam.lib.architecture.Component; +import buttondevteam.lib.architecture.ComponentMetadata; import buttondevteam.lib.chat.TBMCChatAPI; /** * Downloads plugin updates built from their source using JitPack - older code */ +@ComponentMetadata(enabledByDefault = false) public class PluginUpdaterComponent extends Component { //TODO: Config @Override public void enable() { diff --git a/ButtonCore/src/main/java/buttondevteam/core/component/votifier/VotifierComponent.java b/ButtonCore/src/main/java/buttondevteam/core/component/votifier/VotifierComponent.java index 3eff08d..6329e03 100644 --- a/ButtonCore/src/main/java/buttondevteam/core/component/votifier/VotifierComponent.java +++ b/ButtonCore/src/main/java/buttondevteam/core/component/votifier/VotifierComponent.java @@ -2,6 +2,7 @@ package buttondevteam.core.component.votifier; import buttondevteam.core.MainPlugin; import buttondevteam.lib.architecture.Component; +import buttondevteam.lib.architecture.ComponentMetadata; import buttondevteam.lib.architecture.ConfigData; import com.vexsoftware.votifier.model.Vote; import com.vexsoftware.votifier.model.VotifierEvent; @@ -15,6 +16,7 @@ import org.bukkit.event.EventHandler; * Do not use (EULA) */ @RequiredArgsConstructor +@ComponentMetadata(enabledByDefault = false) public class VotifierComponent extends Component { private final Economy economy; diff --git a/ButtonCore/src/main/java/buttondevteam/lib/architecture/Component.java b/ButtonCore/src/main/java/buttondevteam/lib/architecture/Component.java index c4d34d3..08ee576 100644 --- a/ButtonCore/src/main/java/buttondevteam/lib/architecture/Component.java +++ b/ButtonCore/src/main/java/buttondevteam/lib/architecture/Component.java @@ -17,6 +17,7 @@ import org.bukkit.plugin.java.JavaPlugin; import java.util.Collections; import java.util.HashMap; import java.util.Map; +import java.util.Optional; import java.util.function.Consumer; import java.util.stream.Collectors; @@ -38,7 +39,7 @@ public abstract class Component { private @Getter IHaveConfig data; //TODO public final ConfigData shouldBeEnabled() { - return config.getData("enabled", true); + return config.getData("enabled", Optional.ofNullable(getClass().getAnnotation(ComponentMetadata.class)).map(ComponentMetadata::enabledByDefault).orElse(true)); } /** diff --git a/ButtonCore/src/main/java/buttondevteam/lib/architecture/ComponentMetadata.java b/ButtonCore/src/main/java/buttondevteam/lib/architecture/ComponentMetadata.java index a182df8..5d12c91 100644 --- a/ButtonCore/src/main/java/buttondevteam/lib/architecture/ComponentMetadata.java +++ b/ButtonCore/src/main/java/buttondevteam/lib/architecture/ComponentMetadata.java @@ -9,4 +9,6 @@ import java.lang.annotation.Target; @Retention(RetentionPolicy.RUNTIME) public @interface ComponentMetadata { Class[] depends() default {}; + + boolean enabledByDefault() default true; } diff --git a/ButtonCore/src/main/java/buttondevteam/lib/architecture/ConfigData.java b/ButtonCore/src/main/java/buttondevteam/lib/architecture/ConfigData.java index b750d15..2725866 100644 --- a/ButtonCore/src/main/java/buttondevteam/lib/architecture/ConfigData.java +++ b/ButtonCore/src/main/java/buttondevteam/lib/architecture/ConfigData.java @@ -32,7 +32,7 @@ public class ConfigData { @Getter @Setter(AccessLevel.PACKAGE) private String path; - private final T def; + protected final T def; private final Object primitiveDef; private final Runnable saveAction; /** @@ -125,29 +125,17 @@ public class ConfigData { } private void setInternal(Object val) { - /*//if (path.contains("Channel")) { - System.out.println("Setting value: " + val); - System.out.println("For path: " + path); - if(path.contains("tc.enabled")) - new Exception("Why does this get set on a reload?").printStackTrace();*/ config.set(path, val); if (!saveTasks.containsKey(config.getRoot())) { - /*//if (path.contains("Channel")) - System.out.println("No save task found, adding new one");*/ synchronized (saveTasks) { saveTasks.put(config.getRoot(), new SaveTask(Bukkit.getScheduler().runTaskLaterAsynchronously(MainPlugin.Instance, () -> { - /*//if (path.contains("Channel")) - System.out.println("Executing save task...");*/ synchronized (saveTasks) { saveTasks.remove(config.getRoot()); saveAction.run(); } - /*//if (path.contains("Channel")) - System.out.println("Save task done");*/ }, 100), saveAction)); } - } /*else //if (path.contains("Channel")) - The answer is... The chat plugin goes through the chat channels on command preprocess - System.out.println("Found a save task");*/ + } } @AllArgsConstructor diff --git a/ButtonCore/src/main/java/buttondevteam/lib/architecture/IHaveConfig.java b/ButtonCore/src/main/java/buttondevteam/lib/architecture/IHaveConfig.java index 2a73e16..18b8097 100644 --- a/ButtonCore/src/main/java/buttondevteam/lib/architecture/IHaveConfig.java +++ b/ButtonCore/src/main/java/buttondevteam/lib/architecture/IHaveConfig.java @@ -139,6 +139,21 @@ public final class IHaveConfig { return (ConfigData) data; } + /** + * This method overload should only be used with primitves or String. + * + * @param path The path in config to use + * @param The type of this variable (only use primitives or String) + * @return The data object that can be used to get or set the value + */ + @SuppressWarnings("unchecked") + public ListConfigData getListData(String path) { + ConfigData data = datamap.get(path); + if (data == null) + datamap.put(path, data = new ListConfigData<>(config, path, new ListConfigData.List(), saveAction)); + return (ListConfigData) data; + } + /** * Generates the config YAML. * diff --git a/ButtonCore/src/main/java/buttondevteam/lib/architecture/ListConfigData.java b/ButtonCore/src/main/java/buttondevteam/lib/architecture/ListConfigData.java new file mode 100644 index 0000000..4391f7b --- /dev/null +++ b/ButtonCore/src/main/java/buttondevteam/lib/architecture/ListConfigData.java @@ -0,0 +1,115 @@ +package buttondevteam.lib.architecture; + +import lombok.AccessLevel; +import lombok.Setter; +import lombok.val; +import org.bukkit.configuration.ConfigurationSection; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Comparator; +import java.util.function.Predicate; +import java.util.function.UnaryOperator; + +public class ListConfigData extends ConfigData> { + ListConfigData(ConfigurationSection config, String path, List def, Runnable saveAction) { + super(config, path, def, def, saveAction); + def.listConfig = this; //Can't make the List class non-static or pass this in the super() constructor + } + + public static class List extends ArrayList { + @Setter(AccessLevel.PACKAGE) + ListConfigData listConfig; + + private void update() { + listConfig.set(this); //Update the config model and start save task if needed + } + + @Override + public T set(int index, T element) { + T ret = super.set(index, element); + update(); + return ret; + } + + @Override + public boolean add(T t) { + val ret = super.add(t); + update(); + return ret; + } + + @Override + public void add(int index, T element) { + super.add(index, element); + update(); + } + + @Override + public T remove(int index) { + T ret = super.remove(index); + update(); + return ret; + } + + @Override + public boolean remove(Object o) { + val ret = super.remove(o); + update(); + return ret; + } + + @Override + public boolean addAll(Collection c) { + val ret = super.addAll(c); + update(); + return ret; + } + + @Override + public boolean addAll(int index, Collection c) { + val ret = super.addAll(index, c); + update(); + return ret; + } + + @Override + protected void removeRange(int fromIndex, int toIndex) { + super.removeRange(fromIndex, toIndex); + update(); + } + + @Override + public boolean removeAll(Collection c) { + val ret = super.removeAll(c); + update(); + return ret; + } + + @Override + public boolean retainAll(Collection c) { + val ret = super.retainAll(c); + update(); + return ret; + } + + @Override + public boolean removeIf(Predicate filter) { + val ret = super.removeIf(filter); + update(); + return ret; + } + + @Override + public void replaceAll(UnaryOperator operator) { + super.replaceAll(operator); + update(); + } + + @Override + public void sort(Comparator c) { + super.sort(c); + update(); + } + } +} diff --git a/ButtonCore/src/main/java/buttondevteam/lib/player/TBMCPlayerBase.java b/ButtonCore/src/main/java/buttondevteam/lib/player/TBMCPlayerBase.java index 0093c4e..f6caff0 100755 --- a/ButtonCore/src/main/java/buttondevteam/lib/player/TBMCPlayerBase.java +++ b/ButtonCore/src/main/java/buttondevteam/lib/player/TBMCPlayerBase.java @@ -36,7 +36,7 @@ public abstract class TBMCPlayerBase extends ChromaGamerBase { /** * Use from a method with the name of the key. For example, use flair() for the enclosing method to save to and load from "flair" - * + * * @return A data object with methods to get and set */ @Override @@ -46,7 +46,7 @@ public abstract class TBMCPlayerBase extends ChromaGamerBase { /** * Use from a method with the name of the key. For example, use flair() for the enclosing method to save to and load from "flair" - * + * * @return A data object with methods to get and set */ @Override @@ -56,11 +56,9 @@ public abstract class TBMCPlayerBase extends ChromaGamerBase { /** * Get player as a plugin player - * - * @param uuid - * The UUID of the player to get - * @param cl - * The type of the player + * + * @param uuid The UUID of the player to get + * @param cl The type of the player * @return The requested player object */ @SuppressWarnings("unchecked") @@ -79,7 +77,7 @@ public abstract class TBMCPlayerBase extends ChromaGamerBase { return player; } catch (Exception e) { TBMCCoreAPI.SendException( - "Failed to get player with UUID " + uuid + " and class " + cl.getSimpleName() + "!", e); + "Failed to get player with UUID " + uuid + " and class " + cl.getSimpleName() + "!", e); return null; } } @@ -92,9 +90,8 @@ public abstract class TBMCPlayerBase extends ChromaGamerBase { /** * Gets the TBMCPlayer object as a specific plugin player, keeping it's data
* Make sure to use try-with-resources with this to save the data, as it may need to load the file - * - * @param cl - * The TBMCPlayer subclass + * + * @param cl The TBMCPlayer subclass */ public T asPluginPlayer(Class cl) { return getPlayer(uuid, cl); @@ -122,10 +119,9 @@ public abstract class TBMCPlayerBase extends ChromaGamerBase { player.PlayerName().set(p.getName()); Bukkit.getLogger().info("Player name saved: " + player.PlayerName().get()); } else if (!p.getName().equals(player.PlayerName().get())) { - Bukkit.getLogger().info("Renaming " + player.PlayerName().get() + " to " + p.getName()); TownyComponent.renameInTowny(player.PlayerName().get(), p.getName()); player.PlayerName().set(p.getName()); - Bukkit.getLogger().info("Renaming done."); + Bukkit.getLogger().info("Renamed to " + p.getName()); } playermap.put(p.getUniqueId() + "-" + TBMCPlayer.class.getSimpleName(), player); @@ -142,16 +138,16 @@ public abstract class TBMCPlayerBase extends ChromaGamerBase { final TBMCPlayerBase player = playermap.get(p.getUniqueId() + "-" + TBMCPlayer.class.getSimpleName()); player.save(); Bukkit.getServer().getPluginManager().callEvent(new TBMCPlayerQuitEvent(player, p)); - playermap.entrySet().removeIf(entry -> entry.getKey().startsWith(p.getUniqueId().toString())); + playermap.entrySet().removeIf(entry -> entry.getKey().startsWith(p.getUniqueId().toString())); } public static void savePlayers() { - playermap.values().forEach(p -> { + playermap.values().forEach(p -> { try { p.close(); } catch (Exception e) { TBMCCoreAPI.SendException("Error while saving player " + p.PlayerName().get() + " (" + p.getFolder() - + "/" + p.getFileName() + ")!", e); + + "/" + p.getFileName() + ")!", e); } }); } @@ -159,7 +155,7 @@ public abstract class TBMCPlayerBase extends ChromaGamerBase { /** * This method returns a TBMC player from their name. Calling this method may return an offline player which will load it, therefore it's highly recommended to use {@link #close()} to unload the * player data. Using try-with-resources may be the easiest way to achieve this. Example: - * + * *
 	 * {@code
 	 * try(TBMCPlayer player = getFromName(p))
@@ -167,9 +163,8 @@ public abstract class TBMCPlayerBase extends ChromaGamerBase {
 	 * 	...
 	 * }
 	 * 
- * - * @param name - * The player's name + * + * @param name The player's name * @return The {@link TBMCPlayer} object for the player */ public static T getFromName(String name, Class cl) {