mirror of
https://github.com/Xiao-MoMi/Custom-Crops.git
synced 2025-12-23 00:49:33 +00:00
3.0.6-hotfix
This commit is contained in:
@@ -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'])
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
});
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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<SimpleLocation, GrowingCrop> growingCropMap;
|
||||
private final ConcurrentHashMap<SimpleLocation, Pot> potMap;
|
||||
private final ConcurrentHashMap<SimpleLocation, Sprinkler> sprinklerMap;
|
||||
|
||||
@@ -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> world;
|
||||
private final ConcurrentHashMap<ChunkCoordinate, CCChunk> chunkMap;
|
||||
private final ScheduledThreadPoolExecutor schedule;
|
||||
private final GenericObjectPool<CropCheckTask> cropTaskPool;
|
||||
private final GenericObjectPool<SprinklerCheckTask> sprinklerTaskPool;
|
||||
private final GenericObjectPool<ConsumeCheckTask> 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,10 +237,13 @@ public class CCWorld extends Function {
|
||||
pointTimer--;
|
||||
if (pointTimer <= 0) {
|
||||
pointTimer = ConfigManager.pointGainInterval;
|
||||
plantToday.clear();
|
||||
onReachPoint();
|
||||
}
|
||||
}
|
||||
|
||||
public void onReachPoint() {
|
||||
if (ConfigManager.debug) Log.info("== Grow point ==");
|
||||
|
||||
plantToday.clear();
|
||||
int size = schedule.getQueue().size();
|
||||
if (size != 0) {
|
||||
schedule.getQueue().clear();
|
||||
@@ -278,7 +268,6 @@ public class CCWorld extends Function {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void unload() {
|
||||
if (this.timerTask != null) {
|
||||
@@ -292,104 +281,29 @@ 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);
|
||||
}
|
||||
catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class ScheduledConsumeTask extends ScheduledTask {
|
||||
|
||||
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);
|
||||
}
|
||||
@@ -422,23 +336,18 @@ public class CCWorld extends Function {
|
||||
}
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
this.simpleLocation = null;
|
||||
this.pot = null;
|
||||
}
|
||||
}
|
||||
public class SprinklerCheckTask implements Runnable {
|
||||
|
||||
public class SprinklerCheckTask {
|
||||
private final SimpleLocation simpleLocation;
|
||||
|
||||
private SimpleLocation simpleLocation;
|
||||
private Sprinkler sprinkler;
|
||||
|
||||
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,15 +484,11 @@ 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();
|
||||
}
|
||||
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();
|
||||
}
|
||||
return null;
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
private class CropTaskFactory extends BasePooledObjectFactory<CropCheckTask> {
|
||||
|
||||
@Override
|
||||
public CropCheckTask create() {
|
||||
return new CropCheckTask();
|
||||
}
|
||||
|
||||
@Override
|
||||
public PooledObject<CropCheckTask> wrap(CropCheckTask obj) {
|
||||
return new DefaultPooledObject<>(obj);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void passivateObject(PooledObject<CropCheckTask> obj) {
|
||||
obj.getObject().clear();
|
||||
}
|
||||
}
|
||||
|
||||
private class SprinklerTaskFactory extends BasePooledObjectFactory<SprinklerCheckTask> {
|
||||
|
||||
@Override
|
||||
public SprinklerCheckTask create() {
|
||||
return new SprinklerCheckTask();
|
||||
}
|
||||
|
||||
@Override
|
||||
public PooledObject<SprinklerCheckTask> wrap(SprinklerCheckTask obj) {
|
||||
return new DefaultPooledObject<>(obj);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void passivateObject(PooledObject<SprinklerCheckTask> obj) {
|
||||
obj.getObject().clear();
|
||||
}
|
||||
}
|
||||
|
||||
private class ConsumeTaskFactory extends BasePooledObjectFactory<ConsumeCheckTask> {
|
||||
|
||||
@Override
|
||||
public ConsumeCheckTask create() {
|
||||
return new ConsumeCheckTask();
|
||||
}
|
||||
|
||||
@Override
|
||||
public PooledObject<ConsumeCheckTask> wrap(ConsumeCheckTask obj) {
|
||||
return new DefaultPooledObject<>(obj);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void passivateObject(PooledObject<ConsumeCheckTask> obj) {
|
||||
obj.getObject().clear();
|
||||
}
|
||||
}
|
||||
|
||||
public String getWorldName() {
|
||||
return worldName;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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]);
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user