Log exceptions using the plugin/component logger
This commit is contained in:
parent
01dd8a477e
commit
731065fe2a
16 changed files with 137 additions and 99 deletions
|
@ -83,7 +83,7 @@ public class ComponentCommand extends ICommand2MC {
|
|||
oc.get().shouldBeEnabled().set(enable);
|
||||
sender.sendMessage(oc.get().getClass().getSimpleName() + " " + (enable ? "en" : "dis") + "abled " + (permanent ? "permanently" : "temporarily") + ".");
|
||||
} catch (Exception e) {
|
||||
TBMCCoreAPI.SendException("Couldn't " + (enable ? "en" : "dis") + "able component " + component + "!", e);
|
||||
TBMCCoreAPI.SendException("Couldn't " + (enable ? "en" : "dis") + "able component " + component + "!", e, (JavaPlugin) plugin);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -25,7 +25,7 @@ public final class ComponentManager {
|
|||
try {
|
||||
Component.setComponentEnabled(c, true);
|
||||
} catch (Exception | NoClassDefFoundError e) {
|
||||
TBMCCoreAPI.SendException("Failed to enable one of the components: " + c.getClass().getSimpleName(), e);
|
||||
TBMCCoreAPI.SendException("Failed to enable one of the components: " + c.getClass().getSimpleName(), e, c);
|
||||
}
|
||||
});
|
||||
componentsEnabled = true;
|
||||
|
|
|
@ -142,7 +142,7 @@ public class MainPlugin extends ButtonPlugin {
|
|||
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);
|
||||
TBMCCoreAPI.SendException("Failed to write plugin list!", e, this);
|
||||
}
|
||||
}
|
||||
if (getServer().getPluginManager().isPluginEnabled("Essentials"))
|
||||
|
|
|
@ -77,7 +77,7 @@ public class PlayerListener implements Listener {
|
|||
try {
|
||||
event.setCancelled(ButtonPlugin.getCommand2MC().handleCommand(new Command2MCSender(event.getSender(), event.getChannel(), event.getPermCheck()), event.getMessage()));
|
||||
} catch (Exception e) {
|
||||
TBMCCoreAPI.SendException("Command processing failed for sender '" + event.getSender() + "' and message '" + event.getMessage() + "'", e);
|
||||
TBMCCoreAPI.SendException("Command processing failed for sender '" + event.getSender() + "' and message '" + event.getMessage() + "'", e, MainPlugin.Instance);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@ import buttondevteam.core.MainPlugin;
|
|||
import buttondevteam.core.component.channel.Channel;
|
||||
import buttondevteam.lib.TBMCSystemChatEvent;
|
||||
import buttondevteam.lib.architecture.Component;
|
||||
import buttondevteam.lib.architecture.ComponentMetadata;
|
||||
import buttondevteam.lib.architecture.ConfigData;
|
||||
import buttondevteam.lib.chat.IFakePlayer;
|
||||
import buttondevteam.lib.chat.TBMCChatAPI;
|
||||
|
@ -14,14 +15,15 @@ import org.bukkit.event.EventHandler;
|
|||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.player.PlayerQuitEvent;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.ZoneId;
|
||||
import java.time.ZoneOffset;
|
||||
import java.time.ZonedDateTime;
|
||||
|
||||
/**
|
||||
* Provides commands such as /schrestart (restart after a countdown) and /primerestart (restart when nobody is online)
|
||||
* Provides commands such as /schrestart (restart after a countdown) and /primerestart (restart when nobody is online).
|
||||
* Also can automatically restart at a given time.
|
||||
*/
|
||||
@ComponentMetadata(enabledByDefault = false)
|
||||
public class RestartComponent extends Component<MainPlugin> implements Listener {
|
||||
@Override
|
||||
public void enable() {
|
||||
|
|
|
@ -2,6 +2,7 @@ package buttondevteam.core.component.spawn;
|
|||
|
||||
import buttondevteam.core.MainPlugin;
|
||||
import buttondevteam.lib.architecture.Component;
|
||||
import buttondevteam.lib.architecture.ComponentMetadata;
|
||||
import buttondevteam.lib.architecture.ConfigData;
|
||||
import buttondevteam.lib.chat.Command2;
|
||||
import buttondevteam.lib.chat.CommandClass;
|
||||
|
@ -23,6 +24,7 @@ import java.math.BigDecimal;
|
|||
/**
|
||||
* Provides a /spawn command that works with BungeeCord. Make sure to set up on each server.
|
||||
*/
|
||||
@ComponentMetadata(enabledByDefault = false)
|
||||
public class SpawnComponent extends Component<MainPlugin> implements PluginMessageListener {
|
||||
@Override
|
||||
protected void enable() {
|
||||
|
|
|
@ -8,7 +8,6 @@ import com.palmergames.bukkit.towny.TownyUniverse;
|
|||
import com.palmergames.bukkit.towny.exceptions.AlreadyRegisteredException;
|
||||
import com.palmergames.bukkit.towny.exceptions.NotRegisteredException;
|
||||
import com.palmergames.bukkit.towny.object.Resident;
|
||||
import org.bukkit.Bukkit;
|
||||
|
||||
/**
|
||||
* Automatically renames Towny players if they changed their Minecraft name
|
||||
|
@ -48,9 +47,9 @@ public class TownyComponent extends Component<MainPlugin> {
|
|||
component.log("Renaming done.");
|
||||
}
|
||||
} catch (AlreadyRegisteredException e) {
|
||||
TBMCCoreAPI.SendException("Failed to rename resident, there's already one with this name.", e);
|
||||
TBMCCoreAPI.SendException("Failed to rename resident, there's already one with this name.", e, component);
|
||||
} catch (NotRegisteredException e) {
|
||||
TBMCCoreAPI.SendException("Failed to rename resident, the resident isn't registered.", e);
|
||||
TBMCCoreAPI.SendException("Failed to rename resident, the resident isn't registered.", e, component);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,13 +1,14 @@
|
|||
package buttondevteam.lib;
|
||||
|
||||
import org.bukkit.event.Event;
|
||||
|
||||
class EventExceptionCoreHandler extends EventExceptionHandler {
|
||||
|
||||
@Override
|
||||
public boolean handle(Throwable ex, Event event) {
|
||||
TBMCCoreAPI.SendException("An error occured while executing " + event.getEventName() + "!", ex);
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
package buttondevteam.lib;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.event.Event;
|
||||
|
||||
class EventExceptionCoreHandler extends EventExceptionHandler {
|
||||
|
||||
@Override
|
||||
public boolean handle(Throwable ex, Event event) {
|
||||
TBMCCoreAPI.SendException("An error occured while executing " + event.getEventName() + "!", ex, false, Bukkit.getLogger()::warning);
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,13 +1,14 @@
|
|||
package buttondevteam.lib;
|
||||
|
||||
import buttondevteam.core.MainPlugin;
|
||||
import buttondevteam.lib.architecture.Component;
|
||||
import buttondevteam.lib.player.ChromaGamerBase;
|
||||
import buttondevteam.lib.potato.DebugPotato;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
@ -15,6 +16,7 @@ import java.net.URL;
|
|||
import java.net.URLConnection;
|
||||
import java.util.*;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public class TBMCCoreAPI {
|
||||
static final List<String> coders = new ArrayList<String>() {
|
||||
|
@ -51,11 +53,21 @@ public class TBMCCoreAPI {
|
|||
* @param sourcemsg A message that is shown at the top of the exception (before the exception's message)
|
||||
* @param e The exception to send
|
||||
*/
|
||||
public static void SendException(String sourcemsg, Throwable e) {
|
||||
SendException(sourcemsg, e, false);
|
||||
public static void SendException(String sourcemsg, Throwable e, Component<?> component) {
|
||||
SendException(sourcemsg, e, false, component::logWarn);
|
||||
}
|
||||
|
||||
public static void SendException(String sourcemsg, Throwable e, boolean debugPotato) {
|
||||
/**
|
||||
* Send exception to the {@link TBMCExceptionEvent}.
|
||||
*
|
||||
* @param sourcemsg A message that is shown at the top of the exception (before the exception's message)
|
||||
* @param e The exception to send
|
||||
*/
|
||||
public static void SendException(String sourcemsg, Throwable e, JavaPlugin plugin) {
|
||||
SendException(sourcemsg, e, false, plugin.getLogger()::warning);
|
||||
}
|
||||
|
||||
public static void SendException(String sourcemsg, Throwable e, boolean debugPotato, Consumer<String> logWarn) {
|
||||
try {
|
||||
SendUnsentExceptions();
|
||||
TBMCExceptionEvent event = new TBMCExceptionEvent(sourcemsg, e);
|
||||
|
@ -64,7 +76,7 @@ public class TBMCCoreAPI {
|
|||
if (!event.isHandled())
|
||||
exceptionsToSend.put(sourcemsg, e);
|
||||
}
|
||||
Bukkit.getLogger().warning(sourcemsg);
|
||||
logWarn.accept(sourcemsg);
|
||||
e.printStackTrace();
|
||||
if (debugPotato) {
|
||||
List<Player> devsOnline = new ArrayList<>();
|
||||
|
@ -105,6 +117,7 @@ public class TBMCCoreAPI {
|
|||
}
|
||||
|
||||
private static EventExceptionCoreHandler eventExceptionCoreHandler;
|
||||
|
||||
/**
|
||||
* Registers Bukkit events, handling the exceptions occurring in those events
|
||||
*
|
||||
|
|
|
@ -59,7 +59,7 @@ public abstract class ButtonPlugin extends JavaPlugin {
|
|||
try {
|
||||
pluginEnable();
|
||||
} catch (Exception e) {
|
||||
TBMCCoreAPI.SendException("Error while enabling plugin " + getName() + "!", e);
|
||||
TBMCCoreAPI.SendException("Error while enabling plugin " + getName() + "!", e, this);
|
||||
}
|
||||
if (configGenAllowed(this)) //If it's not disabled (by default it's not)
|
||||
IHaveConfig.pregenConfig(this, null);
|
||||
|
@ -85,7 +85,7 @@ public abstract class ButtonPlugin extends JavaPlugin {
|
|||
getLogger().info("Saved configuration changes.");
|
||||
getCommand2MC().unregisterCommands(this);
|
||||
} catch (Exception e) {
|
||||
TBMCCoreAPI.SendException("Error while disabling plugin " + getName() + "!", e);
|
||||
TBMCCoreAPI.SendException("Error while disabling plugin " + getName() + "!", e, this);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -142,7 +142,7 @@ public abstract class ButtonPlugin extends JavaPlugin {
|
|||
if (yaml != null)
|
||||
yaml.save();
|
||||
} catch (Exception e) {
|
||||
TBMCCoreAPI.SendException("Failed to save config", e);
|
||||
TBMCCoreAPI.SendException("Failed to save config", e, this);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -77,7 +77,7 @@ public abstract class Component<TP extends JavaPlugin> {
|
|||
}
|
||||
if (register) {
|
||||
if (components.containsKey(component.getClass())) {
|
||||
TBMCCoreAPI.SendException("Failed to register component " + component.getClassName(), new IllegalArgumentException("The component is already registered!"));
|
||||
TBMCCoreAPI.SendException("Failed to register component " + component.getClassName(), new IllegalArgumentException("The component is already registered!"), plugin);
|
||||
return false;
|
||||
}
|
||||
component.plugin = plugin;
|
||||
|
@ -92,7 +92,7 @@ public abstract class Component<TP extends JavaPlugin> {
|
|||
setComponentEnabled(component, true);
|
||||
return true;
|
||||
} catch (Exception | NoClassDefFoundError e) {
|
||||
TBMCCoreAPI.SendException("Failed to enable component " + component.getClassName() + "!", e);
|
||||
TBMCCoreAPI.SendException("Failed to enable component " + component.getClassName() + "!", e, component);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -103,7 +103,7 @@ public abstract class Component<TP extends JavaPlugin> {
|
|||
try {
|
||||
setComponentEnabled(component, false);
|
||||
} catch (Exception | NoClassDefFoundError e) {
|
||||
TBMCCoreAPI.SendException("Failed to disable component " + component.getClassName() + "!", e);
|
||||
TBMCCoreAPI.SendException("Failed to disable component " + component.getClassName() + "!", e, component);
|
||||
return false; //If failed to disable, won't unregister either
|
||||
}
|
||||
}
|
||||
|
@ -112,7 +112,7 @@ public abstract class Component<TP extends JavaPlugin> {
|
|||
}
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
TBMCCoreAPI.SendException("Failed to " + (register ? "" : "un") + "register component " + component.getClassName() + "!", e);
|
||||
TBMCCoreAPI.SendException("Failed to " + (register ? "" : "un") + "register component " + component.getClassName() + "!", e, plugin);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -153,7 +153,7 @@ public abstract class Component<TP extends JavaPlugin> {
|
|||
}
|
||||
}
|
||||
|
||||
public static void updateConfig(JavaPlugin plugin, Component component) {
|
||||
public static void updateConfig(JavaPlugin plugin, Component<?> component) {
|
||||
if (plugin.getConfig() != null) { //Production
|
||||
var compconf = plugin.getConfig().getConfigurationSection("components");
|
||||
if (compconf == null) compconf = plugin.getConfig().createSection("components");
|
||||
|
|
|
@ -5,7 +5,9 @@ import buttondevteam.lib.TBMCCoreAPI;
|
|||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import lombok.val;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
|
@ -211,7 +213,13 @@ public final class IHaveConfig {
|
|||
try {
|
||||
return (ConfigData<?>) m.invoke(obj, kv.getValue());
|
||||
} catch (IllegalAccessException | InvocationTargetException e) {
|
||||
TBMCCoreAPI.SendException("Failed to pregenerate " + m.getName() + " for " + obj + " using config " + kv.getKey() + "!", e);
|
||||
String msg = "Failed to pregenerate " + m.getName() + " for " + obj + " using config " + kv.getKey() + "!";
|
||||
if (obj instanceof Component<?>)
|
||||
TBMCCoreAPI.SendException(msg, e, (Component<?>) obj);
|
||||
else if (obj instanceof JavaPlugin)
|
||||
TBMCCoreAPI.SendException(msg, e, (JavaPlugin) obj);
|
||||
else
|
||||
TBMCCoreAPI.SendException(msg, e, false, Bukkit.getLogger()::warning);
|
||||
return null;
|
||||
}
|
||||
}).filter(Objects::nonNull).collect(Collectors.toList());
|
||||
|
@ -228,7 +236,13 @@ public final class IHaveConfig {
|
|||
c.get(); //Saves the default value if needed - also checks validity
|
||||
}
|
||||
} catch (Exception e) {
|
||||
TBMCCoreAPI.SendException("Failed to pregenerate " + m.getName() + " for " + obj + "!", e);
|
||||
String msg = "Failed to pregenerate " + m.getName() + " for " + obj + "!";
|
||||
if (obj instanceof Component<?>)
|
||||
TBMCCoreAPI.SendException(msg, e, (Component<?>) obj);
|
||||
else if (obj instanceof JavaPlugin)
|
||||
TBMCCoreAPI.SendException(msg, e, (JavaPlugin) obj);
|
||||
else
|
||||
TBMCCoreAPI.SendException(msg, e, false, Bukkit.getLogger()::warning);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -147,7 +147,7 @@ public abstract class Command2<TC extends ICommand2<TP>, TP extends Command2Send
|
|||
try {
|
||||
handleCommandAsync(sender, commandline, sd, subcommand, sync);
|
||||
} catch (Exception e) {
|
||||
TBMCCoreAPI.SendException("Command execution failed for sender " + sender.getName() + "(" + sender.getClass().getCanonicalName() + ") and message " + commandline, e);
|
||||
TBMCCoreAPI.SendException("Command execution failed for sender " + sender.getName() + "(" + sender.getClass().getCanonicalName() + ") and message " + commandline, e, MainPlugin.Instance);
|
||||
}
|
||||
});
|
||||
return true; //We found a method
|
||||
|
@ -271,9 +271,9 @@ public abstract class Command2<TC extends ICommand2<TP>, TP extends Command2Send
|
|||
} else if (ret != null)
|
||||
throw new Exception("Wrong return type! Must return a boolean or void. Return value: " + ret);
|
||||
} catch (InvocationTargetException e) {
|
||||
TBMCCoreAPI.SendException("An error occurred in a command handler!", e.getCause());
|
||||
TBMCCoreAPI.SendException("An error occurred in a command handler for " + subcommand + "!", e.getCause(), MainPlugin.Instance);
|
||||
} catch (Exception e) {
|
||||
TBMCCoreAPI.SendException("Command handling failed for sender " + sender + " and subcommand " + subcommand, e);
|
||||
TBMCCoreAPI.SendException("Command handling failed for sender " + sender + " and subcommand " + subcommand, e, MainPlugin.Instance);
|
||||
}
|
||||
};
|
||||
if (sync)
|
||||
|
@ -306,7 +306,7 @@ public abstract class Command2<TC extends ICommand2<TP>, TP extends Command2Send
|
|||
if (!commandHelp.contains(mainPath))
|
||||
commandHelp.add(mainPath);
|
||||
} catch (Exception e) {
|
||||
TBMCCoreAPI.SendException("Could not register default handler for command /" + path, e);
|
||||
TBMCCoreAPI.SendException("Could not register default handler for command /" + path, e, MainPlugin.Instance);
|
||||
}
|
||||
var addedSubcommands = new ArrayList<SubcommandData<TC>>();
|
||||
for (val method : command.getClass().getMethods()) {
|
||||
|
@ -347,7 +347,7 @@ public abstract class Command2<TC extends ICommand2<TP>, TP extends Command2Send
|
|||
private String[] getParameterHelp(Method method, String[] ht, String subcommand, String[] parameters) {
|
||||
val str = method.getDeclaringClass().getResourceAsStream("/commands.yml");
|
||||
if (str == null)
|
||||
TBMCCoreAPI.SendException("Error while getting command data!", new Exception("Resource not found!"));
|
||||
TBMCCoreAPI.SendException("Error while getting command data!", new Exception("Resource not found!"), MainPlugin.Instance);
|
||||
else {
|
||||
if (ht.length > 0)
|
||||
ht[0] = "§6---- " + ht[0] + " ----";
|
||||
|
@ -368,11 +368,11 @@ public abstract class Command2<TC extends ICommand2<TP>, TP extends Command2Send
|
|||
for (int j = 0; j < paramArray.length && j < parameters.length; j++)
|
||||
parameters[j] = paramArray[j];
|
||||
} else
|
||||
TBMCCoreAPI.SendException("Error while getting command data for " + method + "!", new Exception("Method '" + method.toString() + "' != " + mname + " or params is " + params));
|
||||
TBMCCoreAPI.SendException("Error while getting command data for " + method + "!", new Exception("Method '" + method.toString() + "' != " + mname + " or params is " + params), MainPlugin.Instance);
|
||||
} else
|
||||
TBMCCoreAPI.SendException("Error while getting command data for " + method + "!", new Exception("cs is " + cs));
|
||||
TBMCCoreAPI.SendException("Error while getting command data for " + method + "!", new Exception("cs is " + cs), MainPlugin.Instance);
|
||||
} else
|
||||
TBMCCoreAPI.SendException("Error while getting command data for " + method + "!", new Exception("ccs is " + ccs + " - class: " + method.getDeclaringClass().getCanonicalName()));
|
||||
TBMCCoreAPI.SendException("Error while getting command data for " + method + "!", new Exception("ccs is " + ccs + " - class: " + method.getDeclaringClass().getCanonicalName()), MainPlugin.Instance);
|
||||
}
|
||||
return ht;
|
||||
}
|
||||
|
|
|
@ -8,7 +8,6 @@ import buttondevteam.lib.player.ChromaGamerBase;
|
|||
import com.mojang.brigadier.arguments.*;
|
||||
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
|
||||
import com.mojang.brigadier.builder.RequiredArgumentBuilder;
|
||||
import com.mojang.brigadier.suggestion.SuggestionProvider;
|
||||
import com.mojang.brigadier.tree.CommandNode;
|
||||
import com.mojang.brigadier.tree.LiteralCommandNode;
|
||||
import lombok.val;
|
||||
|
@ -233,7 +232,10 @@ public class Command2MC extends Command2<ICommand2MC, Command2MCSender> implemen
|
|||
if (CommodoreProvider.isSupported())
|
||||
TabcompleteHelper.registerTabcomplete(command, subcmds, bukkitCommand);
|
||||
} catch (Exception e) {
|
||||
TBMCCoreAPI.SendException("Failed to register command in command map!", e);
|
||||
if (command.getComponent() == null)
|
||||
TBMCCoreAPI.SendException("Failed to register command in command map!", e, command.getPlugin());
|
||||
else
|
||||
TBMCCoreAPI.SendException("Failed to register command in command map!", e, command.getComponent());
|
||||
shouldRegisterOfficially = false;
|
||||
}
|
||||
}
|
||||
|
@ -241,7 +243,7 @@ public class Command2MC extends Command2<ICommand2MC, Command2MCSender> implemen
|
|||
private boolean executeCommand(CommandSender sender, Command command, String label, String[] args) {
|
||||
var user = ChromaGamerBase.getFromSender(sender);
|
||||
if (user == null) {
|
||||
TBMCCoreAPI.SendException("Failed to run Bukkit command for user!", new Throwable("No Chroma user found"));
|
||||
TBMCCoreAPI.SendException("Failed to run Bukkit command for user!", new Throwable("No Chroma user found"), MainPlugin.Instance);
|
||||
sender.sendMessage("§cAn internal error occurred.");
|
||||
return true;
|
||||
}
|
||||
|
@ -372,7 +374,7 @@ public class Command2MC extends Command2<ICommand2MC, Command2MCSender> implemen
|
|||
.filter(t -> param.replaceAll("[\\[\\]<>]", "").equalsIgnoreCase(t.getValue1().param()))
|
||||
.findAny();
|
||||
var argb = RequiredArgumentBuilder.argument(param, type)
|
||||
.suggests((SuggestionProvider<Object>) (context, builder) -> {
|
||||
.suggests((context, builder) -> {
|
||||
if (parameter.isVarArgs()) { //Do it before the builder is used
|
||||
int nextTokenStart = context.getInput().lastIndexOf(' ') + 1;
|
||||
builder = builder.createOffset(nextTokenStart);
|
||||
|
@ -399,12 +401,9 @@ public class Command2MC extends Command2<ICommand2MC, Command2MCSender> implemen
|
|||
args[j] = paramValueString;
|
||||
continue;
|
||||
}
|
||||
val converter = ButtonPlugin.getCommand2MC().paramConverters.get(params[j].getType());
|
||||
if (converter == null) {
|
||||
TBMCCoreAPI.SendException("Could not find a suitable converter for type " + params[j].getType().getSimpleName(),
|
||||
new NullPointerException("converter is null"));
|
||||
val converter = getParamConverter(params[j].getType(), command2MC);
|
||||
if (converter == null)
|
||||
break;
|
||||
}
|
||||
val paramValue = converter.converter.apply(paramValueString);
|
||||
if (paramValue == null) //For example, the player provided an invalid plugin name
|
||||
break;
|
||||
|
@ -427,16 +426,17 @@ public class Command2MC extends Command2<ICommand2MC, Command2MCSender> implemen
|
|||
else
|
||||
throw new ClassCastException("Bad return type! It should return a String[] or an Iterable<String>.");
|
||||
} catch (Exception e) {
|
||||
TBMCCoreAPI.SendException("Failed to run tabcomplete method " + method.getName() + " for command " + command2MC.getClass().getSimpleName(), e);
|
||||
String msg = "Failed to run tabcomplete method " + method.getName() + " for command " + command2MC.getClass().getSimpleName();
|
||||
if (command2MC.getComponent() == null)
|
||||
TBMCCoreAPI.SendException(msg, e, command2MC.getPlugin());
|
||||
else
|
||||
TBMCCoreAPI.SendException(msg, e, command2MC.getComponent());
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!ignoreCustomParamType && customParamType) {
|
||||
val converter = ButtonPlugin.getCommand2MC().paramConverters.get(ptype);
|
||||
if (converter == null)
|
||||
TBMCCoreAPI.SendException("Could not find a suitable converter for type " + ptype.getSimpleName(),
|
||||
new NullPointerException("converter is null"));
|
||||
else {
|
||||
val converter = getParamConverter(ptype, command2MC);
|
||||
if (converter != null) {
|
||||
var suggestions = converter.allSupplier.get();
|
||||
for (String suggestion : suggestions)
|
||||
builder.suggest(suggestion);
|
||||
|
@ -467,4 +467,18 @@ public class Command2MC extends Command2<ICommand2MC, Command2MCSender> implemen
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static ParamConverter<?> getParamConverter(Class<?> cl, ICommand2MC command2MC) {
|
||||
val converter = ButtonPlugin.getCommand2MC().paramConverters.get(cl);
|
||||
if (converter == null) {
|
||||
String msg = "Could not find a suitable converter for type " + cl.getSimpleName();
|
||||
Exception exception = new NullPointerException("converter is null");
|
||||
if (command2MC.getComponent() == null)
|
||||
TBMCCoreAPI.SendException(msg, exception, command2MC.getPlugin());
|
||||
else
|
||||
TBMCCoreAPI.SendException(msg, exception, command2MC.getComponent());
|
||||
return null;
|
||||
}
|
||||
return converter;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package buttondevteam.lib.player;
|
||||
|
||||
import buttondevteam.core.MainPlugin;
|
||||
import buttondevteam.core.component.channel.Channel;
|
||||
import buttondevteam.lib.TBMCCoreAPI;
|
||||
import com.google.common.collect.HashBiMap;
|
||||
|
@ -30,19 +31,17 @@ public abstract class ChromaGamerBase implements AutoCloseable {
|
|||
playerTypes.put(userclass, userclass.getAnnotation(UserClass.class).foldername());
|
||||
else if (userclass.isAnnotationPresent(AbstractUserClass.class))
|
||||
playerTypes.put(userclass.getAnnotation(AbstractUserClass.class).prototype(),
|
||||
userclass.getAnnotation(AbstractUserClass.class).foldername());
|
||||
userclass.getAnnotation(AbstractUserClass.class).foldername());
|
||||
else // <-- Really important
|
||||
throw new RuntimeException("Class not registered as a user class! Use @UserClass or TBMCPlayerBase");
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the folder name for the given player class.
|
||||
*
|
||||
* @param cl
|
||||
* The class to get the folder from (like {@link TBMCPlayerBase} or one of it's subclasses)
|
||||
*
|
||||
* @param cl The class to get the folder from (like {@link TBMCPlayerBase} or one of it's subclasses)
|
||||
* @return The folder name for the given type
|
||||
* @throws RuntimeException
|
||||
* If the class doesn't have the {@link UserClass} annotation.
|
||||
* @throws RuntimeException If the class doesn't have the {@link UserClass} annotation.
|
||||
*/
|
||||
public static <T extends ChromaGamerBase> String getFolderForType(Class<T> cl) {
|
||||
if (cl.isAnnotationPresent(UserClass.class))
|
||||
|
@ -54,9 +53,8 @@ public abstract class ChromaGamerBase implements AutoCloseable {
|
|||
|
||||
/**
|
||||
* Returns the player class for the given folder name.
|
||||
*
|
||||
* @param foldername
|
||||
* The folder to get the class from (like "minecraft")
|
||||
*
|
||||
* @param foldername The folder to get the class from (like "minecraft")
|
||||
* @return The type for the given folder name or null if not found
|
||||
*/
|
||||
public static Class<? extends ChromaGamerBase> getTypeForFolder(String foldername) {
|
||||
|
@ -72,16 +70,16 @@ public abstract class ChromaGamerBase implements AutoCloseable {
|
|||
}
|
||||
|
||||
/**
|
||||
* Use {@link #data(Object)} or {@link #data(String, Object)} where possible; the 'id' must be always set
|
||||
* Use {@link #data(Object)} or {@link #data(String, Object)} where possible; the 'id' must be always set
|
||||
*/
|
||||
protected YamlConfiguration plugindata;
|
||||
|
||||
/***
|
||||
* Loads a user from disk and returns the user object. Make sure to use the subclasses' methods, where possible, like {@link TBMCPlayerBase#getPlayer(java.util.UUID, Class)}
|
||||
*
|
||||
* @param fname Filename without .yml, usually UUID
|
||||
* @param cl User class
|
||||
* @return The user object
|
||||
* @param fname Filename without .yml, usually UUID
|
||||
* @param cl User class
|
||||
* @return The user object
|
||||
*/
|
||||
public static <T extends ChromaGamerBase> T getUser(String fname, Class<T> cl) {
|
||||
try {
|
||||
|
@ -93,7 +91,7 @@ public abstract class ChromaGamerBase implements AutoCloseable {
|
|||
obj.plugindata.set(folder + "_id", fname);
|
||||
return obj;
|
||||
} catch (Exception e) {
|
||||
TBMCCoreAPI.SendException("An error occured while loading a " + cl.getSimpleName() + "!", e);
|
||||
TBMCCoreAPI.SendException("An error occured while loading a " + cl.getSimpleName() + "!", e, MainPlugin.Instance);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
@ -140,15 +138,14 @@ public abstract class ChromaGamerBase implements AutoCloseable {
|
|||
try {
|
||||
close();
|
||||
} catch (Exception e) {
|
||||
TBMCCoreAPI.SendException("Error while saving player to " + getFolder() + "/" + getFileName() + ".yml!", e);
|
||||
TBMCCoreAPI.SendException("Error while saving player to " + getFolder() + "/" + getFileName() + ".yml!", e, MainPlugin.Instance);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Connect two accounts. Do not use for connecting two Minecraft accounts or similar. Also make sure you have the "id" tag set
|
||||
*
|
||||
* @param user
|
||||
* The account to connect with
|
||||
*
|
||||
* @param user The account to connect with
|
||||
*/
|
||||
public <T extends ChromaGamerBase> void connectWith(T user) {
|
||||
// Set the ID, go through all linked files and connect them as well
|
||||
|
@ -157,7 +154,7 @@ public abstract class ChromaGamerBase implements AutoCloseable {
|
|||
final String ownFolder = getFolder();
|
||||
final String userFolder = user.getFolder();
|
||||
if (ownFolder.equalsIgnoreCase(userFolder))
|
||||
throw new RuntimeException("Do not connect two accounts of the same type! Type: "+ownFolder);
|
||||
throw new RuntimeException("Do not connect two accounts of the same type! Type: " + ownFolder);
|
||||
user.plugindata.set(ownFolder + "_id", plugindata.getString(ownFolder + "_id"));
|
||||
plugindata.set(userFolder + "_id", user.plugindata.getString(userFolder + "_id"));
|
||||
Consumer<YamlConfiguration> sync = sourcedata -> {
|
||||
|
@ -176,7 +173,7 @@ public abstract class ChromaGamerBase implements AutoCloseable {
|
|||
cg.plugindata.set(item.getValue() + "_id", sourcedata.getString(item.getValue() + "_id")); // Set all existing IDs
|
||||
} catch (Exception e) {
|
||||
TBMCCoreAPI.SendException("Failed to update " + sourcefolder + " ID in player files for " + id
|
||||
+ " in folder with " + entry.getValue() + " id " + otherid + "!", e);
|
||||
+ " in folder with " + entry.getValue() + " id " + otherid + "!", e, MainPlugin.Instance);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -186,9 +183,8 @@ public abstract class ChromaGamerBase implements AutoCloseable {
|
|||
|
||||
/**
|
||||
* Retunrs the ID for the T typed player object connected with this one or null if no connection found.
|
||||
*
|
||||
* @param cl
|
||||
* The player class to get the ID from
|
||||
*
|
||||
* @param cl The player class to get the ID from
|
||||
* @return The ID or null if not found
|
||||
*/
|
||||
public <T extends ChromaGamerBase> String getConnectedID(Class<T> cl) {
|
||||
|
@ -198,9 +194,8 @@ public abstract class ChromaGamerBase implements AutoCloseable {
|
|||
/**
|
||||
* Returns this player as a plugin player. This will return a new instance unless the player is online.<br>
|
||||
* Make sure to close both the returned and this object. A try-with-resources block or two can help.<br>
|
||||
*
|
||||
* @param cl
|
||||
* The target player class
|
||||
*
|
||||
* @param cl The target player class
|
||||
* @return The player as a {@link T} object or null if not having an account there
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
|
@ -224,16 +219,16 @@ public abstract class ChromaGamerBase implements AutoCloseable {
|
|||
|
||||
private void ThrowIfNoUser() {
|
||||
if (!getClass().isAnnotationPresent(UserClass.class)
|
||||
&& !getClass().isAnnotationPresent(AbstractUserClass.class))
|
||||
&& !getClass().isAnnotationPresent(AbstractUserClass.class))
|
||||
throw new RuntimeException("Class not registered as a user class! Use @UserClass");
|
||||
}
|
||||
|
||||
@SuppressWarnings("rawtypes")
|
||||
private final HashMap<String, PlayerData> datamap = new HashMap<>();
|
||||
private final HashMap<String, PlayerData> datamap = new HashMap<>();
|
||||
|
||||
/**
|
||||
* Use from a data() method, which is in a method with the name of the key. For example, use flair() for the enclosing method of the outer data() to save to and load from "flair"
|
||||
*
|
||||
*
|
||||
* @return A data object with methods to get and set
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
|
@ -247,7 +242,7 @@ public abstract class ChromaGamerBase implements AutoCloseable {
|
|||
|
||||
/**
|
||||
* Use from a method with the name of the key. For example, use flair() for the enclosing method to save to and load from "flair"
|
||||
*
|
||||
*
|
||||
* @return A data object with methods to get and set
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
|
@ -265,7 +260,7 @@ public abstract class ChromaGamerBase implements AutoCloseable {
|
|||
|
||||
/**
|
||||
* Use from a data() method, which is in a method with the name of the key. For example, use flair() for the enclosing method of the outer data() to save to and load from "flair"
|
||||
*
|
||||
*
|
||||
* @return A data object with methods to get and set
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
|
@ -306,9 +301,8 @@ public abstract class ChromaGamerBase implements AutoCloseable {
|
|||
|
||||
/**
|
||||
* Get player information. This method calls the {@link TBMCPlayerGetInfoEvent} to get all the player information across the TBMC plugins.
|
||||
*
|
||||
* @param target
|
||||
* The {@link InfoTarget} to return the info for.
|
||||
*
|
||||
* @param target The {@link InfoTarget} to return the info for.
|
||||
* @return The player information.
|
||||
*/
|
||||
public String getInfo(InfoTarget target) {
|
||||
|
|
|
@ -16,7 +16,7 @@ import java.util.concurrent.ConcurrentHashMap;
|
|||
public abstract class TBMCPlayerBase extends ChromaGamerBase {
|
||||
protected UUID uuid;
|
||||
|
||||
private String pluginname;
|
||||
private final String pluginname;
|
||||
|
||||
protected TBMCPlayerBase() {
|
||||
if (getClass().isAnnotationPresent(PlayerClass.class))
|
||||
|
@ -77,8 +77,7 @@ public abstract class TBMCPlayerBase extends ChromaGamerBase {
|
|||
player.uuid = uuid;
|
||||
return player;
|
||||
} catch (Exception e) {
|
||||
TBMCCoreAPI.SendException(
|
||||
"Failed to get player with UUID " + uuid + " and class " + cl.getSimpleName() + "!", e);
|
||||
TBMCCoreAPI.SendException("Failed to get player with UUID " + uuid + " and class " + cl.getSimpleName() + "!", e, MainPlugin.Instance);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
@ -86,7 +85,7 @@ public abstract class TBMCPlayerBase extends ChromaGamerBase {
|
|||
/**
|
||||
* Key: UUID-Class
|
||||
*/
|
||||
static final ConcurrentHashMap<String, TBMCPlayerBase> playermap = new ConcurrentHashMap<>();
|
||||
private static final ConcurrentHashMap<String, TBMCPlayerBase> playermap = new ConcurrentHashMap<>();
|
||||
|
||||
/**
|
||||
* Gets the TBMCPlayer object as a specific plugin player, keeping it's data<br>
|
||||
|
@ -147,7 +146,7 @@ public abstract class TBMCPlayerBase extends ChromaGamerBase {
|
|||
p.close();
|
||||
} catch (Exception e) {
|
||||
TBMCCoreAPI.SendException("Error while saving player " + p.PlayerName().get() + " (" + p.getFolder()
|
||||
+ "/" + p.getFileName() + ")!", e);
|
||||
+ "/" + p.getFileName() + ")!", e, MainPlugin.Instance);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue