Merge pull request #56 from TBMCPlugins/dev

Components, components everywhere
This commit is contained in:
Norbi Peti 2019-01-20 22:36:55 +01:00 committed by GitHub
commit 4ee76a97bf
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
39 changed files with 1332 additions and 941 deletions

15
.editorconfig Normal file
View file

@ -0,0 +1,15 @@
[*]
charset=utf-8
end_of_line=lf
insert_final_newline=false
indent_style=space
indent_size=4
[*.java]
indent_style=tab
tab_width=4
[{*.yml,*.yaml}]
indent_style=space
indent_size=2

View file

@ -1,7 +1,7 @@
<component name="InspectionProjectProfileManager"> <component name="InspectionProjectProfileManager">
<profile version="1.0"> <profile version="1.0">
<option name="myName" value="Project Default" /> <option name="myName" value="Project Default" />
<inspection_tool class="WeakerAccess" enabled="true" level="WARNING" enabled_by_default="true"> <inspection_tool class="WeakerAccess" enabled="false" level="WARNING" enabled_by_default="false">
<option name="SUGGEST_PACKAGE_LOCAL_FOR_MEMBERS" value="false" /> <option name="SUGGEST_PACKAGE_LOCAL_FOR_MEMBERS" value="false" />
<option name="SUGGEST_PACKAGE_LOCAL_FOR_TOP_CLASSES" value="false" /> <option name="SUGGEST_PACKAGE_LOCAL_FOR_TOP_CLASSES" value="false" />
<option name="SUGGEST_PRIVATE_FOR_INNERS" value="false" /> <option name="SUGGEST_PRIVATE_FOR_INNERS" value="false" />

View file

@ -1,5 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<project version="4"> <project version="4">
<component name="EntryPointsManager">
<list size="1">
<item index="0" class="java.lang.String" itemvalue="org.bukkit.event.EventHandler" />
</list>
</component>
<component name="MavenProjectsManager"> <component name="MavenProjectsManager">
<option name="originalFiles"> <option name="originalFiles">
<list> <list>

View file

@ -4,7 +4,6 @@
<modules> <modules>
<module fileurl="file://$PROJECT_DIR$/BuildConfigUpdater/BuildConfigUpdater.iml" filepath="$PROJECT_DIR$/BuildConfigUpdater/BuildConfigUpdater.iml" /> <module fileurl="file://$PROJECT_DIR$/BuildConfigUpdater/BuildConfigUpdater.iml" filepath="$PROJECT_DIR$/BuildConfigUpdater/BuildConfigUpdater.iml" />
<module fileurl="file://$PROJECT_DIR$/ButtonCore/ButtonCore (1) (com.github.TBMCPlugins.ButtonCore).iml" filepath="$PROJECT_DIR$/ButtonCore/ButtonCore (1) (com.github.TBMCPlugins.ButtonCore).iml" /> <module fileurl="file://$PROJECT_DIR$/ButtonCore/ButtonCore (1) (com.github.TBMCPlugins.ButtonCore).iml" filepath="$PROJECT_DIR$/ButtonCore/ButtonCore (1) (com.github.TBMCPlugins.ButtonCore).iml" />
<module fileurl="file://$PROJECT_DIR$/ButtonCore/ButtonCore (1) (com.github.TBMCPlugins.ButtonCore).iml" filepath="$PROJECT_DIR$/ButtonCore/ButtonCore (1) (com.github.TBMCPlugins.ButtonCore).iml" />
<module fileurl="file://$PROJECT_DIR$/ButtonProcessor/ButtonProcessor.iml" filepath="$PROJECT_DIR$/ButtonProcessor/ButtonProcessor.iml" /> <module fileurl="file://$PROJECT_DIR$/ButtonProcessor/ButtonProcessor.iml" filepath="$PROJECT_DIR$/ButtonProcessor/ButtonProcessor.iml" />
</modules> </modules>
</component> </component>

View file

