new storage system

This commit is contained in:
Brianna O'Keefe 2019-02-18 09:03:24 -05:00
parent 9cb14b9c51
commit bc594ab7f9
5 changed files with 193 additions and 81 deletions

View File

@ -172,6 +172,8 @@ public class EpicFarmingPlugin extends JavaPlugin implements EpicFarming {
} }
// Save data initially so that if the person reloads again fast they don't lose all their data.
this.saveToFile();
}, 10); }, 10);
this.references = new References(); this.references = new References();
@ -252,35 +254,9 @@ public class EpicFarmingPlugin extends JavaPlugin implements EpicFarming {
* Saves registered farms to file. * Saves registered farms to file.
*/ */
private void saveToFile() { private void saveToFile() {
this.storage.closeConnection();
checkStorage(); checkStorage();
/*
* Dump FarmManager to file.
*/
for (Farm farm : farmManager.getFarms().values()) {
if (farm.getLocation() == null
|| farm.getLocation().getWorld() == null) continue;
String locstr = Methods.serializeLocation(farm.getLocation());
storage.prepareSaveItem("farms",new StorageItem("location",locstr),
new StorageItem("level",farm.getLevel().getLevel()),
new StorageItem("placedby",farm.getPlacedBy().toString()),
new StorageItem("contents",((EFarm)farm).dumpInventory()));
}
/*
* Dump BoostManager to file.
*/
for (BoostData boostData : boostManager.getBoosts()) {
String endTime = String.valueOf(boostData.getEndTime());
storage.prepareSaveItem("boosts",new StorageItem("endtime",endTime),
new StorageItem("amount",boostData.getMultiplier()),
new StorageItem("player",boostData.getPlayer()));
}
//Save to file
storage.doSave(); storage.doSave();
} }
private void update() { private void update() {

View File

@ -28,7 +28,10 @@ public class ELevel implements Level {
EpicFarmingPlugin instance = EpicFarmingPlugin.getInstance(); EpicFarmingPlugin instance = EpicFarmingPlugin.getInstance();
description.add(instance.getLocale().getMessage("interface.button.radius", radius)); description.add(instance
.getLocale()
.getMessage("interface.button.radius",
radius));
description.add(instance.getLocale().getMessage("interface.button.speed", speedMultiplier)); description.add(instance.getLocale().getMessage("interface.button.speed", speedMultiplier));
if (autoHarvest) if (autoHarvest)

View File

@ -1,9 +1,15 @@
package com.songoda.epicfarming.storage; package com.songoda.epicfarming.storage;
import com.songoda.epicfarming.api.farming.Farm;
import com.songoda.epicfarming.boost.BoostData;
import com.songoda.epicfarming.farming.EFarm;
import com.songoda.epicfarming.utils.Methods;
import com.songoda.epicfarming.EpicFarmingPlugin; import com.songoda.epicfarming.EpicFarmingPlugin;
import com.songoda.epicfarming.api.EpicFarming;
import com.songoda.epicfarming.utils.ConfigWrapper; import com.songoda.epicfarming.utils.ConfigWrapper;
import com.songoda.epicfarming.utils.Methods;
import org.bukkit.Material;
import java.util.ArrayList;
import java.util.List; import java.util.List;
public abstract class Storage { public abstract class Storage {
@ -25,8 +31,37 @@ public abstract class Storage {
public abstract void prepareSaveItem(String group, StorageItem... items); public abstract void prepareSaveItem(String group, StorageItem... items);
public void updateData(EpicFarmingPlugin instance) {
/*
* Dump FarmManager to file.
*/
for (Farm farm : instance.getFarmManager().getFarms().values()) {
if (farm.getLocation() == null
|| farm.getLocation().getWorld() == null) continue;
String locstr = Methods.serializeLocation(farm.getLocation());
prepareSaveItem("farms",new StorageItem("location",locstr),
new StorageItem("level",farm.getLevel().getLevel()),
new StorageItem("placedby",farm.getPlacedBy().toString()),
new StorageItem("contents",((EFarm)farm).dumpInventory()));
}
/*
* Dump BoostManager to file.
*/
for (BoostData boostData : instance.getBoostManager().getBoosts()) {
String endTime = String.valueOf(boostData.getEndTime());
prepareSaveItem("boosts",new StorageItem("endtime",endTime),
new StorageItem("amount",boostData.getMultiplier()),
new StorageItem("player",boostData.getPlayer()));
}
}
public abstract void doSave(); public abstract void doSave();
public abstract void save();
public abstract void makeBackup();
public abstract void closeConnection(); public abstract void closeConnection();
} }

View File

@ -1,11 +1,11 @@
package com.songoda.epicfarming.storage.types; package com.songoda.epicfarming.storage.types;
import com.songoda.epicfarming.EpicFarmingPlugin;
import com.songoda.epicfarming.storage.Storage; import com.songoda.epicfarming.storage.Storage;
import com.songoda.epicfarming.storage.StorageItem; import com.songoda.epicfarming.storage.StorageItem;
import com.songoda.epicfarming.storage.StorageRow; import com.songoda.epicfarming.storage.StorageRow;
import com.songoda.epicfarming.utils.MySQLDatabase; import com.songoda.epicfarming.utils.MySQLDatabase;
import com.songoda.epicfarming.EpicFarmingPlugin;
import com.songoda.epicfarming.utils.MySQLDatabase;
import java.sql.DatabaseMetaData; import java.sql.DatabaseMetaData;
import java.sql.ResultSet; import java.sql.ResultSet;
@ -18,8 +18,9 @@ import java.util.Map;
public class StorageMysql extends Storage { 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 MySQLDatabase database;
private static List<String> toSave = new ArrayList<>();
public StorageMysql(EpicFarmingPlugin instance) { public StorageMysql(EpicFarmingPlugin instance) {
super(instance); super(instance);
@ -66,42 +67,106 @@ public class StorageMysql extends Storage {
@Override @Override
public void prepareSaveItem(String group, StorageItem... items) { public void prepareSaveItem(String group, StorageItem... items) {
StringBuilder sql = new StringBuilder(String.format("INSERT INTO `" + instance.getConfig().getString("Database.Prefix") + "%s`", group)); toSave.put(group + "]" + items[0].asObject().toString(), items);
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());
} }
@Override @Override
public void doSave() { public void doSave() {
try { this.updateData(instance);
// Clear database if (toSave.isEmpty()) return;
database.getConnection().createStatement().execute("TRUNCATE `" + instance.getConfig().getString("Database.Prefix") + "farms`"); Map<String, StorageItem[]> nextSave = new HashMap<>(toSave);
database.getConnection().createStatement().execute("TRUNCATE `" + instance.getConfig().getString("Database.Prefix") + "boosts`");
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); Statement stmt = database.getConnection().createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE);
for (String line : toSave) { last:
stmt.addBatch(line); 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().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(); stmt.executeBatch();
@ -113,6 +178,11 @@ public class StorageMysql extends Storage {
} }
} }
@Override
public void makeBackup() {
}
@Override @Override
public void closeConnection() { public void closeConnection() {
try { try {
@ -122,3 +192,4 @@ public class StorageMysql extends Storage {
} }
} }
} }

View File

@ -1,12 +1,11 @@
package com.songoda.epicfarming.storage.types; package com.songoda.epicfarming.storage.types;
import com.songoda.epicfarming.EpicFarmingPlugin;
import com.songoda.epicfarming.storage.Storage; import com.songoda.epicfarming.storage.Storage;
import com.songoda.epicfarming.storage.StorageItem; import com.songoda.epicfarming.storage.StorageItem;
import com.songoda.epicfarming.storage.StorageRow; import com.songoda.epicfarming.storage.StorageRow;
import com.songoda.epicfarming.EpicFarmingPlugin;
import com.songoda.epicfarming.utils.Debugger; import com.songoda.epicfarming.utils.Debugger;
import org.apache.commons.io.FileUtils; import org.apache.commons.io.FileUtils;
import org.bukkit.Bukkit;
import org.bukkit.configuration.ConfigurationSection; import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.configuration.MemorySection; import org.bukkit.configuration.MemorySection;
@ -17,6 +16,7 @@ import java.util.*;
public class StorageYaml extends Storage { public class StorageYaml extends Storage {
private static final Map<String, Object> toSave = new HashMap<>(); private static final Map<String, Object> toSave = new HashMap<>();
private static final Map<String, Object> lastSave = new HashMap<>();
public StorageYaml(EpicFarmingPlugin instance) { public StorageYaml(EpicFarmingPlugin instance) {
super(instance); super(instance);
@ -65,39 +65,66 @@ public class StorageYaml extends Storage {
@Override @Override
public void doSave() { public void doSave() {
try { this.updateData(instance);
dataFile.getConfig().set("data", null); // Clear file if (toSave.isEmpty()) return;
Map<String, Object> nextSave = new HashMap<>(toSave);
File data = new File(instance.getDataFolder() + "/data.yml"); if (lastSave.isEmpty())
File dataClone = new File(instance.getDataFolder() + "/data-backup-" + System.currentTimeMillis() + ".yml"); lastSave.putAll(toSave);
try {
FileUtils.copyFile(data, dataClone); this.makeBackup();
} catch (IOException e) { this.save();
Debugger.runReport(e);
} toSave.clear();
Deque<File> backups = new ArrayDeque<>(); lastSave.clear();
for (File file : Objects.requireNonNull(instance.getDataFolder().listFiles())) { lastSave.putAll(nextSave);
if (file.getName().toLowerCase().contains("data-backup")) { }
backups.add(file);
@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()) { for (Map.Entry<String, Object> entry : toSave.entrySet()) {
dataFile.getConfig().set(entry.getKey(), entry.getValue()); dataFile.getConfig().set(entry.getKey(), entry.getValue());
} }
dataFile.saveConfig(); dataFile.saveConfig();
toSave.clear();
} catch (NullPointerException e) { } catch (NullPointerException e) {
Debugger.runReport(e); Debugger.runReport(e);
} }
} }
@Override
public void makeBackup() {
File data = new File(instance.getDataFolder(), "data.yml");
File dataClone = new File(instance.getDataFolder(), "data-backup-" + System.currentTimeMillis() + ".yml");
try {
FileUtils.copyFile(data, dataClone);
} catch (IOException e) {
Debugger.runReport(e);
}
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 @Override
public void closeConnection() { public void closeConnection() {
dataFile.saveConfig(); dataFile.saveConfig();