9
0
mirror of https://github.com/Xiao-MoMi/Custom-Crops.git synced 2025-12-27 02:49:11 +00:00
This commit is contained in:
Xiao-MoMi
2023-04-19 22:49:02 +08:00
parent 4a130c5e51
commit 8a4042d9da
26 changed files with 270 additions and 179 deletions

View File

@@ -4,7 +4,7 @@ plugins {
}
group = 'net.momirealms'
version = '3.0.0-beta2'
version = '3.0.0'
repositories {
mavenCentral()

View File

@@ -85,6 +85,7 @@ public final class CustomCrops extends JavaPlugin {
@Override
public void onEnable() {
adventure = BukkitAudiences.create(this);
protocolManager = ProtocolLibrary.getProtocolManager();
this.versionHelper = new VersionHelper(this);
if (versionHelper.isSpigot()) {
AdventureUtils.consoleMessage("<red>========================[CustomCrops]=========================");
@@ -96,10 +97,9 @@ public final class CustomCrops extends JavaPlugin {
return;
}
protocolManager = ProtocolLibrary.getProtocolManager();
AdventureUtils.consoleMessage("[CustomCrops] Running on <white>" + Bukkit.getVersion());
if (!this.loadPlatform()) return;
this.registerCommands();
this.loadPlatform();
AdventureUtils.consoleMessage("[CustomCrops] Running on <white>" + Bukkit.getVersion());
ProtectionLib.hook();
this.scheduler = new Scheduler(this);
@@ -191,7 +191,7 @@ public final class CustomCrops extends JavaPlugin {
}
}
private void loadPlatform() {
private boolean loadPlatform() {
PluginManager pluginManager = Bukkit.getPluginManager();
if (pluginManager.isPluginEnabled("ItemsAdder")) {
this.platform = Platform.ItemsAdder;
@@ -202,11 +202,17 @@ public final class CustomCrops extends JavaPlugin {
this.platformInterface = new OraxenPluginImpl();
}
if (this.platform == null) {
AdventureUtils.consoleMessage("<red>========================[CustomCrops]=========================");
AdventureUtils.consoleMessage("<red> Please install ItemsAdder or Oraxen as dependency.");
AdventureUtils.consoleMessage("<red> ItemsAdder Link: https://www.spigotmc.org/resources/73355/");
AdventureUtils.consoleMessage("<red> Oraxen link: https://www.spigotmc.org/resources/72448/");
AdventureUtils.consoleMessage("<red>==============================================================");
Bukkit.getPluginManager().disablePlugin(this);
AdventureUtils.consoleMessage("<red>[CustomCrops] Please install ItemsAdder/Oraxen");
return false;
}
else {
AdventureUtils.consoleMessage("[CustomCrops] Platform: " + platform.name());
AdventureUtils.consoleMessage("[CustomCrops] Platform: <green>" + platform.name());
return true;
}
}

View File

@@ -17,12 +17,15 @@
package net.momirealms.customcrops.api.customplugin;
import io.th0rgal.oraxen.api.OraxenFurniture;
import io.th0rgal.oraxen.mechanics.provided.gameplay.furniture.FurnitureMechanic;
import net.momirealms.customcrops.CustomCrops;
import net.momirealms.customcrops.api.object.ItemMode;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Interaction;
import org.bukkit.entity.ItemDisplay;
import org.bukkit.entity.ItemFrame;
import org.bukkit.inventory.ItemStack;
@@ -138,7 +141,7 @@ public interface PlatformInterface {
@Nullable
default ItemDisplay getItemDisplayAt(Location location) {
Collection<ItemDisplay> itemDisplays = location.clone().add(0.5,0.5,0.5).getNearbyEntitiesByType(ItemDisplay.class, 0.5, 0.5, 0.5);
Collection<ItemDisplay> itemDisplays = location.clone().add(0.5,0,0.5).getNearbyEntitiesByType(ItemDisplay.class, 0.5, 0.5, 0.5);
int i = itemDisplays.size();
int j = 1;
for (ItemDisplay itemDisplay : itemDisplays) {
@@ -155,15 +158,21 @@ public interface PlatformInterface {
ItemFrame itemFrame = getItemFrameAt(location);
if (itemFrame != null) {
itemFrame.remove();
if (CustomCrops.getInstance().getVersionHelper().isVersionNewerThan1_19_R3()) removeInteractions(location);
return true;
}
return false;
}
default void removeInteractions(Location location) {
location.clone().add(0.5,0.5,0.5).getNearbyEntitiesByType(Interaction.class, 0.5, 0.5, 0.5).forEach(Entity::remove);
}
default boolean removeItemDisplay(Location location) {
ItemDisplay itemDisplay = getItemDisplayAt(location);
if (itemDisplay != null) {
itemDisplay.remove();
removeInteractions(location);
return true;
}
return false;
@@ -177,7 +186,7 @@ public interface PlatformInterface {
}
default boolean detectItemDisplay(Location location) {
Collection<Entity> entities = location.clone().add(0.5,0.5,0.5).getNearbyEntitiesByType(ItemDisplay.class, 0.5, 0.5, 0.5);
Collection<Entity> entities = location.clone().add(0.5,0,0.5).getNearbyEntitiesByType(ItemDisplay.class, 0.5, 0.5, 0.5);
return entities.size() != 0;
}

View File

@@ -48,6 +48,7 @@ import net.momirealms.customcrops.api.util.AdventureUtils;
import net.momirealms.protectionlib.ProtectionLib;
import org.bukkit.*;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.bukkit.event.Cancellable;
@@ -58,6 +59,8 @@ import org.bukkit.inventory.EquipmentSlot;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.Nullable;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Objects;
@@ -65,6 +68,7 @@ public class PlatformManager extends Function {
private final CustomCrops plugin;
private final Handler handler;
private static final HashSet<Material> REPLACEABLE = new HashSet<>(Arrays.asList(Material.SNOW, Material.VINE, Material.GRASS, Material.TALL_GRASS, Material.SEAGRASS, Material.FERN, Material.LARGE_FERN, Material.AIR));
public PlatformManager(CustomCrops plugin) {
this.plugin = plugin;
@@ -134,13 +138,13 @@ public class PlatformManager extends Function {
Block block = event.getClickedBlock();
String id = plugin.getPlatformInterface().getBlockID(block);
assert block != null;
onInteractSomething(event.getPlayer(), block.getLocation(), id, event);
onInteractSomething(event.getPlayer(), block.getLocation(), id, event.getBlockFace(), event);
}
}
public void onInteractFurniture(Player player, Entity entity, String id, Cancellable event) {
if (event.isCancelled()) return;
onInteractSomething(player, entity.getLocation().getBlock().getLocation(), id, event);
onInteractSomething(player, entity.getLocation().getBlock().getLocation(), id, null, event);
}
public void onInteractAir(Player player) {
@@ -190,7 +194,7 @@ public class PlatformManager extends Function {
}
}
void onInteractSomething(Player player, Location location, String id, Cancellable event) {
void onInteractSomething(Player player, Location location, String id, @Nullable BlockFace blockFace, Cancellable event) {
ItemStack item_in_hand = player.getInventory().getItemInMainHand();
String item_in_hand_id = plugin.getPlatformInterface().getItemStackID(item_in_hand);
@@ -202,7 +206,7 @@ public class PlatformManager extends Function {
}
if (ProtectionLib.canPlace(player, location)) {
if (onInteractWithSprinkler(player, location, item_in_hand, item_in_hand_id)) {
if (onInteractWithSprinkler(player, location, item_in_hand, item_in_hand_id, blockFace)) {
return;
}
@@ -402,14 +406,13 @@ public class PlatformManager extends Function {
}
}
public boolean onInteractWithSprinkler(Player player, Location location, ItemStack item_in_hand, String item_in_hand_id) {
public boolean onInteractWithSprinkler(Player player, Location location, ItemStack item_in_hand, String item_in_hand_id, @Nullable BlockFace blockFace) {
SprinklerConfig sprinklerConfig = plugin.getSprinklerManager().getConfigByItemID(item_in_hand_id);
if (sprinklerConfig == null) {
return false;
}
// Prevent player from placing sprinkler on furniture
if (location.getBlock().getType() == Material.AIR) {
if (blockFace != BlockFace.UP || REPLACEABLE.contains(location.getBlock().getType())) {
return true;
}
@@ -902,20 +905,22 @@ public class PlatformManager extends Function {
int add = 0;
if (id != null && location != null) {
for (PositiveFillMethod positiveFillMethod : wateringCanConfig.getPositiveFillMethods()) {
if (positiveFillMethod.getId().equals(id)) {
add = positiveFillMethod.getAmount();
if (positiveFillMethod.getSound() != null) {
AdventureUtils.playerSound(player, positiveFillMethod.getSound());
outer: {
if (id != null && location != null) {
for (PositiveFillMethod positiveFillMethod : wateringCanConfig.getPositiveFillMethods()) {
if (positiveFillMethod.getId().equals(id)) {
add = positiveFillMethod.getAmount();
if (positiveFillMethod.getSound() != null) {
AdventureUtils.playerSound(player, positiveFillMethod.getSound());
}
if (positiveFillMethod.getParticle() != null) {
location.getWorld().spawnParticle(positiveFillMethod.getParticle(), location.clone().add(0.5,1.1, 0.5),5,0.1,0.1,0.1);
}
break outer;
}
if (positiveFillMethod.getParticle() != null) {
location.getWorld().spawnParticle(positiveFillMethod.getParticle(), location.clone().add(0.5,1.1, 0.5),5,0.1,0.1,0.1);
}
break;
}
}
} else {
List<Block> lineOfSight = player.getLineOfSight(null, 5);
List<String> blockIds = lineOfSight.stream().map(block -> plugin.getPlatformInterface().getBlockID(block)).toList();

View File

@@ -23,59 +23,48 @@ import org.bukkit.Location;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.bukkit.scheduler.BukkitRunnable;
import org.bukkit.util.Vector;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.ThreadLocalRandom;
public class CrowTask implements Runnable {
public class CrowTask extends BukkitRunnable {
private int timer;
private final int entityID;
private final Vector vectorDown;
private final Vector vectorUp;
private final Location from;
private final Player player;
private final float yaw;
private final ItemStack fly;
private final ItemStack stand;
private ScheduledFuture<?> scheduledFuture;
public CrowTask(Player player, Location crop, String fly_model, String stand_model) {
this.timer = 0;
this.fly = CustomCrops.getInstance().getIntegrationManager().build(fly_model);
this.stand = CustomCrops.getInstance().getIntegrationManager().build(stand_model);
ItemStack stand = CustomCrops.getInstance().getIntegrationManager().build(stand_model);
this.player = player;
this.entityID = ThreadLocalRandom.current().nextInt(Integer.MAX_VALUE);
this.yaw = ThreadLocalRandom.current().nextInt(361) - 180;
this.from = crop.clone().add(10 * Math.sin((Math.PI * yaw)/180), 10, - 10 * Math.cos((Math.PI * yaw)/180));
Location relative = crop.clone().subtract(from);
this.vectorDown = new Vector(relative.getX() / 100, -0.1, relative.getZ() / 100);
this.vectorUp = new Vector(relative.getX() / 100, 0.1, relative.getZ() / 100);
CustomCrops.getProtocolManager().sendServerPacket(player, FakeEntityUtils.getSpawnPacket(entityID, from, EntityType.ARMOR_STAND));
this.vectorUp = new Vector(relative.getX() / 50, 0.1, relative.getZ() / 50);
CustomCrops.getProtocolManager().sendServerPacket(player, FakeEntityUtils.getSpawnPacket(entityID, crop, EntityType.ARMOR_STAND));
CustomCrops.getProtocolManager().sendServerPacket(player, FakeEntityUtils.getVanishArmorStandMetaPacket(entityID));
CustomCrops.getProtocolManager().sendServerPacket(player, FakeEntityUtils.getEquipPacket(entityID, fly));
CustomCrops.getProtocolManager().sendServerPacket(player, FakeEntityUtils.getEquipPacket(entityID, stand));
}
@Override
public void run() {
timer++;
if (timer < 100) {
CustomCrops.getProtocolManager().sendServerPacket(player, FakeEntityUtils.getTeleportPacket(entityID, from.add(vectorDown), yaw));
} else if (timer == 100){
CustomCrops.getProtocolManager().sendServerPacket(player, FakeEntityUtils.getEquipPacket(entityID, stand));
} else if (timer == 150) {
if (timer == 30) {
CustomCrops.getProtocolManager().sendServerPacket(player, FakeEntityUtils.getEquipPacket(entityID, fly));
} else if (timer > 150) {
} else if (timer > 30) {
CustomCrops.getProtocolManager().sendServerPacket(player, FakeEntityUtils.getTeleportPacket(entityID, from.add(vectorUp), yaw));
}
if (timer > 300) {
if (timer > 100) {
CustomCrops.getProtocolManager().sendServerPacket(player, FakeEntityUtils.getDestroyPacket(entityID));
if (scheduledFuture != null) scheduledFuture.cancel(false);
cancel();
}
}
public void setScheduledFuture(ScheduledFuture<?> scheduledFuture) {
this.scheduledFuture = scheduledFuture;
}
}

View File

@@ -37,10 +37,9 @@ public class BreakImpl implements Action {
@Override
public void doOn(@Nullable Player player, @Nullable SimpleLocation crop_loc, ItemMode itemMode) {
if (crop_loc == null) return;
CustomCrops.getInstance().getScheduler().callSyncMethod(() -> {
CustomCrops.getInstance().getScheduler().runTask(() -> {
CustomCrops.getInstance().getPlatformInterface().removeCustomItem(crop_loc.getBukkitLocation(), itemMode);
CustomCrops.getInstance().getWorldDataManager().removeCropData(crop_loc);
return null;
});
if (triggerAction && stage_id != null) {
StageConfig stageConfig = CustomCrops.getInstance().getCropManager().getStageConfig(stage_id);

View File

@@ -23,6 +23,7 @@ import net.momirealms.customcrops.api.util.ConfigUtils;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.configuration.file.YamlConfiguration;
import java.io.File;
import java.util.HashSet;
import java.util.Objects;
@@ -69,7 +70,7 @@ public class ConfigManager extends Function {
}
private void loadConfig() {
ConfigUtils.update("config.yml");
if (new File(plugin.getDataFolder(), "config.yml").exists()) ConfigUtils.update("config.yml");
YamlConfiguration config = ConfigUtils.getConfig("config.yml");
enableBStats = config.getBoolean("metrics");
lang = config.getString("lang");

View File

@@ -22,8 +22,4 @@ import net.momirealms.customcrops.api.object.world.SimpleLocation;
public interface Condition {
boolean isMet(SimpleLocation simpleLocation);
default int getDelay() {
return 0;
}
}

View File

@@ -24,8 +24,6 @@ import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.entity.Player;
import java.util.concurrent.ScheduledFuture;
public class CrowAttack implements Condition {
private final double chance;
@@ -42,20 +40,16 @@ public class CrowAttack implements Condition {
public boolean isMet(SimpleLocation simpleLocation) {
if (Math.random() > chance) return false;
Location location = simpleLocation.getBukkitLocation();
if (location == null || CustomCrops.getInstance().getWorldDataManager().hasScarecrow(simpleLocation)) return false;
if (location == null || CustomCrops.getInstance().getWorldDataManager().hasScarecrow(simpleLocation)) return true;
for (Player player : Bukkit.getOnlinePlayers()) {
SimpleLocation playerLoc = SimpleLocation.getByBukkitLocation(player.getLocation());
if (playerLoc.isNear(simpleLocation, 48)) {
CrowTask crowTask = new CrowTask(player, location.clone().add(0.4,0,0.4), fly_model, stand_model);
ScheduledFuture<?> scheduledFuture = CustomCrops.getInstance().getScheduler().runTaskTimerAsync(crowTask, 50, 50);
crowTask.setScheduledFuture(scheduledFuture);
CustomCrops.getInstance().getScheduler().callSyncMethod(() -> {
new CrowTask(player, location, fly_model, stand_model).runTaskTimerAsynchronously(CustomCrops.getInstance(), 1, 1);
return null;
});
}
}
return true;
}
@Override
public int getDelay() {
return 7000;
}
}

View File

@@ -34,13 +34,13 @@ public class DeathCondition {
this.conditions = conditions;
}
public int checkIfDead(SimpleLocation simpleLocation) {
public boolean checkIfDead(SimpleLocation simpleLocation) {
for (Condition condition : conditions) {
if (condition.isMet(simpleLocation)) {
return condition.getDelay();
return true;
}
}
return -1;
return false;
}
public void applyDeadModel(SimpleLocation simpleLocation, ItemMode itemMode) {

View File

@@ -18,6 +18,7 @@
package net.momirealms.customcrops.api.object.crop;
import net.momirealms.customcrops.CustomCrops;
import net.momirealms.customcrops.api.customplugin.Platform;
import net.momirealms.customcrops.api.object.Function;
import net.momirealms.customcrops.api.object.ItemMode;
import net.momirealms.customcrops.api.object.condition.Condition;
@@ -27,12 +28,14 @@ import net.momirealms.customcrops.api.util.AdventureUtils;
import net.momirealms.customcrops.api.util.ConfigUtils;
import org.bukkit.Bukkit;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.entity.Item;
import org.bukkit.event.EventHandler;
import org.bukkit.event.HandlerList;
import org.bukkit.event.Listener;
import org.bukkit.event.entity.ItemSpawnEvent;
import org.bukkit.plugin.Plugin;
import org.jetbrains.annotations.Nullable;
import java.io.File;
@@ -47,6 +50,7 @@ public class CropManager extends Function implements Listener {
private final HashMap<String, CropConfig> cropConfigMap;
private final HashMap<String, StageConfig> stageConfigMap;
private final HashSet<String> deadCrops;
private boolean hasCheckedTripwire;
public CropManager(CustomCrops plugin) {
this.plugin = plugin;
@@ -77,7 +81,7 @@ public class CropManager extends Function implements Listener {
File crop_folder = new File(plugin.getDataFolder(), "contents" + File.separator + "crops");
if (!crop_folder.exists()) {
if (!crop_folder.mkdirs()) return;
plugin.saveResource("contents" + File.separator + "crops" + File.separator + "tomato.yml", false);
ConfigUtils.getConfig("contents" + File.separator + "crops" + File.separator + "tomato.yml");
}
File[] files = crop_folder.listFiles();
if (files == null) return;
@@ -87,6 +91,9 @@ public class CropManager extends Function implements Listener {
ConfigurationSection cropSec = config.getConfigurationSection(key);
if (cropSec == null) continue;
ItemMode itemMode = ItemMode.valueOf(cropSec.getString("type", "TripWire").toUpperCase());
if (itemMode == ItemMode.TRIPWIRE && !hasCheckedTripwire) {
checkTripwire();
}
String[] bottomBlocks = cropSec.getStringList("pot-whitelist").toArray(new String[0]);
if (bottomBlocks.length == 0) {
AdventureUtils.consoleMessage("<red>[CustomCrops] pot-whitelist is not set for crop: " + key);
@@ -185,7 +192,7 @@ public class CropManager extends Function implements Listener {
if (event.isCancelled()) return;
Item item = event.getEntity();
String id = plugin.getPlatformInterface().getItemStackID(item.getItemStack());
if (containsStage(id)) {
if (containsStage(id) || isDeadCrop(id)) {
event.setCancelled(true);
}
}
@@ -198,4 +205,38 @@ public class CropManager extends Function implements Listener {
public CropConfig getCropConfigBySeed(String seed) {
return seedToCropConfig.get(seed);
}
private void checkTripwire() {
hasCheckedTripwire = true;
if (plugin.getPlatform() == Platform.ItemsAdder) {
Plugin iaP = Bukkit.getPluginManager().getPlugin("ItemsAdder");
if (iaP != null) {
FileConfiguration config = iaP.getConfig();
boolean disabled = config.getBoolean("blocks.disable-REAL_WIRE");
if (disabled) {
AdventureUtils.consoleMessage("<red>========================[CustomCrops]=========================");
AdventureUtils.consoleMessage("<red> Detected that one of your crops is using TRIPWIRE type");
AdventureUtils.consoleMessage("<red> If you want to use tripwire for custom crops, please set");
AdventureUtils.consoleMessage("<red>\"blocks.disable-REAL_WIRE: false\" in /ItemsAdder/config.yml");
AdventureUtils.consoleMessage("<red> Change this setting requires a server restart");
AdventureUtils.consoleMessage("<red> If you have problems with which one to use, read the wiki.");
AdventureUtils.consoleMessage("<red>==============================================================");
}
}
} else if (plugin.getPlatform() == Platform.Oraxen) {
Plugin oxP = Bukkit.getPluginManager().getPlugin("Oraxen");
if (oxP != null) {
YamlConfiguration config = YamlConfiguration.loadConfiguration(new File(oxP.getDataFolder(), "mechanics.yml"));
boolean disabled = !config.getBoolean("stringblock.enabled");
if (disabled) {
AdventureUtils.consoleMessage("<red>========================[CustomCrops]=========================");
AdventureUtils.consoleMessage("<red> Detected that one of your crops is using TRIPWIRE type");
AdventureUtils.consoleMessage("<red> If you want to use tripwire for custom crops, please set");
AdventureUtils.consoleMessage("<red> \"stringblock.enabled: true\" in /Oraxen/mechanics.yml");
AdventureUtils.consoleMessage("<red> If you have problems with which one to use, read the wiki.");
AdventureUtils.consoleMessage("<red>==============================================================");
}
}
}
}
}

View File

@@ -79,11 +79,11 @@ public class FertilizerManager extends Function {
File can_folder = new File(plugin.getDataFolder(), "contents" + File.separator + "fertilizers");
if (!can_folder.exists()) {
if (!can_folder.mkdirs()) return;
plugin.saveResource("contents" + File.separator + "fertilizers" + File.separator + "speed-grow.yml", false);
plugin.saveResource("contents" + File.separator + "fertilizers" + File.separator + "quality.yml", false);
plugin.saveResource("contents" + File.separator + "fertilizers" + File.separator + "soil-retain.yml", false);
plugin.saveResource("contents" + File.separator + "fertilizers" + File.separator + "yield-increase.yml", false);
plugin.saveResource("contents" + File.separator + "fertilizers" + File.separator + "variation.yml", false);
ConfigUtils.getConfig("contents" + File.separator + "fertilizers" + File.separator + "speed-grow.yml");
ConfigUtils.getConfig("contents" + File.separator + "fertilizers" + File.separator + "quality.yml");
ConfigUtils.getConfig("contents" + File.separator + "fertilizers" + File.separator + "soil-retain.yml");
ConfigUtils.getConfig("contents" + File.separator + "fertilizers" + File.separator + "yield-increase.yml");
ConfigUtils.getConfig("contents" + File.separator + "fertilizers" + File.separator + "variation.yml");
}
File[] files = can_folder.listFiles();
if (files == null) return;

View File

@@ -61,7 +61,7 @@ public class PotManager extends Function {
File pot_folder = new File(plugin.getDataFolder(), "contents" + File.separator + "pots");
if (!pot_folder.exists()) {
if (!pot_folder.mkdirs()) return;
plugin.saveResource("contents" + File.separator + "pots" + File.separator + "default.yml", false);
ConfigUtils.getConfig("contents" + File.separator + "pots" + File.separator + "default.yml");
}
File[] files = pot_folder.listFiles();
if (files == null) return;

View File

@@ -34,7 +34,7 @@ public class Scheduler extends Function {
this.schedule = new ScheduledThreadPoolExecutor(1);
this.schedule.setMaximumPoolSize(2);
this.schedule.setKeepAliveTime(ConfigManager.keepAliveTime, TimeUnit.SECONDS);
this.schedule.setRejectedExecutionHandler(new ThreadPoolExecutor.DiscardPolicy());
this.schedule.setRejectedExecutionHandler(new ThreadPoolExecutor.AbortPolicy());
}
@Override

View File

@@ -72,7 +72,7 @@ public class SprinklerManager extends Function implements Listener {
File sprinkler_folder = new File(plugin.getDataFolder(), "contents" + File.separator + "sprinklers");
if (!sprinkler_folder.exists()) {
if (!sprinkler_folder.mkdirs()) return;
plugin.saveResource("contents" + File.separator + "sprinklers" + File.separator + "default.yml", false);
ConfigUtils.getConfig("contents" + File.separator + "sprinklers" + File.separator + "default.yml");
}
File[] files = sprinkler_folder.listFiles();
if (files == null) return;

View File

@@ -67,7 +67,7 @@ public class WateringCanManager extends Function {
File can_folder = new File(plugin.getDataFolder(), "contents" + File.separator + "watering-cans");
if (!can_folder.exists()) {
if (!can_folder.mkdirs()) return;
plugin.saveResource("contents" + File.separator + "watering-cans" + File.separator + "default.yml", false);
ConfigUtils.getConfig("contents" + File.separator + "watering-cans" + File.separator + "default.yml");
}
File[] files = can_folder.listFiles();
if (files == null) return;

View File

@@ -18,6 +18,7 @@
package net.momirealms.customcrops.api.object.world;
import net.momirealms.customcrops.CustomCrops;
import net.momirealms.customcrops.api.object.CrowTask;
import net.momirealms.customcrops.api.object.Function;
import net.momirealms.customcrops.api.object.ItemMode;
import net.momirealms.customcrops.api.object.action.Action;
@@ -71,7 +72,8 @@ public class CCWorld extends Function {
private final GenericObjectPool<ConsumeCheckTask> consumeTaskPool;
private long lastWorkDay;
private long lastConsumeDay;
private ScheduledFuture<?> scheduledTimerTask;
private ScheduledFuture<?> timerTask;
private int timer;
public CCWorld(World world) {
this.world = new WeakReference<>(world);
@@ -90,6 +92,7 @@ public class CCWorld extends Function {
this.consumeTaskPool = new GenericObjectPool<>(new ConsumeTaskFactory(), new GenericObjectPoolConfig<>());
this.consumeTaskPool.setMaxTotal(10);
this.consumeTaskPool.setMinIdle(1);
this.timer = 10;
}
@Override
@@ -124,7 +127,6 @@ public class CCWorld extends Function {
}
this.lastConsumeDay = dataFile.getLong("last-consume-day", 0);
this.lastWorkDay = dataFile.getLong("last-work-day", 0);
this.arrangeTask();
}
@Override
@@ -169,60 +171,55 @@ public class CCWorld extends Function {
}
public void load() {
if (this.scheduledTimerTask == null) {
this.scheduledTimerTask = this.schedule.scheduleAtFixedRate(() -> {
for (CCChunk chunk : chunkMap.values()) {
chunk.scheduleGrowTask(this);
timer = ConfigManager.pointGainInterval;
if (this.timerTask == null) {
this.timerTask = CustomCrops.getInstance().getScheduler().runTaskTimerAsync(() -> {
if (ConfigManager.debug) Log.info("Task queue size: " + schedule.getQueue().size());
World current = world.get();
if (current != null) {
long fullTime = current.getFullTime();
long day = fullTime / 24000;
long time = current.getTime();
if (time < 60 && day != lastConsumeDay) {
lastConsumeDay = day;
if (ConfigManager.enableSeason && !ConfigManager.rsHook && ConfigManager.autoSeasonChange) {
CustomCrops.getInstance().getSeasonManager().addDate(worldName);
}
if (ConfigManager.enableScheduleSystem) {
scheduleConsumeTask();
}
}
else if (time > 1970 && time < 2030 && lastWorkDay != day) {
lastWorkDay = day;
if (ConfigManager.enableScheduleSystem) {
scheduleSprinklerWork();
}
}
timer--;
if (timer <= 0) {
if (ConfigManager.debug) Log.info("== Grow point ==");
timer = ConfigManager.pointGainInterval;
for (CCChunk chunk : chunkMap.values()) {
chunk.scheduleGrowTask(this);
}
}
}
}, ThreadLocalRandom.current().nextInt(20), ConfigManager.pointGainInterval, TimeUnit.SECONDS);
else {
this.schedule.shutdown();
}
}, 1000, 1000L);
}
}
public void unload() {
if (this.scheduledTimerTask != null) {
this.scheduledTimerTask.cancel(false);
this.scheduledTimerTask = null;
if (this.timerTask != null) {
this.timerTask.cancel(false);
this.timerTask = null;
}
}
/**
* Some season plugin would change the length of a day
* So a flag is needed to ensure that all the function would only work once
*/
private void arrangeTask() {
this.schedule.scheduleAtFixedRate(() -> {
World current = world.get();
if (current != null) {
long fullTime = current.getFullTime();
long day = fullTime / 24000;
long time = current.getTime();
if (time < 100 && day != lastConsumeDay) {
lastConsumeDay = day;
if (ConfigManager.enableSeason && !ConfigManager.rsHook && ConfigManager.autoSeasonChange) {
CustomCrops.getInstance().getSeasonManager().addDate(worldName);
}
if (ConfigManager.enableScheduleSystem) {
scheduleConsumeTask();
}
}
else if (time > 1950 && time < 2050 && lastWorkDay != day) {
lastWorkDay = day;
if (ConfigManager.enableScheduleSystem) {
scheduleSprinklerWork();
}
}
}
else {
this.schedule.shutdown();
}
}, 2, 2, TimeUnit.SECONDS);
}
private void closePool() {
this.schedule.shutdown();
//this.cropTaskPool.close();
//this.sprinklerTaskPool.close();
//this.consumeTaskPool.close();
}
public void pushCropTask(SimpleLocation simpleLocation, int delay) {
@@ -426,18 +423,9 @@ public class CCWorld extends Function {
DeathCondition[] deathConditions = cropConfig.getDeathConditions();
if (deathConditions != null) {
for (DeathCondition deathCondition : deathConditions) {
int delay = deathCondition.checkIfDead(simpleLocation);
if (delay != -1) {
if (delay == 0) {
removeCropData(simpleLocation);
deathCondition.applyDeadModel(simpleLocation, itemMode);
} else {
SimpleLocation copied = simpleLocation.copy();
schedule.schedule(() -> {
removeCropData(copied);
deathCondition.applyDeadModel(copied, itemMode);
}, delay, TimeUnit.MILLISECONDS);
}
if (deathCondition.checkIfDead(simpleLocation)) {
removeCropData(simpleLocation);
deathCondition.applyDeadModel(simpleLocation, itemMode);
return;
}
}
@@ -504,7 +492,6 @@ public class CCWorld extends Function {
}
growingCrop.setPoints(current + points);
if (ConfigManager.debug) Log.info(simpleLocation.toString() + ":" + growingCrop.getPoints());
if (growingCrop.getPoints() >= cropConfig.getMaxPoints()) {
removeCropData(simpleLocation);
}
@@ -518,23 +505,32 @@ public class CCWorld extends Function {
chunk.getEntities();
return chunk.isEntitiesLoaded();
});
loadEntities.whenComplete((result, throwable) ->
CustomCrops.getInstance().getScheduler().callSyncMethod(() -> {
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);
}
return null;
}));
} catch (Exception e) {
e.printStackTrace();
}
return null;
});
});
}
else {
asyncGetChunk.whenComplete((result, throwable) ->
CustomCrops.getInstance().getScheduler().callSyncMethod(() -> {
if (CustomCrops.getInstance().getPlatformInterface().removeCustomItem(location, itemMode)) {
CustomCrops.getInstance().getPlatformInterface().placeCustomItem(location, finalNextModel, itemMode);
} else {
removeCropData(simpleLocation);
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;
}));

View File

@@ -246,4 +246,5 @@ public class WorldDataManager extends Function {
public CCWorld getWorld(String world) {
return worldMap.get(world);
}
}

View File

@@ -26,6 +26,7 @@ import dev.dejvokep.boostedyaml.settings.updater.UpdaterSettings;
import net.kyori.adventure.key.Key;
import net.kyori.adventure.sound.Sound;
import net.momirealms.customcrops.CustomCrops;
import net.momirealms.customcrops.api.customplugin.Platform;
import net.momirealms.customcrops.api.object.BoneMeal;
import net.momirealms.customcrops.api.object.InteractWithItem;
import net.momirealms.customcrops.api.object.ItemMode;
@@ -52,8 +53,8 @@ import org.intellij.lang.annotations.Subst;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.File;
import java.io.IOException;
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.stream.Collectors;
@@ -61,15 +62,41 @@ public class ConfigUtils {
/**
* Get a config by name
* @param configName config's name
* @param config_path config's path
* @return yaml
*/
public static YamlConfiguration getConfig(String configName) {
File file = new File(CustomCrops.getInstance().getDataFolder(), configName);
if (!file.exists()) CustomCrops.getInstance().saveResource(configName, false);
public static YamlConfiguration getConfig(String config_path) {
File file = new File(CustomCrops.getInstance().getDataFolder(), config_path);
if (!file.exists()) {
CustomCrops.getInstance().saveResource(config_path, false);
if (CustomCrops.getInstance().getPlatform() == Platform.Oraxen) {
File generated = new File(CustomCrops.getInstance().getDataFolder(), config_path);
if (generated.exists() && generated.getName().endsWith(".yml")) {
removeNamespace(generated);
}
}
}
return YamlConfiguration.loadConfiguration(file);
}
public static void removeNamespace(File file) {
String line;
StringBuilder sb = new StringBuilder();
try (BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(file), StandardCharsets.UTF_8))) {
while ((line = reader.readLine()) != null) {
sb.append(line).append(System.lineSeparator());
}
} catch (IOException e) {
e.printStackTrace();
}
try (BufferedWriter writer = new BufferedWriter(
new OutputStreamWriter(new FileOutputStream(file), StandardCharsets.UTF_8))) {
writer.write(sb.toString().replace(" customcrops:", " ").replace("CHORUS", "TRIPWIRE").replace("<font:customcrops:default>", "<font:minecraft:customcrops>"));
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* Update config
* @param fileName config

View File

@@ -50,11 +50,9 @@ public class FakeEntityUtils {
public static WrappedDataWatcher createInvisibleDataWatcher() {
WrappedDataWatcher wrappedDataWatcher = new WrappedDataWatcher();
WrappedDataWatcher.Serializer serializer1 = WrappedDataWatcher.Registry.get(Boolean.class);
WrappedDataWatcher.Serializer serializer2 = WrappedDataWatcher.Registry.get(Byte.class);
wrappedDataWatcher.setObject(new WrappedDataWatcher.WrappedDataWatcherObject(3, serializer1), false);
//wrappedDataWatcher.setObject(new WrappedDataWatcher.WrappedDataWatcherObject(3, WrappedDataWatcher.Registry.get(Boolean.class)), false);
byte flag = 0x20;
wrappedDataWatcher.setObject(new WrappedDataWatcher.WrappedDataWatcherObject(0, serializer2), flag);
wrappedDataWatcher.setObject(new WrappedDataWatcher.WrappedDataWatcherObject(0, WrappedDataWatcher.Registry.get(Byte.class)), flag);
return wrappedDataWatcher;
}

View File

@@ -29,5 +29,6 @@ public class CustomCropsCommand extends AbstractMainCommand {
regSubCommand(SetDateCommand.INSTANCE);
regSubCommand(ForceCommand.INSTANCE);
regSubCommand(MigrateCommand.INSTANCE);
// regSubCommand(PerformanceTest.INSTANCE);
}
}

View File

@@ -0,0 +1,41 @@
//package net.momirealms.customcrops.command.subcmd;
//
//import net.momirealms.customcrops.CustomCrops;
//import net.momirealms.customcrops.api.object.crop.GrowingCrop;
//import net.momirealms.customcrops.api.object.world.SimpleLocation;
//import net.momirealms.customcrops.api.object.world.WorldDataManager;
//import net.momirealms.customcrops.command.AbstractSubCommand;
//import org.bukkit.command.CommandSender;
//import org.bukkit.entity.Player;
//
//import java.util.List;
//
//public class PerformanceTest extends AbstractSubCommand {
//
// public static final PerformanceTest INSTANCE = new PerformanceTest();
//
// public PerformanceTest() {
// super("test");
// }
//
// @Override
// public boolean onCommand(CommandSender sender, List<String> args) {
// int radius = Integer.parseInt(args.get(0));
// WorldDataManager worldDataManager = CustomCrops.getInstance().getWorldDataManager();
// if (sender instanceof Player player) {
// SimpleLocation simpleLocation = SimpleLocation.getByBukkitLocation(player.getLocation());
// CustomCrops.getInstance().getScheduler().runTaskAsync(() -> {
// SimpleLocation simpleLocation1 = simpleLocation.add(-radius, 0, -radius);
// for (int i = 0; i < radius * 2; i++) {
// for (int j = 0; j < radius * 2; j++) {
// for (int y = 0; y < 10; y++) {
// SimpleLocation temp = simpleLocation1.add(i, y, j);
// worldDataManager.addCropData(temp, new GrowingCrop("tomato", 0));
// }
// }
// }
// });
// }
// return true;
// }
//}

View File

@@ -1,21 +0,0 @@
/*
* Copyright (C) <2022> <XiaoMoMi>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package net.momirealms.customcrops.integration;
public interface ProtectionInterface {
}

View File

@@ -4,6 +4,8 @@ config-version: '25'
metrics: true
# Language: english / spanish / chinese / turkish
lang: english
# debug
debug: false
worlds:
# This is designed for servers that using a separate folder for worlds

View File

@@ -5,7 +5,7 @@ tomato:
# Otherwise some unexpected problems would occur
# TRIPWIRE / ITEM_FRAME / ITEM_DISPLAY (1.19.4+)
# 农作物模式请确保和你的资源包配置等一致否则会出现bug
type: ITEM_FRAME
type: TRIPWIRE
# The crop can only be planted on certain pots
# Pot are stored in /CustomCrops/contents/pots

View File

@@ -49,6 +49,8 @@ permissions :
customcrops.about: true
customcrops.setdate: true
customcrops.setseason: true
customcrops.force: true
customcrops.migrate: true
customcrops.reload:
default: op
customcrops.help:
@@ -58,4 +60,8 @@ permissions :
customcrops.setdate:
default: op
customcrops.setseason:
default: op
customcrops.force:
default: op
customcrops.migrate:
default: op