Probably done with player data (#28)
- Figured out and finished the annotation - Grouped data by plugin names - Player data is saved as an object automatically determining the type
This commit is contained in:
parent
11f13af8cc
commit
153425be5e
7 changed files with 142 additions and 36 deletions
|
@ -31,6 +31,7 @@ public class MainPlugin extends JavaPlugin {
|
||||||
TBMCChatAPI.AddCommand(this, UpdatePluginCommand.class);
|
TBMCChatAPI.AddCommand(this, UpdatePluginCommand.class);
|
||||||
TBMCChatAPI.AddCommand(this, ScheduledRestartCommand.class);
|
TBMCChatAPI.AddCommand(this, ScheduledRestartCommand.class);
|
||||||
TBMCCoreAPI.RegisterEventsForExceptions(new PlayerListener(), this);
|
TBMCCoreAPI.RegisterEventsForExceptions(new PlayerListener(), this);
|
||||||
|
TBMCCoreAPI.RegisterUserClass(TBMCPlayerBase.class);
|
||||||
logger.info(pdfFile.getName() + " has been Enabled (V." + pdfFile.getVersion() + ").");
|
logger.info(pdfFile.getName() + " has been Enabled (V." + pdfFile.getVersion() + ").");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -18,6 +18,7 @@ import org.bukkit.plugin.Plugin;
|
||||||
import com.google.gson.*;
|
import com.google.gson.*;
|
||||||
|
|
||||||
import buttondevteam.core.MainPlugin;
|
import buttondevteam.core.MainPlugin;
|
||||||
|
import buttondevteam.lib.player.ChromaGamerBase;
|
||||||
import buttondevteam.lib.potato.DebugPotato;
|
import buttondevteam.lib.potato.DebugPotato;
|
||||||
|
|
||||||
public final class TBMCCoreAPI {
|
public final class TBMCCoreAPI {
|
||||||
|
@ -83,8 +84,7 @@ public final class TBMCCoreAPI {
|
||||||
info(sender, "Updating TBMC plugin: " + correctname + " from " + correctbranch.get());
|
info(sender, "Updating TBMC plugin: " + correctname + " from " + correctbranch.get());
|
||||||
URL url;
|
URL url;
|
||||||
final boolean isWindows = System.getProperty("os.name").contains("Windows");
|
final boolean isWindows = System.getProperty("os.name").contains("Windows");
|
||||||
File result = new File(
|
File result = new File("plugins/" + correctname + (isWindows ? ".jar" : ".jar_tmp"));
|
||||||
"plugins/" + correctname + (isWindows ? ".jar" : ".jar_tmp"));
|
|
||||||
File finalresult = new File("plugins/" + correctname + ".jar");
|
File finalresult = new File("plugins/" + correctname + ".jar");
|
||||||
try {
|
try {
|
||||||
url = new URL("https://jitpack.io/com/github/TBMCPlugins/"
|
url = new URL("https://jitpack.io/com/github/TBMCPlugins/"
|
||||||
|
@ -250,6 +250,10 @@ public final class TBMCCoreAPI {
|
||||||
EventExceptionHandler.registerEvents(listener, plugin, new EventExceptionCoreHandler());
|
EventExceptionHandler.registerEvents(listener, plugin, new EventExceptionCoreHandler());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static <T extends ChromaGamerBase> void RegisterUserClass(Class<T> userclass) {
|
||||||
|
ChromaGamerBase.RegisterPluginUserClass(userclass);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Send exceptions that haven't been sent (their events didn't get handled). This method is used by the DiscordPlugin's ready event
|
* Send exceptions that haven't been sent (their events didn't get handled). This method is used by the DiscordPlugin's ready event
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -8,7 +8,6 @@ import java.util.function.Consumer;
|
||||||
|
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.configuration.file.YamlConfiguration;
|
import org.bukkit.configuration.file.YamlConfiguration;
|
||||||
|
|
||||||
import buttondevteam.lib.TBMCCoreAPI;
|
import buttondevteam.lib.TBMCCoreAPI;
|
||||||
|
|
||||||
public abstract class ChromaGamerBase implements AutoCloseable {
|
public abstract class ChromaGamerBase implements AutoCloseable {
|
||||||
|
@ -17,29 +16,27 @@ public abstract class ChromaGamerBase implements AutoCloseable {
|
||||||
private static final HashMap<Class<?>, String> playerTypes = new HashMap<>();
|
private static final HashMap<Class<?>, String> playerTypes = new HashMap<>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Use only if outside Minecraft, and use it to register your plugin's class.
|
* Used for connecting with every type of user ({@link #connectWith(ChromaGamerBase)})
|
||||||
*
|
|
||||||
* @param cl
|
|
||||||
* The custom player class
|
|
||||||
* @param folder
|
|
||||||
* The folder to store the data in (like "discord")
|
|
||||||
*/
|
*/
|
||||||
public static <T extends ChromaGamerBase> void addPlayerType(Class<T> cl, String folder) {
|
public static void RegisterPluginUserClass(Class<? extends ChromaGamerBase> userclass) {
|
||||||
playerTypes.put(cl, folder);
|
if (userclass.isAnnotationPresent(UserClass.class))
|
||||||
|
playerTypes.put(userclass, userclass.getAnnotation(UserClass.class).foldername());
|
||||||
|
throw new RuntimeException("Class not registered as a user class! Use @UserClass or TBMCPlayerBase");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the folder name for the given player class. If a direct match is not found, it'll look for superclasses.
|
* Returns the folder name for the given player class.
|
||||||
*
|
*
|
||||||
* @param cl
|
* @param cl
|
||||||
* The class to get the folder from (like {@link TBMCPlayerBase} or one of it's subclasses
|
* The class to get the folder from (like {@link TBMCPlayerBase} or one of it's subclasses
|
||||||
* @return The folder name for the given type
|
* @return The folder name for the given type
|
||||||
|
* @throws RuntimeException
|
||||||
|
* If the class doesn't have the {@link UserClass} annotation.
|
||||||
*/
|
*/
|
||||||
public static <T extends ChromaGamerBase> String getFolderForType(Class<T> cl) {
|
public static <T extends ChromaGamerBase> String getFolderForType(Class<T> cl) {
|
||||||
if (playerTypes.containsKey(cl))
|
if (cl.isAnnotationPresent(UserClass.class))
|
||||||
return playerTypes.get(cl);
|
return cl.getAnnotation(UserClass.class).foldername();
|
||||||
return playerTypes.entrySet().stream().filter(e -> e.getKey().isAssignableFrom(cl)).findAny()
|
throw new RuntimeException("Class not registered as a user class! Use @UserClass");
|
||||||
.orElseThrow(() -> new RuntimeException("Type not registered as a player type!")).getValue();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -57,6 +54,13 @@ public abstract class ChromaGamerBase implements AutoCloseable {
|
||||||
return plugindata != null ? plugindata.getString("id") : null;
|
return plugindata != null ? plugindata.getString("id") : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/***
|
||||||
|
* 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
|
||||||
|
* @param cl
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
public static <T extends ChromaGamerBase> T getUser(String fname, Class<T> cl) {
|
public static <T extends ChromaGamerBase> T getUser(String fname, Class<T> cl) {
|
||||||
try {
|
try {
|
||||||
T obj = cl.newInstance();
|
T obj = cl.newInstance();
|
||||||
|
@ -101,6 +105,8 @@ public abstract class ChromaGamerBase implements AutoCloseable {
|
||||||
*/
|
*/
|
||||||
public <T extends ChromaGamerBase> void connectWith(T user) {
|
public <T extends ChromaGamerBase> void connectWith(T user) {
|
||||||
// Set the ID, go through all linked files and connect them as well
|
// Set the ID, go through all linked files and connect them as well
|
||||||
|
if (!playerTypes.containsKey(getClass()))
|
||||||
|
throw new RuntimeException("Class not registered as a user class! Use TBMCCoreAPI.RegisterUserClass");
|
||||||
plugindata.set(user.getFolder() + "_id", user.plugindata.getString("id"));
|
plugindata.set(user.getFolder() + "_id", user.plugindata.getString("id"));
|
||||||
final String ownFolder = user.getFolder();
|
final String ownFolder = user.getFolder();
|
||||||
user.plugindata.set(ownFolder + "_id", plugindata.getString("id"));
|
user.plugindata.set(ownFolder + "_id", plugindata.getString("id"));
|
||||||
|
@ -159,6 +165,39 @@ public abstract class ChromaGamerBase implements AutoCloseable {
|
||||||
return getFolderForType(getClass());
|
return getFolderForType(getClass());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("rawtypes")
|
||||||
|
private 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")
|
||||||
|
protected <T> PlayerData<T> data(String sectionname) {
|
||||||
|
if (!getClass().isAnnotationPresent(UserClass.class))
|
||||||
|
throw new RuntimeException("Class not registered as a user class! Use @UserClass");
|
||||||
|
String mname = sectionname + "." + new Exception().getStackTrace()[1].getMethodName();
|
||||||
|
if (!datamap.containsKey(mname))
|
||||||
|
datamap.put(mname, new PlayerData<T>(mname, plugindata));
|
||||||
|
return datamap.get(mname);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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")
|
||||||
|
protected <T> PlayerData<T> data() {
|
||||||
|
if (!getClass().isAnnotationPresent(UserClass.class))
|
||||||
|
throw new RuntimeException("Class not registered as a user class! Use @UserClass");
|
||||||
|
String mname = new Exception().getStackTrace()[2].getMethodName();
|
||||||
|
if (!datamap.containsKey(mname))
|
||||||
|
datamap.put(mname, new PlayerData<T>(mname, plugindata));
|
||||||
|
return datamap.get(mname);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get player information. This method calls the {@link TBMCPlayerGetInfoEvent} to get all the player information across the TBMC plugins.
|
* Get player information. This method calls the {@link TBMCPlayerGetInfoEvent} to get all the player information across the TBMC plugins.
|
||||||
*
|
*
|
||||||
|
|
|
@ -5,8 +5,17 @@ import java.lang.annotation.Retention;
|
||||||
import java.lang.annotation.RetentionPolicy;
|
import java.lang.annotation.RetentionPolicy;
|
||||||
import java.lang.annotation.Target;
|
import java.lang.annotation.Target;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specifies a {@link TBMCPlayerBase} direct subclass. For Minecraft data, use {@link UserClass}
|
||||||
|
*
|
||||||
|
* @author NorbiPeti
|
||||||
|
*
|
||||||
|
*/
|
||||||
@Retention(RetentionPolicy.RUNTIME)
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
@Target(ElementType.TYPE)
|
@Target(ElementType.TYPE)
|
||||||
public @interface PlayerClass {
|
public @interface PlayerClass {
|
||||||
|
/**
|
||||||
|
* Indicates the plugin's name which this player class belongs to. Used to create a section for each plugin.
|
||||||
|
*/
|
||||||
String pluginname();
|
String pluginname();
|
||||||
}
|
}
|
||||||
|
|
22
src/main/java/buttondevteam/lib/player/PlayerData.java
Normal file
22
src/main/java/buttondevteam/lib/player/PlayerData.java
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
package buttondevteam.lib.player;
|
||||||
|
|
||||||
|
import org.bukkit.configuration.file.YamlConfiguration;
|
||||||
|
|
||||||
|
public class PlayerData<T> {
|
||||||
|
private String name;
|
||||||
|
private YamlConfiguration yaml;
|
||||||
|
|
||||||
|
public PlayerData(String name, YamlConfiguration yaml) {
|
||||||
|
this.name = name;
|
||||||
|
this.yaml = yaml;
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public T get() {
|
||||||
|
return (T) yaml.get(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void set(String value) {
|
||||||
|
yaml.set(name, value);
|
||||||
|
}
|
||||||
|
}
|
|
@ -17,20 +17,24 @@ import com.palmergames.bukkit.towny.object.TownyUniverse;
|
||||||
|
|
||||||
import buttondevteam.lib.TBMCCoreAPI;
|
import buttondevteam.lib.TBMCCoreAPI;
|
||||||
|
|
||||||
|
@UserClass(foldername = "minecraft")
|
||||||
public abstract class TBMCPlayerBase extends ChromaGamerBase {
|
public abstract class TBMCPlayerBase extends ChromaGamerBase {
|
||||||
private static final String FOLDER_NAME = "minecraft";
|
|
||||||
protected UUID uuid;
|
protected UUID uuid;
|
||||||
|
|
||||||
|
private String pluginname;
|
||||||
|
|
||||||
|
protected TBMCPlayerBase() {
|
||||||
|
if (getClass().isAnnotationPresent(PlayerClass.class))
|
||||||
|
pluginname = getClass().getAnnotation(PlayerClass.class).pluginname();
|
||||||
|
throw new RuntimeException("Class not defined as player class! Use @PlayerClass");
|
||||||
|
}
|
||||||
|
|
||||||
public UUID getUUID() {
|
public UUID getUUID() {
|
||||||
return uuid;
|
return uuid;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getPlayerName() {
|
public PlayerData<String> PlayerName() {
|
||||||
return plugindata.getString("playername", "");
|
return data();
|
||||||
}
|
|
||||||
|
|
||||||
public void setPlayerName(String value) {
|
|
||||||
plugindata.set("playername", value);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -38,8 +42,14 @@ public abstract class TBMCPlayerBase extends ChromaGamerBase {
|
||||||
return getUUID().toString();
|
return getUUID().toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
static {
|
|
||||||
addPlayerType(TBMCPlayerBase.class, FOLDER_NAME);
|
/**
|
||||||
|
* 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
|
||||||
|
*/
|
||||||
|
protected <T> PlayerData<T> data() {
|
||||||
|
return super.data(pluginname);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -96,7 +106,7 @@ public abstract class TBMCPlayerBase extends ChromaGamerBase {
|
||||||
try {
|
try {
|
||||||
player.close();
|
player.close();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
new Exception("Failed to save player data for " + player.getPlayerName(), e).printStackTrace();
|
new Exception("Failed to save player data for " + player.PlayerName().get(), e).printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -105,14 +115,14 @@ public abstract class TBMCPlayerBase extends ChromaGamerBase {
|
||||||
*/
|
*/
|
||||||
public static void joinPlayer(Player p) {
|
public static void joinPlayer(Player p) {
|
||||||
TBMCPlayer player = TBMCPlayerBase.getPlayer(p.getUniqueId(), TBMCPlayer.class);
|
TBMCPlayer player = TBMCPlayerBase.getPlayer(p.getUniqueId(), TBMCPlayer.class);
|
||||||
Bukkit.getLogger().info("Loaded player: " + player.getPlayerName());
|
Bukkit.getLogger().info("Loaded player: " + player.PlayerName().get());
|
||||||
if (player.getPlayerName() == null) {
|
if (player.PlayerName().get() == null) {
|
||||||
player.setPlayerName(p.getName());
|
player.PlayerName().set(p.getName());
|
||||||
Bukkit.getLogger().info("Player name saved: " + player.getPlayerName());
|
Bukkit.getLogger().info("Player name saved: " + player.PlayerName().get());
|
||||||
} else if (!p.getName().equals(player.getPlayerName())) {
|
} else if (!p.getName().equals(player.PlayerName().get())) {
|
||||||
Bukkit.getLogger().info("Renaming " + player.getPlayerName() + " to " + p.getName());
|
Bukkit.getLogger().info("Renaming " + player.PlayerName().get() + " to " + p.getName());
|
||||||
TownyUniverse tu = Towny.getPlugin(Towny.class).getTownyUniverse();
|
TownyUniverse tu = Towny.getPlugin(Towny.class).getTownyUniverse();
|
||||||
Resident resident = tu.getResidentMap().get(player.getPlayerName());
|
Resident resident = tu.getResidentMap().get(player.PlayerName().get());
|
||||||
if (resident == null) {
|
if (resident == null) {
|
||||||
Bukkit.getLogger().warning("Resident not found - couldn't rename in Towny.");
|
Bukkit.getLogger().warning("Resident not found - couldn't rename in Towny.");
|
||||||
TBMCCoreAPI.sendDebugMessage("Resident not found - couldn't rename in Towny.");
|
TBMCCoreAPI.sendDebugMessage("Resident not found - couldn't rename in Towny.");
|
||||||
|
@ -127,7 +137,7 @@ public abstract class TBMCPlayerBase extends ChromaGamerBase {
|
||||||
} catch (NotRegisteredException e) {
|
} 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);
|
||||||
}
|
}
|
||||||
player.setPlayerName(p.getName());
|
player.PlayerName().set(p.getName());
|
||||||
Bukkit.getLogger().info("Renaming done.");
|
Bukkit.getLogger().info("Renaming done.");
|
||||||
}
|
}
|
||||||
playermap.put(p.getUniqueId() + "-" + TBMCPlayer.class.getSimpleName(), player);
|
playermap.put(p.getUniqueId() + "-" + TBMCPlayer.class.getSimpleName(), player);
|
||||||
|
@ -159,8 +169,8 @@ public abstract class TBMCPlayerBase extends ChromaGamerBase {
|
||||||
try {
|
try {
|
||||||
p.close();
|
p.close();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
TBMCCoreAPI.SendException("Error while saving player " + p.getPlayerName() + " (" + p.getFolder() + "/"
|
TBMCCoreAPI.SendException("Error while saving player " + p.PlayerName().get() + " (" + p.getFolder()
|
||||||
+ p.getFileName() + ")!", e);
|
+ "/" + p.getFileName() + ")!", e);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
21
src/main/java/buttondevteam/lib/player/UserClass.java
Normal file
21
src/main/java/buttondevteam/lib/player/UserClass.java
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
package buttondevteam.lib.player;
|
||||||
|
|
||||||
|
import java.lang.annotation.ElementType;
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
import java.lang.annotation.Target;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specifies a {@link ChromaGamerBase} direct subclass. For Minecraft data, use {@link PlayerClass}
|
||||||
|
*
|
||||||
|
* @author NorbiPeti
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
@Target(ElementType.TYPE)
|
||||||
|
public @interface UserClass {
|
||||||
|
/**
|
||||||
|
* Indicates which folder should the player files be saved in.
|
||||||
|
*/
|
||||||
|
String foldername();
|
||||||
|
}
|
Loading…
Reference in a new issue