package de.tobiyas.racesandclasses.saving; import java.util.Collection; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; import java.util.UUID; import de.tobiyas.racesandclasses.RacesAndClasses; import de.tobiyas.racesandclasses.saving.serializer.DatabasePlayerDataSerializer; import de.tobiyas.racesandclasses.saving.serializer.DisabledDataSerializer; import de.tobiyas.racesandclasses.saving.serializer.PlayerDataSerializer; import de.tobiyas.racesandclasses.saving.serializer.PlayerDataSerializer.DataSerializerType; import de.tobiyas.racesandclasses.saving.serializer.YAMLPlayerDataSerializer; import de.tobiyas.util.schedule.DebugBukkitRunnable; public class PlayerSavingManager implements PlayerDataSerializer.PlayerDataLoadedCallback { /** * The Instance to use. */ private static PlayerSavingManager instance; /** * The Serializer to use. */ private final PlayerDataSerializer serializer; /** * The plugin to use. */ private final RacesAndClasses plugin; /** * The Data for Players. */ private final Map<UUID,PlayerSavingData> playerSaveMap = new HashMap<>(); private PlayerSavingManager() { this.plugin = RacesAndClasses.getPlugin(); String serializerName = plugin.getConfigManager().getGeneralConfig().getConfig_serializer(); DataSerializerType type = fromString(serializerName); this.serializer = generateSerializer(type); boolean asyncLoadAll = plugin.getConfigManager().getGeneralConfig().isConfig_preload_data_async(); if(asyncLoadAll) startAsyncLoading(); } /** * Creates and start an Async loading! */ protected void startAsyncLoading() { new DebugBukkitRunnable("BulkID-Loader") { @Override protected void runIntern() { Set<UUID> toLoad = serializer.getAllIDsPresent(); if(toLoad.isEmpty()) return; int i = 0; int MAX_TO_LOAD_PER_BULK = plugin.getConfigManager().getGeneralConfig().getConfig_preload_bulk_amount(); Set<UUID> toLoadCopied = new HashSet<>(); for(UUID id : toLoad){ toLoadCopied.add(id); //Bulk up to MAX: if(i% MAX_TO_LOAD_PER_BULK == 0 && i > 0) { Collection<PlayerSavingData> datas = serializer.bulkLoadDataNow(toLoadCopied); synchronized (playerSaveMap) { for(PlayerSavingData data : datas){ if(data != null && !playerSaveMap.containsKey(data.getPlayerId())) playerSaveMap.put(data.getPlayerId(), data); } } toLoadCopied.clear(); } i++; } RacesAndClasses.getPlugin().log("Pre-Loaded " + i + " Player-Data. Done."); } }.runTaskAsynchronously(plugin); } /** * Generates a Type from the Name passed. * @param name to parse * @return the Type. */ private DataSerializerType fromString(String name){ if(name == null) return DataSerializerType.YAML; name = name.toLowerCase(); if(name.startsWith("y") || name.startsWith("f")) return DataSerializerType.YAML; if(name.startsWith("o") || name.startsWith("di")) return DataSerializerType.DISABLED; if(name.startsWith("da") || name.startsWith("my") || name.startsWith("sql")) return DataSerializerType.DATABASE; return DataSerializerType.YAML; } /** * Generates a Data-Serializer. * @return the Serializer. */ private PlayerDataSerializer generateSerializer(DataSerializerType type){ PlayerDataSerializer serializer = null; switch(type){ case DATABASE : serializer = new DatabasePlayerDataSerializer(plugin); break; case DISABLED : serializer = new DisabledDataSerializer(); break; case YAML : default : serializer = new YAMLPlayerDataSerializer(plugin); break; } if(serializer == null || !serializer.isFunctional()){ if(type == DataSerializerType.DATABASE) RacesAndClasses.getPlugin().logWarning("Could not establish DB-Connection! Switching to YML files!"); serializer = new YAMLPlayerDataSerializer(plugin); } return serializer; } /** * Gets the Serializer to use. * @return the serializer. */ protected PlayerDataSerializer getSerializer() { return serializer; } /** * Gets the Data from the ID. * @param id to search. * @return the PlayerData. */ public PlayerSavingData getPlayerData(UUID id){ PlayerSavingData data = null; synchronized (playerSaveMap) { data = playerSaveMap.get(id); } if(data != null) return data; data = serializer.loadDataNow(id); if(data == null) data = new PlayerSavingData(id); synchronized (playerSaveMap) { playerSaveMap.put(id, data); } return data; } /** * Shuts everything down. */ private void shutdownInstance(){ serializer.shutdown(); } /** * Gets the Instance. * <br>Lazy init. * @return the instance */ public static PlayerSavingManager get(){ if(instance == null) instance = new PlayerSavingManager(); return instance; } /** * Reinits the Manager. */ public static void reload() { shutdown(); instance = new PlayerSavingManager(); } /** * Reinits the Manager. */ public static void shutdown() { if(instance != null) instance.shutdownInstance(); instance = null; } @Override public void playerDataLoaded(PlayerSavingData data) { if(data == null) return; synchronized (playerSaveMap) { if(!playerSaveMap.containsKey(data.getPlayerId())) playerSaveMap.put(data.getPlayerId(), data); } } }