diff --git a/ButtonCore/.gitignore b/.gitignore
similarity index 99%
rename from ButtonCore/.gitignore
rename to .gitignore
index 86472d4..8983379 100755
--- a/ButtonCore/.gitignore
+++ b/.gitignore
@@ -218,7 +218,7 @@ pip-log.txt
.mr.developer.cfg
.metadata/*
TheButtonAutoFlair/out/artifacts/Autoflair/Autoflair.jar
-*.iml
+#*.iml
*.name
.idea/compiler.xml
*.xml
diff --git a/.idea/libraries/Maven__org_spigotmc_spigot_api_1_12_2_R0_1_SNAPSHOT.xml b/.idea/libraries/Maven__org_spigotmc_spigot_api_1_12_2_R0_1_SNAPSHOT.xml
index b6f88ae..42f0d6f 100644
--- a/.idea/libraries/Maven__org_spigotmc_spigot_api_1_12_2_R0_1_SNAPSHOT.xml
+++ b/.idea/libraries/Maven__org_spigotmc_spigot_api_1_12_2_R0_1_SNAPSHOT.xml
@@ -1,13 +1,13 @@
-
+
-
+
-
+
\ No newline at end of file
diff --git a/BuildConfigUpdater/BuildConfigUpdater.iml b/BuildConfigUpdater/BuildConfigUpdater.iml
index f14440c..274b3de 100644
--- a/BuildConfigUpdater/BuildConfigUpdater.iml
+++ b/BuildConfigUpdater/BuildConfigUpdater.iml
@@ -12,7 +12,6 @@
-
diff --git a/ButtonCore/ButtonCore (1) (com.github.TBMCPlugins.ButtonCore).iml b/ButtonCore/ButtonCore (1) (com.github.TBMCPlugins.ButtonCore).iml
new file mode 100644
index 0000000..7c2fa83
--- /dev/null
+++ b/ButtonCore/ButtonCore (1) (com.github.TBMCPlugins.ButtonCore).iml
@@ -0,0 +1,38 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/ButtonCore/pom.xml b/ButtonCore/pom.xml
index e044b9a..ed35499 100755
--- a/ButtonCore/pom.xml
+++ b/ButtonCore/pom.xml
@@ -75,6 +75,7 @@
org.apache.maven.plugins
maven-surefire-plugin
+ 3.0.0-M3
false
@@ -83,6 +84,7 @@
org.apache.maven.plugins
maven-source-plugin
+ 3.0.1
attach-sources
@@ -103,14 +105,18 @@
jitpack.io
https://jitpack.io/
-
- vault-repo
- http://nexus.hc.to/content/repositories/pub_releases
-
+
ess-repo
http://repo.ess3.net/content/repositories/essrel/
+
+ Votifier
+ https://dl.bintray.com/nuvotifier/maven/
+
@@ -175,6 +181,12 @@
2.13.1
provided
+
+ com.vexsoftware
+ nuvotifier-universal
+ 2.3.4
+ provided
+
TBMCPlugins
diff --git a/ButtonCore/src/main/java/buttondevteam/core/ComponentCommand.java b/ButtonCore/src/main/java/buttondevteam/core/ComponentCommand.java
index 4aaceac..10b4b16 100644
--- a/ButtonCore/src/main/java/buttondevteam/core/ComponentCommand.java
+++ b/ButtonCore/src/main/java/buttondevteam/core/ComponentCommand.java
@@ -1,9 +1,12 @@
package buttondevteam.core;
import buttondevteam.lib.TBMCCoreAPI;
+import buttondevteam.lib.architecture.ButtonPlugin;
import buttondevteam.lib.architecture.Component;
-import buttondevteam.lib.chat.Command2MC;
+import buttondevteam.lib.chat.Command2;
+import buttondevteam.lib.chat.Command2.Subcommand;
import buttondevteam.lib.chat.CommandClass;
+import buttondevteam.lib.chat.ICommand2MC;
import lombok.val;
import org.bukkit.Bukkit;
import org.bukkit.command.CommandSender;
@@ -12,30 +15,30 @@ import org.bukkit.plugin.Plugin;
import java.util.Optional;
@CommandClass(modOnly = true, helpText = {
- "§6---- Component command ----",
+ "Component command",
"Can be used to enable/disable/list components"
})
-public class ComponentCommand extends Command2MC {
+public class ComponentCommand extends ICommand2MC {
public ComponentCommand() {
- addParamConverter(Plugin.class, arg -> Bukkit.getPluginManager().getPlugin(arg));
-
+ getManager().addParamConverter(Plugin.class, arg -> Bukkit.getPluginManager().getPlugin(arg), "Plugin not found!");
}
@Subcommand
public boolean enable(CommandSender sender, Plugin plugin, String component) {
- if (plugin == null) return respond(sender, "§cPlugin not found!");
- plugin.reloadConfig(); //Reload config so the new config values are read - All changes are saved to disk on disable
+ if (plugin instanceof ButtonPlugin)
+ ((ButtonPlugin) plugin).justReload();
+ else
+ plugin.reloadConfig(); //Reload config so the new config values are read - All changes are saved to disk on disable
return enable_disable(sender, plugin, component, true);
}
@Subcommand
public boolean disable(CommandSender sender, Plugin plugin, String component) {
- if (plugin == null) return respond(sender, "§cPlugin not found!");
return enable_disable(sender, plugin, component, false);
}
@Subcommand
- public boolean list(CommandSender sender, String plugin) {
+ public boolean list(CommandSender sender, @Command2.OptionalArg String plugin) {
sender.sendMessage("§6List of components:");
Component.getComponents().values().stream().filter(c -> plugin == null || c.getPlugin().getName().equalsIgnoreCase(plugin)) //If plugin is null, don't check
.map(c -> c.getPlugin().getName() + " - " + c.getClass().getSimpleName() + " - " + (c.isEnabled() ? "en" : "dis") + "abled").forEach(sender::sendMessage);
@@ -55,7 +58,7 @@ public class ComponentCommand extends Command2MC {
return true;
}
- private Optional getComponentOrError(Plugin plugin, String arg, CommandSender sender) {
+ private Optional> getComponentOrError(Plugin plugin, String arg, CommandSender sender) {
val oc = Component.getComponents().values().stream()
.filter(c -> plugin.getName().equals(c.getPlugin().getName()))
.filter(c -> c.getClass().getSimpleName().equalsIgnoreCase(arg)).findAny();
diff --git a/ButtonCore/src/main/java/buttondevteam/core/ComponentManager.java b/ButtonCore/src/main/java/buttondevteam/core/ComponentManager.java
index 9a84ddd..db9c2e3 100644
--- a/ButtonCore/src/main/java/buttondevteam/core/ComponentManager.java
+++ b/ButtonCore/src/main/java/buttondevteam/core/ComponentManager.java
@@ -34,9 +34,10 @@ public final class ComponentManager {
/**
* Unregister all components of a plugin that are enabled - called on {@link ButtonPlugin} disable
*/
- public static void unregComponents(ButtonPlugin plugin) {
+ @SuppressWarnings("unchecked")
+ public static void unregComponents(T plugin) {
while (!plugin.getComponentStack().empty()) //Unregister in reverse order
- Component.unregisterComponent(plugin, plugin.getComponentStack().pop()); //Components are pushed on register
+ Component.unregisterComponent(plugin, (Component) plugin.getComponentStack().pop()); //Components are pushed on register
componentsEnabled = false;
}
diff --git a/ButtonCore/src/main/java/buttondevteam/core/MainPlugin.java b/ButtonCore/src/main/java/buttondevteam/core/MainPlugin.java
index b2200a4..e810c67 100755
--- a/ButtonCore/src/main/java/buttondevteam/core/MainPlugin.java
+++ b/ButtonCore/src/main/java/buttondevteam/core/MainPlugin.java
@@ -9,17 +9,20 @@ import buttondevteam.core.component.restart.RestartComponent;
import buttondevteam.core.component.towny.TownyComponent;
import buttondevteam.core.component.updater.PluginUpdater;
import buttondevteam.core.component.updater.PluginUpdaterComponent;
+import buttondevteam.core.component.votifier.VotifierComponent;
import buttondevteam.lib.TBMCCoreAPI;
import buttondevteam.lib.architecture.ButtonPlugin;
import buttondevteam.lib.architecture.Component;
import buttondevteam.lib.architecture.ConfigData;
import buttondevteam.lib.chat.Color;
-import buttondevteam.lib.chat.Command2MC;
import buttondevteam.lib.chat.TBMCChatAPI;
import buttondevteam.lib.player.ChromaGamerBase;
import buttondevteam.lib.player.TBMCPlayer;
import buttondevteam.lib.player.TBMCPlayerBase;
import com.earth2me.essentials.Essentials;
+import lombok.Getter;
+import lombok.Setter;
+import net.milkbowl.vault.economy.Economy;
import net.milkbowl.vault.permission.Permission;
import org.bukkit.Bukkit;
import org.bukkit.command.BlockCommandSender;
@@ -42,41 +45,62 @@ import java.util.logging.Logger;
public class MainPlugin extends ButtonPlugin {
public static MainPlugin Instance;
- @Nullable
public static Permission permission;
public static boolean Test;
public static Essentials ess;
private Logger logger;
+ @Nullable
+ private Economy economy;
+ /**
+ * Whether the Core's chat handler should be enabled.
+ * Other chat plugins handling messages from other platforms should set this to false.
+ */
+ @Getter
+ @Setter
+ private boolean chatHandlerEnabled = true;
private ConfigData writePluginList() {
return getIConfig().getData("writePluginList", false);
}
+ ConfigData chatFormat() {
+ return getIConfig().getData("chatFormat", "[{origin}|" +
+ "{channel}] <{name}> {message}");
+ }
+
@Override
public void pluginEnable() {
// Logs "Plugin Enabled", registers commands
Instance = this;
PluginDescriptionFile pdf = getDescription();
logger = getLogger();
- setupPermissions();
+ if (!setupPermissions())
+ throw new NullPointerException("No permission plugin found!");
+ if (!setupEconomy()) //Though Essentials always provides economy so this shouldn't happen
+ getLogger().warning("No economy plugin found! Components using economy will not be registered.");
Test = getConfig().getBoolean("test", true);
saveConfig();
Component.registerComponent(this, new PluginUpdaterComponent());
Component.registerComponent(this, new RestartComponent());
+ //noinspection unchecked - needed for testing
Component.registerComponent(this, new ChannelComponent());
Component.registerComponent(this, new RandomTPComponent());
Component.registerComponent(this, new MemberComponent());
- Component.registerComponent(this, new TownyComponent());
+ 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)
+ Component.registerComponent(this, new VotifierComponent(economy));
ComponentManager.enableComponents();
- Command2MC.registerCommand(new ComponentCommand());
+ getCommand2MC().registerCommand(new ComponentCommand());
+ getCommand2MC().registerCommand(new ThorpeCommand());
TBMCCoreAPI.RegisterEventsForExceptions(new PlayerListener(), this);
ChromaGamerBase.addConverter(commandSender -> Optional.ofNullable(commandSender instanceof ConsoleCommandSender || commandSender instanceof BlockCommandSender
? TBMCPlayer.getPlayer(new UUID(0, 0), TBMCPlayer.class) : null)); //Console & cmdblocks
ChromaGamerBase.addConverter(sender -> Optional.ofNullable(sender instanceof Player
? TBMCPlayer.getPlayer(((Player) sender).getUniqueId(), TBMCPlayer.class) : null)); //Players, has higher priority
TBMCCoreAPI.RegisterUserClass(TBMCPlayerBase.class);
- TBMCChatAPI.RegisterChatChannel(Channel.GlobalChat = new Channel("§fOOC§f", Color.White, "g", null)); //The /ooc ID has moved to the config
+ TBMCChatAPI.RegisterChatChannel(Channel.GlobalChat = new Channel("§fg§f", Color.White, "g", null)); //The /ooc ID has moved to the config
TBMCChatAPI.RegisterChatChannel(
Channel.AdminChat = new Channel("§cADMIN§f", Color.Red, "a", Channel.inGroupFilter(null)));
TBMCChatAPI.RegisterChatChannel(
@@ -122,14 +146,23 @@ public class MainPlugin extends ButtonPlugin {
}
private boolean setupPermissions() {
- RegisteredServiceProvider permissionProvider = getServer().getServicesManager()
- .getRegistration(Permission.class);
- if (permissionProvider != null) {
- permission = permissionProvider.getProvider();
- }
+ permission = setupProvider(Permission.class);
return (permission != null);
}
+ private boolean setupEconomy() {
+ economy = setupProvider(Economy.class);
+ return (economy != null);
+ }
+
+ private T setupProvider(Class cl) {
+ RegisteredServiceProvider provider = getServer().getServicesManager()
+ .getRegistration(cl);
+ if (provider != null)
+ return provider.getProvider();
+ return null;
+ }
+
@Override
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
if (command.getName().equals("dontrunthiscmd")) return true; //Used in chat preprocess for console
diff --git a/ButtonCore/src/main/java/buttondevteam/core/PlayerListener.java b/ButtonCore/src/main/java/buttondevteam/core/PlayerListener.java
index c5146cd..097b90a 100755
--- a/ButtonCore/src/main/java/buttondevteam/core/PlayerListener.java
+++ b/ButtonCore/src/main/java/buttondevteam/core/PlayerListener.java
@@ -1,17 +1,21 @@
package buttondevteam.core;
-import buttondevteam.lib.TBMCCommandPreprocessEvent;
-import buttondevteam.lib.TBMCCoreAPI;
-import buttondevteam.lib.TBMCSystemChatEvent;
-import buttondevteam.lib.chat.Command2MC;
+import buttondevteam.lib.*;
+import buttondevteam.lib.architecture.ButtonPlugin;
+import buttondevteam.lib.chat.ChatMessage;
+import buttondevteam.lib.chat.Command2MCSender;
+import buttondevteam.lib.chat.TBMCChatAPI;
+import buttondevteam.lib.player.TBMCPlayer;
import buttondevteam.lib.player.TBMCPlayerBase;
import lombok.val;
import org.bukkit.Bukkit;
import org.bukkit.command.CommandSender;
+import org.bukkit.entity.Player;
import org.bukkit.event.Cancellable;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
+import org.bukkit.event.player.AsyncPlayerChatEvent;
import org.bukkit.event.player.PlayerCommandPreprocessEvent;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.event.player.PlayerQuitEvent;
@@ -64,9 +68,36 @@ public class PlayerListener implements Listener {
public void onTBMCPreprocess(TBMCCommandPreprocessEvent event) {
if (event.isCancelled()) return;
try {
- event.setCancelled(Command2MC.handleCommand(event.getSender(), event.getMessage()));
+ event.setCancelled(ButtonPlugin.getCommand2MC().handleCommand(new Command2MCSender(event.getSender()), event.getMessage()));
} catch (Exception e) {
TBMCCoreAPI.SendException("Command processing failed for sender '" + event.getSender() + "' and message '" + event.getMessage() + "'", e);
}
}
+
+ @EventHandler(priority = EventPriority.HIGH) //The one in the chat plugin is set to highest
+ public void onPlayerChat(AsyncPlayerChatEvent event) {
+ if (event.isCancelled())
+ return; //The chat plugin should cancel it after this handler
+ val cp = TBMCPlayer.getPlayer(event.getPlayer().getUniqueId(), TBMCPlayer.class);
+ TBMCChatAPI.SendChatMessage(ChatMessage.builder(event.getPlayer(), cp, event.getMessage()).build());
+ //Not cancelling the original event here, it's cancelled in the chat plugin
+ //This way other plugins can deal with the MC formatting if the chat plugin isn't present, but other platforms still get the message
+ }
+
+ @EventHandler(priority = EventPriority.HIGH) //The one in the chat plugin is set to highest
+ public void onPlayerChat(TBMCChatEvent event) {
+ if (event.isCancelled())
+ return;
+ if (!MainPlugin.Instance.isChatHandlerEnabled()) return;
+ if (event.getOrigin().equals("Minecraft")) return; //Let other plugins handle MC messages
+ String msg = MainPlugin.Instance.chatFormat().get()
+ .replace("{channel}", event.getChannel().DisplayName().get())
+ .replace("{origin}", event.getOrigin().substring(0, 1))
+ .replace("{name}", ThorpeUtils.getDisplayName(event.getSender()))
+ .replace("{message}", event.getMessage());
+ for (Player player : Bukkit.getOnlinePlayers())
+ if (event.shouldSendTo(player))
+ player.sendMessage(msg);
+ Bukkit.getConsoleSender().sendMessage(msg);
+ }
}
\ No newline at end of file
diff --git a/ButtonCore/src/main/java/buttondevteam/core/TestPrepare.java b/ButtonCore/src/main/java/buttondevteam/core/TestPrepare.java
index 67b0a33..13513b4 100755
--- a/ButtonCore/src/main/java/buttondevteam/core/TestPrepare.java
+++ b/ButtonCore/src/main/java/buttondevteam/core/TestPrepare.java
@@ -41,6 +41,7 @@ public class TestPrepare {
return cl.isAssignableFrom(invocation.getMethod().getReturnType());
}
}));
+ //noinspection unchecked
Component.registerComponent(Mockito.mock(JavaPlugin.class), new ChannelComponent());
TBMCChatAPI.RegisterChatChannel(Channel.GlobalChat = new Channel("§fg§f", Color.White, "g", null));
}
diff --git a/ButtonCore/src/main/java/buttondevteam/core/ThorpeCommand.java b/ButtonCore/src/main/java/buttondevteam/core/ThorpeCommand.java
new file mode 100644
index 0000000..91f2d5c
--- /dev/null
+++ b/ButtonCore/src/main/java/buttondevteam/core/ThorpeCommand.java
@@ -0,0 +1,17 @@
+package buttondevteam.core;
+
+import buttondevteam.lib.chat.Command2;
+import buttondevteam.lib.chat.CommandClass;
+import buttondevteam.lib.chat.ICommand2MC;
+import org.bukkit.command.CommandSender;
+
+@CommandClass
+public class ThorpeCommand extends ICommand2MC {
+ @Command2.Subcommand //TODO: Main permissions (groups) like 'mod'
+ public void reload(CommandSender sender) {
+ if (MainPlugin.Instance.tryReloadConfig())
+ sender.sendMessage("§bConfig reloaded.");
+ else
+ sender.sendMessage("§cFailed to reload config. Check console.");
+ }
+}
diff --git a/ButtonCore/src/main/java/buttondevteam/core/component/channel/ChannelComponent.java b/ButtonCore/src/main/java/buttondevteam/core/component/channel/ChannelComponent.java
index 083633d..5e19ea0 100644
--- a/ButtonCore/src/main/java/buttondevteam/core/component/channel/ChannelComponent.java
+++ b/ButtonCore/src/main/java/buttondevteam/core/component/channel/ChannelComponent.java
@@ -1,22 +1,30 @@
package buttondevteam.core.component.channel;
+import buttondevteam.lib.TBMCSystemChatEvent;
import buttondevteam.lib.architecture.Component;
import org.bukkit.plugin.java.JavaPlugin;
+/**
+ * Manages chat channels. If disabled, only global channels will be registered.
+ */
public class ChannelComponent extends Component {
+ static TBMCSystemChatEvent.BroadcastTarget roomJoinLeave;
+
@Override
protected void register(JavaPlugin plugin) {
super.register(plugin);
+ roomJoinLeave = TBMCSystemChatEvent.BroadcastTarget.add("roomJoinLeave"); //Even if it's disabled, global channels continue to work
}
@Override
protected void unregister(JavaPlugin plugin) {
super.unregister(plugin);
+ TBMCSystemChatEvent.BroadcastTarget.remove(roomJoinLeave);
+ roomJoinLeave = null;
}
@Override
protected void enable() {
-
}
@Override
diff --git a/ButtonCore/src/main/java/buttondevteam/core/component/channel/ChatRoom.java b/ButtonCore/src/main/java/buttondevteam/core/component/channel/ChatRoom.java
index a086a42..428007a 100755
--- a/ButtonCore/src/main/java/buttondevteam/core/component/channel/ChatRoom.java
+++ b/ButtonCore/src/main/java/buttondevteam/core/component/channel/ChatRoom.java
@@ -1,5 +1,6 @@
package buttondevteam.core.component.channel;
+import buttondevteam.lib.TBMCSystemChatEvent;
import buttondevteam.lib.chat.Color;
import buttondevteam.lib.chat.TBMCChatAPI;
import org.bukkit.command.CommandSender;
@@ -17,11 +18,11 @@ public class ChatRoom extends Channel {
public void joinRoom(CommandSender sender) {
usersInRoom.add(sender);
- TBMCChatAPI.SendSystemMessage(this, RecipientTestResult.ALL, sender.getName() + " joined the room");
+ TBMCChatAPI.SendSystemMessage(this, RecipientTestResult.ALL, sender.getName() + " joined the room", TBMCSystemChatEvent.BroadcastTarget.ALL); //Always show message in the same kind of channel
}
public void leaveRoom(CommandSender sender) {
usersInRoom.remove(sender);
- TBMCChatAPI.SendSystemMessage(this, RecipientTestResult.ALL, sender.getName() + " left the room");
+ TBMCChatAPI.SendSystemMessage(this, RecipientTestResult.ALL, sender.getName() + " left the room", ChannelComponent.roomJoinLeave);
}
}
diff --git a/ButtonCore/src/main/java/buttondevteam/core/component/members/MemberCommand.java b/ButtonCore/src/main/java/buttondevteam/core/component/members/MemberCommand.java
index d395d99..1059b26 100644
--- a/ButtonCore/src/main/java/buttondevteam/core/component/members/MemberCommand.java
+++ b/ButtonCore/src/main/java/buttondevteam/core/component/members/MemberCommand.java
@@ -1,56 +1,47 @@
package buttondevteam.core.component.members;
import buttondevteam.core.MainPlugin;
+import buttondevteam.lib.chat.Command2;
import buttondevteam.lib.chat.CommandClass;
-import buttondevteam.lib.chat.TBMCCommandBase;
-import lombok.val;
+import buttondevteam.lib.chat.ICommand2MC;
import org.bukkit.Bukkit;
+import org.bukkit.OfflinePlayer;
import org.bukkit.command.CommandSender;
-@CommandClass(modOnly = true, path = "member")
-public class MemberCommand extends TBMCCommandBase {
- @Override
- public boolean OnCommand(CommandSender sender, String alias, String[] args) {
- if (args.length < 2)
- return false;
- final boolean add;
- if (args[0].equalsIgnoreCase("add"))
- add = true;
- else if (args[0].equalsIgnoreCase("remove"))
- add = false;
- else
- return false;
+@CommandClass(modOnly = true, path = "member", helpText = { //
+ "Member command", //
+ "Add or remove server members.", //
+})
+public class MemberCommand extends ICommand2MC {
+ private final MemberComponent component;
+
+ public MemberCommand(MemberComponent component) {
+ getManager().addParamConverter(OfflinePlayer.class, Bukkit::getOfflinePlayer, "Player not found!");
+ this.component = component;
+ }
+
+ @Command2.Subcommand
+ public boolean add(CommandSender sender, OfflinePlayer player) {
+ return addRemove(sender, player, true);
+ }
+
+ @Command2.Subcommand
+ public boolean remove(CommandSender sender, OfflinePlayer player) {
+ return addRemove(sender, player, false);
+ }
+
+ public boolean addRemove(CommandSender sender, OfflinePlayer op, boolean add) {
Bukkit.getScheduler().runTaskAsynchronously(MainPlugin.Instance, () -> {
- if (MainPlugin.permission == null) {
- sender.sendMessage("§cError: No permission plugin found!");
- return;
- }
- val op = Bukkit.getOfflinePlayer(args[1]);
if (!op.hasPlayedBefore()) {
sender.sendMessage("§cCannot find player or haven't played before.");
return;
}
- if (add) {
- if (MainPlugin.permission.playerAddGroup(null, op, "member"))
- sender.sendMessage("§b" + op.getName() + " added as a member!");
- else
- sender.sendMessage("§cFailed to add " + op.getName() + " as a member!");
- } else {
- if (MainPlugin.permission.playerRemoveGroup(null, op, "member"))
- sender.sendMessage("§b" + op.getName() + " removed as a member!");
- else
- sender.sendMessage("§bFailed to remove " + op.getName() + " as a member!");
- }
+ if (add ? MainPlugin.permission.playerAddGroup(null, op, component.memberGroup().get())
+ : MainPlugin.permission.playerRemoveGroup(null, op, component.memberGroup().get()))
+ sender.sendMessage("§b" + op.getName() + " " + (add ? "added" : "removed") + " as a member!");
+ else
+ sender.sendMessage("§cFailed to " + (add ? "add" : "remove") + " " + op.getName() + " as a member!");
});
return true;
}
-
- @Override
- public String[] GetHelpText(String alias) {
- return new String[]{ //
- "06---- Member ----", //
- "Add or remove server members.", //
- "Usage: /member " //
- };
- }
}
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 0caeca7..b5bab6e 100644
--- a/ButtonCore/src/main/java/buttondevteam/core/component/members/MemberComponent.java
+++ b/ButtonCore/src/main/java/buttondevteam/core/component/members/MemberComponent.java
@@ -14,15 +14,35 @@ import java.util.Date;
import static buttondevteam.core.MainPlugin.permission;
-public class MemberComponent extends Component implements Listener {
- private ConfigData memberGroup() {
+/**
+ * Allows giving a 'member' group over some time elapsed OR played.
+ */
+public class MemberComponent extends Component implements Listener {
+ /**
+ * The permission group to give to the player
+ */
+ ConfigData memberGroup() {
return getConfig().getData("memberGroup", "member");
}
+ /**
+ * The amount of hours needed to play before promotion
+ */
+ private ConfigData playedHours() {
+ return getConfig().getData("playedHours", 12);
+ }
+
+ /**
+ * The amount of days passed since first login
+ */
+ private ConfigData registeredForDays() {
+ return getConfig().getData("registeredForDays", 7);
+ }
+
@Override
protected void enable() {
registerListener(this);
- registerCommand(new MemberCommand());
+ registerCommand(new MemberCommand(this));
}
@Override
@@ -32,8 +52,8 @@ public class MemberComponent extends Component implements Listener {
@EventHandler
public void onPlayerJoin(PlayerJoinEvent event) {
if (permission != null && !permission.playerInGroup(event.getPlayer(), memberGroup().get())
- && (new Date(event.getPlayer().getFirstPlayed()).toInstant().plus(7, ChronoUnit.DAYS).isBefore(Instant.now())
- || event.getPlayer().getStatistic(Statistic.PLAY_ONE_TICK) > 20 * 3600 * 12)) {
+ && (new Date(event.getPlayer().getFirstPlayed()).toInstant().plus(registeredForDays().get(), ChronoUnit.DAYS).isBefore(Instant.now())
+ || event.getPlayer().getStatistic(Statistic.PLAY_ONE_TICK) > 20 * 3600 * playedHours().get())) {
permission.playerAddGroup(null, event.getPlayer(), memberGroup().get());
event.getPlayer().sendMessage("§bYou are a member now. YEEHAW");
MainPlugin.Instance.getLogger().info("Added " + event.getPlayer().getName() + " as a member.");
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 e324b3a..0f1fb5e 100644
--- a/ButtonCore/src/main/java/buttondevteam/core/component/randomtp/RandomTPComponent.java
+++ b/ButtonCore/src/main/java/buttondevteam/core/component/randomtp/RandomTPComponent.java
@@ -1,8 +1,13 @@
package buttondevteam.core.component.randomtp;
+import buttondevteam.core.MainPlugin;
import buttondevteam.lib.architecture.Component;
-public class RandomTPComponent extends Component {
+/**
+ * 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.
+ */
+public class RandomTPComponent extends Component {
@Override
protected void enable() {
new RandomTP().onEnable(this); //It registers it's command
diff --git a/ButtonCore/src/main/java/buttondevteam/core/component/restart/PrimeRestartCommand.java b/ButtonCore/src/main/java/buttondevteam/core/component/restart/PrimeRestartCommand.java
index 32773ab..389da82 100644
--- a/ButtonCore/src/main/java/buttondevteam/core/component/restart/PrimeRestartCommand.java
+++ b/ButtonCore/src/main/java/buttondevteam/core/component/restart/PrimeRestartCommand.java
@@ -1,26 +1,31 @@
package buttondevteam.core.component.restart;
+import buttondevteam.core.component.channel.Channel;
import buttondevteam.lib.chat.CommandClass;
+import buttondevteam.lib.chat.TBMCChatAPI;
import buttondevteam.lib.chat.TBMCCommandBase;
import lombok.Getter;
+import lombok.RequiredArgsConstructor;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.command.CommandSender;
@CommandClass(path = "primerestart", modOnly = true)
+@RequiredArgsConstructor
public class PrimeRestartCommand extends TBMCCommandBase {
+ private final RestartComponent component;
@Override
public boolean OnCommand(CommandSender sender, String alias, String[] args) {
loud = args.length > 0;
if (Bukkit.getOnlinePlayers().size() > 0) {
sender.sendMessage("§bPlayers online, restart delayed.");
if (loud)
- Bukkit.broadcastMessage(ChatColor.DARK_RED + "The server will restart as soon as nobody is online.");
+ TBMCChatAPI.SendSystemMessage(Channel.GlobalChat, Channel.RecipientTestResult.ALL, ChatColor.DARK_RED + "The server will restart as soon as nobody is online.", component.getRestartBroadcast());
plsrestart = true;
} else {
sender.sendMessage("§bNobody is online. Restarting now.");
if (loud)
- Bukkit.broadcastMessage("§cNobody is online. Restarting server.");
+ TBMCChatAPI.SendSystemMessage(Channel.GlobalChat, Channel.RecipientTestResult.ALL, "§cNobody is online. Restarting server.", component.getRestartBroadcast());
Bukkit.spigot().restart();
}
return true;
diff --git a/ButtonCore/src/main/java/buttondevteam/core/component/restart/RestartComponent.java b/ButtonCore/src/main/java/buttondevteam/core/component/restart/RestartComponent.java
index e49e3b2..6b431bb 100644
--- a/ButtonCore/src/main/java/buttondevteam/core/component/restart/RestartComponent.java
+++ b/ButtonCore/src/main/java/buttondevteam/core/component/restart/RestartComponent.java
@@ -1,29 +1,39 @@
package buttondevteam.core.component.restart;
+import buttondevteam.core.MainPlugin;
+import buttondevteam.core.component.channel.Channel;
+import buttondevteam.lib.TBMCSystemChatEvent;
import buttondevteam.lib.architecture.Component;
import buttondevteam.lib.chat.IFakePlayer;
import buttondevteam.lib.chat.TBMCChatAPI;
+import lombok.Getter;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerQuitEvent;
-public class RestartComponent extends Component implements Listener {
+/**
+ * Provides commands such as /schrestart (restart after a countdown) and /primerestart (restart when nobody is online)
+ */
+public class RestartComponent extends Component implements Listener {
@Override
public void enable() {
//TODO: Permissions for the commands
- TBMCChatAPI.AddCommand(this, new ScheduledRestartCommand());
- TBMCChatAPI.AddCommand(this, new PrimeRestartCommand());
+ registerCommand(new ScheduledRestartCommand(this));
+ TBMCChatAPI.AddCommand(this, new PrimeRestartCommand(this));
registerListener(this);
+ restartBroadcast = TBMCSystemChatEvent.BroadcastTarget.add("restartCountdown");
}
@Override
public void disable() {
-
+ TBMCSystemChatEvent.BroadcastTarget.remove(restartBroadcast);
}
private long lasttime = 0;
+ @Getter
+ private TBMCSystemChatEvent.BroadcastTarget restartBroadcast;
@EventHandler
public void onPlayerLeave(PlayerQuitEvent event) {
@@ -32,12 +42,12 @@ public class RestartComponent extends Component implements Listener {
&& !event.getQuitMessage().equalsIgnoreCase("Server is restarting")) {
if (Bukkit.getOnlinePlayers().size() <= 1) {
if (PrimeRestartCommand.isLoud())
- Bukkit.broadcastMessage("§cNobody is online anymore. Restarting.");
+ TBMCChatAPI.SendSystemMessage(Channel.GlobalChat, Channel.RecipientTestResult.ALL, "§cNobody is online anymore. Restarting.", restartBroadcast);
Bukkit.spigot().restart();
} else if (!(event.getPlayer() instanceof IFakePlayer) && System.nanoTime() - 10 * 1000000000L - lasttime > 0) { //Ten seconds passed since last reminder
lasttime = System.nanoTime();
if (PrimeRestartCommand.isLoud())
- Bukkit.broadcastMessage(ChatColor.DARK_RED + "The server will restart as soon as nobody is online.");
+ TBMCChatAPI.SendSystemMessage(Channel.GlobalChat, Channel.RecipientTestResult.ALL, ChatColor.DARK_RED + "The server will restart as soon as nobody is online.", restartBroadcast);
}
}
}
diff --git a/ButtonCore/src/main/java/buttondevteam/core/component/restart/ScheduledRestartCommand.java b/ButtonCore/src/main/java/buttondevteam/core/component/restart/ScheduledRestartCommand.java
index fea469e..dabd48a 100755
--- a/ButtonCore/src/main/java/buttondevteam/core/component/restart/ScheduledRestartCommand.java
+++ b/ButtonCore/src/main/java/buttondevteam/core/component/restart/ScheduledRestartCommand.java
@@ -1,10 +1,14 @@
package buttondevteam.core.component.restart;
import buttondevteam.core.MainPlugin;
+import buttondevteam.core.component.channel.Channel;
import buttondevteam.lib.ScheduledServerRestartEvent;
+import buttondevteam.lib.chat.Command2;
import buttondevteam.lib.chat.CommandClass;
-import buttondevteam.lib.chat.TBMCCommandBase;
+import buttondevteam.lib.chat.ICommand2MC;
+import buttondevteam.lib.chat.TBMCChatAPI;
import lombok.Getter;
+import lombok.RequiredArgsConstructor;
import lombok.Setter;
import org.bukkit.Bukkit;
import org.bukkit.boss.BarColor;
@@ -14,16 +18,23 @@ import org.bukkit.boss.BossBar;
import org.bukkit.command.CommandSender;
import org.bukkit.scheduler.BukkitTask;
-@CommandClass(modOnly = true, path = "schrestart")
-public class ScheduledRestartCommand extends TBMCCommandBase {
+@CommandClass(modOnly = true, path = "schrestart", helpText = {
+ "Scheduled restart", //
+ "This command restarts the server 1 minute after it's executed, warning players every 10 seconds.", //
+ "You can optionally set the amount of seconds to wait before the restart." //
+})
+@RequiredArgsConstructor
+public class ScheduledRestartCommand extends ICommand2MC {
@Getter
@Setter
private int restartCounter;
private BukkitTask restarttask;
private volatile BossBar restartbar;
+ @Getter
+ private final RestartComponent component;
- @Override
- public boolean OnCommand(CommandSender sender, String alias, String[] args) {
+ @Command2.Subcommand
+ public boolean def(CommandSender sender, String alias, String[] args) {
int secs = 60;
try {
if (args.length > 0)
@@ -51,20 +62,11 @@ public class ScheduledRestartCommand extends TBMCCommandBase {
Bukkit.spigot().restart();
}
if (restartCounter % 200 == 0)
- Bukkit.broadcastMessage("§c-- The server is restarting in " + restartCounter / 20 + " seconds! (/press)");
+ TBMCChatAPI.SendSystemMessage(Channel.GlobalChat, Channel.RecipientTestResult.ALL, "§c-- The server is restarting in " + restartCounter / 20 + " seconds! (/press)", component.getRestartBroadcast());
restartbar.setProgress(restartCounter / (double) restarttime);
restartbar.setTitle(String.format("Server restart in %.2f", restartCounter / 20f));
restartCounter--;
}, 1, 1);
return true;
}
-
- @Override
- public String[] GetHelpText(String alias) {
- return new String[] { //
- "§6---- Scheduled restart ----", //
- "This command restarts the server 1 minute after it's executed, warning players every 10 seconds.", //
- "You can optionally set the amount of ticks to wait before the restart." //
- };
- }
}
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 1b2bf9d..42c857d 100644
--- a/ButtonCore/src/main/java/buttondevteam/core/component/towny/TownyComponent.java
+++ b/ButtonCore/src/main/java/buttondevteam/core/component/towny/TownyComponent.java
@@ -1,6 +1,7 @@
package buttondevteam.core.component.towny;
import buttondevteam.core.ComponentManager;
+import buttondevteam.core.MainPlugin;
import buttondevteam.lib.TBMCCoreAPI;
import buttondevteam.lib.architecture.Component;
import com.palmergames.bukkit.towny.Towny;
@@ -10,7 +11,10 @@ import com.palmergames.bukkit.towny.object.Resident;
import com.palmergames.bukkit.towny.object.TownyUniverse;
import org.bukkit.Bukkit;
-public class TownyComponent extends Component {
+/**
+ * Automatically renames Towny players if they changed their Minecraft name
+ */
+public class TownyComponent extends Component {
@Override
protected void enable() {
}
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 2ead741..3ea44c8 100644
--- a/ButtonCore/src/main/java/buttondevteam/core/component/updater/PluginUpdaterComponent.java
+++ b/ButtonCore/src/main/java/buttondevteam/core/component/updater/PluginUpdaterComponent.java
@@ -1,9 +1,13 @@
package buttondevteam.core.component.updater;
+import buttondevteam.core.MainPlugin;
import buttondevteam.lib.architecture.Component;
import buttondevteam.lib.chat.TBMCChatAPI;
-public class PluginUpdaterComponent extends Component {
+/**
+ * Downloads plugin updates built from their source using JitPack - older code
+ */
+public class PluginUpdaterComponent extends Component { //TODO: Config
@Override
public void enable() {
TBMCChatAPI.AddCommand(this, new UpdatePluginCommand());
diff --git a/ButtonCore/src/main/java/buttondevteam/core/component/votifier/VotifierComponent.java b/ButtonCore/src/main/java/buttondevteam/core/component/votifier/VotifierComponent.java
new file mode 100644
index 0000000..94ffe55
--- /dev/null
+++ b/ButtonCore/src/main/java/buttondevteam/core/component/votifier/VotifierComponent.java
@@ -0,0 +1,49 @@
+package buttondevteam.core.component.votifier;
+
+import buttondevteam.core.MainPlugin;
+import buttondevteam.lib.architecture.Component;
+import buttondevteam.lib.architecture.ConfigData;
+import com.vexsoftware.votifier.model.Vote;
+import com.vexsoftware.votifier.model.VotifierEvent;
+import lombok.RequiredArgsConstructor;
+import net.milkbowl.vault.economy.Economy;
+import org.bukkit.Bukkit;
+import org.bukkit.entity.Player;
+import org.bukkit.event.EventHandler;
+
+/**
+ * Do not use (EULA)
+ */
+@RequiredArgsConstructor
+public class VotifierComponent extends Component {
+ private final Economy economy;
+
+ private ConfigData rewardAmount() {
+ return getConfig().getData("rewardAmount", 0.0);
+ }
+
+ @Override
+ protected void enable() {
+
+ }
+
+ @Override
+ protected void disable() {
+
+ }
+
+ @EventHandler
+ @SuppressWarnings("deprecation")
+ public void onVotifierEvent(VotifierEvent event) {
+ Vote vote = event.getVote();
+ getPlugin().getLogger().info("Vote: " + vote);
+ org.bukkit.OfflinePlayer op = Bukkit.getOfflinePlayer(vote.getUsername());
+ Player p = Bukkit.getPlayer(vote.getUsername());
+ if (op != null) {
+ economy.depositPlayer(op, rewardAmount().get());
+ }
+ if (p != null) {
+ p.sendMessage("§bThanks for voting! $50 was added to your account.");
+ }
+ }
+}
diff --git a/ButtonCore/src/main/java/buttondevteam/lib/TBMCCommandPreprocessEvent.java b/ButtonCore/src/main/java/buttondevteam/lib/TBMCCommandPreprocessEvent.java
index a72c0b7..d7cd103 100755
--- a/ButtonCore/src/main/java/buttondevteam/lib/TBMCCommandPreprocessEvent.java
+++ b/ButtonCore/src/main/java/buttondevteam/lib/TBMCCommandPreprocessEvent.java
@@ -25,7 +25,7 @@ public class TBMCCommandPreprocessEvent extends Event implements Cancellable {
public TBMCCommandPreprocessEvent(CommandSender sender, String message) {
this.sender = sender;
- this.message = message; //TODO: Actually call from Discord as well
+ this.message = message;
}
@Override
diff --git a/ButtonCore/src/main/java/buttondevteam/lib/TBMCSystemChatEvent.java b/ButtonCore/src/main/java/buttondevteam/lib/TBMCSystemChatEvent.java
index 80cd634..f5d5a0f 100755
--- a/ButtonCore/src/main/java/buttondevteam/lib/TBMCSystemChatEvent.java
+++ b/ButtonCore/src/main/java/buttondevteam/lib/TBMCSystemChatEvent.java
@@ -1,10 +1,18 @@
package buttondevteam.lib;
import buttondevteam.core.component.channel.Channel;
+import lombok.AccessLevel;
import lombok.Getter;
+import lombok.RequiredArgsConstructor;
+import lombok.val;
import org.bukkit.command.CommandSender;
import org.bukkit.event.HandlerList;
+import javax.annotation.Nullable;
+import java.util.HashSet;
+import java.util.Objects;
+import java.util.stream.Stream;
+
/**
* Make sure to only send the message to users who {@link #shouldSendTo(CommandSender)} returns true.
*
@@ -14,15 +22,17 @@ import org.bukkit.event.HandlerList;
@Getter
public class TBMCSystemChatEvent extends TBMCChatEventBase {
private final String[] exceptions;
+ private final BroadcastTarget target;
private boolean handled;
public void setHandled() {
handled = true;
}
- public TBMCSystemChatEvent(Channel channel, String message, int score, String groupid, String[] exceptions) { // TODO: Rich message
+ public TBMCSystemChatEvent(Channel channel, String message, int score, String groupid, String[] exceptions, BroadcastTarget target) { // TODO: Rich message
super(channel, message, score, groupid);
this.exceptions = exceptions;
+ this.target = target;
}
private static final HandlerList handlers = new HandlerList();
@@ -35,4 +45,30 @@ public class TBMCSystemChatEvent extends TBMCChatEventBase {
public static HandlerList getHandlerList() {
return handlers;
}
+
+ @RequiredArgsConstructor(access = AccessLevel.PRIVATE)
+ public static class BroadcastTarget {
+ private final @Getter String name;
+ private static final HashSet targets = new HashSet<>();
+ public static final BroadcastTarget ALL = new BroadcastTarget("ALL");
+
+ public static BroadcastTarget add(String name) {
+ val bt = new BroadcastTarget(Objects.requireNonNull(name));
+ targets.add(bt);
+ return bt;
+ }
+
+ public static void remove(BroadcastTarget target) {
+ targets.remove(target);
+ }
+
+ @Nullable
+ public static BroadcastTarget get(String name) {
+ return targets.stream().filter(bt -> bt.name.equalsIgnoreCase(name)).findAny().orElse(null);
+ }
+
+ public static Stream stream() {
+ return targets.stream();
+ }
+ }
}
diff --git a/ButtonCore/src/main/java/buttondevteam/lib/ThorpeUtils.java b/ButtonCore/src/main/java/buttondevteam/lib/ThorpeUtils.java
index 4f8560c..d69983e 100644
--- a/ButtonCore/src/main/java/buttondevteam/lib/ThorpeUtils.java
+++ b/ButtonCore/src/main/java/buttondevteam/lib/ThorpeUtils.java
@@ -35,4 +35,20 @@ public final class ThorpeUtils {
*/
String getFancyFullName();
}
+
+ public static Number convertNumber(Number number, Class extends Number> targetcl) {
+ if (targetcl == long.class || Long.class.isAssignableFrom(targetcl))
+ return number.longValue();
+ else if (targetcl == int.class || Integer.class.isAssignableFrom(targetcl))
+ return number.intValue(); //Needed because the parser can get longs
+ else if (targetcl == short.class || Short.class.isAssignableFrom(targetcl))
+ return number.shortValue();
+ else if (targetcl == byte.class || Byte.class.isAssignableFrom(targetcl))
+ return number.byteValue();
+ else if (targetcl == float.class || Float.class.isAssignableFrom(targetcl))
+ return number.floatValue();
+ else if (targetcl == double.class || Double.class.isAssignableFrom(targetcl))
+ return number.doubleValue();
+ return number;
+ }
}
diff --git a/ButtonCore/src/main/java/buttondevteam/lib/architecture/ButtonPlugin.java b/ButtonCore/src/main/java/buttondevteam/lib/architecture/ButtonPlugin.java
index 5b26d9d..25df8af 100644
--- a/ButtonCore/src/main/java/buttondevteam/lib/architecture/ButtonPlugin.java
+++ b/ButtonCore/src/main/java/buttondevteam/lib/architecture/ButtonPlugin.java
@@ -2,6 +2,7 @@ package buttondevteam.lib.architecture;
import buttondevteam.core.ComponentManager;
import buttondevteam.lib.TBMCCoreAPI;
+import buttondevteam.lib.chat.Command2MC;
import buttondevteam.lib.chat.TBMCChatAPI;
import lombok.AccessLevel;
import lombok.Getter;
@@ -10,14 +11,20 @@ import org.bukkit.plugin.java.JavaPlugin;
import java.util.Stack;
+@HasConfig
public abstract class ButtonPlugin extends JavaPlugin {
+ @Getter
+ private static Command2MC command2MC = new Command2MC();
@Getter(AccessLevel.PROTECTED)
private IHaveConfig iConfig;
+ @Getter(AccessLevel.PROTECTED)
+ private IHaveConfig data; //TODO
+ private boolean loaded = false;
/**
- * Used to unregister components in the right order
+ * Used to unregister components in the right order - and to reload configs
*/
@Getter
- private Stack componentStack = new Stack<>();
+ private Stack> componentStack = new Stack<>();
protected abstract void pluginEnable();
@@ -34,9 +41,7 @@ public abstract class ButtonPlugin extends JavaPlugin {
@Override
public final void onEnable() {
- var section = super.getConfig().getConfigurationSection("global");
- if (section == null) section = super.getConfig().createSection("global");
- iConfig = new IHaveConfig(section);
+ loadConfig();
try {
pluginEnable();
} catch (Exception e) {
@@ -44,6 +49,12 @@ public abstract class ButtonPlugin extends JavaPlugin {
}
}
+ private void loadConfig() {
+ var section = super.getConfig().getConfigurationSection("global");
+ if (section == null) section = super.getConfig().createSection("global");
+ iConfig = new IHaveConfig(section, this::saveConfig);
+ }
+
@Override
public final void onDisable() {
try {
@@ -57,4 +68,26 @@ public abstract class ButtonPlugin extends JavaPlugin {
TBMCCoreAPI.SendException("Error while disabling plugin " + getName() + "!", e);
}
}
+
+ @Override
+ public void reloadConfig() {
+ tryReloadConfig();
+ }
+
+ public boolean tryReloadConfig() {
+ if (!justReload()) return false;
+ loadConfig();
+ componentStack.forEach(c -> Component.updateConfig(this, c));
+ return true;
+ }
+
+ public boolean justReload() {
+ if (loaded && ConfigData.saveNow(getConfig())) {
+ getLogger().warning("Saved pending configuration changes to the file, didn't reload (try again).");
+ return false;
+ }
+ super.reloadConfig();
+ loaded = true; //Needed because for the first time it uses reloadConfig() to load it
+ return true;
+ }
}
diff --git a/ButtonCore/src/main/java/buttondevteam/lib/architecture/Component.java b/ButtonCore/src/main/java/buttondevteam/lib/architecture/Component.java
index e052555..4d2c9cf 100644
--- a/ButtonCore/src/main/java/buttondevteam/lib/architecture/Component.java
+++ b/ButtonCore/src/main/java/buttondevteam/lib/architecture/Component.java
@@ -3,34 +3,39 @@ package buttondevteam.lib.architecture;
import buttondevteam.core.ComponentManager;
import buttondevteam.lib.TBMCCoreAPI;
import buttondevteam.lib.architecture.exceptions.UnregisteredComponentException;
-import buttondevteam.lib.chat.Command2MC;
+import buttondevteam.lib.chat.ICommand2MC;
import buttondevteam.lib.chat.TBMCChatAPI;
import buttondevteam.lib.chat.TBMCCommandBase;
import lombok.Getter;
import lombok.NonNull;
import lombok.experimental.var;
import lombok.val;
+import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.event.Listener;
import org.bukkit.plugin.java.JavaPlugin;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
+import java.util.function.Consumer;
+import java.util.stream.Collectors;
/**
* Configuration is based on class name
*/
-public abstract class Component {
- private static HashMap, Component> components = new HashMap<>();
+@HasConfig //Used for obtaining javadoc
+public abstract class Component {
+ private static HashMap, Component extends JavaPlugin>> components = new HashMap<>();
@Getter
private boolean enabled = false;
@Getter
@NonNull
- private JavaPlugin plugin;
+ private TP plugin;
@NonNull
private @Getter
IHaveConfig config;
+ private @Getter IHaveConfig data; //TODO
public final ConfigData shouldBeEnabled() {
return config.getData("enabled", true);
@@ -45,7 +50,7 @@ public abstract class Component {
* @param component The component to register
* @return Whether the component is registered successfully (it may have failed to enable)
*/
- public static boolean registerComponent(JavaPlugin plugin, Component component) {
+ public static boolean registerComponent(T plugin, Component component) {
return registerUnregisterComponent(plugin, component, true);
}
@@ -57,11 +62,11 @@ public abstract class Component {
* @param component The component to unregister
* @return Whether the component is unregistered successfully (it also got disabled)
*/
- public static boolean unregisterComponent(JavaPlugin plugin, Component component) {
+ public static boolean unregisterComponent(T plugin, Component component) {
return registerUnregisterComponent(plugin, component, false);
}
- public static boolean registerUnregisterComponent(JavaPlugin plugin, Component component, boolean register) {
+ public static boolean registerUnregisterComponent(T plugin, Component component, boolean register) {
try {
val metaAnn = component.getClass().getAnnotation(ComponentMetadata.class);
if (metaAnn != null) {
@@ -135,16 +140,16 @@ public abstract class Component {
}
}
- private static void updateConfig(JavaPlugin plugin, Component component) {
+ public static void updateConfig(JavaPlugin plugin, Component component) {
if (plugin.getConfig() != null) { //Production
var compconf = plugin.getConfig().getConfigurationSection("components");
if (compconf == null) compconf = plugin.getConfig().createSection("components");
var configSect = compconf.getConfigurationSection(component.getClassName());
if (configSect == null)
configSect = compconf.createSection(component.getClassName());
- component.config = new IHaveConfig(configSect);
+ component.config = new IHaveConfig(configSect, plugin::saveConfig);
} else //Testing
- component.config = new IHaveConfig(null);
+ component.config = new IHaveConfig(null, plugin::saveConfig);
}
/**
@@ -152,7 +157,7 @@ public abstract class Component {
*
* @return The currently registered components
*/
- public static Map, Component> getComponents() {
+ public static Map, Component extends JavaPlugin>> getComponents() {
return Collections.unmodifiableMap(components);
}
@@ -197,8 +202,8 @@ public abstract class Component {
*
* @param commandBase Custom coded command class
*/
- protected final void registerCommand(Command2MC commandBase) {
- Command2MC.registerCommand(commandBase);
+ protected final void registerCommand(ICommand2MC commandBase) {
+ ButtonPlugin.getCommand2MC().registerCommand(commandBase);
}
/**
@@ -221,6 +226,28 @@ public abstract class Component {
return listener;
}
+ /**
+ * Returns a map of configs that are under the given key.
+ * @param key The key to use
+ * @param defaultProvider A mapping between config paths and config generators
+ * @return A map containing configs
+ */
+ protected Map getConfigMap(String key, Map> defaultProvider) {
+ val c=getConfig().getConfig();
+ var cs=c.getConfigurationSection(key);
+ if(cs==null) cs=c.createSection(key);
+ val res = cs.getValues(false).entrySet().stream().filter(e -> e.getValue() instanceof ConfigurationSection)
+ .collect(Collectors.toMap(Map.Entry::getKey, kv -> new IHaveConfig((ConfigurationSection) kv.getValue(), getPlugin()::saveConfig)));
+ if (res.size() == 0) {
+ for (val entry : defaultProvider.entrySet()) {
+ val conf = new IHaveConfig(cs.createSection(entry.getKey()), getPlugin()::saveConfig);
+ entry.getValue().accept(conf);
+ res.put(entry.getKey(), conf);
+ }
+ }
+ return res;
+ }
+
private String getClassName() {
return getClass().getSimpleName();
}
diff --git a/ButtonCore/src/main/java/buttondevteam/lib/architecture/ComponentMetadata.java b/ButtonCore/src/main/java/buttondevteam/lib/architecture/ComponentMetadata.java
index 6519fca..a182df8 100644
--- a/ButtonCore/src/main/java/buttondevteam/lib/architecture/ComponentMetadata.java
+++ b/ButtonCore/src/main/java/buttondevteam/lib/architecture/ComponentMetadata.java
@@ -8,5 +8,5 @@ import java.lang.annotation.Target;
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface ComponentMetadata {
- Class extends Component>[] depends();
+ Class extends Component>[] depends() default {};
}
diff --git a/ButtonCore/src/main/java/buttondevteam/lib/architecture/ConfigData.java b/ButtonCore/src/main/java/buttondevteam/lib/architecture/ConfigData.java
index 1a3a11f..6374db0 100644
--- a/ButtonCore/src/main/java/buttondevteam/lib/architecture/ConfigData.java
+++ b/ButtonCore/src/main/java/buttondevteam/lib/architecture/ConfigData.java
@@ -1,10 +1,19 @@
package buttondevteam.lib.architecture;
+import buttondevteam.core.MainPlugin;
+import buttondevteam.lib.ThorpeUtils;
import lombok.AccessLevel;
+import lombok.AllArgsConstructor;
import lombok.RequiredArgsConstructor;
+import org.bukkit.Bukkit;
+import org.bukkit.configuration.Configuration;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.configuration.file.YamlConfiguration;
+import org.bukkit.scheduler.BukkitTask;
+import java.lang.reflect.Array;
+import java.util.HashMap;
+import java.util.List;
import java.util.Objects;
import java.util.function.Function;
@@ -14,7 +23,8 @@ import java.util.function.Function;
*/
@RequiredArgsConstructor(access = AccessLevel.PACKAGE)
//@AllArgsConstructor(access = AccessLevel.PACKAGE)
-public class ConfigData { //TODO: Save after a while
+public class ConfigData {
+ private static final HashMap saveTasks = new HashMap<>();
/**
* May be null for testing
*/
@@ -22,6 +32,7 @@ public class ConfigData { //TODO: Save after a while
private final String path;
private final T def;
private final Object primitiveDef;
+ private final Runnable saveAction;
/**
* The parameter is of a primitive type as returned by {@link YamlConfiguration#get(String)}
*/
@@ -35,15 +46,20 @@ public class ConfigData { //TODO: Save after a while
* The config value should not change outside this instance
*/
private T value;
+ /**
+ * Whether the default value is saved in the yaml
+ */
private boolean saved = false;
- public ConfigData(ConfigurationSection config, String path, T def, Object primitiveDef, Function