Components, components everywhere

Channel disable is respected everywhere
Some fixes
Components can be enabled/disabled/listed at runtime
Made RTP a component
Made  e v e r y t h i n g  a component
Made  e v e r y t h i n g  configurable
The plugin list is no longer written by default
#48
This commit is contained in:
Norbi Peti 2019-01-12 22:26:08 +01:00
parent 1b152d8b4e
commit 788c2e8a87
No known key found for this signature in database
GPG key ID: DBA4C4549A927E56
21 changed files with 304 additions and 118 deletions

View file

@ -12,11 +12,13 @@ import org.bukkit.entity.Player;
import javax.annotation.Nullable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.function.BiFunction;
import java.util.function.BiPredicate;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Stream;
public class Channel {
/**
@ -41,11 +43,14 @@ public class Channel {
if (component == null) throw new RuntimeException("Cannot access channel properties until registered!");
}
public final ConfigData<Boolean> Enabled() { //TODO: Implement in all plugins
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);
@ -137,8 +142,22 @@ public class Channel {
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);
}
/**

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.TBMCCommandBase;
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.TBMCChatAPI;
import buttondevteam.lib.chat.TBMCCommandBase;
import org.bukkit.*;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.plugin.java.JavaPlugin;
// @formatter:off
@CommandClass
@SuppressWarnings("FieldCanBeLocal")@CommandClass
public class RandomTP extends TBMCCommandBase
{
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");
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.TBMCCommandBase;

View file

@ -1,20 +1,44 @@
package buttondevteam.component.restart;
import buttondevteam.core.PrimeRestartCommand;
import buttondevteam.core.ScheduledRestartCommand;
import buttondevteam.lib.architecture.Component;
import buttondevteam.lib.chat.IFakePlayer;
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
public void enable() {
//TODO: Permissions for the commands
TBMCChatAPI.AddCommand(this, new ScheduledRestartCommand());
TBMCChatAPI.AddCommand(this, new PrimeRestartCommand());
registerListener(this);
}
@Override
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.chat.CommandClass;
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

@ -1,30 +1,63 @@
package buttondevteam.core;
import buttondevteam.lib.TBMCCoreAPI;
import buttondevteam.lib.architecture.Component;
import buttondevteam.lib.chat.CommandClass;
import buttondevteam.lib.chat.TBMCCommandBase;
import lombok.val;
import org.bukkit.command.CommandSender;
import java.util.Optional;
@CommandClass(modOnly = true)
public class ComponentCommand extends TBMCCommandBase {
@Override
public boolean OnCommand(CommandSender sender, String alias, String[] args) {
if (args.length < 2)
if (args.length < 1)
return false;
boolean enable = true;
try {
switch (args[0]) {
case "enable":
enable = true;
break;
case "disable":
enable = false;
break;
case "list":
break;
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;
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;
}
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
public String[] GetHelpText(String alias) {
return new String[0];
return new String[]{
"§6---- Component command ----",
"Enable or disable or list components"
};
}
}

View file

@ -3,11 +3,16 @@ 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.towny.TownyComponent;
import buttondevteam.component.updater.PluginUpdater;
import buttondevteam.component.updater.PluginUpdaterComponent;
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.TBMCChatAPI;
import buttondevteam.lib.player.ChromaGamerBase;
@ -23,7 +28,6 @@ import org.bukkit.command.ConsoleCommandSender;
import org.bukkit.entity.Player;
import org.bukkit.plugin.PluginDescriptionFile;
import org.bukkit.plugin.RegisteredServiceProvider;
import org.bukkit.plugin.java.JavaPlugin;
import javax.annotation.Nullable;
import java.io.File;
@ -35,7 +39,7 @@ import java.util.Optional;
import java.util.UUID;
import java.util.logging.Logger;
public class MainPlugin extends JavaPlugin {
public class MainPlugin extends ButtonPlugin {
public static MainPlugin Instance;
@Nullable
public static Permission permission;
@ -44,8 +48,12 @@ public class MainPlugin extends JavaPlugin {
private Logger logger;
private ConfigData<Boolean> writePluginList() {
return getIConfig().getData("writePluginList", false);
}
@Override
public void onEnable() {
public void pluginEnable() {
// Logs "Plugin Enabled", registers commands
Instance = this;
PluginDescriptionFile pdf = getDescription();
@ -56,8 +64,11 @@ public class MainPlugin extends JavaPlugin {
Component.registerComponent(this, new PluginUpdaterComponent());
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();
TBMCChatAPI.AddCommand(this, MemberCommand.class);
TBMCChatAPI.AddCommand(this, ComponentCommand.class);
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
@ -76,18 +87,19 @@ public class MainPlugin extends JavaPlugin {
TBMCChatAPI.RegisterChatChannel(new ChatRoom("§aGREEN§f", Color.Green, "green"));
TBMCChatAPI.RegisterChatChannel(new ChatRoom("§bBLUE§f", Color.Blue, "blue"));
TBMCChatAPI.RegisterChatChannel(new ChatRoom("§5PURPLE§f", Color.DarkPurple, "purple"));
if (writePluginList().get()) {
try {
Files.write(new File("plugins", "plugins.txt").toPath(), Arrays.stream(Bukkit.getPluginManager().getPlugins()).map(p -> (CharSequence) p.getDataFolder().getName())::iterator);
} catch (IOException e) {
TBMCCoreAPI.SendException("Failed to write plugin list!", e);
}
}
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 + ".");
}
@Override
public void onDisable() {
public void pluginDisable() {
ComponentManager.disableComponents();
logger.info("Saving player data...");
TBMCPlayerBase.savePlayers();
@ -96,16 +108,16 @@ public class MainPlugin extends JavaPlugin {
File[] files = PluginUpdater.updatedir.listFiles();
if (files == null)
return;
System.out.println("Updating " + files.length + " plugins...");
logger.info("Updating " + files.length + " plugins...");
for (File file : files) {
try {
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) {
e.printStackTrace();
}
}
System.out.println("Update complete!");
logger.info("Update complete!");
}).start();
}

View file

@ -1,61 +1,32 @@
package buttondevteam.core;
import buttondevteam.lib.TBMCSystemChatEvent;
import buttondevteam.lib.chat.IFakePlayer;
import buttondevteam.lib.player.TBMCPlayerBase;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.Statistic;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.event.player.PlayerQuitEvent;
import java.time.Instant;
import java.time.temporal.ChronoUnit;
import java.util.Arrays;
import java.util.Date;
import static buttondevteam.core.MainPlugin.permission;
public class PlayerListener implements Listener {
@EventHandler(priority = EventPriority.NORMAL)
public void OnPlayerJoin(PlayerJoinEvent event) {
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)
public void OnPlayerLeave(PlayerQuitEvent event) {
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)
public void onSystemChat(TBMCSystemChatEvent event) {
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)

View file

@ -16,7 +16,7 @@ public abstract class ButtonPlugin extends JavaPlugin {
protected abstract void pluginDisable();
@Override
public void onEnable() {
public final void onEnable() {
var section = super.getConfig().getConfigurationSection("global");
if (section == null) section = super.getConfig().createSection("global");
iConfig = new IHaveConfig(section);
@ -28,7 +28,7 @@ public abstract class ButtonPlugin extends JavaPlugin {
}
@Override
public void onDisable() {
public final void onDisable() {
try {
pluginDisable();
saveConfig();

View file

@ -127,6 +127,7 @@ public abstract class Component {
public static void setComponentEnabled(Component component, boolean enabled) throws UnregisteredComponentException {
if (!components.containsKey(component.getClass()))
throw new UnregisteredComponentException(component);
if (component.enabled == enabled) return; //Don't do anything
if (component.enabled = enabled)
component.enable();
else {
@ -202,13 +203,6 @@ public abstract class Component {
}
private String getClassName() {
Class<?> enclosingClass = getClass().getEnclosingClass();
String className;
if (enclosingClass != null) {
className = (enclosingClass.getName());
} else {
className = (getClass().getName());
}
return className;
return getClass().getSimpleName();
}
}

View file

@ -74,7 +74,7 @@ public final class IHaveConfig {
/**
* Deletes the config cache. Call this on component/plugin disable so that new values are read.
*/
*/ //Currently only the /component command reloads the config, otherwise this doesn't really have effect
public void resetConfigurationCache() {
datamap.clear();
}

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.
*/
boolean excludeFromPath() default false;
/**
* The help text to show for the players.
*
* @return The help text
*/
String[] helpText() default {};
}