@ -1,17 +1,24 @@
package buttondevteam.lib.chat; package buttondevteam.component.channel;
import buttondevteam.core.ComponentManager;
import buttondevteam.core.MainPlugin; import buttondevteam.core.MainPlugin;
import buttondevteam.lib.architecture.Component;
import buttondevteam.lib.architecture.ConfigData;
import buttondevteam.lib.chat.Color;
import com.google.common.collect.Lists;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.function.BiFunction; import java.util.function.BiFunction;
import java.util.function.BiPredicate; import java.util.function.BiPredicate;
import java.util.function.Function; import java.util.function.Function;
import java.util.function.Predicate; import java.util.function.Predicate;
import java.util.stream.Stream;
public class Channel { public class Channel {
/** /**
@ -26,11 +33,40 @@ public class Channel {
* Send the message to everyone <i>who has access to the channel</i> - this does not necessarily mean all players * Send the message to everyone <i>who has access to the channel</i> - this does not necessarily mean all players
*/ */
public static final String GROUP_EVERYONE = "everyone"; public static final String GROUP_EVERYONE = "everyone";
public final String DisplayName;
public final Color color; private static ChannelComponent component;
private String defDisplayName;
private Color defColor;
private void throwGame() {
if (component == null) throw new RuntimeException("Cannot access channel properties until registered!");
}
public final ConfigData<Boolean> Enabled() {
throwGame();
return component.getConfig().getData(ID + ".enabled", true);
}
/**
* Must start with a color code
*/
public final ConfigData<String> DisplayName() {
throwGame();
return component.getConfig().getData(ID + ".displayName", defDisplayName);
}
public final ConfigData<Color> Color() {
throwGame();
return component.getConfig().getData(ID + ".color", defColor, c -> Color.valueOf((String) c), Enum::toString);
}
public final String ID; public final String ID;
@Nullable
public String[] IDs; @SuppressWarnings("unchecked")
public ConfigData<String[]> IDs() {
throwGame();
return component.getConfig().getData(ID + ".IDs", new String[0], l -> ((List<String>) l).toArray(new String[0]), Lists::newArrayList);
}
/** /**
* Filters both the sender and the targets * Filters both the sender and the targets
*/ */
@ -49,8 +85,8 @@ public class Channel {
*/ */
public Channel(String displayname, Color color, String command, public Channel(String displayname, Color color, String command,
Function<CommandSender, RecipientTestResult> filteranderrormsg) { Function<CommandSender, RecipientTestResult> filteranderrormsg) {
DisplayName = displayname; defDisplayName = displayname;
this.color = color; defColor = color;
ID = command; ID = command;
this.filteranderrormsg = filteranderrormsg; this.filteranderrormsg = filteranderrormsg;
} }
@ -63,8 +99,8 @@ public class Channel {
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
protected <T extends Channel> Channel(String displayname, Color color, String command, protected <T extends Channel> Channel(String displayname, Color color, String command,
BiFunction<T, CommandSender, RecipientTestResult> filteranderrormsg) { BiFunction<T, CommandSender, RecipientTestResult> filteranderrormsg) {
DisplayName = displayname; defDisplayName = displayname;
this.color = color; defColor = color;
ID = command; ID = command;
this.filteranderrormsg = s -> filteranderrormsg.apply((T) this, s); this.filteranderrormsg = s -> filteranderrormsg.apply((T) this, s);
} }
@ -106,9 +142,23 @@ public class Channel {
return filteranderrormsg.apply(sender); return filteranderrormsg.apply(sender);
} }
public static List<Channel> getChannels() { /**
return channels; * Get a stream of the enabled channels
} *
* @return Only the enabled channels
*/
public static Stream<Channel> getChannels() {
return channels.stream().filter(ch -> ch.Enabled().get());
}
/**
* Return all channels whether they're enabled or not
*
* @return A list of all channels
*/
public static List<Channel> getChannelList() {
return Collections.unmodifiableList(channels);
}
/** /**
* Convenience method for the function parameter of {@link #Channel(String, Color, String, Function)}. It checks if the sender is OP or optionally has the specified group. The error message is * Convenience method for the function parameter of {@link #Channel(String, Color, String, Function)}. It checks if the sender is OP or optionally has the specified group. The error message is
@ -137,9 +187,15 @@ public class Channel {
public static Channel AdminChat; public static Channel AdminChat;
public static Channel ModChat; public static Channel ModChat;
static void RegisterChannel(Channel channel) { public static void RegisterChannel(Channel channel) {
channels.add(channel); if (!channel.isGlobal() && !ComponentManager.isEnabled(ChannelComponent.class))
Bukkit.getScheduler().runTask(MainPlugin.Instance, () -> Bukkit.getPluginManager().callEvent(new ChatChannelRegisterEvent(channel))); // Wait for server start return; //Allow registering the global chat (and I guess other chats like the RP chat)
if (component == null)
component = (ChannelComponent) Component.getComponents().get(ChannelComponent.class);
if (component == null)
throw new RuntimeException("Attempting to register a channel before the component is registered!");
channels.add(channel);
Bukkit.getScheduler().runTask(MainPlugin.Instance, () -> Bukkit.getPluginManager().callEvent(new ChatChannelRegisterEvent(channel))); // Wait for server start
} }
public static class RecipientTestResult { public static class RecipientTestResult {

View file

@ -0,0 +1,26 @@
package buttondevteam.component.channel;
import buttondevteam.lib.architecture.Component;
import org.bukkit.plugin.java.JavaPlugin;
public class ChannelComponent extends Component {
@Override
protected void register(JavaPlugin plugin) {
super.register(plugin);
}
@Override
protected void unregister(JavaPlugin plugin) {
super.unregister(plugin);
}
@Override
protected void enable() {
}
@Override
protected void disable() {
}
}

View file

@ -1,4 +1,4 @@
package buttondevteam.lib.chat; package buttondevteam.component.channel;
import org.bukkit.event.Event; import org.bukkit.event.Event;
import org.bukkit.event.HandlerList; import org.bukkit.event.HandlerList;

View file

@ -1,5 +1,7 @@
package buttondevteam.lib.chat; package buttondevteam.component.channel;
import buttondevteam.lib.chat.Color;
import buttondevteam.lib.chat.TBMCChatAPI;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import java.util.ArrayList; import java.util.ArrayList;

View file

@ -1,15 +0,0 @@
package buttondevteam.component.commands;
import buttondevteam.lib.architecture.Component;
public class CommandComponent extends Component { //TODO: Do we just move everything here?
@Override
public void enable() {
}
@Override
public void disable() {
}
}

View file

@ -1,5 +1,6 @@
package buttondevteam.core; package buttondevteam.component.members;
import buttondevteam.core.MainPlugin;
import buttondevteam.lib.chat.CommandClass; import buttondevteam.lib.chat.CommandClass;
import buttondevteam.lib.chat.TBMCCommandBase; import buttondevteam.lib.chat.TBMCCommandBase;
import lombok.val; import lombok.val;

View file

@ -0,0 +1,42 @@
package buttondevteam.component.members;
import buttondevteam.core.MainPlugin;
import buttondevteam.lib.architecture.Component;
import buttondevteam.lib.architecture.ConfigData;
import org.bukkit.Statistic;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerJoinEvent;
import java.time.Instant;
import java.time.temporal.ChronoUnit;
import java.util.Date;
import static buttondevteam.core.MainPlugin.permission;
public class MemberComponent extends Component implements Listener {
private ConfigData<String> memberGroup() {
return getConfig().getData("memberGroup", "member");
}
@Override
protected void enable() {
registerListener(this);
registerCommand(new MemberCommand());
}
@Override
protected void disable() {
}
@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)) {
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.");
}
}
}

View file

@ -1,15 +1,15 @@
package buttondevteam.core; package buttondevteam.component.randomtp;
import buttondevteam.lib.architecture.Component;
import buttondevteam.lib.chat.CommandClass; import buttondevteam.lib.chat.CommandClass;
import buttondevteam.lib.chat.TBMCChatAPI; import buttondevteam.lib.chat.TBMCChatAPI;
import buttondevteam.lib.chat.TBMCCommandBase; import buttondevteam.lib.chat.TBMCCommandBase;
import org.bukkit.*; import org.bukkit.*;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.plugin.java.JavaPlugin;
// @formatter:off // @formatter:off
@CommandClass @SuppressWarnings("FieldCanBeLocal")@CommandClass
public class RandomTP extends TBMCCommandBase public class RandomTP extends TBMCCommandBase
{ {
private final int radius = 70; //set how far apart the five teleport positions are private final int radius = 70; //set how far apart the five teleport positions are
@ -51,9 +51,9 @@ public class RandomTP extends TBMCCommandBase
/*================================================================================================*/ /*================================================================================================*/
public void onEnable(JavaPlugin plugin) public void onEnable(Component component)
{ {
TBMCChatAPI.AddCommand(plugin, this); TBMCChatAPI.AddCommand(component, this);
world = Bukkit.getWorld("World"); world = Bukkit.getWorld("World");
border = world.getWorldBorder(); border = world.getWorldBorder();

View file

@ -0,0 +1,15 @@
package buttondevteam.component.randomtp;
import buttondevteam.lib.architecture.Component;
public class RandomTPComponent extends Component {
@Override
protected void enable() {
new RandomTP().onEnable(this); //It registers it's command
}
@Override
protected void disable() {
}
}

View file

@ -1,4 +1,4 @@
package buttondevteam.core; package buttondevteam.component.restart;
import buttondevteam.lib.chat.CommandClass; import buttondevteam.lib.chat.CommandClass;
import buttondevteam.lib.chat.TBMCCommandBase; import buttondevteam.lib.chat.TBMCCommandBase;

View file

@ -1,20 +1,44 @@
package buttondevteam.component.restart; package buttondevteam.component.restart;
import buttondevteam.core.PrimeRestartCommand;
import buttondevteam.core.ScheduledRestartCommand;
import buttondevteam.lib.architecture.Component; import buttondevteam.lib.architecture.Component;
import buttondevteam.lib.chat.IFakePlayer;
import buttondevteam.lib.chat.TBMCChatAPI; import buttondevteam.lib.chat.TBMCChatAPI;
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 { public class RestartComponent extends Component implements Listener {
@Override @Override
public void enable() { public void enable() {
//TODO: Permissions for the commands //TODO: Permissions for the commands
TBMCChatAPI.AddCommand(getPlugin(), ScheduledRestartCommand.class); TBMCChatAPI.AddCommand(this, new ScheduledRestartCommand());
TBMCChatAPI.AddCommand(getPlugin(), PrimeRestartCommand.class); TBMCChatAPI.AddCommand(this, new PrimeRestartCommand());
registerListener(this);
} }
@Override @Override
public void disable() { public void disable() {
} }
private long lasttime = 0;
@EventHandler
public void onPlayerLeave(PlayerQuitEvent event) {
if (PrimeRestartCommand.isPlsrestart()
&& !event.getQuitMessage().equalsIgnoreCase("Server closed")
&& !event.getQuitMessage().equalsIgnoreCase("Server is restarting")) {
if (Bukkit.getOnlinePlayers().size() <= 1) {
if (PrimeRestartCommand.isLoud())
Bukkit.broadcastMessage("§cNobody is online anymore. Restarting.");
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.");
}
}
}
} }

View file

@ -1,5 +1,6 @@
package buttondevteam.core; package buttondevteam.component.restart;
import buttondevteam.core.MainPlugin;
import buttondevteam.lib.ScheduledServerRestartEvent; import buttondevteam.lib.ScheduledServerRestartEvent;
import buttondevteam.lib.chat.CommandClass; import buttondevteam.lib.chat.CommandClass;
import buttondevteam.lib.chat.TBMCCommandBase; import buttondevteam.lib.chat.TBMCCommandBase;

View file

@ -0,0 +1,47 @@
package buttondevteam.component.towny;
import buttondevteam.core.ComponentManager;
import buttondevteam.lib.TBMCCoreAPI;
import buttondevteam.lib.architecture.Component;
import com.palmergames.bukkit.towny.Towny;
import com.palmergames.bukkit.towny.exceptions.AlreadyRegisteredException;
import com.palmergames.bukkit.towny.exceptions.NotRegisteredException;
import com.palmergames.bukkit.towny.object.Resident;
import com.palmergames.bukkit.towny.object.TownyUniverse;
import org.bukkit.Bukkit;
public class TownyComponent extends Component {
@Override
protected void enable() {
}
@Override
protected void disable() {
}
/**
* Only renames the resident if this component is enabled. Used to handle name changes.
*
* @param oldName The player's old name as known by us
* @param newName The player's new name
*/
public static void renameInTowny(String oldName, String newName) {
if (!ComponentManager.isEnabled(TownyComponent.class))
return; 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.");
TBMCCoreAPI.sendDebugMessage("Resident not found - couldn't rename in Towny.");
} else if (tu.getResidentMap().contains(newName.toLowerCase())) {
Bukkit.getLogger().warning("Target resident name is already in use."); // TODO: Handle
TBMCCoreAPI.sendDebugMessage("Target resident name is already in use.");
} else
try {
TownyUniverse.getDataSource().renamePlayer(resident, newName); //Fixed in Towny 0.91.1.2
} catch (AlreadyRegisteredException e) {
TBMCCoreAPI.SendException("Failed to rename resident, there's already one with this name.", e);
} catch (NotRegisteredException e) {
TBMCCoreAPI.SendException("Failed to rename resident, the resident isn't registered.", e);
}
}
}

View file

@ -6,11 +6,11 @@ import buttondevteam.lib.chat.TBMCChatAPI;
public class PluginUpdaterComponent extends Component { public class PluginUpdaterComponent extends Component {
@Override @Override
public void enable() { public void enable() {
TBMCChatAPI.AddCommand(getPlugin(), UpdatePluginCommand.class); TBMCChatAPI.AddCommand(this, new UpdatePluginCommand());
} }
@Override @Override
public void disable() { //TODO: Unregister commands and such public void disable() { //Commands are automatically unregistered
} }
} }

View file

@ -21,41 +21,27 @@ public class CommandCaller implements CommandExecutor {
public static void RegisterCommand(TBMCCommandBase cmd) throws Exception { public static void RegisterCommand(TBMCCommandBase cmd) throws Exception {
if (instance == null) if (instance == null)
instance = new CommandCaller(); instance = new CommandCaller();
String topcmd = cmd.GetCommandPath(); String[] topcmd = new String[1]; //Holds out param
if (topcmd == null) PluginCommand pc = getPluginCommand(cmd, topcmd);
throw new Exception("Command " + cmd.getClass().getSimpleName() + " has no command path!"); pc.setExecutor(instance);
if (cmd.getPlugin() == null) String[] helptext = cmd.GetHelpText(topcmd[0]);
throw new Exception("Command " + cmd.GetCommandPath() + " has no plugin!"); if (helptext == null || helptext.length == 0)
int i; throw new Exception("Command " + cmd.GetCommandPath() + " has no help text!");
if ((i = topcmd.indexOf(' ')) != -1) // Get top-level command pc.setUsage(helptext.length > 1 ? helptext[1] : helptext[0]);
topcmd = topcmd.substring(0, i);
{
PluginCommand pc = ((JavaPlugin) cmd.getPlugin()).getCommand(topcmd);
if (pc == null)
throw new Exception("Top level command " + topcmd + " not registered in plugin.yml for plugin: "
+ cmd.getPlugin().getName());
else {
pc.setExecutor(instance);
String[] helptext = cmd.GetHelpText(topcmd);
if (helptext == null || helptext.length == 0)
throw new Exception("Command " + cmd.GetCommandPath() + " has no help text!");
pc.setUsage(helptext.length > 1 ? helptext[1] : helptext[0]);
}
}
} }
@Override @Override
public boolean onCommand(CommandSender sender, Command command, String alias, String[] args) { public boolean onCommand(CommandSender sender, Command command, String alias, String[] args) {
String path = command.getName().toLowerCase(); StringBuilder path = new StringBuilder(command.getName().toLowerCase());
for (String arg : args) for (String arg : args)
path += " " + arg; path.append(" ").append(arg);
TBMCCommandBase cmd = TBMCChatAPI.GetCommands().get(path); TBMCCommandBase cmd = TBMCChatAPI.GetCommands().get(path.toString());
int argc = 0; int argc = 0;
String[] subcmds = null; String[] subcmds = null;
while (cmd == null && (subcmds = TBMCChatAPI.GetSubCommands(path, sender)).length == 0 && path.contains(" ")) { while (cmd == null && (subcmds = TBMCChatAPI.GetSubCommands(path.toString(), sender)).length == 0 && path.toString().contains(" ")) {
path = path.substring(0, path.lastIndexOf(' ')); path = new StringBuilder(path.substring(0, path.toString().lastIndexOf(' ')));
argc++; argc++;
cmd = TBMCChatAPI.GetCommands().get(path); cmd = TBMCChatAPI.GetCommands().get(path.toString());
} }
if (cmd == null) { if (cmd == null) {
if (subcmds.length > 0) //Subcmds will always have value here (see assignment above) if (subcmds.length > 0) //Subcmds will always have value here (see assignment above)
@ -85,4 +71,37 @@ public class CommandCaller implements CommandExecutor {
} }
return true; return true;
} }
public static void UnregisterCommand(TBMCCommandBase cmd) throws Exception {
PluginCommand pc = getPluginCommand(cmd, null);
pc.setExecutor(null); //Sets the executor to this plugin
}
/**
* Gets the plugin command from the TBMC command.
*
* @param cmd The TBMC command
* @param out_topcmd An array with at least 1 elements or null
* @return The Bukkit plugin command - an exception is generated if null
* @throws Exception If the command isn't set up properly (or a different error)
*/
public static PluginCommand getPluginCommand(TBMCCommandBase cmd, String[] out_topcmd) throws Exception {
String topcmd = cmd.GetCommandPath();
if (topcmd == null)
throw new Exception("Command " + cmd.getClass().getSimpleName() + " has no command path!");
if (cmd.getPlugin() == null)
throw new Exception("Command " + cmd.GetCommandPath() + " has no plugin!");
int i;
if ((i = topcmd.indexOf(' ')) != -1) // Get top-level command
topcmd = topcmd.substring(0, i);
if (out_topcmd != null && out_topcmd.length > 0)
out_topcmd[0] = topcmd;
{
PluginCommand pc = ((JavaPlugin) cmd.getPlugin()).getCommand(topcmd);
if (pc == null)
throw new Exception("Top level command " + topcmd + " not registered in plugin.yml for plugin: "
+ cmd.getPlugin().getName());
return pc;
}
}
} }

View file

@ -1,30 +1,63 @@
package buttondevteam.core; package buttondevteam.core;
import buttondevteam.lib.TBMCCoreAPI;
import buttondevteam.lib.architecture.Component;
import buttondevteam.lib.chat.CommandClass; import buttondevteam.lib.chat.CommandClass;
import buttondevteam.lib.chat.TBMCCommandBase; import buttondevteam.lib.chat.TBMCCommandBase;
import lombok.val;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import java.util.Optional;
@CommandClass(modOnly = true) @CommandClass(modOnly = true)
public class ComponentCommand extends TBMCCommandBase { public class ComponentCommand extends TBMCCommandBase {
@Override @Override
public boolean OnCommand(CommandSender sender, String alias, String[] args) { public boolean OnCommand(CommandSender sender, String alias, String[] args) {
if (args.length < 2) if (args.length < 1)
return false; return false;
switch (args[0]) { boolean enable = true;
case "enable": try {
break; switch (args[0]) {
case "disable": case "enable":
break; enable = true;
case "list": break;
break; case "disable":
default: enable = false;
break;
case "list":
sender.sendMessage("§6List of components:");
Component.getComponents().values().stream().map(c -> c.getPlugin().getName() + " - " + c.getClass().getSimpleName() + " - " + (c.isEnabled() ? "en" : "dis") + "abled").forEach(sender::sendMessage);
return true;
default:
return false;
}
if (args.length < 2)
return false; return false;
val oc = getComponentOrError(args[1], sender);
if (!oc.isPresent())
return true;
if (enable) //Reload config so the new config values are read
getPlugin().reloadConfig(); //All changes are saved to disk on disable
Component.setComponentEnabled(oc.get(), enable);
sender.sendMessage(oc.get().getClass().getSimpleName() + " " + (enable ? "en" : "dis") + "abled.");
} catch (Exception e) {
TBMCCoreAPI.SendException("Couldn't " + (enable ? "en" : "dis") + "able component " + args[0] + "!", e);
} }
return true; return true;
} }
private Optional<Component> getComponentOrError(String arg, CommandSender sender) {
val oc = Component.getComponents().values().stream().filter(c -> c.getClass().getSimpleName().equalsIgnoreCase(arg)).findAny();
if (!oc.isPresent())
sender.sendMessage("§cComponent not found!");
return oc;
}
@Override @Override
public String[] GetHelpText(String alias) { public String[] GetHelpText(String alias) {
return new String[0]; return new String[]{
"§6---- Component command ----",
"Enable or disable or list components"
};
} }
} }

View file

@ -1,12 +1,18 @@
package buttondevteam.core; package buttondevteam.core;
import buttondevteam.component.channel.Channel;
import buttondevteam.component.channel.ChannelComponent;
import buttondevteam.component.channel.ChatRoom;
import buttondevteam.component.members.MemberComponent;
import buttondevteam.component.randomtp.RandomTPComponent;
import buttondevteam.component.restart.RestartComponent; import buttondevteam.component.restart.RestartComponent;
import buttondevteam.component.towny.TownyComponent;
import buttondevteam.component.updater.PluginUpdater; import buttondevteam.component.updater.PluginUpdater;
import buttondevteam.component.updater.PluginUpdaterComponent; import buttondevteam.component.updater.PluginUpdaterComponent;
import buttondevteam.lib.TBMCCoreAPI; import buttondevteam.lib.TBMCCoreAPI;
import buttondevteam.lib.architecture.ButtonPlugin;
import buttondevteam.lib.architecture.Component; import buttondevteam.lib.architecture.Component;
import buttondevteam.lib.chat.Channel; import buttondevteam.lib.architecture.ConfigData;
import buttondevteam.lib.chat.ChatRoom;
import buttondevteam.lib.chat.Color; import buttondevteam.lib.chat.Color;
import buttondevteam.lib.chat.TBMCChatAPI; import buttondevteam.lib.chat.TBMCChatAPI;
import buttondevteam.lib.player.ChromaGamerBase; import buttondevteam.lib.player.ChromaGamerBase;
@ -16,11 +22,12 @@ import com.earth2me.essentials.Essentials;
import net.milkbowl.vault.permission.Permission; import net.milkbowl.vault.permission.Permission;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.command.BlockCommandSender; import org.bukkit.command.BlockCommandSender;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.command.ConsoleCommandSender; import org.bukkit.command.ConsoleCommandSender;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.plugin.PluginDescriptionFile; import org.bukkit.plugin.PluginDescriptionFile;
import org.bukkit.plugin.RegisteredServiceProvider; import org.bukkit.plugin.RegisteredServiceProvider;
import org.bukkit.plugin.java.JavaPlugin;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import java.io.File; import java.io.File;
@ -32,7 +39,7 @@ import java.util.Optional;
import java.util.UUID; import java.util.UUID;
import java.util.logging.Logger; import java.util.logging.Logger;
public class MainPlugin extends JavaPlugin { public class MainPlugin extends ButtonPlugin {
public static MainPlugin Instance; public static MainPlugin Instance;
@Nullable @Nullable
public static Permission permission; public static Permission permission;
@ -41,8 +48,12 @@ public class MainPlugin extends JavaPlugin {
private Logger logger; private Logger logger;
private ConfigData<Boolean> writePluginList() {
return getIConfig().getData("writePluginList", false);
}
@Override @Override
public void onEnable() { public void pluginEnable() {
// Logs "Plugin Enabled", registers commands // Logs "Plugin Enabled", registers commands
Instance = this; Instance = this;
PluginDescriptionFile pdf = getDescription(); PluginDescriptionFile pdf = getDescription();
@ -52,16 +63,19 @@ public class MainPlugin extends JavaPlugin {
saveConfig(); saveConfig();
Component.registerComponent(this, new PluginUpdaterComponent()); Component.registerComponent(this, new PluginUpdaterComponent());
Component.registerComponent(this, new RestartComponent()); Component.registerComponent(this, new RestartComponent());
Component.registerComponent(this, new ChannelComponent());
Component.registerComponent(this, new RandomTPComponent());
Component.registerComponent(this, new MemberComponent());
Component.registerComponent(this, new TownyComponent());
ComponentManager.enableComponents(); ComponentManager.enableComponents();
TBMCChatAPI.AddCommand(this, MemberCommand.class); TBMCChatAPI.AddCommand(this, ComponentCommand.class);
TBMCCoreAPI.RegisterEventsForExceptions(new PlayerListener(), this); TBMCCoreAPI.RegisterEventsForExceptions(new PlayerListener(), this);
ChromaGamerBase.addConverter(commandSender -> Optional.ofNullable(commandSender instanceof ConsoleCommandSender || commandSender instanceof BlockCommandSender ChromaGamerBase.addConverter(commandSender -> Optional.ofNullable(commandSender instanceof ConsoleCommandSender || commandSender instanceof BlockCommandSender
? TBMCPlayer.getPlayer(new UUID(0, 0), TBMCPlayer.class) : null)); //Console & cmdblocks ? TBMCPlayer.getPlayer(new UUID(0, 0), TBMCPlayer.class) : null)); //Console & cmdblocks
ChromaGamerBase.addConverter(sender -> Optional.ofNullable(sender instanceof Player ChromaGamerBase.addConverter(sender -> Optional.ofNullable(sender instanceof Player
? TBMCPlayer.getPlayer(((Player) sender).getUniqueId(), TBMCPlayer.class) : null)); //Players, has higher priority ? TBMCPlayer.getPlayer(((Player) sender).getUniqueId(), TBMCPlayer.class) : null)); //Players, has higher priority
TBMCCoreAPI.RegisterUserClass(TBMCPlayerBase.class); TBMCCoreAPI.RegisterUserClass(TBMCPlayerBase.class);
TBMCChatAPI.RegisterChatChannel(Channel.GlobalChat = new Channel("§fOOC§f", Color.White, "ooc", null)); TBMCChatAPI.RegisterChatChannel(Channel.GlobalChat = new Channel("§fOOC§f", Color.White, "g", null)); //The /ooc ID has moved to the config
Channel.GlobalChat.IDs = new String[]{"g"}; //Support /g as well
TBMCChatAPI.RegisterChatChannel( TBMCChatAPI.RegisterChatChannel(
Channel.AdminChat = new Channel("§cADMIN§f", Color.Red, "a", Channel.inGroupFilter(null))); Channel.AdminChat = new Channel("§cADMIN§f", Color.Red, "a", Channel.inGroupFilter(null)));
TBMCChatAPI.RegisterChatChannel( TBMCChatAPI.RegisterChatChannel(
@ -73,18 +87,19 @@ public class MainPlugin extends JavaPlugin {
TBMCChatAPI.RegisterChatChannel(new ChatRoom("§aGREEN§f", Color.Green, "green")); TBMCChatAPI.RegisterChatChannel(new ChatRoom("§aGREEN§f", Color.Green, "green"));
TBMCChatAPI.RegisterChatChannel(new ChatRoom("§bBLUE§f", Color.Blue, "blue")); TBMCChatAPI.RegisterChatChannel(new ChatRoom("§bBLUE§f", Color.Blue, "blue"));
TBMCChatAPI.RegisterChatChannel(new ChatRoom("§5PURPLE§f", Color.DarkPurple, "purple")); TBMCChatAPI.RegisterChatChannel(new ChatRoom("§5PURPLE§f", Color.DarkPurple, "purple"));
try { if (writePluginList().get()) {
Files.write(new File("plugins", "plugins.txt").toPath(), Arrays.stream(Bukkit.getPluginManager().getPlugins()).map(p -> (CharSequence) p.getDataFolder().getName())::iterator); try {
} catch (IOException e) { Files.write(new File("plugins", "plugins.txt").toPath(), Arrays.stream(Bukkit.getPluginManager().getPlugins()).map(p -> (CharSequence) p.getDataFolder().getName())::iterator);
TBMCCoreAPI.SendException("Failed to write plugin list!", e); } catch (IOException e) {
TBMCCoreAPI.SendException("Failed to write plugin list!", e);
}
} }
ess = Essentials.getPlugin(Essentials.class); ess = Essentials.getPlugin(Essentials.class);
new RandomTP().onEnable(this); //It registers it's command
logger.info(pdf.getName() + " has been Enabled (V." + pdf.getVersion() + ") Test: " + Test + "."); logger.info(pdf.getName() + " has been Enabled (V." + pdf.getVersion() + ") Test: " + Test + ".");
} }
@Override @Override
public void onDisable() { public void pluginDisable() {
ComponentManager.disableComponents(); ComponentManager.disableComponents();
logger.info("Saving player data..."); logger.info("Saving player data...");
TBMCPlayerBase.savePlayers(); TBMCPlayerBase.savePlayers();
@ -93,16 +108,16 @@ public class MainPlugin extends JavaPlugin {
File[] files = PluginUpdater.updatedir.listFiles(); File[] files = PluginUpdater.updatedir.listFiles();
if (files == null) if (files == null)
return; return;
System.out.println("Updating " + files.length + " plugins..."); logger.info("Updating " + files.length + " plugins...");
for (File file : files) { for (File file : files) {
try { try {
Files.move(file.toPath(), new File("plugins", file.getName()).toPath(), StandardCopyOption.REPLACE_EXISTING); Files.move(file.toPath(), new File("plugins", file.getName()).toPath(), StandardCopyOption.REPLACE_EXISTING);
System.out.println("Updated " + file.getName()); logger.info("Updated " + file.getName());
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); e.printStackTrace();
} }
} }
System.out.println("Update complete!"); logger.info("Update complete!");
}).start(); }).start();
} }
@ -114,4 +129,10 @@ public class MainPlugin extends JavaPlugin {
} }
return (permission != null); return (permission != null);
} }
@Override
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
sender.sendMessage("§cThis command isn't available."); //In theory, unregistered commands use this method
return true;
}
} }

View file

@ -1,61 +1,35 @@
package buttondevteam.core; package buttondevteam.core;
import buttondevteam.lib.TBMCSystemChatEvent; import buttondevteam.lib.TBMCSystemChatEvent;
import buttondevteam.lib.chat.IFakePlayer;
import buttondevteam.lib.player.TBMCPlayerBase; import buttondevteam.lib.player.TBMCPlayerBase;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.Statistic;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority; import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener; import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerJoinEvent; import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.event.player.PlayerQuitEvent; import org.bukkit.event.player.PlayerQuitEvent;
import java.time.Instant; import java.util.Arrays;
import java.time.temporal.ChronoUnit;
import java.util.Date;
import static buttondevteam.core.MainPlugin.permission;
public class PlayerListener implements Listener { public class PlayerListener implements Listener {
@EventHandler(priority = EventPriority.NORMAL) @EventHandler(priority = EventPriority.NORMAL)
public void OnPlayerJoin(PlayerJoinEvent event) { public void OnPlayerJoin(PlayerJoinEvent event) {
TBMCPlayerBase.joinPlayer(event.getPlayer()); TBMCPlayerBase.joinPlayer(event.getPlayer());
if (permission != null && !permission.playerInGroup(event.getPlayer(), "member")
&& (new Date(event.getPlayer().getFirstPlayed()).toInstant().plus(7, ChronoUnit.DAYS).isBefore(Instant.now())
|| event.getPlayer().getStatistic(Statistic.PLAY_ONE_TICK) > 20 * 3600 * 12)) {
permission.playerAddGroup(null, event.getPlayer(), "member");
event.getPlayer().sendMessage("§bYou are a member now. YEEHAW");
MainPlugin.Instance.getLogger().info("Added " + event.getPlayer().getName() + " as a member.");
}
} }
private long lasttime = 0;
@EventHandler(priority = EventPriority.NORMAL) @EventHandler(priority = EventPriority.NORMAL)
public void OnPlayerLeave(PlayerQuitEvent event) { public void OnPlayerLeave(PlayerQuitEvent event) {
TBMCPlayerBase.quitPlayer(event.getPlayer()); TBMCPlayerBase.quitPlayer(event.getPlayer());
if (PrimeRestartCommand.isPlsrestart()
&& !event.getQuitMessage().equalsIgnoreCase("Server closed")
&& !event.getQuitMessage().equalsIgnoreCase("Server is restarting")) {
if (Bukkit.getOnlinePlayers().size() <= 1) {
if (PrimeRestartCommand.isLoud())
Bukkit.broadcastMessage("§cNobody is online anymore. Restarting.");
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.");
}
}
} }
@EventHandler(priority = EventPriority.HIGHEST) @EventHandler(priority = EventPriority.HIGHEST)
public void onSystemChat(TBMCSystemChatEvent event) { public void onSystemChat(TBMCSystemChatEvent event) {
if (event.isHandled()) if (event.isHandled())
return; // Only handle here if ButtonChat couldn't return; // Only handle here if ButtonChat couldn't - ButtonChat doesn't even handle this
if (Arrays.stream(event.getExceptions()).anyMatch("Minecraft"::equalsIgnoreCase))
return;
Bukkit.getOnlinePlayers().stream().filter(event::shouldSendTo) Bukkit.getOnlinePlayers().stream().filter(event::shouldSendTo)
.forEach(p -> p.sendMessage(event.getChannel().DisplayName.substring(0, 2) + event.getMessage())); .forEach(p -> p.sendMessage(event.getChannel().DisplayName().get().substring(0, 2) + event.getMessage()));
} }
} }

View file

@ -1,6 +1,8 @@
package buttondevteam.core; package buttondevteam.core;
import buttondevteam.lib.chat.Channel; import buttondevteam.component.channel.Channel;
import buttondevteam.component.channel.ChannelComponent;
import buttondevteam.lib.architecture.Component;
import buttondevteam.lib.chat.Color; import buttondevteam.lib.chat.Color;
import buttondevteam.lib.chat.TBMCChatAPI; import buttondevteam.lib.chat.TBMCChatAPI;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
@ -38,6 +40,7 @@ public class TestPrepare {
return cl.isAssignableFrom(invocation.getMethod().getReturnType()); return cl.isAssignableFrom(invocation.getMethod().getReturnType());
} }
})); }));
Component.registerComponent(Mockito.mock(MainPlugin.class), new ChannelComponent());
TBMCChatAPI.RegisterChatChannel(Channel.GlobalChat = new Channel("§fg§f", Color.White, "g", null)); TBMCChatAPI.RegisterChatChannel(Channel.GlobalChat = new Channel("§fg§f", Color.White, "g", null));
} }
} }

