mirror of
https://github.com/Xiao-MoMi/Custom-Crops.git
synced 2025-12-27 10:59:20 +00:00
3.0.0
This commit is contained in:
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -22,8 +22,4 @@ import net.momirealms.customcrops.api.object.world.SimpleLocation;
|
||||
public interface Condition {
|
||||
|
||||
boolean isMet(SimpleLocation simpleLocation);
|
||||
|
||||
default int getDelay() {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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) {
|
||||
|
||||
@@ -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>==============================================================");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}));
|
||||
|
||||
@@ -246,4 +246,5 @@ public class WorldDataManager extends Function {
|
||||
public CCWorld getWorld(String world) {
|
||||
return worldMap.get(world);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -29,5 +29,6 @@ public class CustomCropsCommand extends AbstractMainCommand {
|
||||
regSubCommand(SetDateCommand.INSTANCE);
|
||||
regSubCommand(ForceCommand.INSTANCE);
|
||||
regSubCommand(MigrateCommand.INSTANCE);
|
||||
// regSubCommand(PerformanceTest.INSTANCE);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
// }
|
||||
//}
|
||||
@@ -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 {
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
Reference in New Issue
Block a user