View file

@ -277,8 +277,12 @@ public class TBMCChatAPI {
* @return The event cancelled state
*/
public static boolean SendChatMessage(ChatMessage cm, Channel channel) {
if (!Channel.getChannels().contains(channel))
if (!Channel.getChannelList().contains(channel))
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();
RecipientTestResult rtr = getScoreOrSendError(channel, permcheck);
int score = rtr.score;
@ -308,8 +312,10 @@ public class TBMCChatAPI {
* @return The event cancelled state
*/
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().get() + " not registered!");
if (!channel.Enabled().get())
return true; //Cancel sending
TBMCSystemChatEvent event = new TBMCSystemChatEvent(channel, message, rtr.score, rtr.groupID, exceptions);
Bukkit.getPluginManager().callEvent(event);
return event.isCancelled();

View file

@ -16,7 +16,7 @@ public class ChannelPlayerData { //I just want this to work
String str = data.get();
if (str.isEmpty())
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) {

View file

@ -1,11 +1,7 @@
package buttondevteam.lib.player;
import buttondevteam.component.towny.TownyComponent;
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.OfflinePlayer;
import org.bukkit.entity.Player;
@ -127,22 +123,7 @@ public abstract class TBMCPlayerBase extends ChromaGamerBase {
Bukkit.getLogger().info("Player name saved: " + player.PlayerName().get());
} else if (!p.getName().equals(player.PlayerName().get())) {
Bukkit.getLogger().info("Renaming " + player.PlayerName().get() + " to " + p.getName());
TownyUniverse tu = Towny.getPlugin(Towny.class).getTownyUniverse();
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);
}
TownyComponent.renameInTowny(player.PlayerName().get(), p.getName());
player.PlayerName().set(p.getName());
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.
member:
description: Add or remove a member
component:
description: Enable or disable or list components