mirror of
https://github.com/songoda/EpicFurnaces.git
synced 2024-11-27 20:35:24 +01:00
Upgraded Storage System.
This commit is contained in:
parent
db951a879f
commit
856dc3e6c4
@ -125,7 +125,7 @@ public class EpicFurnaces extends JavaPlugin {
|
||||
int timeout = getConfig().getInt("Main.Auto Save Interval In Seconds") * 60 * 20;
|
||||
|
||||
Bukkit.getScheduler().runTaskLater(this, furnaceManager::loadFurnaces, 10);
|
||||
Bukkit.getScheduler().runTaskTimerAsynchronously(this, this::saveToFile, timeout, timeout);
|
||||
Bukkit.getScheduler().runTaskTimerAsynchronously(this, () -> storage.doSave(), timeout, timeout);
|
||||
|
||||
// Start Tasks
|
||||
HologramTask.startTask(this);
|
||||
@ -171,7 +171,8 @@ public class EpicFurnaces extends JavaPlugin {
|
||||
Bukkit.getConsoleSender().sendMessage(formatText("&a============================="));
|
||||
getHologramManager().ifPresent(HologramManager::clearAll);
|
||||
this.hologramManager = null;
|
||||
saveToFile();
|
||||
storage.doSave();
|
||||
storage.closeConnection();
|
||||
}
|
||||
|
||||
private void checkStorage() {
|
||||
@ -182,14 +183,6 @@ public class EpicFurnaces extends JavaPlugin {
|
||||
}
|
||||
}
|
||||
|
||||
private void saveToFile() {
|
||||
this.storage.closeConnection();
|
||||
checkStorage();
|
||||
furnaceManager.saveToFile();
|
||||
boostManager.saveToFile();
|
||||
storage.doSave();
|
||||
}
|
||||
|
||||
public void reload() {
|
||||
Bukkit.getScheduler().cancelTasks(this);
|
||||
reloadConfig();
|
||||
|
@ -39,12 +39,4 @@ public class BoostManager {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public void saveToFile() {
|
||||
for (BoostData boostData : getBoosts()) {
|
||||
instance.getStorage().prepareSaveItem("boosts", new StorageItem("endtime", String.valueOf(boostData.getEndTime())),
|
||||
new StorageItem("amount", boostData.getMultiplier()),
|
||||
new StorageItem("uuid", boostData.getPlayer().toString()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -126,24 +126,6 @@ public class FurnaceManager {
|
||||
getFurnaces().values().forEach(furnace -> instance.getHologramManager().ifPresent(manager -> manager.updateHologram(furnace)));
|
||||
}
|
||||
|
||||
public void saveToFile() {
|
||||
for (FurnaceObject furnace : getFurnaces().values()) {
|
||||
if (furnace == null || furnace.getLocation() == null || furnace.getLocation().getWorld() == null) {
|
||||
continue;
|
||||
}
|
||||
String locationStr = Methods.serializeLocation(furnace.getLocation());
|
||||
|
||||
instance.getStorage().prepareSaveItem("charged",
|
||||
new StorageItem("location", locationStr),
|
||||
new StorageItem("level", furnace.getLevel().getLevel()),
|
||||
new StorageItem("uses", furnace.getUses()),
|
||||
new StorageItem("tolevel", furnace.getToLevel()),
|
||||
new StorageItem("nickname", furnace.getNickname()),
|
||||
new StorageItem("accesslist", furnace.getOriginalAccessList()),
|
||||
new StorageItem("placedby", furnace.getPlacedBy() == null ? null : furnace.getPlacedBy().toString()));
|
||||
}
|
||||
}
|
||||
|
||||
public Map<Location, FurnaceObject> getFurnaces() {
|
||||
return Collections.unmodifiableMap(registeredFurnaces);
|
||||
}
|
||||
|
@ -1,18 +1,24 @@
|
||||
package com.songoda.epicfurnaces.storage;
|
||||
|
||||
import com.songoda.epicfurnaces.EpicFurnaces;
|
||||
import org.bukkit.configuration.file.FileConfiguration;
|
||||
import com.songoda.epicfurnaces.objects.BoostData;
|
||||
import com.songoda.epicfurnaces.objects.FurnaceObject;
|
||||
import com.songoda.epicfurnaces.utils.ConfigWrapper;
|
||||
import com.songoda.epicfurnaces.utils.Methods;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public abstract class Storage {
|
||||
|
||||
protected final EpicFurnaces instance;
|
||||
protected final FileConfiguration dataFile;
|
||||
protected final ConfigWrapper dataFile;
|
||||
|
||||
public Storage(EpicFurnaces instance) {
|
||||
this.instance = instance;
|
||||
this.dataFile = instance.getConfiguration("data");
|
||||
this.dataFile = new ConfigWrapper(instance, "", "data.yml");
|
||||
this.dataFile.createNewFile(null, "EpicFurnaces Data File");
|
||||
this.dataFile.getConfig().options().copyDefaults(true);
|
||||
this.dataFile.saveConfig();
|
||||
}
|
||||
|
||||
public abstract boolean containsGroup(String group);
|
||||
@ -21,8 +27,37 @@ public abstract class Storage {
|
||||
|
||||
public abstract void prepareSaveItem(String group, StorageItem... items);
|
||||
|
||||
public void updateData(EpicFurnaces instance) {
|
||||
// Save game data
|
||||
for (FurnaceObject furnace : instance.getFurnaceManager().getFurnaces().values()) {
|
||||
if (furnace == null || furnace.getLocation() == null || furnace.getLocation().getWorld() == null) {
|
||||
continue;
|
||||
}
|
||||
String locationStr = Methods.serializeLocation(furnace.getLocation());
|
||||
|
||||
instance.getStorage().prepareSaveItem("charged",
|
||||
new StorageItem("location", locationStr),
|
||||
new StorageItem("level", furnace.getLevel().getLevel()),
|
||||
new StorageItem("uses", furnace.getUses()),
|
||||
new StorageItem("tolevel", furnace.getToLevel()),
|
||||
new StorageItem("nickname", furnace.getNickname()),
|
||||
new StorageItem("accesslist", furnace.getOriginalAccessList()),
|
||||
new StorageItem("placedby", furnace.getPlacedBy() == null ? null : furnace.getPlacedBy().toString()));
|
||||
}
|
||||
|
||||
for (BoostData boostData : instance.getBoostManager().getBoosts()) {
|
||||
instance.getStorage().prepareSaveItem("boosts", new StorageItem("endtime", String.valueOf(boostData.getEndTime())),
|
||||
new StorageItem("amount", boostData.getMultiplier()),
|
||||
new StorageItem("uuid", boostData.getPlayer().toString()));
|
||||
}
|
||||
}
|
||||
|
||||
public abstract void doSave();
|
||||
|
||||
public abstract void save();
|
||||
|
||||
public abstract void makeBackup();
|
||||
|
||||
public abstract void closeConnection();
|
||||
|
||||
}
|
||||
|
@ -17,8 +17,9 @@ import java.util.Map;
|
||||
|
||||
public class StorageMysql extends Storage {
|
||||
|
||||
private static Map<String, StorageItem[]> toSave = new HashMap<>();
|
||||
private static Map<String, StorageItem[]> lastSave = new HashMap<>();
|
||||
private MySQLDatabase database;
|
||||
private static List<String> toSave = new ArrayList<>();
|
||||
|
||||
public StorageMysql(EpicFurnaces instance) {
|
||||
super(instance);
|
||||
@ -65,42 +66,107 @@ public class StorageMysql extends Storage {
|
||||
|
||||
@Override
|
||||
public void prepareSaveItem(String group, StorageItem... items) {
|
||||
StringBuilder sql = new StringBuilder(String.format("INSERT INTO `" + instance.getConfig().getString("Database.Prefix") + "%s`", group));
|
||||
|
||||
sql.append(" (");
|
||||
|
||||
for (StorageItem item : items) {
|
||||
if (item == null || item.asObject() == null) continue;
|
||||
sql.append(String.format("`%s`, ", item.getKey()));
|
||||
}
|
||||
|
||||
sql = new StringBuilder(sql.substring(0, sql.length() - 2));
|
||||
|
||||
sql.append(") VALUES (");
|
||||
|
||||
for (StorageItem item : items) {
|
||||
if (item == null || item.asObject() == null) continue;
|
||||
sql.append(String.format("'%s', ", item.asObject().toString()));
|
||||
}
|
||||
|
||||
sql = new StringBuilder(sql.substring(0, sql.length() - 2));
|
||||
|
||||
sql.append(");");
|
||||
|
||||
toSave.add(sql.toString());
|
||||
toSave.put(group + "]" + items[0].asObject().toString(), items);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doSave() {
|
||||
try {
|
||||
// Clear database
|
||||
database.getConnection().createStatement().execute("TRUNCATE `" + instance.getConfig().getString("Database.Prefix") + "charged`");
|
||||
database.getConnection().createStatement().execute("TRUNCATE `" + instance.getConfig().getString("Database.Prefix") + "boosts`");
|
||||
this.updateData(instance);
|
||||
if (toSave.isEmpty()) return;
|
||||
Map<String, StorageItem[]> nextSave = new HashMap<>(toSave);
|
||||
|
||||
if (lastSave.isEmpty())
|
||||
lastSave.putAll(toSave);
|
||||
|
||||
this.makeBackup();
|
||||
this.save();
|
||||
|
||||
toSave.clear();
|
||||
lastSave.clear();
|
||||
lastSave.putAll(nextSave);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void save() {
|
||||
try {
|
||||
Statement stmt = database.getConnection().createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE);
|
||||
|
||||
for (String line : toSave) {
|
||||
stmt.addBatch(line);
|
||||
last:
|
||||
for (Map.Entry<String, StorageItem[]> last : lastSave.entrySet()) {
|
||||
String lastKey = last.getKey().split("]")[0];
|
||||
String lastValue = last.getValue()[0].asObject().toString();
|
||||
|
||||
for (Map.Entry<String, StorageItem[]> to : toSave.entrySet()) {
|
||||
String toKey = to.getKey().split("]")[0];
|
||||
if (!toKey.equals(lastKey)
|
||||
|| !to.getValue()[0].asObject().equals(lastValue)
|
||||
|| to.getValue().length != last.getValue().length)
|
||||
continue;
|
||||
toSave.remove(toKey);
|
||||
for (int i = 0; i < to.getValue().length - 1; i ++) {
|
||||
if (to.getValue()[i].asObject() != null
|
||||
&& !to.getValue()[i].asObject().toString()
|
||||
.equals(last.getValue()[i].asObject().toString())) {
|
||||
//Update
|
||||
StorageItem[] items = to.getValue();
|
||||
StringBuilder sql = new StringBuilder(String.format("UPDATE `" + instance.getConfig().getString("Database.Prefix") + "%s`", toKey));
|
||||
|
||||
sql.append(" SET");
|
||||
|
||||
for (StorageItem item : items) {
|
||||
if (item == null || item.asObject() == null) continue;
|
||||
String key = item.getKey().split("]")[0];
|
||||
sql.append(String.format("`%s` = '%s', ", key, item.asObject().toString()));
|
||||
}
|
||||
|
||||
sql = new StringBuilder(sql.substring(0, sql.length() - 2));
|
||||
|
||||
sql.append(String.format(" WHERE `%s`='%s'", last.getValue()[0].getKey(), last.getValue()[0].asObject().toString()));
|
||||
|
||||
stmt.addBatch(sql.toString());
|
||||
|
||||
continue last;
|
||||
}
|
||||
}
|
||||
// Already up to date.
|
||||
|
||||
continue last;
|
||||
}
|
||||
//Was not found delete.
|
||||
StringBuilder sql = new StringBuilder(String.format("DELETE FROM `" + instance.getConfig().getString("Database.Prefix") + "%s`", lastKey));
|
||||
sql.append(String.format(" WHERE `%s`='%s'", last.getValue()[0].getKey(), last.getValue()[0].asObject().toString()));
|
||||
stmt.addBatch(sql.toString());
|
||||
|
||||
}
|
||||
|
||||
for (Map.Entry<String, StorageItem[]> to : toSave.entrySet()) {
|
||||
String toKey = to.getKey().split("]")[0];
|
||||
//Add
|
||||
StorageItem[] items = to.getValue();
|
||||
StringBuilder sql = new StringBuilder(String.format("INSERT INTO `" + instance.getConfig().getString("Database.Prefix") + "%s`", toKey));
|
||||
|
||||
sql.append(" (");
|
||||
|
||||
for (StorageItem item : items) {
|
||||
if (item == null || item.asObject() == null) continue;
|
||||
String key = item.getKey().split("]")[0];
|
||||
sql.append(String.format("`%s`, ", key));
|
||||
}
|
||||
|
||||
sql = new StringBuilder(sql.substring(0, sql.length() - 2));
|
||||
|
||||
sql.append(") VALUES (");
|
||||
|
||||
for (StorageItem item : items) {
|
||||
if (item == null || item.asObject() == null) continue;
|
||||
sql.append(String.format("'%s', ", item.asObject().toString()));
|
||||
}
|
||||
|
||||
sql = new StringBuilder(sql.substring(0, sql.length() - 2));
|
||||
|
||||
sql.append(");");
|
||||
|
||||
stmt.addBatch(sql.toString());
|
||||
}
|
||||
|
||||
stmt.executeBatch();
|
||||
@ -112,6 +178,11 @@ public class StorageMysql extends Storage {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void makeBackup() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void closeConnection() {
|
||||
try {
|
||||
@ -122,4 +193,3 @@ public class StorageMysql extends Storage {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -13,6 +13,7 @@ import java.util.*;
|
||||
public class StorageYaml extends Storage {
|
||||
|
||||
private static final Map<String, Object> toSave = new HashMap<>();
|
||||
private static final Map<String, Object> lastSave = new HashMap<>();
|
||||
|
||||
public StorageYaml(EpicFurnaces instance) {
|
||||
super(instance);
|
||||
@ -20,21 +21,21 @@ public class StorageYaml extends Storage {
|
||||
|
||||
@Override
|
||||
public boolean containsGroup(String group) {
|
||||
return dataFile.contains("data." + group);
|
||||
return dataFile.getConfig().contains("data." + group);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<StorageRow> getRowsByGroup(String group) {
|
||||
List<StorageRow> rows = new ArrayList<>();
|
||||
ConfigurationSection currentSection = dataFile.getConfigurationSection("data." + group);
|
||||
ConfigurationSection currentSection = dataFile.getConfig().getConfigurationSection("data." + group);
|
||||
for (String key : currentSection.getKeys(false)) {
|
||||
|
||||
Map<String, StorageItem> items = new HashMap<>();
|
||||
ConfigurationSection currentSection2 = dataFile.getConfigurationSection("data." + group + "." + key);
|
||||
ConfigurationSection currentSection2 = dataFile.getConfig().getConfigurationSection("data." + group + "." + key);
|
||||
for (String key2 : currentSection2.getKeys(false)) {
|
||||
String path = "data." + group + "." + key + "." + key2;
|
||||
items.put(key2, new StorageItem(dataFile.get(path) instanceof MemorySection
|
||||
? convertToInLineList(path) : dataFile.get(path)));
|
||||
items.put(key2, new StorageItem(dataFile.getConfig().get(path) instanceof MemorySection
|
||||
? convertToInLineList(path) : dataFile.getConfig().get(path)));
|
||||
}
|
||||
if (items.isEmpty()) continue;
|
||||
StorageRow row = new StorageRow(key, items);
|
||||
@ -45,8 +46,8 @@ public class StorageYaml extends Storage {
|
||||
|
||||
private String convertToInLineList(String path) {
|
||||
StringBuilder converted = new StringBuilder();
|
||||
for (String key : dataFile.getConfigurationSection(path).getKeys(false)) {
|
||||
converted.append(key).append(":").append(dataFile.getInt(path + "." + key)).append(";");
|
||||
for (String key : dataFile.getConfig().getConfigurationSection(path).getKeys(false)) {
|
||||
converted.append(key).append(":").append(dataFile.getConfig().getInt(path + "." + key)).append(";");
|
||||
}
|
||||
return converted.toString();
|
||||
}
|
||||
@ -55,51 +56,78 @@ public class StorageYaml extends Storage {
|
||||
public void prepareSaveItem(String group, StorageItem... items) {
|
||||
for (StorageItem item : items) {
|
||||
if (item == null || item.asObject() == null) continue;
|
||||
toSave.put("data." + group + "." + items[0].asString() + "." + item.getKey(), item.asObject());
|
||||
toSave.put("data." + group + "." + items[0].asObject()+ "." + item.getKey(), item.asObject());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doSave() {
|
||||
if (toSave.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
dataFile.set("data", null); // Clear file
|
||||
this.updateData(instance);
|
||||
if (toSave.isEmpty()) return;
|
||||
Map<String, Object> nextSave = new HashMap<>(toSave);
|
||||
|
||||
File data = new File(instance.getDataFolder() + "/data.yml");
|
||||
File dataClone = new File(instance.getDataFolder() + "/backup/data-backup-" + System.currentTimeMillis() + ".yml");
|
||||
try {
|
||||
copyFile(data, dataClone);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
Deque<File> backups = new ArrayDeque<>();
|
||||
for (File file : Objects.requireNonNull(instance.getDataFolder().listFiles())) {
|
||||
if (file.getName().toLowerCase().contains("data-backup")) {
|
||||
backups.add(file);
|
||||
if (lastSave.isEmpty())
|
||||
lastSave.putAll(toSave);
|
||||
|
||||
this.makeBackup();
|
||||
this.save();
|
||||
|
||||
toSave.clear();
|
||||
lastSave.clear();
|
||||
lastSave.putAll(nextSave);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void save() {
|
||||
try {
|
||||
for (Map.Entry<String, Object> entry : lastSave.entrySet()) {
|
||||
if (toSave.containsKey(entry.getKey())) {
|
||||
Object newValue = toSave.get(entry.getKey());
|
||||
if (!entry.getValue().equals(newValue)) {
|
||||
dataFile.getConfig().set(entry.getKey(), entry.getValue());
|
||||
}
|
||||
toSave.remove(newValue);
|
||||
} else {
|
||||
dataFile.getConfig().set(entry.getKey(), null);
|
||||
}
|
||||
}
|
||||
if (backups.size() > 5) {
|
||||
backups.getFirst().delete();
|
||||
}
|
||||
|
||||
for (Map.Entry<String, Object> entry : toSave.entrySet()) {
|
||||
dataFile.set(entry.getKey(), entry.getValue());
|
||||
dataFile.getConfig().set(entry.getKey(), entry.getValue());
|
||||
}
|
||||
|
||||
instance.save("data");
|
||||
toSave.clear();
|
||||
dataFile.saveConfig();
|
||||
} catch (NullPointerException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void closeConnection() {
|
||||
instance.save("data");
|
||||
public void makeBackup() {
|
||||
File data = new File(instance.getDataFolder(), "data.yml");
|
||||
File dataClone = new File(instance.getDataFolder(), "data-backup-" + System.currentTimeMillis() + ".yml");
|
||||
try {
|
||||
copyFile(data, dataClone);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
Deque<File> backups = new ArrayDeque<>();
|
||||
for (File file : Objects.requireNonNull(instance.getDataFolder().listFiles())) {
|
||||
if (file.getName().toLowerCase().contains("data-backup")) {
|
||||
backups.add(file);
|
||||
}
|
||||
}
|
||||
if (backups.size() > 3) {
|
||||
backups.getFirst().delete();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void closeConnection() {
|
||||
dataFile.saveConfig();
|
||||
}
|
||||
|
||||
|
||||
private static void copyFile(File source, File dest) throws IOException {
|
||||
InputStream is = null;
|
||||
OutputStream os = null;
|
||||
|
@ -0,0 +1,67 @@
|
||||
package com.songoda.epicfurnaces.utils;
|
||||
|
||||
import org.bukkit.configuration.file.FileConfiguration;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.logging.Level;
|
||||
|
||||
/**
|
||||
* ConfigWrapper made by @clip
|
||||
*/
|
||||
public class ConfigWrapper {
|
||||
|
||||
private final JavaPlugin plugin;
|
||||
private final String folderName, fileName;
|
||||
private FileConfiguration config;
|
||||
private File configFile;
|
||||
|
||||
public ConfigWrapper(final JavaPlugin instance, final String folderName, final String fileName) {
|
||||
this.plugin = instance;
|
||||
this.folderName = folderName;
|
||||
this.fileName = fileName;
|
||||
}
|
||||
|
||||
public void createNewFile(final String message, final String header) {
|
||||
reloadConfig();
|
||||
saveConfig();
|
||||
loadConfig(header);
|
||||
|
||||
if (message != null) {
|
||||
plugin.getLogger().info(message);
|
||||
}
|
||||
}
|
||||
|
||||
public FileConfiguration getConfig() {
|
||||
if (config == null) {
|
||||
reloadConfig();
|
||||
}
|
||||
return config;
|
||||
}
|
||||
|
||||
public void loadConfig(final String header) {
|
||||
config.options().header(header);
|
||||
config.options().copyDefaults(true);
|
||||
saveConfig();
|
||||
}
|
||||
|
||||
public void reloadConfig() {
|
||||
if (configFile == null) {
|
||||
configFile = new File(plugin.getDataFolder() + folderName, fileName);
|
||||
}
|
||||
config = YamlConfiguration.loadConfiguration(configFile);
|
||||
}
|
||||
|
||||
public void saveConfig() {
|
||||
if (config == null || configFile == null) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
getConfig().save(configFile);
|
||||
} catch (final IOException ex) {
|
||||
plugin.getLogger().log(Level.SEVERE, "Could not save config to " + configFile, ex);
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user