diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/AutoSavingService.java b/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/AutoSavingService.java index adc353194..f148ec9f6 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/AutoSavingService.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/AutoSavingService.java @@ -64,7 +64,7 @@ public class AutoSavingService { } if (players > 0) { - Slimefun.getLogger().log(Level.INFO, "Auto-Saved Player Data for {0} Player(s)!", players); + Slimefun.getLogger().log(Level.INFO, "Auto-saved all player data for {0} player(s)!", players); } } @@ -86,12 +86,14 @@ public class AutoSavingService { } if (!worlds.isEmpty()) { - Slimefun.getLogger().log(Level.INFO, "Auto-Saving Block Data... (Next Auto-Save: {0}m)", interval); + Slimefun.getLogger().log(Level.INFO, "Auto-saving block data... (Next auto-save: {0}m)", interval); for (BlockStorage storage : worlds) { storage.save(false); } } + + BlockStorage.saveChunks(); } } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/SlimefunPlugin.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/SlimefunPlugin.java index 60ab03eb5..48debc048 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/SlimefunPlugin.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/SlimefunPlugin.java @@ -111,6 +111,7 @@ public final class SlimefunPlugin extends JavaPlugin implements SlimefunAddon { private static SlimefunPlugin instance; private MinecraftVersion minecraftVersion = MinecraftVersion.UNKNOWN; + private boolean isNewlyInstalled = false; private final SlimefunRegistry registry = new SlimefunRegistry(); private final TickerTask ticker = new TickerTask(); @@ -180,6 +181,8 @@ public final class SlimefunPlugin extends JavaPlugin implements SlimefunAddon { if (!new File("data-storage/Slimefun").exists()) { config.setValue("options.backwards-compatibility", false); config.save(); + + isNewlyInstalled = true; } // Creating all necessary Folders @@ -660,6 +663,16 @@ public final class SlimefunPlugin extends JavaPlugin implements SlimefunAddon { return instance.minecraftVersion; } + /** + * This method returns whether this version of Slimefun was newly installed. + * It will return true if this {@link Server} uses Slimefun for the very first time. + * + * @return Whether this is a new installation of Slimefun + */ + public static boolean isNewlyInstalled() { + return instance.isNewlyInstalled; + } + public static String getCSCoreLibVersion() { return CSCoreLib.getLib().getDescription().getVersion(); } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/reactors/Reactor.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/reactors/Reactor.java index 81e77ce96..d180d4803 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/reactors/Reactor.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/reactors/Reactor.java @@ -87,41 +87,7 @@ public abstract class Reactor extends AbstractEnergyProvider { BlockStorage.addBlockInfo(b, MODE, ReactorMode.GENERATOR.toString()); } - if (!BlockStorage.hasBlockInfo(b) || BlockStorage.getLocationInfo(b.getLocation(), MODE).equals(ReactorMode.GENERATOR.toString())) { - menu.replaceExistingItem(4, new CustomItem(SlimefunItems.NUCLEAR_REACTOR, "&7Focus: &eElectricity", "", "&6Your Reactor will focus on Power Generation", "&6If your Energy Network doesn't need Power", "&6it will not produce any either", "", "&7\u21E8 Click to change the Focus to &eProduction")); - menu.addMenuClickHandler(4, (p, slot, item, action) -> { - BlockStorage.addBlockInfo(b, MODE, ReactorMode.PRODUCTION.toString()); - newInstance(menu, b); - return false; - }); - } - else { - menu.replaceExistingItem(4, new CustomItem(SlimefunItems.PLUTONIUM, "&7Focus: &eProduction", "", "&6Your Reactor will focus on producing goods", "&6If your Energy Network doesn't need Power", "&6it will continue to run and simply will", "&6not generate any Power in the mean time", "", "&7\u21E8 Click to change the Focus to &ePower Generation")); - menu.addMenuClickHandler(4, (p, slot, item, action) -> { - BlockStorage.addBlockInfo(b, MODE, ReactorMode.GENERATOR.toString()); - newInstance(menu, b); - return false; - }); - } - - BlockMenu port = getAccessPort(b.getLocation()); - if (port != null) { - menu.replaceExistingItem(INFO_SLOT, new CustomItem(Material.GREEN_WOOL, "&7Access Port", "", "&6Detected", "", "&7> Click to view Access Port")); - menu.addMenuClickHandler(INFO_SLOT, (p, slot, item, action) -> { - port.open(p); - newInstance(menu, b); - - return false; - }); - } - else { - menu.replaceExistingItem(INFO_SLOT, new CustomItem(Material.RED_WOOL, "&7Access Port", "", "&cNot detected", "", "&7Access Port must be", "&7placed 3 blocks above", "&7a reactor!")); - menu.addMenuClickHandler(INFO_SLOT, (p, slot, item, action) -> { - newInstance(menu, b); - menu.open(p); - return false; - }); - } + updateInventory(menu, b); } @Override @@ -170,6 +136,51 @@ public abstract class Reactor extends AbstractEnergyProvider { registerDefaultFuelTypes(); } + protected void updateInventory(BlockMenu menu, Block b) { + ReactorMode mode = getReactorMode(b.getLocation()); + + switch (mode) { + case GENERATOR: + menu.replaceExistingItem(4, new CustomItem(SlimefunItems.NUCLEAR_REACTOR, "&7Focus: &eElectricity", "", "&6Your Reactor will focus on Power Generation", "&6If your Energy Network doesn't need Power", "&6it will not produce any either", "", "&7\u21E8 Click to change the Focus to &eProduction")); + menu.addMenuClickHandler(4, (p, slot, item, action) -> { + BlockStorage.addBlockInfo(b, MODE, ReactorMode.PRODUCTION.toString()); + updateInventory(menu, b); + return false; + }); + break; + case PRODUCTION: + menu.replaceExistingItem(4, new CustomItem(SlimefunItems.PLUTONIUM, "&7Focus: &eProduction", "", "&6Your Reactor will focus on producing goods", "&6If your Energy Network doesn't need Power", "&6it will continue to run and simply will", "&6not generate any Power in the mean time", "", "&7\u21E8 Click to change the Focus to &ePower Generation")); + menu.addMenuClickHandler(4, (p, slot, item, action) -> { + BlockStorage.addBlockInfo(b, MODE, ReactorMode.GENERATOR.toString()); + updateInventory(menu, b); + return false; + }); + break; + default: + break; + } + + BlockMenu port = getAccessPort(b.getLocation()); + + if (port != null) { + menu.replaceExistingItem(INFO_SLOT, new CustomItem(Material.GREEN_WOOL, "&7Access Port", "", "&6Detected", "", "&7> Click to view Access Port")); + menu.addMenuClickHandler(INFO_SLOT, (p, slot, item, action) -> { + port.open(p); + updateInventory(menu, b); + + return false; + }); + } + else { + menu.replaceExistingItem(INFO_SLOT, new CustomItem(Material.RED_WOOL, "&7Access Port", "", "&cNot detected", "", "&7Access Port must be", "&7placed 3 blocks above", "&7a reactor!")); + menu.addMenuClickHandler(INFO_SLOT, (p, slot, item, action) -> { + updateInventory(menu, b); + menu.open(p); + return false; + }); + } + } + private void constructMenu(BlockMenuPreset preset) { for (int i : border) { preset.addItem(i, new CustomItem(new ItemStack(Material.GRAY_STAINED_GLASS_PANE), " "), ChestMenuUtils.getEmptyClickHandler()); @@ -203,6 +214,16 @@ public abstract class Reactor extends AbstractEnergyProvider { } } + protected ReactorMode getReactorMode(Location l) { + ReactorMode mode = ReactorMode.GENERATOR; + + if (BlockStorage.hasBlockInfo(l) && BlockStorage.getLocationInfo(l, MODE).equals(ReactorMode.PRODUCTION.toString())) { + mode = ReactorMode.PRODUCTION; + } + + return mode; + } + public abstract void extraTick(Location l); /** @@ -278,7 +299,7 @@ public abstract class Reactor extends AbstractEnergyProvider { int space = getCapacity() - charge; - if (space >= produced || !ReactorMode.GENERATOR.toString().equals(BlockStorage.getLocationInfo(l, MODE))) { + if (space >= produced || getReactorMode(l) != ReactorMode.GENERATOR) { progress.put(l, timeleft - 1); checkForWaterBlocks(l); @@ -453,10 +474,10 @@ public abstract class Reactor extends AbstractEnergyProvider { } protected BlockMenu getAccessPort(Location l) { - Location portL = new Location(l.getWorld(), l.getX(), l.getY() + 3, l.getZ()); + Location port = new Location(l.getWorld(), l.getX(), l.getY() + 3, l.getZ()); - if (BlockStorage.check(portL, SlimefunItems.REACTOR_ACCESS_PORT.getItemId())) { - return BlockStorage.getInventory(portL); + if (BlockStorage.check(port, SlimefunItems.REACTOR_ACCESS_PORT.getItemId())) { + return BlockStorage.getInventory(port); } else { return null; diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/tasks/TickerTask.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/tasks/TickerTask.java index d80bc6e1c..f90b0a937 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/tasks/TickerTask.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/tasks/TickerTask.java @@ -52,7 +52,7 @@ public class TickerTask implements Runnable { Iterator> removals = deletionQueue.entrySet().iterator(); while (removals.hasNext()) { Map.Entry entry = removals.next(); - BlockStorage._integrated_removeBlockInfo(entry.getKey(), entry.getValue()); + BlockStorage.deleteLocationInfoUnsafely(entry.getKey(), entry.getValue()); removals.remove(); } @@ -81,7 +81,7 @@ public class TickerTask implements Runnable { Iterator> moves = movingQueue.entrySet().iterator(); while (moves.hasNext()) { Map.Entry entry = moves.next(); - BlockStorage._integrated_moveLocationInfo(entry.getKey(), entry.getValue()); + BlockStorage.moveLocationInfoUnsafely(entry.getKey(), entry.getValue()); moves.remove(); } @@ -154,7 +154,7 @@ public class TickerTask implements Runnable { Slimefun.getLogger().log(Level.SEVERE, " "); bugs.remove(position); - BlockStorage._integrated_removeBlockInfo(l, true); + BlockStorage.deleteLocationInfoUnsafely(l, true); Bukkit.getScheduler().scheduleSyncDelayedTask(SlimefunPlugin.instance(), () -> l.getBlock().setType(Material.AIR)); } else { diff --git a/src/main/java/me/mrCookieSlime/Slimefun/api/BlockStorage.java b/src/main/java/me/mrCookieSlime/Slimefun/api/BlockStorage.java index 9e198997a..275b93927 100644 --- a/src/main/java/me/mrCookieSlime/Slimefun/api/BlockStorage.java +++ b/src/main/java/me/mrCookieSlime/Slimefun/api/BlockStorage.java @@ -271,7 +271,7 @@ public class BlockStorage { } public void computeChanges() { - changes = blocksCache.size() + chunkChanges; + changes = blocksCache.size(); Map inventories2 = new HashMap<>(inventories); for (Map.Entry entry : inventories2.entrySet()) { @@ -301,8 +301,7 @@ public class BlockStorage { return; } - Slimefun.getLogger().log(Level.INFO, "Saving Blocks for World \"{0}\" ({1} Change(s) queued)", new Object[] { world.getName(), changes }); - + Slimefun.getLogger().log(Level.INFO, "Saving block data for world \"{0}\" ({1} change(s) queued)", new Object[] { world.getName(), changes }); Map cache = new HashMap<>(blocksCache); for (Map.Entry entry : cache.entrySet()) { @@ -334,44 +333,41 @@ public class BlockStorage { } } - Map inventories2 = new HashMap<>(inventories); - - for (Map.Entry entry : inventories2.entrySet()) { + Map unsavedInventories = new HashMap<>(inventories); + for (Map.Entry entry : unsavedInventories.entrySet()) { entry.getValue().save(entry.getKey()); } - Map universalInventories2 = new HashMap<>(SlimefunPlugin.getRegistry().getUniversalInventories()); - - for (Map.Entry entry : universalInventories2.entrySet()) { + Map unsavedUniversalInventories = new HashMap<>(SlimefunPlugin.getRegistry().getUniversalInventories()); + for (Map.Entry entry : unsavedUniversalInventories.entrySet()) { entry.getValue().save(); } - if (chunkChanges > 0) { - saveChunks(remove); - } - changes = 0; - chunkChanges = 0; - } - - private void saveChunks(boolean remove) { - File chunks = new File(PATH_CHUNKS + "chunks.sfc"); - Config cfg = new Config(PATH_CHUNKS + "chunks.temp"); - - for (Map.Entry entry : SlimefunPlugin.getRegistry().getChunks().entrySet()) { - // Saving empty chunk data is pointless - if (!entry.getValue().getKeys().isEmpty()) { - cfg.setValue(entry.getKey(), entry.getValue().toJSON()); - } - } - - cfg.save(chunks); if (remove) { SlimefunPlugin.getRegistry().getWorlds().remove(world.getName()); } } + public static void saveChunks() { + if (chunkChanges > 0) { + File chunks = new File(PATH_CHUNKS + "chunks.sfc"); + Config cfg = new Config(PATH_CHUNKS + "chunks.temp"); + + for (Map.Entry entry : SlimefunPlugin.getRegistry().getChunks().entrySet()) { + // Saving empty chunk data is pointless + if (!entry.getValue().getKeys().isEmpty()) { + cfg.setValue(entry.getKey(), entry.getValue().toJSON()); + } + } + + cfg.save(chunks); + + chunkChanges = 0; + } + } + public static void store(Block block, ItemStack item) { SlimefunItem sfitem = SlimefunItem.getByItem(item); @@ -587,7 +583,21 @@ public class BlockStorage { SlimefunPlugin.getTickerTask().queueDelete(l, destroy); } + @Deprecated public static void _integrated_removeBlockInfo(Location l, boolean destroy) { + deleteLocationInfoUnsafely(l, destroy); + } + + /** + * Do not call this method!. + * This method is used for internal purposes only. + * + * @param l + * The {@link Location} + * @param destroy + * Whether to completely destroy the block data + */ + public static void deleteLocationInfoUnsafely(Location l, boolean destroy) { BlockStorage storage = getStorage(l.getWorld()); if (hasBlockInfo(l)) { @@ -628,7 +638,16 @@ public class BlockStorage { SlimefunPlugin.getTickerTask().queueMove(from, to); } - public static void _integrated_moveLocationInfo(Location from, Location to) { + /** + * Do not call this method!. + * This method is used for internal purposes only. + * + * @param from + * The origin {@link Location} + * @param to + * The destination {@link Location} + */ + public static void moveLocationInfoUnsafely(Location from, Location to) { if (!hasBlockInfo(from)) { return; }