Log exceptions using the plugin/component logger

This commit is contained in:
Norbi Peti 2020-10-09 00:08:53 +02:00
parent 01dd8a477e
commit 731065fe2a
No known key found for this signature in database
GPG key ID: DBA4C4549A927E56
16 changed files with 137 additions and 99 deletions

View file

@ -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;
}

View file

@ -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;

View file

@ -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"))

View file

@ -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);
}
}

View file

@ -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() {

View file

@ -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() {

View file

@ -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);
}
}
}

View file

@ -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;
}
}

View file

@ -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
*

View file

@ -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);
}
}

View file

@ -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");

View file

@ -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);
}
}
}

View file

@ -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;
}

View file

@ -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;
}
}

View file

@ -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) {

View file

@ -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);
}
});
}