Making progress on player data

This commit is contained in:
Norbi Peti 2017-01-21 19:45:54 +01:00
parent 4aa7cccb5c
commit 28fcb2f8d8
2 changed files with 86 additions and 15 deletions

View file

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

View file

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