mirror of
https://github.com/Xiao-MoMi/Custom-Crops.git
synced 2025-12-23 00:49:33 +00:00
3.6.8
This commit is contained in:
@@ -394,7 +394,7 @@ public class CropBlock extends AbstractCustomCropsBlock {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, bukkitLocation);
|
}, bukkitLocation);
|
||||||
}, plugin.getScheduler().async());
|
}, world.scheduler().async());
|
||||||
}
|
}
|
||||||
|
|
||||||
public int point(CustomCropsBlockState state) {
|
public int point(CustomCropsBlockState state) {
|
||||||
|
|||||||
@@ -156,6 +156,13 @@ public interface CustomCropsWorld<W> {
|
|||||||
*/
|
*/
|
||||||
CustomCropsChunk[] lazyChunks();
|
CustomCropsChunk[] lazyChunks();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets all the loaded regions in this world.
|
||||||
|
*
|
||||||
|
* @return An array of {@link CustomCropsRegion} representing the loaded regions.
|
||||||
|
*/
|
||||||
|
CustomCropsRegion[] loadedRegions();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the block state at a specific location.
|
* Gets the block state at a specific location.
|
||||||
*
|
*
|
||||||
@@ -186,8 +193,10 @@ public interface CustomCropsWorld<W> {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Saves the world data to a file.
|
* Saves the world data to a file.
|
||||||
|
*
|
||||||
|
* @param async async or not
|
||||||
*/
|
*/
|
||||||
void save();
|
void save(boolean async);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets whether the ticking task is ongoing.
|
* Sets whether the ticking task is ongoing.
|
||||||
@@ -301,5 +310,12 @@ public interface CustomCropsWorld<W> {
|
|||||||
*/
|
*/
|
||||||
@NotNull
|
@NotNull
|
||||||
CustomCropsRegion getOrCreateRegion(RegionPos regionPos);
|
CustomCropsRegion getOrCreateRegion(RegionPos regionPos);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the scheduler for this world
|
||||||
|
*
|
||||||
|
* @return the scheduler
|
||||||
|
*/
|
||||||
|
WorldScheduler scheduler();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -52,6 +52,7 @@ public class CustomCropsWorldImpl<W> implements CustomCropsWorld<W> {
|
|||||||
private WorldSetting setting;
|
private WorldSetting setting;
|
||||||
private final WorldAdaptor<W> adaptor;
|
private final WorldAdaptor<W> adaptor;
|
||||||
private final WorldExtraData extraData;
|
private final WorldExtraData extraData;
|
||||||
|
private final WorldScheduler scheduler;
|
||||||
|
|
||||||
public CustomCropsWorldImpl(W world, WorldAdaptor<W> adaptor) {
|
public CustomCropsWorldImpl(W world, WorldAdaptor<W> adaptor) {
|
||||||
this.world = new WeakReference<>(world);
|
this.world = new WeakReference<>(world);
|
||||||
@@ -61,6 +62,7 @@ public class CustomCropsWorldImpl<W> implements CustomCropsWorld<W> {
|
|||||||
this.adaptor = adaptor;
|
this.adaptor = adaptor;
|
||||||
this.extraData = adaptor.loadExtraData(world);
|
this.extraData = adaptor.loadExtraData(world);
|
||||||
this.currentMinecraftDay = (int) (bukkitWorld().getFullTime() / 24_000);
|
this.currentMinecraftDay = (int) (bukkitWorld().getFullTime() / 24_000);
|
||||||
|
this.scheduler = new WorldScheduler(BukkitCustomCropsPlugin.getInstance());
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@@ -140,6 +142,11 @@ public class CustomCropsWorldImpl<W> implements CustomCropsWorld<W> {
|
|||||||
return lazyChunks.values().toArray(new CustomCropsChunk[0]);
|
return lazyChunks.values().toArray(new CustomCropsChunk[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CustomCropsRegion[] loadedRegions() {
|
||||||
|
return loadedRegions.values().toArray(new CustomCropsRegion[0]);
|
||||||
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public Optional<CustomCropsBlockState> getBlockState(Pos3 location) {
|
public Optional<CustomCropsBlockState> getBlockState(Pos3 location) {
|
||||||
@@ -181,7 +188,15 @@ public class CustomCropsWorldImpl<W> implements CustomCropsWorld<W> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void save() {
|
public void save(boolean async) {
|
||||||
|
if (async) {
|
||||||
|
this.scheduler.async().execute(this::save);
|
||||||
|
} else {
|
||||||
|
BukkitCustomCropsPlugin.getInstance().getScheduler().sync().run(this::save, null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void save() {
|
||||||
long time1 = System.currentTimeMillis();
|
long time1 = System.currentTimeMillis();
|
||||||
this.adaptor.saveExtraData(this);
|
this.adaptor.saveExtraData(this);
|
||||||
for (CustomCropsChunk chunk : loadedChunks.values()) {
|
for (CustomCropsChunk chunk : loadedChunks.values()) {
|
||||||
@@ -201,7 +216,7 @@ public class CustomCropsWorldImpl<W> implements CustomCropsWorld<W> {
|
|||||||
public void setTicking(boolean tick) {
|
public void setTicking(boolean tick) {
|
||||||
if (tick) {
|
if (tick) {
|
||||||
if (this.tickTask == null || this.tickTask.isCancelled())
|
if (this.tickTask == null || this.tickTask.isCancelled())
|
||||||
this.tickTask = BukkitCustomCropsPlugin.getInstance().getScheduler().asyncRepeating(this::timer, 1, 1, TimeUnit.SECONDS);
|
this.tickTask = this.scheduler.asyncRepeating(this::timer, 1, 1, TimeUnit.SECONDS);
|
||||||
} else {
|
} else {
|
||||||
if (this.tickTask != null && !this.tickTask.isCancelled())
|
if (this.tickTask != null && !this.tickTask.isCancelled())
|
||||||
this.tickTask.cancel();
|
this.tickTask.cancel();
|
||||||
@@ -257,7 +272,8 @@ public class CustomCropsWorldImpl<W> implements CustomCropsWorld<W> {
|
|||||||
|
|
||||||
private void saveLazyRegions() {
|
private void saveLazyRegions() {
|
||||||
this.regionTimer++;
|
this.regionTimer++;
|
||||||
if (this.regionTimer >= 600) {
|
// To avoid the same timing as saving
|
||||||
|
if (this.regionTimer >= 666) {
|
||||||
this.regionTimer = 0;
|
this.regionTimer = 0;
|
||||||
ArrayList<CustomCropsRegion> removed = new ArrayList<>();
|
ArrayList<CustomCropsRegion> removed = new ArrayList<>();
|
||||||
for (Map.Entry<RegionPos, CustomCropsRegion> entry : loadedRegions.entrySet()) {
|
for (Map.Entry<RegionPos, CustomCropsRegion> entry : loadedRegions.entrySet()) {
|
||||||
@@ -461,11 +477,12 @@ public class CustomCropsWorldImpl<W> implements CustomCropsWorld<W> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private boolean shouldUnloadRegion(RegionPos regionPos) {
|
private boolean shouldUnloadRegion(RegionPos regionPos) {
|
||||||
|
World bukkitWorld = bukkitWorld();
|
||||||
for (int chunkX = regionPos.x() * 32; chunkX < regionPos.x() * 32 + 32; chunkX++) {
|
for (int chunkX = regionPos.x() * 32; chunkX < regionPos.x() * 32 + 32; chunkX++) {
|
||||||
for (int chunkZ = regionPos.z() * 32; chunkZ < regionPos.z() * 32 + 32; chunkZ++) {
|
for (int chunkZ = regionPos.z() * 32; chunkZ < regionPos.z() * 32 + 32; chunkZ++) {
|
||||||
// if a chunk is unloaded, then it should not be in the loaded chunks map
|
// if a chunk is unloaded, then it should not be in the loaded chunks map
|
||||||
ChunkPos pos = ChunkPos.of(chunkX, chunkZ);
|
ChunkPos pos = ChunkPos.of(chunkX, chunkZ);
|
||||||
if (isChunkLoaded(pos) || this.lazyChunks.containsKey(pos)) {
|
if (isChunkLoaded(pos) || this.lazyChunks.containsKey(pos) || bukkitWorld.isChunkLoaded(chunkX, chunkZ)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -492,8 +509,14 @@ public class CustomCropsWorldImpl<W> implements CustomCropsWorld<W> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.loadedRegions.remove(region.regionPos());
|
|
||||||
this.adaptor.saveRegion(this, region);
|
this.adaptor.saveRegion(this, region);
|
||||||
|
this.loadedRegions.remove(region.regionPos());
|
||||||
|
BukkitCustomCropsPlugin.getInstance().debug(() -> "[" + worldName + "] " + "Region " + region.regionPos() + " unloaded.");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public WorldScheduler scheduler() {
|
||||||
|
return scheduler;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,144 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of LuckPerms, licensed under the MIT License.
|
||||||
|
*
|
||||||
|
* Copyright (c) lucko (Luck) <luck@lucko.me>
|
||||||
|
* Copyright (c) contributors
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.momirealms.customcrops.api.core.world;
|
||||||
|
|
||||||
|
import net.momirealms.customcrops.common.plugin.CustomCropsPlugin;
|
||||||
|
import net.momirealms.customcrops.common.plugin.scheduler.SchedulerTask;
|
||||||
|
|
||||||
|
import java.lang.Thread.UncaughtExceptionHandler;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.concurrent.*;
|
||||||
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
import java.util.function.Predicate;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
public class WorldScheduler {
|
||||||
|
private static final int PARALLELISM = 1;
|
||||||
|
|
||||||
|
private final CustomCropsPlugin plugin;
|
||||||
|
|
||||||
|
private final ScheduledThreadPoolExecutor scheduler;
|
||||||
|
private final ForkJoinPool worker;
|
||||||
|
|
||||||
|
public WorldScheduler(CustomCropsPlugin plugin) {
|
||||||
|
this.plugin = plugin;
|
||||||
|
|
||||||
|
this.scheduler = new ScheduledThreadPoolExecutor(1, r -> {
|
||||||
|
Thread thread = Executors.defaultThreadFactory().newThread(r);
|
||||||
|
thread.setName("customcrops-world-scheduler");
|
||||||
|
return thread;
|
||||||
|
});
|
||||||
|
this.scheduler.setRemoveOnCancelPolicy(true);
|
||||||
|
this.scheduler.setExecuteExistingDelayedTasksAfterShutdownPolicy(false);
|
||||||
|
this.worker = new ForkJoinPool(PARALLELISM, new WorkerThreadFactory(), new ExceptionHandler(), false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Executor async() {
|
||||||
|
return this.worker;
|
||||||
|
}
|
||||||
|
|
||||||
|
public SchedulerTask asyncLater(Runnable task, long delay, TimeUnit unit) {
|
||||||
|
ScheduledFuture<?> future = this.scheduler.schedule(() -> this.worker.execute(task), delay, unit);
|
||||||
|
return new JavaCancellable(future);
|
||||||
|
}
|
||||||
|
|
||||||
|
public SchedulerTask asyncRepeating(Runnable task, long delay, long interval, TimeUnit unit) {
|
||||||
|
ScheduledFuture<?> future = this.scheduler.scheduleAtFixedRate(() -> this.worker.execute(task), delay, interval, unit);
|
||||||
|
return new JavaCancellable(future);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void shutdownScheduler() {
|
||||||
|
this.scheduler.shutdown();
|
||||||
|
try {
|
||||||
|
if (!this.scheduler.awaitTermination(1, TimeUnit.MINUTES)) {
|
||||||
|
this.plugin.getPluginLogger().severe("Timed out waiting for the CustomCrops scheduler to terminate");
|
||||||
|
reportRunningTasks(thread -> thread.getName().equals("customcrops-world-scheduler"));
|
||||||
|
}
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void shutdownExecutor() {
|
||||||
|
this.worker.shutdown();
|
||||||
|
try {
|
||||||
|
if (!this.worker.awaitTermination(1, TimeUnit.MINUTES)) {
|
||||||
|
this.plugin.getPluginLogger().severe("Timed out waiting for the CustomCrops worker thread pool to terminate");
|
||||||
|
reportRunningTasks(thread -> thread.getName().startsWith("customcrops-world-worker-"));
|
||||||
|
}
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void reportRunningTasks(Predicate<Thread> predicate) {
|
||||||
|
Thread.getAllStackTraces().forEach((thread, stack) -> {
|
||||||
|
if (predicate.test(thread)) {
|
||||||
|
this.plugin.getPluginLogger().warn("Thread " + thread.getName() + " is blocked, and may be the reason for the slow shutdown!\n" +
|
||||||
|
Arrays.stream(stack).map(el -> " " + el).collect(Collectors.joining("\n"))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final class WorkerThreadFactory implements ForkJoinPool.ForkJoinWorkerThreadFactory {
|
||||||
|
private static final AtomicInteger COUNT = new AtomicInteger(0);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ForkJoinWorkerThread newThread(ForkJoinPool pool) {
|
||||||
|
ForkJoinWorkerThread thread = ForkJoinPool.defaultForkJoinWorkerThreadFactory.newThread(pool);
|
||||||
|
thread.setDaemon(true);
|
||||||
|
thread.setName("customcrops-world-worker-" + COUNT.getAndIncrement());
|
||||||
|
return thread;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private final class ExceptionHandler implements UncaughtExceptionHandler {
|
||||||
|
@Override
|
||||||
|
public void uncaughtException(Thread t, Throwable e) {
|
||||||
|
WorldScheduler.this.plugin.getPluginLogger().warn("Thread " + t.getName() + " threw an uncaught exception", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class JavaCancellable implements SchedulerTask {
|
||||||
|
|
||||||
|
private final ScheduledFuture<?> future;
|
||||||
|
|
||||||
|
public JavaCancellable(ScheduledFuture<?> future) {
|
||||||
|
this.future = future;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void cancel() {
|
||||||
|
this.future.cancel(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isCancelled() {
|
||||||
|
return future.isCancelled();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -17,9 +17,7 @@
|
|||||||
|
|
||||||
package net.momirealms.customcrops.api.event;
|
package net.momirealms.customcrops.api.event;
|
||||||
|
|
||||||
import net.momirealms.customcrops.api.core.BuiltInBlockMechanics;
|
|
||||||
import net.momirealms.customcrops.api.core.block.BreakReason;
|
import net.momirealms.customcrops.api.core.block.BreakReason;
|
||||||
import net.momirealms.customcrops.api.core.block.CropBlock;
|
|
||||||
import net.momirealms.customcrops.api.core.mechanic.crop.CropConfig;
|
import net.momirealms.customcrops.api.core.mechanic.crop.CropConfig;
|
||||||
import net.momirealms.customcrops.api.core.world.CustomCropsBlockState;
|
import net.momirealms.customcrops.api.core.world.CustomCropsBlockState;
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
|
|||||||
@@ -17,7 +17,10 @@
|
|||||||
|
|
||||||
package net.momirealms.customcrops.api.util;
|
package net.momirealms.customcrops.api.util;
|
||||||
|
|
||||||
import com.flowpowered.nbt.*;
|
import com.flowpowered.nbt.CompoundMap;
|
||||||
|
import com.flowpowered.nbt.CompoundTag;
|
||||||
|
import com.flowpowered.nbt.Tag;
|
||||||
|
import com.flowpowered.nbt.TagType;
|
||||||
import com.flowpowered.nbt.stream.NBTInputStream;
|
import com.flowpowered.nbt.stream.NBTInputStream;
|
||||||
import com.flowpowered.nbt.stream.NBTOutputStream;
|
import com.flowpowered.nbt.stream.NBTOutputStream;
|
||||||
|
|
||||||
|
|||||||
@@ -65,7 +65,8 @@ public class ItemsAdderListener extends AbstractCustomEventListener {
|
|||||||
itemManager.handlePlayerInteractBlock(
|
itemManager.handlePlayerInteractBlock(
|
||||||
event.getPlayer(),
|
event.getPlayer(),
|
||||||
event.getBlockClicked(),
|
event.getBlockClicked(),
|
||||||
event.getNamespacedID(), event.getBlockFace(),
|
event.getNamespacedID(),
|
||||||
|
event.getBlockFace(),
|
||||||
event.getHand(),
|
event.getHand(),
|
||||||
event.getItem(),
|
event.getItem(),
|
||||||
event
|
event
|
||||||
|
|||||||
@@ -39,7 +39,6 @@ import net.momirealms.customcrops.api.core.ConfigManager;
|
|||||||
import net.momirealms.customcrops.api.core.world.CustomCropsBlockState;
|
import net.momirealms.customcrops.api.core.world.CustomCropsBlockState;
|
||||||
import net.momirealms.customcrops.api.core.world.CustomCropsWorld;
|
import net.momirealms.customcrops.api.core.world.CustomCropsWorld;
|
||||||
import net.momirealms.customcrops.api.core.world.Pos3;
|
import net.momirealms.customcrops.api.core.world.Pos3;
|
||||||
import net.momirealms.customcrops.api.util.PluginUtils;
|
|
||||||
import net.momirealms.customcrops.common.plugin.feature.Reloadable;
|
import net.momirealms.customcrops.common.plugin.feature.Reloadable;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
# Project settings
|
# Project settings
|
||||||
# Rule: [major update].[feature update].[bug fix]
|
# Rule: [major update].[feature update].[bug fix]
|
||||||
project_version=3.6.7
|
project_version=3.6.8
|
||||||
config_version=39
|
config_version=39
|
||||||
project_group=net.momirealms
|
project_group=net.momirealms
|
||||||
|
|
||||||
@@ -18,10 +18,10 @@ adventure_platform_version=4.3.4
|
|||||||
sparrow_heart_version=0.43
|
sparrow_heart_version=0.43
|
||||||
cloud_core_version=2.0.0
|
cloud_core_version=2.0.0
|
||||||
cloud_services_version=2.0.0
|
cloud_services_version=2.0.0
|
||||||
cloud_brigadier_version=2.0.0-beta.9
|
cloud_brigadier_version=2.0.0-beta.10
|
||||||
cloud_bukkit_version=2.0.0-beta.9
|
cloud_bukkit_version=2.0.0-beta.10
|
||||||
cloud_paper_version=2.0.0-beta.9
|
cloud_paper_version=2.0.0-beta.10
|
||||||
cloud_minecraft_extras_version=2.0.0-beta.9
|
cloud_minecraft_extras_version=2.0.0-beta.10
|
||||||
boosted_yaml_version=1.3.7
|
boosted_yaml_version=1.3.7
|
||||||
byte_buddy_version=1.14.18
|
byte_buddy_version=1.14.18
|
||||||
mojang_brigadier_version=1.0.18
|
mojang_brigadier_version=1.0.18
|
||||||
|
|||||||
@@ -42,6 +42,7 @@ public class DebugWorldsCommand extends BukkitCommandFeature<CommandSender> {
|
|||||||
for (World world : Bukkit.getWorlds()) {
|
for (World world : Bukkit.getWorlds()) {
|
||||||
BukkitCustomCropsPlugin.getInstance().getWorldManager().getWorld(world).ifPresent(w -> {
|
BukkitCustomCropsPlugin.getInstance().getWorldManager().getWorld(world).ifPresent(w -> {
|
||||||
sender.sendMessage(AdventureHelper.miniMessage("<gold>World: " + world.getName() + "</gold>"));
|
sender.sendMessage(AdventureHelper.miniMessage("<gold>World: " + world.getName() + "</gold>"));
|
||||||
|
sender.sendMessage(AdventureHelper.miniMessage(" - Loaded regions: " + w.loadedRegions().length));
|
||||||
sender.sendMessage(AdventureHelper.miniMessage(" - Loaded chunks: " + w.loadedChunks().length));
|
sender.sendMessage(AdventureHelper.miniMessage(" - Loaded chunks: " + w.loadedChunks().length));
|
||||||
sender.sendMessage(AdventureHelper.miniMessage(" - Lazy chunks: " + w.lazyChunks().length));
|
sender.sendMessage(AdventureHelper.miniMessage(" - Lazy chunks: " + w.lazyChunks().length));
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -87,7 +87,7 @@ public class ForceTickCommand extends BukkitCommandFeature<CommandSender> {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
CustomCropsWorld<?> customCropsWorld = optionalWorld.get();
|
CustomCropsWorld<?> customCropsWorld = optionalWorld.get();
|
||||||
BukkitCustomCropsPlugin.getInstance().getScheduler().async().execute(() -> {
|
customCropsWorld.scheduler().async().execute(() -> {
|
||||||
int amount = 0;
|
int amount = 0;
|
||||||
long time1 = System.currentTimeMillis();
|
long time1 = System.currentTimeMillis();
|
||||||
for (CustomCropsChunk customCropsChunk : customCropsWorld.loadedChunks()) {
|
for (CustomCropsChunk customCropsChunk : customCropsWorld.loadedChunks()) {
|
||||||
|
|||||||
@@ -184,6 +184,12 @@ public class BukkitWorldAdaptor extends AbstractWorldAdaptor<World> {
|
|||||||
@Override
|
@Override
|
||||||
public void saveRegion(CustomCropsWorld<World> world, CustomCropsRegion region) {
|
public void saveRegion(CustomCropsWorld<World> world, CustomCropsRegion region) {
|
||||||
File file = getRegionDataFile(world.world(), region.regionPos());
|
File file = getRegionDataFile(world.world(), region.regionPos());
|
||||||
|
if (region.canPrune()) {
|
||||||
|
if (file.exists()) {
|
||||||
|
file.delete();
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
long time1 = System.currentTimeMillis();
|
long time1 = System.currentTimeMillis();
|
||||||
File parentDir = file.getParentFile();
|
File parentDir = file.getParentFile();
|
||||||
if (parentDir != null && !parentDir.exists()) {
|
if (parentDir != null && !parentDir.exists()) {
|
||||||
|
|||||||
@@ -209,13 +209,11 @@ public class BukkitWorldManager implements WorldManager, Listener {
|
|||||||
if (world.isChunkLoaded(pos)) return;
|
if (world.isChunkLoaded(pos)) return;
|
||||||
Optional<CustomCropsChunk> customChunk = world.getChunk(pos);
|
Optional<CustomCropsChunk> customChunk = world.getChunk(pos);
|
||||||
// don't load bukkit chunk again since it has been loaded
|
// don't load bukkit chunk again since it has been loaded
|
||||||
customChunk.ifPresent(customCropsChunk -> {
|
customChunk.ifPresent(customCropsChunk -> customCropsChunk.load(false));
|
||||||
customCropsChunk.load(false);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void notifyOfflineUpdates(CustomCropsWorld<?> world, ChunkPos pos) {
|
public void notifyOfflineUpdates(CustomCropsWorld<?> world, ChunkPos pos) {
|
||||||
world.getChunk(pos).ifPresent(CustomCropsChunk::notifyOfflineTask);
|
world.getLoadedChunk(pos).ifPresent(CustomCropsChunk::notifyOfflineTask);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -225,14 +223,16 @@ public class BukkitWorldManager implements WorldManager, Listener {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
removedWorld.setTicking(false);
|
removedWorld.setTicking(false);
|
||||||
removedWorld.save();
|
removedWorld.save(false);
|
||||||
|
removedWorld.scheduler().shutdownScheduler();
|
||||||
|
removedWorld.scheduler().shutdownExecutor();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@EventHandler
|
@EventHandler
|
||||||
public void onWorldSave(WorldSaveEvent event) {
|
public void onWorldSave(WorldSaveEvent event) {
|
||||||
final World world = event.getWorld();
|
final World world = event.getWorld();
|
||||||
getWorld(world).ifPresent(CustomCropsWorld::save);
|
getWorld(world).ifPresent(world1 -> world1.save(true));
|
||||||
}
|
}
|
||||||
|
|
||||||
@EventHandler (priority = EventPriority.HIGH)
|
@EventHandler (priority = EventPriority.HIGH)
|
||||||
|
|||||||
Reference in New Issue
Block a user