Making progress on player data
This commit is contained in:
parent
4aa7cccb5c
commit
28fcb2f8d8
2 changed files with 86 additions and 15 deletions
|
@ -1,11 +1,8 @@
|
|||
package buttondevteam.lib.player;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
|
@ -17,12 +14,30 @@ public abstract class ChromaGamerBase implements AutoCloseable {
|
|||
|
||||
private static final HashMap<Class<?>, String> playerTypes = new HashMap<>();
|
||||
|
||||
/**
|
||||
* Use only if outside Minecraft, and use it to register your plugin's class.
|
||||
*
|
||||
* @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) {
|
||||
playerTypes.put(cl, folder);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the folder name for the given player class. If a direct match is not found, it'll look for superclasses.
|
||||
*
|
||||
* @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
|
||||
*/
|
||||
public static <T extends ChromaGamerBase> String getFolderForType(Class<T> cl) {
|
||||
return playerTypes.get(cl);
|
||||
if (playerTypes.containsKey(cl))
|
||||
return playerTypes.get(cl);
|
||||
return playerTypes.entrySet().stream().filter(e -> e.getKey().isAssignableFrom(cl)).findAny()
|
||||
.orElseThrow(() -> new RuntimeException("Type not registered as a player type!")).getValue();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -35,10 +50,6 @@ public abstract class ChromaGamerBase implements AutoCloseable {
|
|||
*/
|
||||
protected YamlConfiguration plugindata;
|
||||
|
||||
public YamlConfiguration getData() {
|
||||
return plugindata;
|
||||
}
|
||||
|
||||
public String getID() {
|
||||
return plugindata != null ? plugindata.getString("id") : null;
|
||||
}
|
||||
|
@ -47,7 +58,7 @@ public abstract class ChromaGamerBase implements AutoCloseable {
|
|||
try {
|
||||
T obj = cl.newInstance();
|
||||
obj.plugindata = YamlConfiguration
|
||||
.loadConfiguration(new File(TBMC_PLAYERS_DIR + playerTypes.get(cl), fname));
|
||||
.loadConfiguration(new File(TBMC_PLAYERS_DIR + getFolderForType(cl), fname));
|
||||
return obj;
|
||||
} catch (Exception e) {
|
||||
TBMCCoreAPI.SendException("An error occured while loading a " + cl.getSimpleName() + "!", e);
|
||||
|
@ -60,15 +71,54 @@ public abstract class ChromaGamerBase implements AutoCloseable {
|
|||
plugindata.save(new File(TBMC_PLAYERS_DIR + getFolderForType(getClass()), getFileName()));
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
public <T extends ChromaGamerBase> void connectWith(T user) {
|
||||
// Set the ID, go through all linked files and connect them as well
|
||||
plugindata.set(playerTypes.get(user.getClass()) + "_id", user.plugindata.getString("id"));
|
||||
plugindata.set(getFolderForType(user.getClass()) + "_id", user.plugindata.getString("id"));
|
||||
final String ownFolder = getFolderForType(getClass());
|
||||
user.plugindata.set(ownFolder + "_id", plugindata.getString("id"));
|
||||
BiConsumer<YamlConfiguration, YamlConfiguration> sync = (pdata1, pdata2) -> {
|
||||
for (Entry<Class<?>, String> entry : playerTypes.entrySet())
|
||||
if (pdata1.contains(entry.getValue() + "_id", false))
|
||||
pdata2.set(entry.getValue() + "_id", pdata1.getString(entry.getValue() + "_id"));
|
||||
}; // ...
|
||||
Consumer<YamlConfiguration> sync = sourcedata -> {
|
||||
final String sourcefolder = sourcedata == plugindata ? ownFolder : getFolderForType(user.getClass());
|
||||
final String id = sourcedata.getString("id");
|
||||
for (Entry<Class<?>, String> entry : playerTypes.entrySet()) { // Set our ID in all files we can find, both from our connections and the new ones
|
||||
final String otherid = sourcedata.getString(entry.getValue() + "_id");
|
||||
if (otherid == null)
|
||||
continue;
|
||||
try (@SuppressWarnings("unchecked")
|
||||
ChromaGamerBase cg = getUser(otherid, (Class<T>) entry.getKey())) {
|
||||
cg.plugindata.set(sourcefolder + "_id", id); // Set new IDs
|
||||
for (Entry<Class<?>, String> item : playerTypes.entrySet())
|
||||
if (sourcedata.contains(item.getValue() + "_id"))
|
||||
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);
|
||||
}
|
||||
}
|
||||
};
|
||||
sync.accept(plugindata);
|
||||
sync.accept(user.plugindata);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
* @return The player as a {@link T} object or null if not having an account there
|
||||
*/
|
||||
public <T extends ChromaGamerBase> T getAs(Class<T> cl) {
|
||||
String newfolder = getFolderForType(cl);
|
||||
if (newfolder == null)
|
||||
throw new RuntimeException("The specified class " + cl.getSimpleName() + " isn't registered!");
|
||||
if (!plugindata.contains(newfolder + "_id"))
|
||||
return null;
|
||||
return getUser(plugindata.getString(newfolder + "_id"), cl);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package buttondevteam.lib.player;
|
||||
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
public abstract class TBMCPlayerBase extends ChromaGamerBase {
|
||||
private static final String FOLDER_NAME = "minecraft";
|
||||
|
@ -28,9 +29,29 @@ public abstract class TBMCPlayerBase extends ChromaGamerBase {
|
|||
addPlayerType(TBMCPlayerBase.class, FOLDER_NAME);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <T extends TBMCPlayerBase> T getPlayer(UUID uuid, Class<T> cl) {
|
||||
if (playermap.containsKey(uuid + "-" + cl.getSimpleName()))
|
||||
return (T) playermap.get(uuid + "-" + cl.getSimpleName());
|
||||
T obj = ChromaGamerBase.getUser(uuid.toString(), cl);
|
||||
obj.uuid = uuid;
|
||||
return obj;
|
||||
}
|
||||
|
||||
/**
|
||||
* Key: UUID-Class
|
||||
*/
|
||||
static final ConcurrentHashMap<String, TBMCPlayerBase> playermap = new ConcurrentHashMap<>();
|
||||
|
||||
/**
|
||||
* Gets the TBMCPlayer object as a specific plugin player, keeping it's data *
|
||||
*
|
||||
* @param p
|
||||
* Player to get
|
||||
* @param cl
|
||||
* The TBMCPlayer subclass
|
||||
*/
|
||||
public <T extends TBMCPlayerBase> T asPluginPlayer(Class<T> cl) {
|
||||
return getPlayer(uuid, cl);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue