mirror of
https://github.com/exituser/Brewery.git
synced 2026-09-17 06:38:56 +00:00
Async Saving on World Unload
This commit is contained in:
@@ -507,14 +507,22 @@ public class BCauldron {
|
|||||||
/**
|
/**
|
||||||
* Are any Cauldrons in that World
|
* Are any Cauldrons in that World
|
||||||
*/
|
*/
|
||||||
public static boolean hasDataInWorld(String name) {
|
public static boolean hasDataInWorld(World world) {
|
||||||
return bcauldrons.keySet().stream().anyMatch(block -> block.getWorld().getName().equals(name));
|
return bcauldrons.keySet().stream().anyMatch(block -> block.getWorld().equals(world));
|
||||||
}
|
}
|
||||||
|
|
||||||
// unloads cauldrons that are in a unloading world
|
// unloads cauldrons that are in a unloading world
|
||||||
// as they were written to file just before, this is safe to do
|
// as they were written to file just before, this is safe to do
|
||||||
public static void onUnload(String name) {
|
public static void onUnload(World world) {
|
||||||
bcauldrons.keySet().removeIf(block -> block.getWorld().getName().equals(name));
|
bcauldrons.keySet().removeIf(block -> block.getWorld().equals(world));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unload all Cauldrons that have are in a unloaded World
|
||||||
|
*/
|
||||||
|
public static void unloadWorlds() {
|
||||||
|
List<World> worlds = P.p.getServer().getWorlds();
|
||||||
|
bcauldrons.keySet().removeIf(block -> !worlds.contains(block.getWorld()));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void save(ConfigurationSection config, ConfigurationSection oldData) {
|
public static void save(ConfigurationSection config, ConfigurationSection oldData) {
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ import org.bukkit.Location;
|
|||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
import org.bukkit.Sound;
|
import org.bukkit.Sound;
|
||||||
import org.bukkit.SoundCategory;
|
import org.bukkit.SoundCategory;
|
||||||
|
import org.bukkit.World;
|
||||||
import org.bukkit.block.Block;
|
import org.bukkit.block.Block;
|
||||||
import org.bukkit.configuration.ConfigurationSection;
|
import org.bukkit.configuration.ConfigurationSection;
|
||||||
import org.bukkit.entity.HumanEntity;
|
import org.bukkit.entity.HumanEntity;
|
||||||
@@ -125,13 +126,9 @@ public class Barrel implements InventoryHolder {
|
|||||||
|
|
||||||
// Call event
|
// Call event
|
||||||
BarrelAccessEvent accessEvent = new BarrelAccessEvent(this, player, event.getClickedBlock(), event.getBlockFace());
|
BarrelAccessEvent accessEvent = new BarrelAccessEvent(this, player, event.getClickedBlock(), event.getBlockFace());
|
||||||
// Listened to by WGBarrel7, WGBarrelNew, WGBarrelOld, GriefPreventionBarrel (IntegrationListener)
|
// Listened to by IntegrationListener
|
||||||
P.p.getServer().getPluginManager().callEvent(accessEvent);
|
P.p.getServer().getPluginManager().callEvent(accessEvent);
|
||||||
if (accessEvent.isCancelled()) {
|
return !accessEvent.isCancelled();
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -475,15 +472,23 @@ public class Barrel implements InventoryHolder {
|
|||||||
/**
|
/**
|
||||||
* Are any Barrels in that World
|
* Are any Barrels in that World
|
||||||
*/
|
*/
|
||||||
public static boolean hasDataInWorld(String name) {
|
public static boolean hasDataInWorld(World world) {
|
||||||
return barrels.stream().anyMatch(barrel -> barrel.spigot.getWorld().getName().equals(name));
|
return barrels.stream().anyMatch(barrel -> barrel.spigot.getWorld().equals(world));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* unloads barrels that are in a unloading world
|
* unloads barrels that are in a unloading world
|
||||||
*/
|
*/
|
||||||
public static void onUnload(String name) {
|
public static void onUnload(World world) {
|
||||||
barrels.removeIf(barrel -> barrel.spigot.getWorld().getName().equals(name));
|
barrels.removeIf(barrel -> barrel.spigot.getWorld().equals(world));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unload all Barrels that have a Block in a unloaded World
|
||||||
|
*/
|
||||||
|
public static void unloadWorlds() {
|
||||||
|
List<World> worlds = P.p.getServer().getWorlds();
|
||||||
|
barrels.removeIf(barrel -> !worlds.contains(barrel.spigot.getWorld()));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package com.dre.brewery;
|
|||||||
|
|
||||||
import com.dre.brewery.utility.BUtil;
|
import com.dre.brewery.utility.BUtil;
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
|
import org.bukkit.World;
|
||||||
import org.bukkit.command.CommandSender;
|
import org.bukkit.command.CommandSender;
|
||||||
import org.bukkit.configuration.ConfigurationSection;
|
import org.bukkit.configuration.ConfigurationSection;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
@@ -266,8 +267,13 @@ public class Wakeup {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void onUnload(String worldName) {
|
public static void onUnload(World world) {
|
||||||
wakeups.removeIf(wakeup -> wakeup.loc.getWorld().getName().equals(worldName));
|
wakeups.removeIf(wakeup -> wakeup.loc.getWorld().equals(world));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void unloadWorlds() {
|
||||||
|
List<World> worlds = P.p.getServer().getWorlds();
|
||||||
|
wakeups.removeIf(wakeup -> !worlds.contains(wakeup.loc.getWorld()));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import org.bukkit.scheduler.BukkitRunnable;
|
|||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.concurrent.CopyOnWriteArrayList;
|
||||||
|
|
||||||
public class DataSave extends BukkitRunnable {
|
public class DataSave extends BukkitRunnable {
|
||||||
|
|
||||||
@@ -19,18 +20,22 @@ public class DataSave extends BukkitRunnable {
|
|||||||
public static int autosave = 3;
|
public static int autosave = 3;
|
||||||
final public static String dataVersion = "1.2";
|
final public static String dataVersion = "1.2";
|
||||||
public static DataSave running;
|
public static DataSave running;
|
||||||
|
public static List<World> unloadingWorlds = new CopyOnWriteArrayList<>();
|
||||||
|
|
||||||
public ReadOldData read;
|
public ReadOldData read;
|
||||||
private long time;
|
private final long time;
|
||||||
|
private final List<World> loadedWorlds;
|
||||||
public boolean collected = false;
|
public boolean collected = false;
|
||||||
|
|
||||||
// Not Thread-Safe! Needs to be run in main thread but uses async Read/Write
|
// Not Thread-Safe! Needs to be run in main thread but uses async Read/Write
|
||||||
public DataSave(ReadOldData read) {
|
public DataSave(ReadOldData read) {
|
||||||
this.read = read;
|
this.read = read;
|
||||||
time = System.currentTimeMillis();
|
time = System.currentTimeMillis();
|
||||||
|
loadedWorlds = P.p.getServer().getWorlds();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Running in Main Thread
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
try {
|
try {
|
||||||
@@ -107,6 +112,20 @@ public class DataSave extends BukkitRunnable {
|
|||||||
|
|
||||||
collected = true;
|
collected = true;
|
||||||
|
|
||||||
|
if (!unloadingWorlds.isEmpty()) {
|
||||||
|
try {
|
||||||
|
for (World world : unloadingWorlds) {
|
||||||
|
// In the very most cases, it is just one world, so just looping like this is fine
|
||||||
|
Barrel.onUnload(world);
|
||||||
|
BCauldron.onUnload(world);
|
||||||
|
Wakeup.onUnload(world);
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
unloadingWorlds.clear();
|
||||||
|
}
|
||||||
|
|
||||||
P.p.debugLog("saving: " + ((System.nanoTime() - saveTime) / 1000000.0) + "ms");
|
P.p.debugLog("saving: " + ((System.nanoTime() - saveTime) / 1000000.0) + "ms");
|
||||||
|
|
||||||
if (P.p.isEnabled()) {
|
if (P.p.isEnabled()) {
|
||||||
@@ -121,6 +140,22 @@ public class DataSave extends BukkitRunnable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void saveWorldNames(FileConfiguration root, ConfigurationSection old) {
|
||||||
|
if (old != null) {
|
||||||
|
root.set("Worlds", old);
|
||||||
|
}
|
||||||
|
for (World world : loadedWorlds) {
|
||||||
|
String worldName = world.getName();
|
||||||
|
if (worldName.startsWith("DXL_")) {
|
||||||
|
worldName = BUtil.getDxlName(worldName);
|
||||||
|
root.set("Worlds." + worldName, 0);
|
||||||
|
} else {
|
||||||
|
worldName = world.getUID().toString();
|
||||||
|
root.set("Worlds." + worldName, world.getName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Finish the collection of data immediately
|
// Finish the collection of data immediately
|
||||||
public void now() {
|
public void now() {
|
||||||
if (!read.done) {
|
if (!read.done) {
|
||||||
@@ -164,20 +199,4 @@ public class DataSave extends BukkitRunnable {
|
|||||||
lastSave++;
|
lastSave++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void saveWorldNames(FileConfiguration root, ConfigurationSection old) {
|
|
||||||
if (old != null) {
|
|
||||||
root.set("Worlds", old);
|
|
||||||
}
|
|
||||||
for (World world : P.p.getServer().getWorlds()) {
|
|
||||||
String worldName = world.getName();
|
|
||||||
if (worldName.startsWith("DXL_")) {
|
|
||||||
worldName = BUtil.getDxlName(worldName);
|
|
||||||
root.set("Worlds." + worldName, 0);
|
|
||||||
} else {
|
|
||||||
worldName = world.getUID().toString();
|
|
||||||
root.set("Worlds." + worldName, world.getName());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -45,13 +45,17 @@ public class WorldListener implements Listener {
|
|||||||
|
|
||||||
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||||
public void onWorldUnload(WorldUnloadEvent event) {
|
public void onWorldUnload(WorldUnloadEvent event) {
|
||||||
String worldName = event.getWorld().getName();
|
World world = event.getWorld();
|
||||||
if (Barrel.hasDataInWorld(worldName) || BCauldron.hasDataInWorld(worldName)) {
|
if (DataSave.running == null) {
|
||||||
DataSave.save(true);
|
// No datasave running, save data if we have any in that world
|
||||||
Barrel.onUnload(worldName);
|
if (Barrel.hasDataInWorld(world) || BCauldron.hasDataInWorld(world)) {
|
||||||
BCauldron.onUnload(worldName);
|
DataSave.unloadingWorlds.add(world);
|
||||||
|
DataSave.save(false);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// already running, tell it to unload world
|
||||||
|
DataSave.unloadingWorlds.add(world);
|
||||||
}
|
}
|
||||||
Wakeup.onUnload(worldName);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user