diff --git a/build.gradle b/build.gradle index 23eeccd..3b767b6 100644 --- a/build.gradle +++ b/build.gradle @@ -4,7 +4,7 @@ plugins { } group = 'net.momirealms' -version = '3.0.6' +version = '3.0.6-hotfix' repositories { mavenCentral() @@ -41,7 +41,6 @@ dependencies { implementation ('net.kyori:adventure-text-minimessage:4.13.1') implementation ("de.tr7zw:item-nbt-api:2.11.2") implementation ('org.bstats:bstats-bukkit:3.0.1') - implementation ('org.apache.commons:commons-pool2:2.11.1') implementation fileTree(dir:'libs',includes:['BiomeAPI.jar','ProtectionLib.jar']) } diff --git a/src/main/java/net/momirealms/customcrops/api/object/action/ReplantImpl.java b/src/main/java/net/momirealms/customcrops/api/object/action/ReplantImpl.java index 0d3972c..1356011 100644 --- a/src/main/java/net/momirealms/customcrops/api/object/action/ReplantImpl.java +++ b/src/main/java/net/momirealms/customcrops/api/object/action/ReplantImpl.java @@ -55,7 +55,7 @@ public class ReplantImpl implements Action { } if (!CustomCrops.getInstance().getPlatformInterface().detectAnyThing(location)) { CustomCrops.getInstance().getPlatformInterface().placeCustomItem(location, model, newCMode); - CustomCrops.getInstance().getWorldDataManager().addCropData(crop_loc, new GrowingCrop(crop, point), false); + CustomCrops.getInstance().getWorldDataManager().addCropData(crop_loc, new GrowingCrop(crop, point), true); } return null; }); diff --git a/src/main/java/net/momirealms/customcrops/api/object/action/SwingHandImpl.java b/src/main/java/net/momirealms/customcrops/api/object/action/SwingHandImpl.java new file mode 100644 index 0000000..93bb483 --- /dev/null +++ b/src/main/java/net/momirealms/customcrops/api/object/action/SwingHandImpl.java @@ -0,0 +1,16 @@ +package net.momirealms.customcrops.api.object.action; + +import net.momirealms.customcrops.api.object.ItemMode; +import net.momirealms.customcrops.api.object.world.SimpleLocation; +import org.bukkit.entity.Player; +import org.jetbrains.annotations.Nullable; + +public class SwingHandImpl implements Action { + + @Override + public void doOn(@Nullable Player player, @Nullable SimpleLocation crop_loc, ItemMode itemMode) { + if (player != null) { + player.swingMainHand(); + } + } +} diff --git a/src/main/java/net/momirealms/customcrops/api/object/crop/GrowingCrop.java b/src/main/java/net/momirealms/customcrops/api/object/crop/GrowingCrop.java index f9a1396..03de0f0 100644 --- a/src/main/java/net/momirealms/customcrops/api/object/crop/GrowingCrop.java +++ b/src/main/java/net/momirealms/customcrops/api/object/crop/GrowingCrop.java @@ -19,10 +19,14 @@ package net.momirealms.customcrops.api.object.crop; import net.momirealms.customcrops.CustomCrops; +import java.io.Serial; import java.io.Serializable; public class GrowingCrop implements Serializable { + @Serial + private static final long serialVersionUID = 2828962866548871991L; + private int points; private final String crop; diff --git a/src/main/java/net/momirealms/customcrops/api/object/pot/Pot.java b/src/main/java/net/momirealms/customcrops/api/object/pot/Pot.java index 6667f50..edd5443 100644 --- a/src/main/java/net/momirealms/customcrops/api/object/pot/Pot.java +++ b/src/main/java/net/momirealms/customcrops/api/object/pot/Pot.java @@ -21,10 +21,14 @@ import net.momirealms.customcrops.CustomCrops; import net.momirealms.customcrops.api.object.fertilizer.Fertilizer; import org.jetbrains.annotations.NotNull; +import java.io.Serial; import java.io.Serializable; public class Pot implements Serializable { + @Serial + private static final long serialVersionUID = -6598493908660891824L; + private Fertilizer fertilizer; private int water; private final String key; diff --git a/src/main/java/net/momirealms/customcrops/api/object/sprinkler/Sprinkler.java b/src/main/java/net/momirealms/customcrops/api/object/sprinkler/Sprinkler.java index 79e87a1..6b30a3f 100644 --- a/src/main/java/net/momirealms/customcrops/api/object/sprinkler/Sprinkler.java +++ b/src/main/java/net/momirealms/customcrops/api/object/sprinkler/Sprinkler.java @@ -20,10 +20,14 @@ package net.momirealms.customcrops.api.object.sprinkler; import net.momirealms.customcrops.CustomCrops; import org.jetbrains.annotations.Nullable; +import java.io.Serial; import java.io.Serializable; public class Sprinkler implements Serializable { + @Serial + private static final long serialVersionUID = -1994328062935821245L; + private int water; private final String key; diff --git a/src/main/java/net/momirealms/customcrops/api/object/world/CCChunk.java b/src/main/java/net/momirealms/customcrops/api/object/world/CCChunk.java index ff4cdc1..867c674 100644 --- a/src/main/java/net/momirealms/customcrops/api/object/world/CCChunk.java +++ b/src/main/java/net/momirealms/customcrops/api/object/world/CCChunk.java @@ -29,6 +29,7 @@ import org.bukkit.Material; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.io.Serial; import java.io.Serializable; import java.util.Collections; import java.util.HashSet; @@ -39,6 +40,9 @@ import java.util.concurrent.ThreadLocalRandom; public class CCChunk implements Serializable { + @Serial + private static final long serialVersionUID = 5300805317167684402L; + private final ConcurrentHashMap growingCropMap; private final ConcurrentHashMap potMap; private final ConcurrentHashMap sprinklerMap; diff --git a/src/main/java/net/momirealms/customcrops/api/object/world/CCWorld.java b/src/main/java/net/momirealms/customcrops/api/object/world/CCWorld.java index b50cbef..8fe4503 100644 --- a/src/main/java/net/momirealms/customcrops/api/object/world/CCWorld.java +++ b/src/main/java/net/momirealms/customcrops/api/object/world/CCWorld.java @@ -43,11 +43,6 @@ import net.momirealms.customcrops.api.util.AdventureUtils; import net.momirealms.customcrops.api.util.ConfigUtils; import net.momirealms.customcrops.api.util.FakeEntityUtils; import net.momirealms.customcrops.helper.Log; -import org.apache.commons.pool2.BasePooledObjectFactory; -import org.apache.commons.pool2.PooledObject; -import org.apache.commons.pool2.impl.DefaultPooledObject; -import org.apache.commons.pool2.impl.GenericObjectPool; -import org.apache.commons.pool2.impl.GenericObjectPoolConfig; import org.bukkit.*; import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.entity.Player; @@ -69,9 +64,6 @@ public class CCWorld extends Function { private final Reference world; private final ConcurrentHashMap chunkMap; private final ScheduledThreadPoolExecutor schedule; - private final GenericObjectPool cropTaskPool; - private final GenericObjectPool sprinklerTaskPool; - private final GenericObjectPool consumeTaskPool; private long current_day; private ScheduledFuture timerTask; private int pointTimer; @@ -88,17 +80,7 @@ public class CCWorld extends Function { this.schedule.setMaximumPoolSize(ConfigManager.maxPoolSize); this.schedule.setKeepAliveTime(ConfigManager.keepAliveTime, TimeUnit.SECONDS); this.schedule.setRejectedExecutionHandler(new ThreadPoolExecutor.DiscardPolicy()); - this.cropTaskPool = new GenericObjectPool<>(new CropTaskFactory(), new GenericObjectPoolConfig<>()); - this.cropTaskPool.setMaxTotal(10); - this.cropTaskPool.setMinIdle(1); - this.sprinklerTaskPool = new GenericObjectPool<>(new SprinklerTaskFactory(), new GenericObjectPoolConfig<>()); - this.sprinklerTaskPool.setMaxTotal(10); - this.sprinklerTaskPool.setMinIdle(1); - this.consumeTaskPool = new GenericObjectPool<>(new ConsumeTaskFactory(), new GenericObjectPoolConfig<>()); - this.consumeTaskPool.setMaxTotal(10); - this.consumeTaskPool.setMinIdle(1); this.plantToday = new HashSet<>(128); - this.pointTimer = 10; this.cacheTimer = ConfigManager.cacheSaveInterval; } @@ -122,6 +104,8 @@ public class CCWorld extends Function { if (chunkCoordinate != null) chunkMap.put(chunkCoordinate, chunk); } catch (IOException | ClassNotFoundException e) { e.printStackTrace(); + Log.info("Error at " + file.getAbsolutePath()); + outdated.add(file); } } @@ -211,7 +195,9 @@ public class CCWorld extends Function { World current = world.get(); if (current != null) { - if (ConfigManager.debug) Log.info("Task queue size: " + schedule.getQueue().size()); + if (ConfigManager.debug) { + Log.info("Queue size: " + schedule.getQueue().size() + " Completed: " + schedule.getCompletedTaskCount()); + } long day = current.getFullTime() / 24000; long time = current.getTime(); @@ -242,6 +228,7 @@ public class CCWorld extends Function { if (ConfigManager.debug) Log.info("== Save cache =="); cacheTimer = ConfigManager.cacheSaveInterval; schedule.execute(this::saveDate); + schedule.execute(this::saveCrop); } } } @@ -250,32 +237,34 @@ public class CCWorld extends Function { pointTimer--; if (pointTimer <= 0) { pointTimer = ConfigManager.pointGainInterval; - plantToday.clear(); + onReachPoint(); + } + } - if (ConfigManager.debug) Log.info("== Grow point =="); + public void onReachPoint() { + if (ConfigManager.debug) Log.info("== Grow point =="); + plantToday.clear(); + int size = schedule.getQueue().size(); + if (size != 0) { + schedule.getQueue().clear(); + if (ConfigManager.debug) Log.info("== Clear queue =="); + } - int size = schedule.getQueue().size(); - if (size != 0) { - schedule.getQueue().clear(); - if (ConfigManager.debug) Log.info("== Clear queue =="); + for (CCChunk chunk : chunkMap.values()) { + chunk.scheduleGrowTask(this); + } + if (ConfigManager.enableScheduleSystem) { + workCounter--; + consumeCounter--; + if (consumeCounter <= 0) { + consumeCounter = ConfigManager.intervalConsume; + if (ConfigManager.debug) Log.info("== Consume time =="); + scheduleConsumeTask(); } - - for (CCChunk chunk : chunkMap.values()) { - chunk.scheduleGrowTask(this); - } - if (ConfigManager.enableScheduleSystem) { - workCounter--; - consumeCounter--; - if (consumeCounter <= 0) { - consumeCounter = ConfigManager.intervalConsume; - if (ConfigManager.debug) Log.info("== Consume time =="); - scheduleConsumeTask(); - } - if (workCounter <= 0) { - workCounter = ConfigManager.intervalWork; - if (ConfigManager.debug) Log.info("== Work time =="); - scheduleSprinklerWork(); - } + if (workCounter <= 0) { + workCounter = ConfigManager.intervalWork; + if (ConfigManager.debug) Log.info("== Work time =="); + scheduleSprinklerWork(); } } } @@ -292,153 +281,73 @@ public class CCWorld extends Function { } public void pushCropTask(SimpleLocation simpleLocation, int delay) { - schedule.schedule(new ScheduledCropTask(simpleLocation), delay, TimeUnit.SECONDS); + schedule.schedule(new CropCheckTask(simpleLocation), delay, TimeUnit.SECONDS); } public void pushSprinklerTask(SimpleLocation simpleLocation, int delay) { - schedule.schedule(new ScheduledSprinklerTask(simpleLocation), delay, TimeUnit.SECONDS); + schedule.schedule(new SprinklerCheckTask(simpleLocation), delay, TimeUnit.SECONDS); } public void pushConsumeTask(SimpleLocation simpleLocation, int delay) { - schedule.schedule(new ScheduledConsumeTask(simpleLocation), delay, TimeUnit.SECONDS); + schedule.schedule(new ConsumeCheckTask(simpleLocation), delay, TimeUnit.SECONDS); } - public abstract static class ScheduledTask implements Runnable { + public class ConsumeCheckTask implements Runnable { - SimpleLocation simpleLocation; + private final SimpleLocation simpleLocation; - public ScheduledTask(SimpleLocation simpleLocation) { + public ConsumeCheckTask(SimpleLocation simpleLocation) { this.simpleLocation = simpleLocation; } - } - public class ScheduledCropTask extends ScheduledTask { - - public ScheduledCropTask(SimpleLocation simpleLocation) { - super(simpleLocation); - } - - @Override public void run() { - try { - CropCheckTask cropCheckTask = cropTaskPool.borrowObject(); - GrowingCrop growingCrop = getCropData(simpleLocation); - if (growingCrop == null) return; - cropCheckTask.setArgs(simpleLocation.copy(), growingCrop); - cropCheckTask.execute(); - cropTaskPool.returnObject(cropCheckTask); + Pot pot = getPotData(simpleLocation); + if (pot == null) return; + + if (pot.isWet() && CustomCrops.getInstance().getFertilizerManager().getConfigByFertilizer(pot.getFertilizer()) instanceof SoilRetain soilRetain && soilRetain.canTakeEffect()) { + pot.setWater(pot.getWater() + 1); } - catch (Exception e) { - e.printStackTrace(); - } - } - } + if (pot.reduceWater() | pot.reduceFertilizer()) { - public class ScheduledConsumeTask extends ScheduledTask { + PotConfig potConfig = pot.getConfig(); + Fertilizer fertilizer = pot.getFertilizer(); + boolean wet = pot.isWet(); - public ScheduledConsumeTask(SimpleLocation simpleLocation) { - super(simpleLocation); - } - - @Override - public void run() { - try { - ConsumeCheckTask consumeCheckTask = consumeTaskPool.borrowObject(); - Pot pot = getPotData(simpleLocation); - if (pot == null) return; - consumeCheckTask.setArgs(simpleLocation, pot); - consumeCheckTask.execute(); - consumeTaskPool.returnObject(consumeCheckTask); - } - catch (Exception e) { - e.printStackTrace(); - } - } - } - - public class ScheduledSprinklerTask extends ScheduledTask { - - public ScheduledSprinklerTask(SimpleLocation simpleLocation) { - super(simpleLocation); - } - - @Override - public void run() { - try { - SprinklerCheckTask sprinklerCheckTask = sprinklerTaskPool.borrowObject(); - Sprinkler sprinkler = getSprinklerData(simpleLocation); - if (sprinkler == null) return; - sprinklerCheckTask.setArgs(simpleLocation, sprinkler); - sprinklerCheckTask.execute(); - sprinklerTaskPool.returnObject(sprinklerCheckTask); - } - catch (Exception e) { - e.printStackTrace(); - } - } - } - - public class ConsumeCheckTask { - - private SimpleLocation simpleLocation; - private Pot pot; - - public void setArgs(SimpleLocation simpleLocation, Pot pot) { - this.simpleLocation = simpleLocation; - this.pot = pot; - } - - public void execute() { - if (pot != null) { - if (pot.isWet() && CustomCrops.getInstance().getFertilizerManager().getConfigByFertilizer(pot.getFertilizer()) instanceof SoilRetain soilRetain && soilRetain.canTakeEffect()) { - pot.setWater(pot.getWater() + 1); + if (!wet && fertilizer == null) { + removePotData(simpleLocation); } - if (pot.reduceWater() | pot.reduceFertilizer()) { - PotConfig potConfig = pot.getConfig(); - Fertilizer fertilizer = pot.getFertilizer(); - boolean wet = pot.isWet(); - - if (!wet && fertilizer == null) { - removePotData(simpleLocation); - } - - Location location = simpleLocation.getBukkitLocation(); - if (location == null) { - return; - } - - CustomCrops.getInstance().getScheduler().callSyncMethod(() -> { - if (CustomCrops.getInstance().getPlatformInterface().removeAnyBlock(location)) { - String replacer = wet ? potConfig.getWetPot(fertilizer) : potConfig.getDryPot(fertilizer); - if (ConfigUtils.isVanillaItem(replacer)) location.getBlock().setType(Material.valueOf(replacer)); - else CustomCrops.getInstance().getPlatformInterface().placeNoteBlock(location, replacer); - } else { - CustomCrops.getInstance().getWorldDataManager().removePotData(SimpleLocation.getByBukkitLocation(location)); - } - return null; - }); + Location location = simpleLocation.getBukkitLocation(); + if (location == null) { + return; } - } - } - public void clear() { - this.simpleLocation = null; - this.pot = null; + CustomCrops.getInstance().getScheduler().callSyncMethod(() -> { + if (CustomCrops.getInstance().getPlatformInterface().removeAnyBlock(location)) { + String replacer = wet ? potConfig.getWetPot(fertilizer) : potConfig.getDryPot(fertilizer); + if (ConfigUtils.isVanillaItem(replacer)) location.getBlock().setType(Material.valueOf(replacer)); + else CustomCrops.getInstance().getPlatformInterface().placeNoteBlock(location, replacer); + } else { + CustomCrops.getInstance().getWorldDataManager().removePotData(SimpleLocation.getByBukkitLocation(location)); + } + return null; + }); + } } } - public class SprinklerCheckTask { + public class SprinklerCheckTask implements Runnable { - private SimpleLocation simpleLocation; - private Sprinkler sprinkler; + private final SimpleLocation simpleLocation; - public void setArgs(SimpleLocation simpleLocation, Sprinkler sprinkler) { + public SprinklerCheckTask(SimpleLocation simpleLocation) { this.simpleLocation = simpleLocation; - this.sprinkler = sprinkler; } - public void execute() { + public void run() { + Sprinkler sprinkler = getSprinklerData(simpleLocation); + if (sprinkler == null) return; + SprinklerConfig sprinklerConfig = sprinkler.getConfig(); if (sprinklerConfig == null) { removeSprinklerData(simpleLocation); @@ -472,24 +381,20 @@ public class CCWorld extends Function { } } } - - public void clear() { - this.simpleLocation = null; - this.sprinkler = null; - } } - public class CropCheckTask { + public class CropCheckTask implements Runnable { - private SimpleLocation simpleLocation; - private GrowingCrop growingCrop; + private final SimpleLocation simpleLocation; - public void setArgs(SimpleLocation simpleLocation, GrowingCrop growingCrop) { + public CropCheckTask(SimpleLocation simpleLocation) { this.simpleLocation = simpleLocation; - this.growingCrop = growingCrop; } - public void execute() { + public void run() { + GrowingCrop growingCrop = getCropData(simpleLocation); + if (growingCrop == null) return; + CropConfig cropConfig = growingCrop.getConfig(); if (cropConfig == null) { removeCropData(simpleLocation); @@ -527,11 +432,6 @@ public class CCWorld extends Function { } addCropPoint(points, cropConfig, growingCrop, simpleLocation, itemMode); } - - public void clear() { - simpleLocation = null; - growingCrop = null; - } } public boolean addCropPointAt(SimpleLocation simpleLocation, int points) { @@ -584,14 +484,10 @@ public class CCWorld extends Function { }); loadEntities.whenComplete((result, throwable) -> { CustomCrops.getInstance().getScheduler().callSyncMethod(() -> { - try { - if (CustomCrops.getInstance().getPlatformInterface().removeCustomItem(location, itemMode)) { - CustomCrops.getInstance().getPlatformInterface().placeCustomItem(location, finalNextModel, itemMode); - } else { - removeCropData(simpleLocation); - } - } catch (Exception e) { - e.printStackTrace(); + if (CustomCrops.getInstance().getPlatformInterface().removeCustomItem(location, itemMode)) { + CustomCrops.getInstance().getPlatformInterface().placeCustomItem(location, finalNextModel, itemMode); + } else { + removeCropData(simpleLocation); } return null; }); @@ -600,74 +496,16 @@ public class CCWorld extends Function { else { asyncGetChunk.whenComplete((result, throwable) -> CustomCrops.getInstance().getScheduler().callSyncMethod(() -> { - try { - if (CustomCrops.getInstance().getPlatformInterface().removeCustomItem(location, itemMode)) { - CustomCrops.getInstance().getPlatformInterface().placeCustomItem(location, finalNextModel, itemMode); - } else { - removeCropData(simpleLocation); - } - } catch (Exception e) { - e.printStackTrace(); + if (CustomCrops.getInstance().getPlatformInterface().removeCustomItem(location, itemMode)) { + CustomCrops.getInstance().getPlatformInterface().placeCustomItem(location, finalNextModel, itemMode); + } else { + removeCropData(simpleLocation); } return null; })); } } - private class CropTaskFactory extends BasePooledObjectFactory { - - @Override - public CropCheckTask create() { - return new CropCheckTask(); - } - - @Override - public PooledObject wrap(CropCheckTask obj) { - return new DefaultPooledObject<>(obj); - } - - @Override - public void passivateObject(PooledObject obj) { - obj.getObject().clear(); - } - } - - private class SprinklerTaskFactory extends BasePooledObjectFactory { - - @Override - public SprinklerCheckTask create() { - return new SprinklerCheckTask(); - } - - @Override - public PooledObject wrap(SprinklerCheckTask obj) { - return new DefaultPooledObject<>(obj); - } - - @Override - public void passivateObject(PooledObject obj) { - obj.getObject().clear(); - } - } - - private class ConsumeTaskFactory extends BasePooledObjectFactory { - - @Override - public ConsumeCheckTask create() { - return new ConsumeCheckTask(); - } - - @Override - public PooledObject wrap(ConsumeCheckTask obj) { - return new DefaultPooledObject<>(obj); - } - - @Override - public void passivateObject(PooledObject obj) { - obj.getObject().clear(); - } - } - public String getWorldName() { return worldName; } diff --git a/src/main/java/net/momirealms/customcrops/api/object/world/SimpleLocation.java b/src/main/java/net/momirealms/customcrops/api/object/world/SimpleLocation.java index 4972886..d8e5132 100644 --- a/src/main/java/net/momirealms/customcrops/api/object/world/SimpleLocation.java +++ b/src/main/java/net/momirealms/customcrops/api/object/world/SimpleLocation.java @@ -23,11 +23,15 @@ import org.bukkit.Location; import org.bukkit.World; import org.jetbrains.annotations.Nullable; +import java.io.Serial; import java.io.Serializable; import java.util.Objects; public class SimpleLocation implements Serializable { + @Serial + private static final long serialVersionUID = -1288860694388882412L; + private final int x; private final int y; private final int z; diff --git a/src/main/java/net/momirealms/customcrops/api/object/world/WorldDataManager.java b/src/main/java/net/momirealms/customcrops/api/object/world/WorldDataManager.java index 79704b2..5601915 100644 --- a/src/main/java/net/momirealms/customcrops/api/object/world/WorldDataManager.java +++ b/src/main/java/net/momirealms/customcrops/api/object/world/WorldDataManager.java @@ -74,6 +74,7 @@ public class WorldDataManager extends Function { CCWorld ccWorld = new CCWorld(world); ccWorld.init(); ccWorld.load(); + ccWorld.onReachPoint(); worldMap.put(world.getName(), ccWorld); } diff --git a/src/main/java/net/momirealms/customcrops/api/util/ConfigUtils.java b/src/main/java/net/momirealms/customcrops/api/util/ConfigUtils.java index 59de949..9a9db18 100644 --- a/src/main/java/net/momirealms/customcrops/api/util/ConfigUtils.java +++ b/src/main/java/net/momirealms/customcrops/api/util/ConfigUtils.java @@ -328,6 +328,7 @@ public class ConfigUtils { getActions(actionSec.getConfigurationSection("value"), model_id), actionSec.getDouble("chance") )); + case "swing-hand" -> actions.add(new SwingHandImpl()); } } return actions.toArray(new Action[0]); diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index 96a3d83..43a3295 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -32,6 +32,7 @@ schedule-system: enable: true # Water amount and fertilizer would reduce every two points are gained # As the default point-gain-interval is 600s, so here it would be 1200s(20min = a minecraft day) + # 默认每两个生长点进行一次水分、肥料消耗/洒水器工作 consume-water-fertilizer-every-x-point: 2 # Sprinkler would work every two points are gained sprinkler-work-every-x-point: 2