View file

@ -1,6 +1,6 @@
package buttondevteam.lib; package buttondevteam.lib;
import buttondevteam.lib.chat.Channel; import buttondevteam.component.channel.Channel;
import buttondevteam.lib.chat.ChatMessage; import buttondevteam.lib.chat.ChatMessage;
import lombok.Getter; import lombok.Getter;
import lombok.experimental.Delegate; import lombok.experimental.Delegate;

View file

@ -1,6 +1,6 @@
package buttondevteam.lib; package buttondevteam.lib;
import buttondevteam.lib.chat.Channel; import buttondevteam.component.channel.Channel;
import lombok.Getter; import lombok.Getter;
import lombok.NonNull; import lombok.NonNull;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;

View file

@ -1,6 +1,6 @@
package buttondevteam.lib; package buttondevteam.lib;
import buttondevteam.lib.chat.Channel; import buttondevteam.component.channel.Channel;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;

View file

@ -1,6 +1,6 @@
package buttondevteam.lib; package buttondevteam.lib;
import buttondevteam.lib.chat.Channel; import buttondevteam.component.channel.Channel;
import lombok.Getter; import lombok.Getter;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.event.HandlerList; import org.bukkit.event.HandlerList;
@ -13,14 +13,16 @@ import org.bukkit.event.HandlerList;
*/ */
@Getter @Getter
public class TBMCSystemChatEvent extends TBMCChatEventBase { public class TBMCSystemChatEvent extends TBMCChatEventBase {
private final String[] exceptions;
private boolean handled; private boolean handled;
public void setHandled() { public void setHandled() {
handled = true; handled = true;
} }
public TBMCSystemChatEvent(Channel channel, String message, int score, String groupid) { // TODO: Rich message public TBMCSystemChatEvent(Channel channel, String message, int score, String groupid, String[] exceptions) { // TODO: Rich message
super(channel, message, score, groupid); super(channel, message, score, groupid);
this.exceptions = exceptions;
} }
private static final HandlerList handlers = new HandlerList(); private static final HandlerList handlers = new HandlerList();

View file

@ -1,25 +1,25 @@
package buttondevteam.lib.architecture; package buttondevteam.lib.architecture;
import buttondevteam.lib.TBMCCoreAPI; import buttondevteam.lib.TBMCCoreAPI;
import org.bukkit.configuration.ConfigurationSection; import buttondevteam.lib.chat.TBMCChatAPI;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.experimental.var;
import org.bukkit.plugin.java.JavaPlugin; import org.bukkit.plugin.java.JavaPlugin;
import java.util.HashMap;
import java.util.Map;
import java.util.function.Function;
public abstract class ButtonPlugin extends JavaPlugin { public abstract class ButtonPlugin extends JavaPlugin {
private final HashMap<String, ConfigData<?>> datamap = new HashMap<>(); @Getter(AccessLevel.PROTECTED)
private ConfigurationSection section; private IHaveConfig iConfig;
protected abstract void pluginEnable(); protected abstract void pluginEnable();
protected abstract void pluginDisable(); protected abstract void pluginDisable();
@Override @Override
public void onEnable() { public final void onEnable() {
section = getConfig().getConfigurationSection("global"); var section = super.getConfig().getConfigurationSection("global");
if (section == null) section = getConfig().createSection("global"); if (section == null) section = super.getConfig().createSection("global");
iConfig = new IHaveConfig(section);
try { try {
pluginEnable(); pluginEnable();
} catch (Exception e) { } catch (Exception e) {
@ -28,25 +28,14 @@ public abstract class ButtonPlugin extends JavaPlugin {
} }
@Override @Override
public void onDisable() { public final void onDisable() {
try { try {
pluginDisable(); pluginDisable();
saveConfig();
iConfig = null; //Clearing the hashmap is not enough, we need to update the section as well
TBMCChatAPI.RemoveCommands(this);
} catch (Exception e) { } catch (Exception e) {
TBMCCoreAPI.SendException("Error while disabling plugin " + getName() + "!", e); TBMCCoreAPI.SendException("Error while disabling plugin " + getName() + "!", e);
} }
} }
/**
* @see IHaveConfig#getData(Map, ConfigurationSection, String, Object)
*/
protected <T> ConfigData<T> getData(String path, T def) {
return IHaveConfig.getData(datamap, section, path, def);
}
/**
* @see IHaveConfig#getData(Map, ConfigurationSection, String, Object, Function, Function)
*/
protected <T> ConfigData<T> getData(String path, T def, Function<Object, T> getter, Function<T, Object> setter) {
return IHaveConfig.getData(datamap, section, path, def, getter, setter);
}
} }

View file

@ -5,19 +5,16 @@ import buttondevteam.lib.TBMCCoreAPI;
import buttondevteam.lib.architecture.exceptions.UnregisteredComponentException; import buttondevteam.lib.architecture.exceptions.UnregisteredComponentException;
import buttondevteam.lib.chat.TBMCChatAPI; import buttondevteam.lib.chat.TBMCChatAPI;
import buttondevteam.lib.chat.TBMCCommandBase; import buttondevteam.lib.chat.TBMCCommandBase;
import lombok.AccessLevel;
import lombok.Getter; import lombok.Getter;
import lombok.NonNull; import lombok.NonNull;
import lombok.experimental.var; import lombok.experimental.var;
import lombok.val; import lombok.val;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.event.Listener; import org.bukkit.event.Listener;
import org.bukkit.plugin.java.JavaPlugin; import org.bukkit.plugin.java.JavaPlugin;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.function.Function;
/** /**
* Configuration is based on class name * Configuration is based on class name
@ -27,30 +24,15 @@ public abstract class Component {
@Getter @Getter
private boolean enabled = false; private boolean enabled = false;
@Getter(value = AccessLevel.PROTECTED) @Getter
@NonNull @NonNull
private JavaPlugin plugin; private JavaPlugin plugin;
@NonNull @NonNull
private ConfigurationSection config; private @Getter
IHaveConfig config;
public ConfigData<Boolean> shouldBeEnabled() { public final ConfigData<Boolean> shouldBeEnabled() {
return getData("enabled", true); return config.getData("enabled", true);
}
private HashMap<String, ConfigData<?>> datamap = new HashMap<>();
/**
* @see IHaveConfig#getData(Map, ConfigurationSection, String, Object)
*/
protected <T> ConfigData<T> getData(String path, T def) {
return IHaveConfig.getData(datamap, config, path, def);
}
/**
* @see IHaveConfig#getData(Map, ConfigurationSection, String, Object, Function, Function)
*/
protected <T> ConfigData<T> getData(String path, T def, Function<Object, T> getter, Function<T, Object> setter) {
return IHaveConfig.getData(datamap, config, path, def, getter, setter);
} }
/** /**
@ -84,7 +66,7 @@ public abstract class Component {
val metaAnn = component.getClass().getAnnotation(ComponentMetadata.class); val metaAnn = component.getClass().getAnnotation(ComponentMetadata.class);
if (metaAnn != null) { if (metaAnn != null) {
Class<? extends Component>[] dependencies = metaAnn.depends(); Class<? extends Component>[] dependencies = metaAnn.depends();
for (val dep : dependencies) { for (val dep : dependencies) { //TODO: Support dependencies at enable/disable as well
if (!components.containsKey(dep)) { if (!components.containsKey(dep)) {
plugin.getLogger().warning("Failed to " + (register ? "" : "un") + "register component " + component.getClassName() + " as a required dependency is missing/disabled: " + dep.getSimpleName()); plugin.getLogger().warning("Failed to " + (register ? "" : "un") + "register component " + component.getClassName() + " as a required dependency is missing/disabled: " + dep.getSimpleName());
return false; return false;
@ -93,10 +75,7 @@ public abstract class Component {
} }
if (register) { if (register) {
component.plugin = plugin; component.plugin = plugin;
var compconf = plugin.getConfig().getConfigurationSection("components"); updateConfig(plugin, component);
if (compconf == null) compconf = plugin.getConfig().createSection("components");
component.config = compconf.getConfigurationSection(component.getClassName());
if (component.config == null) component.config = compconf.createSection(component.getClassName());
component.register(plugin); component.register(plugin);
components.put(component.getClass(), component); components.put(component.getClass(), component);
if (ComponentManager.areComponentsEnabled() && component.shouldBeEnabled().get()) { if (ComponentManager.areComponentsEnabled() && component.shouldBeEnabled().get()) {
@ -108,12 +87,11 @@ public abstract class Component {
return true; return true;
} }
} }
return true; return true; //Component shouldn't be enabled
} else { } else {
if (component.enabled) { if (component.enabled) {
try { try {
component.disable(); setComponentEnabled(component, false);
component.enabled = false;
} catch (Exception | NoClassDefFoundError e) { } catch (Exception | NoClassDefFoundError e) {
TBMCCoreAPI.SendException("Failed to disable component " + component.getClassName() + "!", e); TBMCCoreAPI.SendException("Failed to disable component " + component.getClassName() + "!", e);
return false; //If failed to disable, won't unregister either return false; //If failed to disable, won't unregister either
@ -138,10 +116,27 @@ public abstract class Component {
public static void setComponentEnabled(Component component, boolean enabled) throws UnregisteredComponentException { public static void setComponentEnabled(Component component, boolean enabled) throws UnregisteredComponentException {
if (!components.containsKey(component.getClass())) if (!components.containsKey(component.getClass()))
throw new UnregisteredComponentException(component); throw new UnregisteredComponentException(component);
if (component.enabled = enabled) if (component.enabled == enabled) return; //Don't do anything
if (component.enabled = enabled) {
updateConfig(component.getPlugin(), component);
component.enable(); component.enable();
else } else {
component.disable(); component.disable();
component.plugin.saveConfig();
TBMCChatAPI.RemoveCommands(component);
}
}
private 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);
} else //Testing
component.config = new IHaveConfig(null);
} }
/** /**
@ -159,6 +154,7 @@ public abstract class Component {
* *
* @param plugin Plugin object * @param plugin Plugin object
*/ */
@SuppressWarnings({"unused", "WeakerAccess"})
protected void register(JavaPlugin plugin) { protected void register(JavaPlugin plugin) {
} }
@ -169,6 +165,7 @@ public abstract class Component {
* *
* @param plugin Plugin object * @param plugin Plugin object
*/ */
@SuppressWarnings({"WeakerAccess", "unused"})
protected void unregister(JavaPlugin plugin) { protected void unregister(JavaPlugin plugin) {
} }
@ -187,35 +184,26 @@ public abstract class Component {
protected abstract void disable(); protected abstract void disable();
/** /**
* Registers a TBMCCommand to the plugin. Make sure to add it to plugin.yml and use {@link buttondevteam.lib.chat.CommandClass}. * Registers a TBMCCommand to the component. Make sure to add it to plugin.yml and use {@link buttondevteam.lib.chat.CommandClass}.
* *
* @param plugin Main plugin responsible for stuff
* @param commandBase Custom coded command class * @param commandBase Custom coded command class
*/ */
protected void registerCommand(JavaPlugin plugin, TBMCCommandBase commandBase) { protected final void registerCommand(TBMCCommandBase commandBase) {
TBMCChatAPI.AddCommand(plugin, commandBase); TBMCChatAPI.AddCommand(this, commandBase);
} }
/** /**
* Registers a Listener to this plugin * Registers a Listener to this component
* *
* @param plugin Main plugin responsible for stuff
* @param listener The event listener to register * @param listener The event listener to register
* @return The provided listener * @return The provided listener
*/ */
protected Listener registerListener(JavaPlugin plugin, Listener listener) { protected final Listener registerListener(Listener listener) {
TBMCCoreAPI.RegisterEventsForExceptions(listener, plugin); TBMCCoreAPI.RegisterEventsForExceptions(listener, plugin);
return listener; return listener;
} }
private String getClassName() { private String getClassName() {
Class<?> enclosingClass = getClass().getEnclosingClass(); return getClass().getSimpleName();
String className;
if (enclosingClass != null) {
className = (enclosingClass.getName());
} else {
className = (getClass().getName());
}
return className;
} }
} }

View file

@ -1,23 +1,27 @@
package buttondevteam.lib.architecture; package buttondevteam.lib.architecture;
import lombok.AccessLevel; import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import org.bukkit.configuration.ConfigurationSection; import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.configuration.file.YamlConfiguration;
import java.util.Objects;
import java.util.function.Function; import java.util.function.Function;
/** /**
* Use the getter/setter constructor if {@link T} isn't a primitive type or String.<br> * Use the getter/setter constructor if {@link T} isn't a primitive type or String.<br>
* Use {@link Component#getData(String, Object)} or {@link ButtonPlugin#getData(String, Object)} to get an instance. * Use {@link Component#getConfig()} or {@link ButtonPlugin#getIConfig()} then {@link IHaveConfig#getData(String, Object)} to get an instance.
*/ */
@RequiredArgsConstructor(access = AccessLevel.PACKAGE) @RequiredArgsConstructor(access = AccessLevel.PACKAGE)
@AllArgsConstructor(access = AccessLevel.PACKAGE) //@AllArgsConstructor(access = AccessLevel.PACKAGE)
public class ConfigData<T> { //TODO: Save after a while public class ConfigData<T> { //TODO: Save after a while
/**
* May be null for testing
*/
private final ConfigurationSection config; private final ConfigurationSection config;
private final String path; private final String path;
private final T def; private final T def;
private final Object primitiveDef;
/** /**
* The parameter is of a primitive type as returned by {@link YamlConfiguration#get(String)} * The parameter is of a primitive type as returned by {@link YamlConfiguration#get(String)}
*/ */
@ -27,9 +31,32 @@ public class ConfigData<T> { //TODO: Save after a while
*/ */
private Function<T, Object> setter; private Function<T, Object> setter;
/**
* The config value should not change outside this instance
*/
private T value;
private boolean saved = false;
public ConfigData(ConfigurationSection config, String path, T def, Object primitiveDef, Function<Object, T> getter, Function<T, Object> setter) {
this.config = config;
this.path = path;
this.def = def;
this.primitiveDef = primitiveDef;
this.getter = getter;
this.setter = setter;
}
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public T get() { public T get() {
Object val = config.get(path, def); if (value != null) return value; //Speed things up
Object val = config == null ? null : config.get(path); //config==null: testing
if (val == null) {
val = primitiveDef;
}
if (!saved && Objects.equals(val, primitiveDef)) { //String needs .equals()
set(def); //Save default value - def is always set
saved = true;
}
if (getter != null) { if (getter != null) {
T hmm = getter.apply(val); T hmm = getter.apply(val);
if (hmm == null) hmm = def; //Set if the getter returned null if (hmm == null) hmm = def; //Set if the getter returned null
@ -43,6 +70,8 @@ public class ConfigData<T> { //TODO: Save after a while
if (setter != null) if (setter != null)
val = setter.apply(value); val = setter.apply(value);
else val = value; else val = value;
config.set(path, val); if (config != null)
config.set(path, val);
this.value = value;
} }
} }

View file

@ -1,15 +1,27 @@
package buttondevteam.lib.architecture; package buttondevteam.lib.architecture;
import lombok.Getter;
import org.bukkit.configuration.ConfigurationSection; import org.bukkit.configuration.ConfigurationSection;
import java.util.Map; import java.util.HashMap;
import java.util.function.Function; import java.util.function.Function;
/** /**
* Members of this interface should be protected (access level) * Members of this interface should be protected (access level)
*/ */
final class IHaveConfig { public final class IHaveConfig {
private IHaveConfig() {} private final HashMap<String, ConfigData<?>> datamap = new HashMap<>();
@Getter
private ConfigurationSection config;
/**
* May be used in testing
*
* @param section May be null for testing
*/
IHaveConfig(ConfigurationSection section) {
config = section;
}
/** /**
* This method overload should only be used with primitves or String. * This method overload should only be used with primitves or String.
@ -20,9 +32,9 @@ final class IHaveConfig {
* @return The data object that can be used to get or set the value * @return The data object that can be used to get or set the value
*/ */
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
protected static <T> ConfigData<T> getData(Map<String, ConfigData<?>> datamap, ConfigurationSection config, String path, T def) { public <T> ConfigData<T> getData(String path, T def) {
ConfigData<?> data = datamap.get(path); ConfigData<?> data = datamap.get(path);
if (data == null) datamap.put(path, data = new ConfigData<>(config, path, def)); if (data == null) datamap.put(path, data = new ConfigData<>(config, path, def, def));
return (ConfigData<T>) data; return (ConfigData<T>) data;
} }
@ -37,9 +49,28 @@ final class IHaveConfig {
* @return The data object that can be used to get or set the value * @return The data object that can be used to get or set the value
*/ */
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
protected static <T> ConfigData<T> getData(Map<String, ConfigData<?>> datamap, ConfigurationSection config, String path, T def, Function<Object, T> getter, Function<T, Object> setter) { public <T> ConfigData<T> getData(String path, T def, Function<Object, T> getter, Function<T, Object> setter) {
ConfigData<?> data = datamap.get(path); ConfigData<?> data = datamap.get(path);
if (data == null) datamap.put(path, data = new ConfigData<>(config, path, def, getter, setter)); if (data == null)
datamap.put(path, data = new ConfigData<>(config, path, def, setter.apply(def), getter, setter));
return (ConfigData<T>) data;
}
/**
* This method overload may be used with any class. The given default value will be run through the getter.
*
* @param path The path in config to use
* @param primitiveDef The <b>primitive</b> value to use by default
* @param getter A function that converts a primitive representation to the correct value
* @param setter A function that converts a value to a primitive representation
* @param <T> The type of this variable (can be any class)
* @return The data object that can be used to get or set the value
*/
@SuppressWarnings("unchecked")
public <T> ConfigData<T> getDataPrimDef(String path, Object primitiveDef, Function<Object, T> getter, Function<T, Object> setter) {
ConfigData<?> data = datamap.get(path);
if (data == null)
datamap.put(path, data = new ConfigData<>(config, path, getter.apply(primitiveDef), primitiveDef, getter, setter));
return (ConfigData<T>) data; return (ConfigData<T>) data;
} }
} }

View file

@ -0,0 +1,31 @@
package buttondevteam.lib.chat;
import org.bukkit.command.CommandSender;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
public abstract class Command2 {
/**
* Default handler for commands, can be used to copy the args too.
*
* @param sender The sender which ran the command
* @param command The (sub)command ran by the user
* @param args All of the arguments passed as is
* @return
*/
public boolean def(CommandSender sender, String command, @TextArg String args) {
return false;
}
/**
* TODO: @CommandClass(helpText=...)
* Parameters annotated with this receive all of the remaining arguments
*/
@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
public @interface TextArg {
}
}

View file

@ -36,4 +36,11 @@ public @interface CommandClass {
* Exclude this class from the path. Useful if more commands share some property but aren't subcommands of a common command. See {@link CommandClass} for more details. * Exclude this class from the path. Useful if more commands share some property but aren't subcommands of a common command. See {@link CommandClass} for more details.
*/ */
boolean excludeFromPath() default false; boolean excludeFromPath() default false;
/**
* The help text to show for the players.
*
* @return The help text
*/
String[] helpText() default {};
} }

View file

@ -1,12 +1,14 @@
package buttondevteam.lib.chat; package buttondevteam.lib.chat;
import buttondevteam.component.channel.Channel;
import buttondevteam.component.channel.Channel.RecipientTestResult;
import buttondevteam.core.CommandCaller; import buttondevteam.core.CommandCaller;
import buttondevteam.core.MainPlugin; import buttondevteam.core.MainPlugin;
import buttondevteam.lib.TBMCChatEvent; import buttondevteam.lib.TBMCChatEvent;
import buttondevteam.lib.TBMCChatPreprocessEvent; import buttondevteam.lib.TBMCChatPreprocessEvent;
import buttondevteam.lib.TBMCCoreAPI; import buttondevteam.lib.TBMCCoreAPI;
import buttondevteam.lib.TBMCSystemChatEvent; import buttondevteam.lib.TBMCSystemChatEvent;
import buttondevteam.lib.chat.Channel.RecipientTestResult; import buttondevteam.lib.architecture.Component;
import lombok.val; import lombok.val;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
@ -119,10 +121,8 @@ public class TBMCChatAPI {
continue; continue;
TBMCCommandBase c = cmd.newInstance(); TBMCCommandBase c = cmd.newInstance();
c.plugin = plugin; c.plugin = plugin;
if (HasNulls(plugin, c)) CommandCaller.RegisterCommand(c); //Will check for nulls
continue;
commands.put(c.GetCommandPath(), c); commands.put(c.GetCommandPath(), c);
CommandCaller.RegisterCommand(c);
} catch (Exception e) { } catch (Exception e) {
TBMCCoreAPI.SendException("An error occured while registering command " + cmd.getName(), e); TBMCCoreAPI.SendException("An error occured while registering command " + cmd.getName(), e);
} }
@ -131,7 +131,7 @@ public class TBMCChatAPI {
/** /**
* <p> * <p>
* This method adds a plugin's command to help and sets it's executor. * This method adds a plugin's command to help and sets it's executor. They will be automatically unregistered on plugin disable.
* </p> * </p>
* <p> * <p>
* The <u>command must be registered</u> in the caller plugin's plugin.yml. Otherwise the plugin will output a messsage to console. * The <u>command must be registered</u> in the caller plugin's plugin.yml. Otherwise the plugin will output a messsage to console.
@ -155,21 +155,19 @@ public class TBMCChatAPI {
else else
c = thecmdclass.newInstance(); c = thecmdclass.newInstance();
c.plugin = plugin; c.plugin = plugin;
if (HasNulls(plugin, c)) CommandCaller.RegisterCommand(c); //Will check for nulls
return;
commands.put(c.GetCommandPath(), c); commands.put(c.GetCommandPath(), c);
CommandCaller.RegisterCommand(c);
} catch (Exception e) { } catch (Exception e) {
TBMCCoreAPI.SendException("An error occured while registering command " + thecmdclass.getSimpleName(), e); TBMCCoreAPI.SendException("An error occured while registering command " + thecmdclass.getSimpleName(), e);
} }
} } //TODO: onCommand(CommandSender sender, String alias, int arg1, String arg2) (planned for a while)
/** /**
* <p> * <p>
* This method adds a plugin's command to help and sets it's executor. * This method adds a plugin's command to help and sets its executor. They will be automatically unregistered on plugin disable.
* </p> * </p>
* <p> * <p>
* The <u>command must be registered</u> in the caller plugin's plugin.yml. Otherwise the plugin will output a messsage to console. * The <u>command must be registered</u> in the caller plugin's plugin.yml. Otherwise the plugin will output a message to console.
* </p> * </p>
* <p> * <p>
* <i>Using this method after the server is done loading will have no effect.</i> * <i>Using this method after the server is done loading will have no effect.</i>
@ -181,29 +179,82 @@ public class TBMCChatAPI {
* The command to add * The command to add
*/ */
public static void AddCommand(JavaPlugin plugin, TBMCCommandBase cmd) { public static void AddCommand(JavaPlugin plugin, TBMCCommandBase cmd) {
if (HasNulls(plugin, cmd))
return;
// plugin.getLogger().info("Registering command /" + cmd.GetCommandPath() + " for " + plugin.getName());
try { try {
if (plugin == null) throw new IllegalArgumentException("The plugin is null!");
if (cmd == null) throw new IllegalArgumentException("The command is null!");
cmd.plugin = plugin; cmd.plugin = plugin;
CommandCaller.RegisterCommand(cmd); //Checks for other nulls
commands.put(cmd.GetCommandPath(), cmd); commands.put(cmd.GetCommandPath(), cmd);
CommandCaller.RegisterCommand(cmd);
} catch (Exception e) { } catch (Exception e) {
TBMCCoreAPI.SendException("An error occured while registering command " + cmd.GetCommandPath(), e); TBMCCoreAPI.SendException("An error occured while registering command " + (cmd == null ? "n u l l" : cmd.GetCommandPath()), e);
} }
} }
private static boolean HasNulls(JavaPlugin plugin, TBMCCommandBase cmd) { /**
if (cmd == null) { * <p>
TBMCCoreAPI.SendException("An error occured while registering a command for plugin " + plugin.getName(), * This method adds a plugin's command to help and sets its executor. They will be automatically unregistered on component disable.
new Exception("The command is null!")); * </p>
return true; * <p>
} else if (cmd.GetCommandPath() == null) { * The <u>command must be registered</u> in the caller plugin's plugin.yml. Otherwise the plugin will output a message to console.
TBMCCoreAPI.SendException("An error occured while registering command " + cmd.getClass().getSimpleName() * </p>
+ " for plugin " + plugin.getName(), new Exception("The command path is null!")); * <p>
return true; * <i>Using this method after the server is done loading will have no effect.</i>
* </p>
*
* @param component The caller component
* @param cmd The command to add
*/
public static void AddCommand(Component component, TBMCCommandBase cmd) {
try {
if (component == null) throw new IllegalArgumentException("The component is null!");
if (cmd == null) throw new IllegalArgumentException("The command is null!");
cmd.plugin = component.getPlugin();
cmd.component = component;
CommandCaller.RegisterCommand(cmd); //Checks for other nulls
commands.put(cmd.GetCommandPath(), cmd);
} catch (Exception e) {
TBMCCoreAPI.SendException("An error occured while registering command " + (cmd == null ? "n u l l" : cmd.GetCommandPath()), e);
} }
return false; }
/**
* Removes all commands from the plugin
*
* @param plugin The plugin to remove commands from
*/
public static void RemoveCommands(JavaPlugin plugin) {
commands.values().removeIf(c -> {
try {
if (c.plugin == plugin) {
CommandCaller.UnregisterCommand(c);
return true; //Remove
}
return false;
} catch (Exception e) {
TBMCCoreAPI.SendException("An error occured while unregistering commands for " + plugin.getName(), e);
return true; //Remove if it couldn't get the plugin command
}
});
}
/**
* Removes all commands from the component
*
* @param component The component to remove commands from
*/
public static void RemoveCommands(Component component) {
commands.values().removeIf(c -> {
try {
if (c.component == component) {
CommandCaller.UnregisterCommand(c);
return true; //Remove
}
return false;
} catch (Exception e) {
TBMCCoreAPI.SendException("An error occured while unregistering commands for " + component.getClass().getSimpleName(), e);
return true; //Remove if it couldn't get the plugin command
}
});
} }
/** /**
@ -226,8 +277,12 @@ public class TBMCChatAPI {
* @return The event cancelled state * @return The event cancelled state
*/ */
public static boolean SendChatMessage(ChatMessage cm, Channel channel) { public static boolean SendChatMessage(ChatMessage cm, Channel channel) {
if (!Channel.getChannels().contains(channel)) if (!Channel.getChannelList().contains(channel))
throw new RuntimeException("Channel " + channel.DisplayName + " not registered!"); throw new RuntimeException("Channel " + channel.DisplayName().get() + " not registered!");
if (!channel.Enabled().get()) {
cm.getSender().sendMessage("§cThe channel '" + channel.DisplayName().get() + "' is disabled!");
return true; //Cancel sending if channel is disabled
}
val permcheck = cm.getPermCheck(); val permcheck = cm.getPermCheck();
RecipientTestResult rtr = getScoreOrSendError(channel, permcheck); RecipientTestResult rtr = getScoreOrSendError(channel, permcheck);
int score = rtr.score; int score = rtr.score;
@ -253,12 +308,15 @@ public class TBMCChatAPI {
* The score&group to use to find the group - use {@link RecipientTestResult#ALL} if the channel doesn't have scores * The score&group to use to find the group - use {@link RecipientTestResult#ALL} if the channel doesn't have scores
* @param message * @param message
* The message to send * The message to send
* @param exceptions Platforms where this message shouldn't be sent (same as {@link ChatMessage#getOrigin()}
* @return The event cancelled state * @return The event cancelled state
*/ */
public static boolean SendSystemMessage(Channel channel, RecipientTestResult rtr, String message) { public static boolean SendSystemMessage(Channel channel, RecipientTestResult rtr, String message, String... exceptions) {
if (!Channel.getChannels().contains(channel)) if (!Channel.getChannelList().contains(channel))
throw new RuntimeException("Channel " + channel.DisplayName + " not registered!"); throw new RuntimeException("Channel " + channel.DisplayName().get() + " not registered!");
TBMCSystemChatEvent event = new TBMCSystemChatEvent(channel, message, rtr.score, rtr.groupID); if (!channel.Enabled().get())
return true; //Cancel sending
TBMCSystemChatEvent event = new TBMCSystemChatEvent(channel, message, rtr.score, rtr.groupID, exceptions);
Bukkit.getPluginManager().callEvent(event); Bukkit.getPluginManager().callEvent(event);
return event.isCancelled(); return event.isCancelled();
} }

View file

@ -1,6 +1,8 @@
package buttondevteam.lib.chat; package buttondevteam.lib.chat;
import buttondevteam.lib.architecture.Component;
import javassist.Modifier; import javassist.Modifier;
import lombok.Getter;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.plugin.Plugin; import org.bukkit.plugin.Plugin;
@ -103,4 +105,7 @@ public abstract class TBMCCommandBase {
} }
return modOnly; return modOnly;
} }
@Getter
Component component; //May be null
} }

View file

@ -1,6 +1,6 @@
package buttondevteam.lib.player; package buttondevteam.lib.player;
import buttondevteam.lib.chat.Channel; import buttondevteam.component.channel.Channel;
import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.configuration.file.YamlConfiguration;
public class ChannelPlayerData { //I just want this to work public class ChannelPlayerData { //I just want this to work
@ -16,7 +16,7 @@ public class ChannelPlayerData { //I just want this to work
String str = data.get(); String str = data.get();
if (str.isEmpty()) if (str.isEmpty())
return def; return def;
return Channel.getChannels().stream().filter(c -> str.equals(c.ID)).findAny().orElse(def); return Channel.getChannels().filter(c -> str.equals(c.ID)).findAny().orElse(def);
} }
public void set(Channel value) { public void set(Channel value) {

View file

@ -1,7 +1,7 @@
package buttondevteam.lib.player; package buttondevteam.lib.player;
import buttondevteam.component.channel.Channel;
import buttondevteam.lib.TBMCCoreAPI; import buttondevteam.lib.TBMCCoreAPI;
import buttondevteam.lib.chat.Channel;
import com.google.common.collect.HashBiMap; import com.google.common.collect.HashBiMap;
import lombok.val; import lombok.val;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;

View file

@ -1,11 +1,7 @@
package buttondevteam.lib.player; package buttondevteam.lib.player;
import buttondevteam.component.towny.TownyComponent;
import buttondevteam.lib.TBMCCoreAPI; import buttondevteam.lib.TBMCCoreAPI;
import com.palmergames.bukkit.towny.Towny;
import com.palmergames.bukkit.towny.exceptions.AlreadyRegisteredException;
import com.palmergames.bukkit.towny.exceptions.NotRegisteredException;
import com.palmergames.bukkit.towny.object.Resident;
import com.palmergames.bukkit.towny.object.TownyUniverse;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.OfflinePlayer; import org.bukkit.OfflinePlayer;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
@ -127,22 +123,7 @@ public abstract class TBMCPlayerBase extends ChromaGamerBase {
Bukkit.getLogger().info("Player name saved: " + player.PlayerName().get()); Bukkit.getLogger().info("Player name saved: " + player.PlayerName().get());
} else if (!p.getName().equals(player.PlayerName().get())) { } else if (!p.getName().equals(player.PlayerName().get())) {
Bukkit.getLogger().info("Renaming " + player.PlayerName().get() + " to " + p.getName()); Bukkit.getLogger().info("Renaming " + player.PlayerName().get() + " to " + p.getName());
TownyUniverse tu = Towny.getPlugin(Towny.class).getTownyUniverse(); TownyComponent.renameInTowny(player.PlayerName().get(), p.getName());
Resident resident = tu.getResidentMap().get(player.PlayerName().get().toLowerCase()); //The map keys are lowercase
if (resident == null) {
Bukkit.getLogger().warning("Resident not found - couldn't rename in Towny.");
TBMCCoreAPI.sendDebugMessage("Resident not found - couldn't rename in Towny.");
} else if (tu.getResidentMap().contains(p.getName().toLowerCase())) {
Bukkit.getLogger().warning("Target resident name is already in use."); // TODO: Handle
TBMCCoreAPI.sendDebugMessage("Target resident name is already in use.");
} else
try {
TownyUniverse.getDataSource().renamePlayer(resident, p.getName()); //Fixed in Towny 0.91.1.2
} catch (AlreadyRegisteredException e) {
TBMCCoreAPI.SendException("Failed to rename resident, there's already one with this name.", e);
} catch (NotRegisteredException e) {
TBMCCoreAPI.SendException("Failed to rename resident, the resident isn't registered.", e);
}
player.PlayerName().set(p.getName()); player.PlayerName().set(p.getName());
Bukkit.getLogger().info("Renaming done."); Bukkit.getLogger().info("Renaming done.");
} }

View file

@ -13,3 +13,5 @@ commands:
description: 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. description: 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.
member: member:
description: Add or remove a member description: Add or remove a member
component:
description: Enable or disable or list components