mirror of
https://github.com/songoda/EpicHoppers.git
synced 2025-01-10 09:57:45 +01:00
Updated storage system.
This commit is contained in:
parent
a6653f0044
commit
38f84dcb79
@ -202,6 +202,8 @@ public class EpicHoppersPlugin extends JavaPlugin implements EpicHoppers {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Save data initially so that if the person reloads again fast they don't lose all their data.
|
||||||
|
this.saveToFile();
|
||||||
}, 10);
|
}, 10);
|
||||||
|
|
||||||
references = new References();
|
references = new References();
|
||||||
@ -298,42 +300,8 @@ public class EpicHoppersPlugin extends JavaPlugin implements EpicHoppers {
|
|||||||
* Saves registered hopper to file.
|
* Saves registered hopper to file.
|
||||||
*/
|
*/
|
||||||
private void saveToFile() {
|
private void saveToFile() {
|
||||||
|
|
||||||
this.storage.closeConnection();
|
|
||||||
checkStorage();
|
checkStorage();
|
||||||
|
|
||||||
/*
|
|
||||||
* Dump HopperManager to file.
|
|
||||||
*/
|
|
||||||
for (Hopper hopper : hopperManager.getHoppers().values()) {
|
|
||||||
if (hopper.getLevel() == null || hopper.getLocation() == null)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
String locationStr = Methods.serializeLocation(hopper.getLocation());
|
|
||||||
|
|
||||||
storage.prepareSaveItem("sync", new StorageItem("location", locationStr),
|
|
||||||
new StorageItem("level", hopper.getLevel().getLevel()),
|
|
||||||
new StorageItem("block", true, hopper.getLinkedBlocks() == null || hopper.getLinkedBlocks().isEmpty() ? new ArrayList<>() : hopper.getLinkedBlocks()),
|
|
||||||
new StorageItem("placedby", hopper.getPlacedBy() == null ? null : hopper.getPlacedBy().toString()),
|
|
||||||
new StorageItem("player", hopper.getLastPlayer() == null ? null : hopper.getLastPlayer().toString()),
|
|
||||||
new StorageItem("teleporttrigger", hopper.getTeleportTrigger().toString()),
|
|
||||||
|
|
||||||
new StorageItem("autocrafting", hopper.getAutoCrafting() == null || hopper.getAutoCrafting() == Material.AIR ? null : hopper.getAutoCrafting().name()),
|
|
||||||
new StorageItem("whitelist", hopper.getFilter().getWhiteList()),
|
|
||||||
new StorageItem("blacklist", hopper.getFilter().getBlackList()),
|
|
||||||
new StorageItem("void", hopper.getFilter().getVoidList()),
|
|
||||||
new StorageItem("black", hopper.getFilter().getEndPoint() == null ? null : Methods.serializeLocation(hopper.getFilter().getEndPoint())));
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Dump BoostManager to file.
|
|
||||||
*/
|
|
||||||
for (BoostData boostData : boostManager.getBoosts()) {
|
|
||||||
storage.prepareSaveItem("boosts", new StorageItem("endtime", String.valueOf(boostData.getEndTime())),
|
|
||||||
new StorageItem("amount", boostData.getMultiplier()),
|
|
||||||
new StorageItem("uuid", boostData.getPlayer().toString()));
|
|
||||||
}
|
|
||||||
|
|
||||||
storage.doSave();
|
storage.doSave();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,8 +1,13 @@
|
|||||||
package com.songoda.epichoppers.storage;
|
package com.songoda.epichoppers.storage;
|
||||||
|
|
||||||
import com.songoda.epichoppers.EpicHoppersPlugin;
|
import com.songoda.epichoppers.EpicHoppersPlugin;
|
||||||
|
import com.songoda.epichoppers.api.hopper.Hopper;
|
||||||
|
import com.songoda.epichoppers.boost.BoostData;
|
||||||
import com.songoda.epichoppers.utils.ConfigWrapper;
|
import com.songoda.epichoppers.utils.ConfigWrapper;
|
||||||
|
import com.songoda.epichoppers.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 {
|
||||||
@ -13,7 +18,7 @@ public abstract class Storage {
|
|||||||
public Storage(EpicHoppersPlugin instance) {
|
public Storage(EpicHoppersPlugin instance) {
|
||||||
this.instance = instance;
|
this.instance = instance;
|
||||||
this.dataFile = new ConfigWrapper(instance, "", "data.yml");
|
this.dataFile = new ConfigWrapper(instance, "", "data.yml");
|
||||||
this.dataFile.createNewFile(null, "EpicHoppers Data File");
|
this.dataFile.createNewFile(null, "EpicSpawners Data File");
|
||||||
this.dataFile.getConfig().options().copyDefaults(true);
|
this.dataFile.getConfig().options().copyDefaults(true);
|
||||||
this.dataFile.saveConfig();
|
this.dataFile.saveConfig();
|
||||||
}
|
}
|
||||||
@ -24,8 +29,46 @@ public abstract class Storage {
|
|||||||
|
|
||||||
public abstract void prepareSaveItem(String group, StorageItem... items);
|
public abstract void prepareSaveItem(String group, StorageItem... items);
|
||||||
|
|
||||||
|
public void updateData(EpicHoppersPlugin instance) {
|
||||||
|
/*
|
||||||
|
* Dump HopperManager to file.
|
||||||
|
*/
|
||||||
|
for (Hopper hopper : instance.getHopperManager().getHoppers().values()) {
|
||||||
|
if (hopper.getLevel() == null || hopper.getLocation() == null)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
String locationStr = Methods.serializeLocation(hopper.getLocation());
|
||||||
|
|
||||||
|
prepareSaveItem("sync", new StorageItem("location", locationStr),
|
||||||
|
new StorageItem("level", hopper.getLevel().getLevel()),
|
||||||
|
new StorageItem("block", true, hopper.getLinkedBlocks() == null || hopper.getLinkedBlocks().isEmpty() ? new ArrayList<>() : hopper.getLinkedBlocks()),
|
||||||
|
new StorageItem("placedby", hopper.getPlacedBy() == null ? null : hopper.getPlacedBy().toString()),
|
||||||
|
new StorageItem("player", hopper.getLastPlayer() == null ? null : hopper.getLastPlayer().toString()),
|
||||||
|
new StorageItem("teleporttrigger", hopper.getTeleportTrigger().toString()),
|
||||||
|
|
||||||
|
new StorageItem("autocrafting", hopper.getAutoCrafting() == null || hopper.getAutoCrafting() == Material.AIR ? null : hopper.getAutoCrafting().name()),
|
||||||
|
new StorageItem("whitelist", hopper.getFilter().getWhiteList()),
|
||||||
|
new StorageItem("blacklist", hopper.getFilter().getBlackList()),
|
||||||
|
new StorageItem("void", hopper.getFilter().getVoidList()),
|
||||||
|
new StorageItem("black", hopper.getFilter().getEndPoint() == null ? null : Methods.serializeLocation(hopper.getFilter().getEndPoint())));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Dump BoostManager to file.
|
||||||
|
*/
|
||||||
|
for (BoostData boostData : instance.getBoostManager().getBoosts()) {
|
||||||
|
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 doSave();
|
||||||
|
|
||||||
|
public abstract void save();
|
||||||
|
|
||||||
|
public abstract void makeBackup();
|
||||||
|
|
||||||
public abstract void closeConnection();
|
public abstract void closeConnection();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -15,9 +15,12 @@ import java.util.HashMap;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
import static me.ryanhamshire.GriefPrevention.GriefPrevention.instance;
|
||||||
|
|
||||||
public class StorageMysql extends Storage {
|
public class StorageMysql extends Storage {
|
||||||
|
|
||||||
private static List<String> toSave = new ArrayList<>();
|
private static Map<String, StorageItem[]> toSave = new HashMap<>();
|
||||||
|
private static Map<String, StorageItem[]> lastSave = new HashMap<>();
|
||||||
private MySQLDatabase database;
|
private MySQLDatabase database;
|
||||||
|
|
||||||
public StorageMysql(EpicHoppersPlugin instance) {
|
public StorageMysql(EpicHoppersPlugin instance) {
|
||||||
@ -65,42 +68,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") + "sync`");
|
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();
|
||||||
@ -112,6 +179,11 @@ public class StorageMysql extends Storage {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void makeBackup() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void closeConnection() {
|
public void closeConnection() {
|
||||||
try {
|
try {
|
||||||
@ -122,4 +194,3 @@ public class StorageMysql extends Storage {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package com.songoda.epichoppers.storage.types;
|
package com.songoda.epichoppers.storage.types;
|
||||||
|
|
||||||
import com.songoda.epichoppers.EpicHoppersPlugin;
|
import com.songoda.epichoppers.EpicHoppersPlugin;
|
||||||
|
import com.songoda.epichoppers.api.EpicHoppers;
|
||||||
import com.songoda.epichoppers.storage.Storage;
|
import com.songoda.epichoppers.storage.Storage;
|
||||||
import com.songoda.epichoppers.storage.StorageItem;
|
import com.songoda.epichoppers.storage.StorageItem;
|
||||||
import com.songoda.epichoppers.storage.StorageRow;
|
import com.songoda.epichoppers.storage.StorageRow;
|
||||||
@ -16,6 +17,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(EpicHoppersPlugin instance) {
|
public StorageYaml(EpicHoppersPlugin instance) {
|
||||||
super(instance);
|
super(instance);
|
||||||
@ -64,38 +66,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();
|
||||||
|
Loading…
Reference in New Issue
Block a user