mirror of
https://github.com/Xiao-MoMi/Custom-Crops.git
synced 2025-12-22 08:29:35 +00:00
first commit
This commit is contained in:
113
.gitignore
vendored
Normal file
113
.gitignore
vendored
Normal file
@@ -0,0 +1,113 @@
|
|||||||
|
# User-specific stuff
|
||||||
|
.idea/
|
||||||
|
|
||||||
|
*.iml
|
||||||
|
*.ipr
|
||||||
|
*.iws
|
||||||
|
|
||||||
|
# IntelliJ
|
||||||
|
out/
|
||||||
|
|
||||||
|
# Compiled class file
|
||||||
|
*.class
|
||||||
|
|
||||||
|
# Log file
|
||||||
|
*.log
|
||||||
|
|
||||||
|
# BlueJ files
|
||||||
|
*.ctxt
|
||||||
|
|
||||||
|
# Package Files #
|
||||||
|
*.jar
|
||||||
|
*.war
|
||||||
|
*.nar
|
||||||
|
*.ear
|
||||||
|
*.zip
|
||||||
|
*.tar.gz
|
||||||
|
*.rar
|
||||||
|
|
||||||
|
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
|
||||||
|
hs_err_pid*
|
||||||
|
|
||||||
|
*~
|
||||||
|
|
||||||
|
# temporary files which can be created if a process still has a handle open of a deleted file
|
||||||
|
.fuse_hidden*
|
||||||
|
|
||||||
|
# KDE directory preferences
|
||||||
|
.directory
|
||||||
|
|
||||||
|
# Linux trash folder which might appear on any partition or disk
|
||||||
|
.Trash-*
|
||||||
|
|
||||||
|
# .nfs files are created when an open file is removed but is still being accessed
|
||||||
|
.nfs*
|
||||||
|
|
||||||
|
# General
|
||||||
|
.DS_Store
|
||||||
|
.AppleDouble
|
||||||
|
.LSOverride
|
||||||
|
|
||||||
|
# Icon must end with two \r
|
||||||
|
Icon
|
||||||
|
|
||||||
|
# Thumbnails
|
||||||
|
._*
|
||||||
|
|
||||||
|
# Files that might appear in the root of a volume
|
||||||
|
.DocumentRevisions-V100
|
||||||
|
.fseventsd
|
||||||
|
.Spotlight-V100
|
||||||
|
.TemporaryItems
|
||||||
|
.Trashes
|
||||||
|
.VolumeIcon.icns
|
||||||
|
.com.apple.timemachine.donotpresent
|
||||||
|
|
||||||
|
# Directories potentially created on remote AFP share
|
||||||
|
.AppleDB
|
||||||
|
.AppleDesktop
|
||||||
|
Network Trash Folder
|
||||||
|
Temporary Items
|
||||||
|
.apdisk
|
||||||
|
|
||||||
|
# Windows thumbnail cache files
|
||||||
|
Thumbs.db
|
||||||
|
Thumbs.db:encryptable
|
||||||
|
ehthumbs.db
|
||||||
|
ehthumbs_vista.db
|
||||||
|
|
||||||
|
# Dump file
|
||||||
|
*.stackdump
|
||||||
|
|
||||||
|
# Folder config file
|
||||||
|
[Dd]esktop.ini
|
||||||
|
|
||||||
|
# Recycle Bin used on file shares
|
||||||
|
$RECYCLE.BIN/
|
||||||
|
|
||||||
|
# Windows Installer files
|
||||||
|
*.cab
|
||||||
|
*.msi
|
||||||
|
*.msix
|
||||||
|
*.msm
|
||||||
|
*.msp
|
||||||
|
|
||||||
|
# Windows shortcuts
|
||||||
|
*.lnk
|
||||||
|
|
||||||
|
target/
|
||||||
|
|
||||||
|
pom.xml.tag
|
||||||
|
pom.xml.releaseBackup
|
||||||
|
pom.xml.versionsBackup
|
||||||
|
pom.xml.next
|
||||||
|
|
||||||
|
release.properties
|
||||||
|
dependency-reduced-pom.xml
|
||||||
|
buildNumber.properties
|
||||||
|
.mvn/timing.properties
|
||||||
|
.mvn/wrapper/maven-wrapper.jar
|
||||||
|
.flattened-pom.xml
|
||||||
|
|
||||||
|
# Common working directory
|
||||||
|
run/
|
||||||
117
pom.xml
Normal file
117
pom.xml
Normal file
@@ -0,0 +1,117 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
<groupId>net.momirealms</groupId>
|
||||||
|
<artifactId>CustomCrops</artifactId>
|
||||||
|
<version>1.0-SNAPSHOT</version>
|
||||||
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
|
<name>CustomCrops</name>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<java.version>1.8</java.version>
|
||||||
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
|
<version>3.8.1</version>
|
||||||
|
<configuration>
|
||||||
|
<source>${java.version}</source>
|
||||||
|
<target>${java.version}</target>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-shade-plugin</artifactId>
|
||||||
|
<version>3.2.4</version>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<phase>package</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>shade</goal>
|
||||||
|
</goals>
|
||||||
|
<configuration>
|
||||||
|
<createDependencyReducedPom>false</createDependencyReducedPom>
|
||||||
|
</configuration>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
<resources>
|
||||||
|
<resource>
|
||||||
|
<directory>src/main/resources</directory>
|
||||||
|
<filtering>true</filtering>
|
||||||
|
</resource>
|
||||||
|
</resources>
|
||||||
|
</build>
|
||||||
|
|
||||||
|
<repositories>
|
||||||
|
<repository>
|
||||||
|
<id>dmulloy2-repo</id>
|
||||||
|
<url>https://repo.dmulloy2.net/repository/public/</url>
|
||||||
|
</repository>
|
||||||
|
<repository>
|
||||||
|
<id>placeholderapi</id>
|
||||||
|
<url>https://repo.extendedclip.com/content/repositories/placeholderapi/</url>
|
||||||
|
</repository>
|
||||||
|
<repository>
|
||||||
|
<id>sonatype-oss-snapshots1</id>
|
||||||
|
<url>https://s01.oss.sonatype.org/content/repositories/snapshots/</url>
|
||||||
|
</repository>
|
||||||
|
<repository>
|
||||||
|
<id>papermc-repo</id>
|
||||||
|
<url>https://papermc.io/repo/repository/maven-public/</url>
|
||||||
|
</repository>
|
||||||
|
<repository>
|
||||||
|
<id>jitpack-repo</id>
|
||||||
|
<url>https://jitpack.io</url>
|
||||||
|
</repository>
|
||||||
|
<repository>
|
||||||
|
<id>sonatype</id>
|
||||||
|
<url>https://oss.sonatype.org/content/groups/public/</url>
|
||||||
|
</repository>
|
||||||
|
</repositories>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.comphenix.protocol</groupId>
|
||||||
|
<artifactId>ProtocolLib</artifactId>
|
||||||
|
<version>4.8.0</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>me.clip</groupId>
|
||||||
|
<artifactId>placeholderapi</artifactId>
|
||||||
|
<version>2.11.1</version>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>net.kyori</groupId>
|
||||||
|
<artifactId>adventure-text-minimessage</artifactId>
|
||||||
|
<version>4.10.1</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>net.kyori</groupId>
|
||||||
|
<artifactId>adventure-platform-bukkit</artifactId>
|
||||||
|
<version>4.1.0</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>io.papermc.paper</groupId>
|
||||||
|
<artifactId>paper-api</artifactId>
|
||||||
|
<version>1.18.1-R0.1-SNAPSHOT</version>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.github.LoneDev6</groupId>
|
||||||
|
<artifactId>api-itemsadder</artifactId>
|
||||||
|
<version>3.1.0b</version>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
</project>
|
||||||
96
src/main/java/net/momirealms/customcrops/CommandHandler.java
Normal file
96
src/main/java/net/momirealms/customcrops/CommandHandler.java
Normal file
@@ -0,0 +1,96 @@
|
|||||||
|
package net.momirealms.customcrops;
|
||||||
|
|
||||||
|
import net.momirealms.customcrops.DataManager.BackUp;
|
||||||
|
import net.momirealms.customcrops.DataManager.CropManager;
|
||||||
|
import net.momirealms.customcrops.DataManager.SprinklerManager;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.command.Command;
|
||||||
|
import org.bukkit.command.CommandExecutor;
|
||||||
|
import org.bukkit.command.CommandSender;
|
||||||
|
import org.bukkit.configuration.file.FileConfiguration;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
|
import javax.annotation.ParametersAreNonnullByDefault;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
public class CommandHandler implements CommandExecutor {
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@ParametersAreNonnullByDefault
|
||||||
|
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
|
||||||
|
|
||||||
|
if(sender instanceof Player && !sender.isOp()){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
FileConfiguration config = CustomCrops.instance.getConfig();
|
||||||
|
|
||||||
|
if(args[0].equalsIgnoreCase("reload")){
|
||||||
|
CustomCrops.loadConfig();
|
||||||
|
if(sender instanceof Player){
|
||||||
|
MessageManager.playerMessage(config.getString("messages.prefix") + config.getString("messages.reload"), (Player) sender);
|
||||||
|
}else {
|
||||||
|
MessageManager.consoleMessage(config.getString("messages.prefix") + config.getString("messages.reload"), Bukkit.getConsoleSender());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(args[0].equalsIgnoreCase("setseason")){
|
||||||
|
if(config.getBoolean("enable-season")){
|
||||||
|
config.set("current-season", args[1]);
|
||||||
|
if(sender instanceof Player){
|
||||||
|
MessageManager.playerMessage(config.getString("messages.prefix") + Objects.requireNonNull(config.getString("messages.season-set")).replace("{Season}",args[1])
|
||||||
|
.replace("spring", Objects.requireNonNull(config.getString("messages.spring")))
|
||||||
|
.replace("summer", Objects.requireNonNull(config.getString("messages.summer")))
|
||||||
|
.replace("autumn", Objects.requireNonNull(config.getString("messages.autumn")))
|
||||||
|
.replace("winter", Objects.requireNonNull(config.getString("messages.winter"))), (Player) sender);
|
||||||
|
}else {
|
||||||
|
MessageManager.consoleMessage(config.getString("messages.prefix") + Objects.requireNonNull(config.getString("messages.season-set")).replace("{Season}",args[1])
|
||||||
|
.replace("spring", Objects.requireNonNull(config.getString("messages.spring")))
|
||||||
|
.replace("summer", Objects.requireNonNull(config.getString("messages.summer")))
|
||||||
|
.replace("autumn", Objects.requireNonNull(config.getString("messages.autumn")))
|
||||||
|
.replace("winter", Objects.requireNonNull(config.getString("messages.winter"))), Bukkit.getConsoleSender());
|
||||||
|
}
|
||||||
|
CustomCrops.instance.saveConfig();
|
||||||
|
}else{
|
||||||
|
if(sender instanceof Player){
|
||||||
|
MessageManager.playerMessage(config.getString("messages.prefix") + config.getString("messages.season-disabled"), (Player) sender);
|
||||||
|
}else {
|
||||||
|
MessageManager.consoleMessage(config.getString("messages.prefix") + config.getString("messages.season-disabled"), Bukkit.getConsoleSender());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(args[0].equalsIgnoreCase("forcesave")){
|
||||||
|
CropManager.saveData();
|
||||||
|
SprinklerManager.saveData();
|
||||||
|
if(sender instanceof Player){
|
||||||
|
MessageManager.playerMessage(config.getString("messages.prefix") + config.getString("messages.force-save"), (Player) sender);
|
||||||
|
}else {
|
||||||
|
MessageManager.consoleMessage(config.getString("messages.prefix") + config.getString("messages.force-save"), Bukkit.getConsoleSender());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(args[0].equalsIgnoreCase("cleancache")){
|
||||||
|
Bukkit.getScheduler().runTaskAsynchronously(CustomCrops.instance,()->{
|
||||||
|
CropManager.cleanLoadedCache();
|
||||||
|
SprinklerManager.cleanCache();
|
||||||
|
});
|
||||||
|
if(sender instanceof Player){
|
||||||
|
MessageManager.playerMessage(config.getString("messages.prefix") + config.getString("messages.clean-cache"), (Player) sender);
|
||||||
|
}else {
|
||||||
|
MessageManager.consoleMessage(config.getString("messages.prefix") + config.getString("messages.clean-cache"), Bukkit.getConsoleSender());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(args[0].equalsIgnoreCase("backup")){
|
||||||
|
BackUp.backUpData();
|
||||||
|
if(sender instanceof Player){
|
||||||
|
MessageManager.playerMessage(config.getString("messages.prefix") + config.getString("messages.backup"), (Player) sender);
|
||||||
|
}else {
|
||||||
|
MessageManager.consoleMessage(config.getString("messages.prefix") + config.getString("messages.backup"), Bukkit.getConsoleSender());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
package net.momirealms.customcrops;
|
||||||
|
|
||||||
|
import org.bukkit.command.Command;
|
||||||
|
import org.bukkit.command.CommandSender;
|
||||||
|
import org.bukkit.command.TabCompleter;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import javax.annotation.ParametersAreNonnullByDefault;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class CommandTabComplete implements TabCompleter {
|
||||||
|
@Override
|
||||||
|
@ParametersAreNonnullByDefault
|
||||||
|
public @Nullable List<String> onTabComplete(CommandSender sender, Command command, String alias, String[] args) {
|
||||||
|
if (args.length == 1) {
|
||||||
|
return Arrays.asList("backup" , "cleancache", "forcesave", "reload", "setseason");
|
||||||
|
}
|
||||||
|
if(args[0].equalsIgnoreCase("setseason")){
|
||||||
|
return Arrays.asList("spring","summer","autumn","winter");
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
package net.momirealms.customcrops.Crops;
|
||||||
|
|
||||||
|
import net.momirealms.customcrops.CustomCrops;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.scheduler.BukkitTask;
|
||||||
|
|
||||||
|
public class CropTimer {
|
||||||
|
|
||||||
|
int taskID;
|
||||||
|
|
||||||
|
public static void stopTimer(int ID) {
|
||||||
|
Bukkit.getScheduler().cancelTask(ID);
|
||||||
|
Bukkit.getServer().getScheduler().cancelTask(ID);
|
||||||
|
}
|
||||||
|
|
||||||
|
public CropTimer() {
|
||||||
|
TimeCheck tc = new TimeCheck();
|
||||||
|
BukkitTask task = tc.runTaskTimerAsynchronously(CustomCrops.instance, 1,1);
|
||||||
|
this.taskID = task.getTaskId();
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getTaskID() {
|
||||||
|
return this.taskID;
|
||||||
|
}
|
||||||
|
}
|
||||||
167
src/main/java/net/momirealms/customcrops/Crops/TimeCheck.java
Normal file
167
src/main/java/net/momirealms/customcrops/Crops/TimeCheck.java
Normal file
@@ -0,0 +1,167 @@
|
|||||||
|
package net.momirealms.customcrops.Crops;
|
||||||
|
|
||||||
|
import com.comphenix.protocol.PacketType;
|
||||||
|
import com.comphenix.protocol.events.PacketContainer;
|
||||||
|
import dev.lone.itemsadder.api.CustomBlock;
|
||||||
|
import net.momirealms.customcrops.CustomCrops;
|
||||||
|
import net.momirealms.customcrops.DataManager.CropManager;
|
||||||
|
import net.momirealms.customcrops.DataManager.SprinklerManager;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.Location;
|
||||||
|
import org.bukkit.World;
|
||||||
|
import org.bukkit.configuration.file.FileConfiguration;
|
||||||
|
import org.bukkit.configuration.file.YamlConfiguration;
|
||||||
|
import org.bukkit.scheduler.BukkitRunnable;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
public class TimeCheck extends BukkitRunnable {
|
||||||
|
|
||||||
|
FileConfiguration config = CustomCrops.instance.getConfig();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
long time = Bukkit.getWorld("world").getTime();
|
||||||
|
if(time == 23500){
|
||||||
|
CropManager.cleanLoadedCache();
|
||||||
|
}
|
||||||
|
if(time == 23700){
|
||||||
|
CropManager.saveData();
|
||||||
|
}
|
||||||
|
if(time == 23900){
|
||||||
|
File file = new File(CustomCrops.instance.getDataFolder(), "crop-data.yml");
|
||||||
|
FileConfiguration data;
|
||||||
|
data = YamlConfiguration.loadConfiguration(file);
|
||||||
|
boolean enable_season = config.getBoolean("enable-season");
|
||||||
|
boolean enable_greenhouse = config.getBoolean("config.enable-greenhouse");
|
||||||
|
int range = config.getInt("config.greenhouse-range");
|
||||||
|
String glass = config.getString("config.greenhouse-glass");
|
||||||
|
config.getStringList("config.whitelist-worlds").forEach(worldName -> CropManager.getCrops(Objects.requireNonNull(Bukkit.getWorld(worldName))).forEach(seedLocation -> {
|
||||||
|
World world = Bukkit.getWorld(worldName);
|
||||||
|
Location potLocation = seedLocation.clone().subtract(0,1,0);
|
||||||
|
String[] seasons = Objects.requireNonNull(data.getString(worldName + "." + seedLocation.getBlockX() + "," + seedLocation.getBlockY() + "," + seedLocation.getBlockZ())).split(",");
|
||||||
|
if (CustomBlock.byAlreadyPlaced(world.getBlockAt(potLocation)) != null && CustomBlock.byAlreadyPlaced(world.getBlockAt(seedLocation)) != null){
|
||||||
|
if (CustomBlock.byAlreadyPlaced((world.getBlockAt(potLocation))).getNamespacedID().equalsIgnoreCase(config.getString("config.watered-pot")) && CustomBlock.byAlreadyPlaced(world.getBlockAt(seedLocation)).getNamespacedID().contains("stage")){
|
||||||
|
if (CustomBlock.byAlreadyPlaced(world.getBlockAt(seedLocation)).getNamespacedID().equalsIgnoreCase(config.getString("config.dead-crop"))){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
String[] cropNameList = CustomBlock.byAlreadyPlaced(world.getBlockAt(seedLocation)).getNamespacedID().split("_");
|
||||||
|
Label_out:
|
||||||
|
if(enable_season){
|
||||||
|
if(enable_greenhouse){
|
||||||
|
for(int i = 1; i <= range; i++){
|
||||||
|
Location tempLocation = seedLocation.clone().add(0,i,0);
|
||||||
|
if (CustomBlock.byAlreadyPlaced(world.getBlockAt(tempLocation)) != null){
|
||||||
|
if(CustomBlock.byAlreadyPlaced(world.getBlockAt(tempLocation)).getNamespacedID().equalsIgnoreCase(glass)){
|
||||||
|
break Label_out;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
boolean wrongSeason = true;
|
||||||
|
for(String season : seasons){
|
||||||
|
if(Objects.equals(season, config.getString("current-season"))){
|
||||||
|
wrongSeason = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(wrongSeason){
|
||||||
|
Bukkit.getScheduler().callSyncMethod(CustomCrops.instance, () -> {
|
||||||
|
CustomBlock.remove(seedLocation);
|
||||||
|
CustomBlock.place(config.getString("config.dead-crop"),seedLocation);
|
||||||
|
return null;
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
int nextStage = Integer.parseInt(cropNameList[2]) + 1;
|
||||||
|
if (CustomBlock.getInstance(cropNameList[0] + "_" +cropNameList[1] +"_" + nextStage) != null) {
|
||||||
|
Bukkit.getScheduler().callSyncMethod(CustomCrops.instance, () ->{
|
||||||
|
CustomBlock.remove(potLocation);
|
||||||
|
CustomBlock.place(config.getString("config.pot"),potLocation);
|
||||||
|
if(Math.random()< config.getDouble("config.grow-success-chance")){
|
||||||
|
CustomBlock.remove(seedLocation);
|
||||||
|
CustomBlock.place(cropNameList[0] + "_" +cropNameList[1] +"_" + nextStage,seedLocation);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}else if(CustomBlock.byAlreadyPlaced((world.getBlockAt(potLocation))).getNamespacedID().equalsIgnoreCase(config.getString("config.pot")) && CustomBlock.byAlreadyPlaced(world.getBlockAt(seedLocation)).getNamespacedID().contains("stage")){
|
||||||
|
if (CustomBlock.byAlreadyPlaced(world.getBlockAt(seedLocation)).getNamespacedID().equalsIgnoreCase(config.getString("config.dead-crop"))){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(enable_season) {
|
||||||
|
if(enable_greenhouse){
|
||||||
|
for(int i = 1; i <= range; i++){
|
||||||
|
Location tempLocation = seedLocation.clone().add(0,i,0);
|
||||||
|
if (CustomBlock.byAlreadyPlaced(world.getBlockAt(tempLocation)) != null){
|
||||||
|
if(CustomBlock.byAlreadyPlaced(world.getBlockAt(tempLocation)).getNamespacedID().equalsIgnoreCase(config.getString("config.greenhouse-glass"))){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
boolean wrongSeason = true;
|
||||||
|
for (String season : seasons) {
|
||||||
|
if (Objects.equals(season, config.getString("current-season"))) {
|
||||||
|
wrongSeason = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (wrongSeason) {
|
||||||
|
Bukkit.getScheduler().callSyncMethod(CustomCrops.instance, () -> {
|
||||||
|
CustomBlock.remove(seedLocation);
|
||||||
|
CustomBlock.place(config.getString("config.dead-crop"), seedLocation);
|
||||||
|
return null;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
if (time == 100){
|
||||||
|
SprinklerManager.cleanCache();
|
||||||
|
}
|
||||||
|
if (time == 300){
|
||||||
|
SprinklerManager.saveData();
|
||||||
|
}
|
||||||
|
if(time == 500){
|
||||||
|
File file = new File(CustomCrops.instance.getDataFolder(), "sprinkler-data.yml");
|
||||||
|
FileConfiguration data;
|
||||||
|
data = YamlConfiguration.loadConfiguration(file);
|
||||||
|
config.getStringList("config.whitelist-worlds").forEach(worldName -> SprinklerManager.getSprinklers(Objects.requireNonNull(Bukkit.getWorld(worldName))).forEach(location -> {
|
||||||
|
World world = Bukkit.getWorld(worldName);
|
||||||
|
String type = Objects.requireNonNull(data.getString(worldName + "." + location.getBlockX() + "," + location.getBlockY() + "," + location.getBlockZ()));
|
||||||
|
if(type.equals("s1")){
|
||||||
|
for(int i = -1; i <= 1;i++){
|
||||||
|
for (int j = -1; j <= 1; j++){
|
||||||
|
Location tempLoc = location.clone().add(i,-1,j);
|
||||||
|
waterPot(tempLoc, world);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}else if(type.equals("s2")){
|
||||||
|
for(int i = -2; i <= 2;i++){
|
||||||
|
for (int j = -2; j <= 2; j++){
|
||||||
|
Location tempLoc = location.clone().add(i,-1,j);
|
||||||
|
waterPot(tempLoc, world);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private void waterPot(Location tempLoc, World world) {
|
||||||
|
if(CustomBlock.byAlreadyPlaced(world.getBlockAt(tempLoc)) != null){
|
||||||
|
if(CustomBlock.byAlreadyPlaced(world.getBlockAt(tempLoc)).getNamespacedID().equalsIgnoreCase(config.getString("config.pot"))){
|
||||||
|
|
||||||
|
PacketContainer fakeWater = new PacketContainer(PacketType.Play.Server.ENTITY_HEAD_ROTATION);
|
||||||
|
|
||||||
|
Bukkit.getScheduler().callSyncMethod(CustomCrops.instance,()->{
|
||||||
|
CustomBlock.remove(tempLoc);
|
||||||
|
CustomBlock.place(config.getString("config.watered-pot"), tempLoc);
|
||||||
|
return null;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
110
src/main/java/net/momirealms/customcrops/CustomCrops.java
Normal file
110
src/main/java/net/momirealms/customcrops/CustomCrops.java
Normal file
@@ -0,0 +1,110 @@
|
|||||||
|
package net.momirealms.customcrops;
|
||||||
|
|
||||||
|
import net.kyori.adventure.platform.bukkit.BukkitAudiences;
|
||||||
|
import net.momirealms.customcrops.Crops.CropTimer;
|
||||||
|
import net.momirealms.customcrops.DataManager.BackUp;
|
||||||
|
import net.momirealms.customcrops.DataManager.CropManager;
|
||||||
|
import net.momirealms.customcrops.DataManager.SprinklerManager;
|
||||||
|
import net.momirealms.customcrops.listener.BreakCustomBlock;
|
||||||
|
import net.momirealms.customcrops.listener.BreakFurniture;
|
||||||
|
import net.momirealms.customcrops.listener.RightClickBlock;
|
||||||
|
import net.momirealms.customcrops.listener.RightClickCustomBlock;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.configuration.file.FileConfiguration;
|
||||||
|
import org.bukkit.configuration.file.YamlConfiguration;
|
||||||
|
import org.bukkit.plugin.java.JavaPlugin;
|
||||||
|
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
public final class CustomCrops extends JavaPlugin {
|
||||||
|
|
||||||
|
public static JavaPlugin instance;
|
||||||
|
public static ProtocolManager manager;
|
||||||
|
public static CropTimer timer;
|
||||||
|
public static CropManager cropManager;
|
||||||
|
public static SprinklerManager sprinklerManager;
|
||||||
|
private BukkitAudiences adventure;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onEnable() {
|
||||||
|
instance = this;
|
||||||
|
saveDefaultConfig();
|
||||||
|
|
||||||
|
Objects.requireNonNull(Bukkit.getPluginCommand("customcrops")).setExecutor(new CommandHandler());
|
||||||
|
Objects.requireNonNull(Bukkit.getPluginCommand("customcrops")).setTabCompleter(new CommandTabComplete());
|
||||||
|
Bukkit.getPluginManager().registerEvents(new RightClickCustomBlock(),this);
|
||||||
|
Bukkit.getPluginManager().registerEvents(new BreakCustomBlock(),this);
|
||||||
|
Bukkit.getPluginManager().registerEvents(new RightClickBlock(),this);
|
||||||
|
Bukkit.getPluginManager().registerEvents(new BreakFurniture(),this);
|
||||||
|
|
||||||
|
startTimer();
|
||||||
|
|
||||||
|
File crop_file = new File(CustomCrops.instance.getDataFolder(), "crop-data.yml");
|
||||||
|
File sprinkler_file = new File(CustomCrops.instance.getDataFolder(), "sprinkler-data.yml");
|
||||||
|
if(!crop_file.exists()){
|
||||||
|
try {
|
||||||
|
crop_file.createNewFile();
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(!sprinkler_file.exists()){
|
||||||
|
try {
|
||||||
|
sprinkler_file.createNewFile();
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FileConfiguration crop_data;
|
||||||
|
FileConfiguration sprinkler_data;
|
||||||
|
crop_data = YamlConfiguration.loadConfiguration(crop_file);
|
||||||
|
sprinkler_data = YamlConfiguration.loadConfiguration(sprinkler_file);
|
||||||
|
CustomCrops.cropManager = new CropManager(crop_data);
|
||||||
|
CustomCrops.sprinklerManager = new SprinklerManager(sprinkler_data);
|
||||||
|
|
||||||
|
if(Bukkit.getPluginManager().getPlugin("PlaceholderAPI") != null){
|
||||||
|
new Placeholders(this).register();
|
||||||
|
MessageManager.consoleMessage("<gradient:#ccfbff:#ef96c5>[CustomCorps] 检测到PlaceHolderAPI 已启用季节变量!</gradient>",Bukkit.getConsoleSender());
|
||||||
|
}
|
||||||
|
|
||||||
|
MessageManager.consoleMessage("<gradient:#ccfbff:#ef96c5>[CustomCorps] 自定义农作物插件已启用!作者:小默米</gradient>",Bukkit.getConsoleSender());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDisable() {
|
||||||
|
if (CustomCrops.timer != null) {
|
||||||
|
CropTimer.stopTimer(CustomCrops.timer.getTaskID());
|
||||||
|
}
|
||||||
|
|
||||||
|
CropManager.saveData();
|
||||||
|
SprinklerManager.saveData();
|
||||||
|
|
||||||
|
if(this.adventure != null) {
|
||||||
|
this.adventure.close();
|
||||||
|
this.adventure = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
BackUp.backUpData();
|
||||||
|
MessageManager.consoleMessage("<gradient:#ccfbff:#ef96c5>[CustomCorps] 自定义农作物插件已卸载!作者:小默米</gradient>",Bukkit.getConsoleSender());
|
||||||
|
}
|
||||||
|
|
||||||
|
public @NonNull BukkitAudiences adventure() {
|
||||||
|
if(this.adventure == null) {
|
||||||
|
throw new IllegalStateException("Tried to access Adventure when the plugin was disabled!");
|
||||||
|
}
|
||||||
|
return this.adventure;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void startTimer() {
|
||||||
|
CustomCrops.timer = new CropTimer();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void loadConfig(){
|
||||||
|
instance.reloadConfig();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,48 @@
|
|||||||
|
package net.momirealms.customcrops.DataManager;
|
||||||
|
|
||||||
|
import net.momirealms.customcrops.CustomCrops;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.io.FileOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
public class BackUp {
|
||||||
|
public static void backUpData(){
|
||||||
|
|
||||||
|
Date date = new Date();
|
||||||
|
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss");
|
||||||
|
|
||||||
|
File crop_data = new File(CustomCrops.instance.getDataFolder(), "crop-data.yml");
|
||||||
|
File cropBackUp = new File(CustomCrops.instance.getDataFolder(), "backups/"+ format.format(date) + "/" + "crop-data.yml");
|
||||||
|
File sprinkler_data = new File(CustomCrops.instance.getDataFolder(), "sprinkler-data.yml");
|
||||||
|
File sprinklerBackUp = new File(CustomCrops.instance.getDataFolder(), "backups/"+ format.format(date) + "/" + "sprinkler-data.yml");
|
||||||
|
|
||||||
|
try {
|
||||||
|
BackUp.backUp(crop_data,cropBackUp);
|
||||||
|
BackUp.backUp(sprinkler_data,sprinklerBackUp);
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void backUp(File file_from, File file_to) throws IOException {
|
||||||
|
if(!file_to.exists()){
|
||||||
|
file_to.getParentFile().mkdirs();
|
||||||
|
}
|
||||||
|
FileInputStream fis = new FileInputStream(file_from);
|
||||||
|
if(!file_to.exists()){
|
||||||
|
file_to.createNewFile();
|
||||||
|
}
|
||||||
|
FileOutputStream fos = new FileOutputStream(file_to);
|
||||||
|
byte[] b = new byte[1024];
|
||||||
|
int len;
|
||||||
|
while ((len = fis.read(b))!= -1){
|
||||||
|
fos.write(b,0,len);
|
||||||
|
}
|
||||||
|
fos.close();
|
||||||
|
fis.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,119 @@
|
|||||||
|
package net.momirealms.customcrops.DataManager;
|
||||||
|
|
||||||
|
import net.momirealms.customcrops.CustomCrops;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.Location;
|
||||||
|
import org.bukkit.Material;
|
||||||
|
import org.bukkit.World;
|
||||||
|
import org.bukkit.configuration.file.FileConfiguration;
|
||||||
|
import org.bukkit.configuration.file.YamlConfiguration;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
public class CropManager {
|
||||||
|
|
||||||
|
public static HashMap<Location, String> instances;
|
||||||
|
|
||||||
|
public CropManager(FileConfiguration data) {
|
||||||
|
FileConfiguration config = CustomCrops.instance.getConfig();
|
||||||
|
File file = new File(CustomCrops.instance.getDataFolder(), "crop-data.yml");
|
||||||
|
data = YamlConfiguration.loadConfiguration(file);
|
||||||
|
try {
|
||||||
|
for (String world : config.getStringList("config.whitelist-worlds")) {
|
||||||
|
CropManager.instances = new HashMap<Location, String>();
|
||||||
|
if(data.getConfigurationSection(world) != null){
|
||||||
|
for (String coordinate : data.getConfigurationSection(world).getKeys(false)) {
|
||||||
|
Location tempLocation = new Location(Bukkit.getWorld(world), (double)Integer.parseInt(coordinate.split(",")[0]), (double)Integer.parseInt(coordinate.split(",")[1]), (double)Integer.parseInt(coordinate.split(",")[2]));
|
||||||
|
String season = data.getString(world + "." + coordinate);
|
||||||
|
CropManager.instances.put(tempLocation, season);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception e) {
|
||||||
|
CropManager.instances = new HashMap<Location, String>();
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
saveData();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<Location> getCrops(World world){
|
||||||
|
FileConfiguration config = CustomCrops.instance.getConfig();
|
||||||
|
File file = new File(CustomCrops.instance.getDataFolder(), "crop-data.yml");
|
||||||
|
FileConfiguration data;
|
||||||
|
data = YamlConfiguration.loadConfiguration(file);
|
||||||
|
List<Location> locations = new ArrayList<Location>();
|
||||||
|
if (config.getStringList("config.whitelist-worlds").contains(world.getName())){
|
||||||
|
if(data.contains(world.getName())){
|
||||||
|
data.getConfigurationSection(world.getName()).getKeys(false).forEach(key ->{
|
||||||
|
String[] string_list = key.split(",");
|
||||||
|
if (config.getBoolean("config.only-grow-in-loaded-chunks")){
|
||||||
|
if (world.isChunkLoaded(Integer.parseInt(string_list[0])/16, Integer.parseInt(string_list[2])/16)){
|
||||||
|
locations.add(new Location(world, Double.parseDouble(string_list[0]),Double.parseDouble(string_list[1]),Double.parseDouble(string_list[2])));
|
||||||
|
}
|
||||||
|
}else {
|
||||||
|
locations.add(new Location(world, Double.parseDouble(string_list[0]),Double.parseDouble(string_list[1]),Double.parseDouble(string_list[2])));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return locations;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void saveData(){
|
||||||
|
File file = new File(CustomCrops.instance.getDataFolder(), "crop-data.yml");
|
||||||
|
FileConfiguration data;
|
||||||
|
data = YamlConfiguration.loadConfiguration(file);
|
||||||
|
if (CropManager.instances != null) {
|
||||||
|
Set<Map.Entry<Location, String>> en = instances.entrySet();
|
||||||
|
for(Map.Entry<Location, String> entry : en){
|
||||||
|
data.set(entry.getKey().getWorld().getName() + "." + entry.getKey().getBlockX() + "," + entry.getKey().getBlockY()+ ","+entry.getKey().getBlockZ(), entry.getValue());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
CropManager.instances = new HashMap<Location, String>();
|
||||||
|
Bukkit.getConsoleSender().sendMessage("错误");
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
data.save(file);
|
||||||
|
}
|
||||||
|
catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//test
|
||||||
|
public static void putInstance(Location location, String season) {
|
||||||
|
CropManager.instances.put(location, season);
|
||||||
|
}
|
||||||
|
public HashMap<Location, String> getMap() {
|
||||||
|
return CropManager.instances;
|
||||||
|
}
|
||||||
|
public static void cleanLoadedCache() {
|
||||||
|
FileConfiguration config = CustomCrops.instance.getConfig();
|
||||||
|
File file = new File(CustomCrops.instance.getDataFolder(), "crop-data.yml");
|
||||||
|
FileConfiguration data;
|
||||||
|
data = YamlConfiguration.loadConfiguration(file);
|
||||||
|
config.getStringList("config.whitelist-worlds").forEach(worldName ->{
|
||||||
|
if(data.contains(worldName)){
|
||||||
|
World world = Bukkit.getWorld(worldName);
|
||||||
|
data.getConfigurationSection(worldName).getKeys(false).forEach(key ->{
|
||||||
|
String[] string_list = key.split(",");
|
||||||
|
if (world.isChunkLoaded(Integer.parseInt(string_list[0])/16, Integer.parseInt(string_list[2])/16)){
|
||||||
|
Location tempLoc = new Location(world,Double.parseDouble(string_list[0]),Double.parseDouble(string_list[1]),Double.parseDouble(string_list[2]));
|
||||||
|
if(world.getBlockAt(tempLoc).getType() != Material.TRIPWIRE){
|
||||||
|
CropManager.instances.remove(tempLoc);
|
||||||
|
data.set(worldName+"."+string_list[0]+","+string_list[1]+","+string_list[2], null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
try{
|
||||||
|
data.save(file);
|
||||||
|
}catch (IOException e){
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
package net.momirealms.customcrops.DataManager;
|
||||||
|
|
||||||
|
import dev.lone.itemsadder.api.CustomBlock;
|
||||||
|
import net.momirealms.customcrops.CustomCrops;
|
||||||
|
import org.bukkit.Location;
|
||||||
|
import org.bukkit.configuration.file.FileConfiguration;
|
||||||
|
|
||||||
|
public class MaxCropsPerChunk {
|
||||||
|
|
||||||
|
public static boolean maxCropsPerChunk(Location location){
|
||||||
|
FileConfiguration config = CustomCrops.instance.getConfig();
|
||||||
|
if(!config.getBoolean("config.enable-limit")){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
int maxY = config.getInt("config.height.max");
|
||||||
|
int minY = config.getInt("config.height.min");
|
||||||
|
int maxAmount = config.getInt("config.max-crops");
|
||||||
|
|
||||||
|
int n = 1;
|
||||||
|
|
||||||
|
Location chunkLocation = new Location(location.getWorld(),location.getChunk().getX()*16,minY,location.getChunk().getZ()*16);
|
||||||
|
|
||||||
|
Label_out:
|
||||||
|
for (int i = 0; i < 16; ++i) {
|
||||||
|
for (int j = 0; j < 16; ++j) {
|
||||||
|
final Location square = chunkLocation.clone().add((double)i, 0.0, (double)j);
|
||||||
|
for (int k = minY; k <= maxY; ++k) {
|
||||||
|
square.add(0.0, 1.0, 0.0);
|
||||||
|
if(CustomBlock.byAlreadyPlaced(location.getWorld().getBlockAt(square))!= null){
|
||||||
|
if (CustomBlock.byAlreadyPlaced(location.getWorld().getBlockAt(square)).getNamespacedID().contains("stage")) {
|
||||||
|
if (n++ > maxAmount) {
|
||||||
|
break Label_out;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return n > maxAmount;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
package net.momirealms.customcrops.DataManager;
|
||||||
|
|
||||||
|
import net.momirealms.customcrops.CustomCrops;
|
||||||
|
import net.momirealms.customcrops.IAFurniture;
|
||||||
|
import org.bukkit.Location;
|
||||||
|
import org.bukkit.World;
|
||||||
|
import org.bukkit.configuration.file.FileConfiguration;
|
||||||
|
|
||||||
|
public class MaxSprinklersPerChunk {
|
||||||
|
public static boolean maxSprinklersPerChunk(Location location){
|
||||||
|
FileConfiguration config = CustomCrops.instance.getConfig();
|
||||||
|
if(!config.getBoolean("config.enable-limit")){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
int maxY = config.getInt("config.height.max");
|
||||||
|
int minY = config.getInt("config.height.min");
|
||||||
|
int maxAmount = config.getInt("config.max-sprinklers");
|
||||||
|
|
||||||
|
int n = 1;
|
||||||
|
|
||||||
|
Location chunkLocation = new Location(location.getWorld(),location.getChunk().getX()*16,minY,location.getChunk().getZ()*16);
|
||||||
|
World world = location.getWorld();
|
||||||
|
|
||||||
|
Label_out:
|
||||||
|
for (int i = 0; i < 16; ++i) {
|
||||||
|
for (int j = 0; j < 16; ++j) {
|
||||||
|
final Location square = chunkLocation.clone().add((double)i, 0.0, (double)j);
|
||||||
|
for (int k = minY; k <= maxY; ++k) {
|
||||||
|
square.add(0.0, 1.0, 0.0);
|
||||||
|
if(IAFurniture.getFromLocation(square.clone().add(0.5,0.5,0.5), world)){
|
||||||
|
if (n++ > maxAmount) {
|
||||||
|
break Label_out;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return n > maxAmount;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,113 @@
|
|||||||
|
package net.momirealms.customcrops.DataManager;
|
||||||
|
|
||||||
|
import net.momirealms.customcrops.CustomCrops;
|
||||||
|
import net.momirealms.customcrops.IAFurniture;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.Location;
|
||||||
|
import org.bukkit.World;
|
||||||
|
import org.bukkit.configuration.file.FileConfiguration;
|
||||||
|
import org.bukkit.configuration.file.YamlConfiguration;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
public class SprinklerManager {
|
||||||
|
|
||||||
|
public static HashMap<Location, String> instances;
|
||||||
|
|
||||||
|
public SprinklerManager(FileConfiguration data) {
|
||||||
|
FileConfiguration config = CustomCrops.instance.getConfig();
|
||||||
|
File file = new File(CustomCrops.instance.getDataFolder(), "sprinkler-data.yml");
|
||||||
|
data = YamlConfiguration.loadConfiguration(file);
|
||||||
|
try {
|
||||||
|
for (String world : config.getStringList("config.whitelist-worlds")) {
|
||||||
|
SprinklerManager.instances = new HashMap<Location, String>();
|
||||||
|
if(data.getConfigurationSection(world) != null){
|
||||||
|
for (String coordinate : data.getConfigurationSection(world).getKeys(false)) {
|
||||||
|
Location tempLocation = new Location(Bukkit.getWorld(world), Integer.parseInt(coordinate.split(",")[0]), Integer.parseInt(coordinate.split(",")[1]), Integer.parseInt(coordinate.split(",")[2]));
|
||||||
|
String type = data.getString(world + "." + coordinate);
|
||||||
|
SprinklerManager.instances.put(tempLocation, type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception e) {
|
||||||
|
SprinklerManager.instances = new HashMap<Location, String>();
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
saveData();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<Location> getSprinklers(World world){
|
||||||
|
FileConfiguration config = CustomCrops.instance.getConfig();
|
||||||
|
File file = new File(CustomCrops.instance.getDataFolder(), "sprinkler-data.yml");
|
||||||
|
FileConfiguration data;
|
||||||
|
data = YamlConfiguration.loadConfiguration(file);
|
||||||
|
List<Location> locations = new ArrayList<Location>();
|
||||||
|
if (config.getStringList("config.whitelist-worlds").contains(world.getName())){
|
||||||
|
if(data.contains(world.getName())){
|
||||||
|
data.getConfigurationSection(world.getName()).getKeys(false).forEach(key ->{
|
||||||
|
String[] string_list = key.split(",");
|
||||||
|
if (config.getBoolean("config.only-grow-in-loaded-chunks")){
|
||||||
|
if (world.isChunkLoaded(Integer.parseInt(string_list[0])/16, Integer.parseInt(string_list[2])/16)){
|
||||||
|
locations.add(new Location(world, Double.parseDouble(string_list[0]),Double.parseDouble(string_list[1]),Double.parseDouble(string_list[2])));
|
||||||
|
}
|
||||||
|
}else {
|
||||||
|
locations.add(new Location(world, Double.parseDouble(string_list[0]),Double.parseDouble(string_list[1]),Double.parseDouble(string_list[2])));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return locations;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void saveData(){
|
||||||
|
File file = new File(CustomCrops.instance.getDataFolder(), "sprinkler-data.yml");
|
||||||
|
FileConfiguration data;
|
||||||
|
data = YamlConfiguration.loadConfiguration(file);
|
||||||
|
if (SprinklerManager.instances != null) {
|
||||||
|
Set<Map.Entry<Location, String>> en = instances.entrySet();
|
||||||
|
for(Map.Entry<Location, String> entry : en){
|
||||||
|
data.set(entry.getKey().getWorld().getName() + "." + entry.getKey().getBlockX() + "," + entry.getKey().getBlockY()+ ","+entry.getKey().getBlockZ(), entry.getValue());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
SprinklerManager.instances = new HashMap<Location, String>();
|
||||||
|
Bukkit.getConsoleSender().sendMessage("错误");
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
data.save(file);
|
||||||
|
}
|
||||||
|
catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public static void putInstance(Location location, String type) {
|
||||||
|
SprinklerManager.instances.put(location, type);
|
||||||
|
}
|
||||||
|
public static void cleanCache() {
|
||||||
|
File file = new File(CustomCrops.instance.getDataFolder(), "sprinkler-data.yml");
|
||||||
|
FileConfiguration data;
|
||||||
|
data = YamlConfiguration.loadConfiguration(file);
|
||||||
|
Bukkit.getScheduler().callSyncMethod(CustomCrops.instance,()->{
|
||||||
|
Set<Location> key = new HashSet(instances.keySet());
|
||||||
|
try{
|
||||||
|
for(Location u_key : key) {
|
||||||
|
if (!IAFurniture.getFromLocation(u_key.clone().add(0.5,0.5,0.5), u_key.getWorld())){
|
||||||
|
SprinklerManager.instances.remove(u_key);
|
||||||
|
data.set(u_key.getWorld().getName()+"."+u_key.getBlockX()+","+u_key.getBlockY()+","+u_key.getBlockZ(), null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}catch (ConcurrentModificationException e){
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
try{
|
||||||
|
data.save(file);
|
||||||
|
}catch (IOException e){
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
30
src/main/java/net/momirealms/customcrops/IAFurniture.java
Normal file
30
src/main/java/net/momirealms/customcrops/IAFurniture.java
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
package net.momirealms.customcrops;
|
||||||
|
|
||||||
|
import dev.lone.itemsadder.api.CustomFurniture;
|
||||||
|
import org.bukkit.Location;
|
||||||
|
import org.bukkit.World;
|
||||||
|
import org.bukkit.configuration.file.FileConfiguration;
|
||||||
|
import org.bukkit.entity.ArmorStand;
|
||||||
|
import org.bukkit.entity.Entity;
|
||||||
|
|
||||||
|
public class IAFurniture {
|
||||||
|
|
||||||
|
static FileConfiguration config = CustomCrops.instance.getConfig();
|
||||||
|
|
||||||
|
public static void placeFurniture(String name, Location location){
|
||||||
|
CustomFurniture.spawn(name,location.getWorld().getBlockAt(location));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean getFromLocation(Location location, World world){
|
||||||
|
for(Entity entity : world.getNearbyEntities(location,0,0,0)){
|
||||||
|
if(entity instanceof ArmorStand){
|
||||||
|
if(CustomFurniture.byAlreadySpawned((ArmorStand) entity) != null){
|
||||||
|
if(CustomFurniture.byAlreadySpawned((ArmorStand) entity).getNamespacedID().equalsIgnoreCase(config.getString("config.sprinkler-1")) || CustomFurniture.byAlreadySpawned((ArmorStand) entity).getNamespacedID().equalsIgnoreCase(config.getString("config.sprinkler-2"))){
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
26
src/main/java/net/momirealms/customcrops/MessageManager.java
Normal file
26
src/main/java/net/momirealms/customcrops/MessageManager.java
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
package net.momirealms.customcrops;
|
||||||
|
|
||||||
|
import net.kyori.adventure.audience.Audience;
|
||||||
|
import net.kyori.adventure.platform.bukkit.BukkitAudiences;
|
||||||
|
import net.kyori.adventure.text.Component;
|
||||||
|
import net.kyori.adventure.text.minimessage.MiniMessage;
|
||||||
|
import org.bukkit.command.CommandSender;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
|
public class MessageManager{
|
||||||
|
|
||||||
|
public static void consoleMessage(String s, CommandSender sender) {
|
||||||
|
BukkitAudiences bukkitAudiences = BukkitAudiences.create(CustomCrops.instance);
|
||||||
|
Audience player = bukkitAudiences.sender(sender);
|
||||||
|
MiniMessage mm = MiniMessage.miniMessage();
|
||||||
|
Component parsed = mm.deserialize(s);
|
||||||
|
player.sendMessage(parsed);
|
||||||
|
}
|
||||||
|
public static void playerMessage(String s, Player player){
|
||||||
|
BukkitAudiences bukkitAudiences = BukkitAudiences.create(CustomCrops.instance);
|
||||||
|
Audience p = bukkitAudiences.player(player);
|
||||||
|
MiniMessage mm = MiniMessage.miniMessage();
|
||||||
|
Component parsed = mm.deserialize(s);
|
||||||
|
p.sendMessage(parsed);
|
||||||
|
}
|
||||||
|
}
|
||||||
47
src/main/java/net/momirealms/customcrops/Placeholders.java
Normal file
47
src/main/java/net/momirealms/customcrops/Placeholders.java
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
package net.momirealms.customcrops;
|
||||||
|
|
||||||
|
import me.clip.placeholderapi.expansion.PlaceholderExpansion;
|
||||||
|
import org.bukkit.OfflinePlayer;
|
||||||
|
import org.bukkit.configuration.file.FileConfiguration;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
public class Placeholders extends PlaceholderExpansion{
|
||||||
|
|
||||||
|
|
||||||
|
private CustomCrops plugin;
|
||||||
|
|
||||||
|
public Placeholders(CustomCrops customCrops) {
|
||||||
|
this.plugin = plugin;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull String getIdentifier() {
|
||||||
|
return "customcrops";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull String getAuthor() {
|
||||||
|
return "XiaoMoMi";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull String getVersion() {
|
||||||
|
return "1.0";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String onRequest(OfflinePlayer player, String params) {
|
||||||
|
|
||||||
|
FileConfiguration config = CustomCrops.instance.getConfig();
|
||||||
|
|
||||||
|
if(params.equalsIgnoreCase("season")){
|
||||||
|
return config.getString("current-season")
|
||||||
|
.replace("spring", config.getString("messages.spring"))
|
||||||
|
.replace("summer", config.getString("messages.summer"))
|
||||||
|
.replace("autumn", config.getString("messages.autumn"))
|
||||||
|
.replace("winter", config.getString("messages.winter"));
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
package net.momirealms.customcrops.listener;
|
||||||
|
|
||||||
|
import dev.lone.itemsadder.api.CustomBlock;
|
||||||
|
import dev.lone.itemsadder.api.Events.CustomBlockBreakEvent;
|
||||||
|
import net.momirealms.customcrops.CustomCrops;
|
||||||
|
import org.bukkit.Location;
|
||||||
|
import org.bukkit.Material;
|
||||||
|
import org.bukkit.configuration.file.FileConfiguration;
|
||||||
|
import org.bukkit.enchantments.Enchantment;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.event.EventHandler;
|
||||||
|
import org.bukkit.event.Listener;
|
||||||
|
|
||||||
|
public class BreakCustomBlock implements Listener {
|
||||||
|
|
||||||
|
FileConfiguration config = CustomCrops.instance.getConfig();
|
||||||
|
|
||||||
|
@EventHandler
|
||||||
|
public void breakCustomBlock(CustomBlockBreakEvent event){
|
||||||
|
Player player =event.getPlayer();
|
||||||
|
Location location = event.getBlock().getLocation();
|
||||||
|
if(event.getNamespacedID().contains("stage")){
|
||||||
|
if(player.getInventory().getItemInMainHand().containsEnchantment(Enchantment.SILK_TOUCH) || player.getInventory().getItemInMainHand().getType() == Material.SHEARS){
|
||||||
|
event.setCancelled(true);
|
||||||
|
CustomBlock.place(event.getNamespacedID(), location);
|
||||||
|
CustomBlock.byAlreadyPlaced(location.getWorld().getBlockAt(location)).getLoot().forEach(itemStack -> {
|
||||||
|
location.getWorld().dropItem(location.clone().add(0.5,0.2,0.5), itemStack);
|
||||||
|
CustomBlock.remove(location);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}else if(event.getNamespacedID().equalsIgnoreCase(config.getString("config.watered-pot")) || event.getNamespacedID().equalsIgnoreCase(config.getString("config.pot"))){
|
||||||
|
if(CustomBlock.byAlreadyPlaced(location.getWorld().getBlockAt(location.clone().add(0,1,0))) != null){
|
||||||
|
if(CustomBlock.byAlreadyPlaced(location.getWorld().getBlockAt(location.clone().add(0,1,0))).getNamespacedID().contains("stage")){
|
||||||
|
CustomBlock.byAlreadyPlaced(location.getWorld().getBlockAt(location.clone().add(0,1,0))).getLoot().forEach(itemStack -> {
|
||||||
|
location.getWorld().dropItem(location.clone().add(0.5,1.2,0.5), itemStack);
|
||||||
|
});
|
||||||
|
CustomBlock.remove(location.clone().add(0,1,0));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
package net.momirealms.customcrops.listener;
|
||||||
|
|
||||||
|
import dev.lone.itemsadder.api.CustomStack;
|
||||||
|
import net.momirealms.customcrops.CustomCrops;
|
||||||
|
import org.bukkit.configuration.file.FileConfiguration;
|
||||||
|
import org.bukkit.entity.Entity;
|
||||||
|
import org.bukkit.entity.Item;
|
||||||
|
import org.bukkit.event.EventHandler;
|
||||||
|
import org.bukkit.event.Listener;
|
||||||
|
import org.bukkit.event.entity.EntitySpawnEvent;
|
||||||
|
|
||||||
|
public class BreakFurniture implements Listener {
|
||||||
|
|
||||||
|
FileConfiguration config = CustomCrops.instance.getConfig();
|
||||||
|
|
||||||
|
@EventHandler
|
||||||
|
public void breakFurniture(EntitySpawnEvent event){
|
||||||
|
Entity entity = event.getEntity();
|
||||||
|
if(!(entity instanceof Item)){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(CustomStack.byItemStack(((Item) entity).getItemStack()) != null){
|
||||||
|
if(CustomStack.byItemStack(((Item) entity).getItemStack()).getNamespacedID().equalsIgnoreCase(config.getString("config.sprinkler-1"))){
|
||||||
|
entity.remove();
|
||||||
|
entity.getWorld().dropItem(entity.getLocation() ,CustomStack.getInstance(config.getString("config.sprinkler-1-item")).getItemStack());
|
||||||
|
}else if(CustomStack.byItemStack(((Item) entity).getItemStack()).getNamespacedID().equalsIgnoreCase(config.getString("config.sprinkler-2"))){
|
||||||
|
entity.remove();
|
||||||
|
entity.getWorld().dropItem(entity.getLocation() ,CustomStack.getInstance(config.getString("config.sprinkler-2-item")).getItemStack());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,101 @@
|
|||||||
|
package net.momirealms.customcrops.listener;
|
||||||
|
|
||||||
|
import dev.lone.itemsadder.api.CustomStack;
|
||||||
|
import net.momirealms.customcrops.CustomCrops;
|
||||||
|
import net.momirealms.customcrops.DataManager.MaxSprinklersPerChunk;
|
||||||
|
import net.momirealms.customcrops.DataManager.SprinklerManager;
|
||||||
|
import net.momirealms.customcrops.IAFurniture;
|
||||||
|
import net.momirealms.customcrops.MessageManager;
|
||||||
|
import org.bukkit.GameMode;
|
||||||
|
import org.bukkit.Location;
|
||||||
|
import org.bukkit.Material;
|
||||||
|
import org.bukkit.Sound;
|
||||||
|
import org.bukkit.block.Block;
|
||||||
|
import org.bukkit.block.BlockFace;
|
||||||
|
import org.bukkit.configuration.file.FileConfiguration;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.event.EventHandler;
|
||||||
|
import org.bukkit.event.Listener;
|
||||||
|
import org.bukkit.event.block.Action;
|
||||||
|
import org.bukkit.event.player.PlayerInteractEvent;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class RightClickBlock implements Listener {
|
||||||
|
|
||||||
|
FileConfiguration config = CustomCrops.instance.getConfig();
|
||||||
|
|
||||||
|
@EventHandler
|
||||||
|
public void rightClickBlock(PlayerInteractEvent event){
|
||||||
|
if(event.getAction() != Action.RIGHT_CLICK_BLOCK || !event.hasItem()){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Player player = event.getPlayer();
|
||||||
|
ItemStack itemStack = event.getItem();
|
||||||
|
|
||||||
|
if(itemStack.getType() == Material.WOODEN_SWORD){
|
||||||
|
List<Block> lineOfSight = player.getLineOfSight(null, 3);
|
||||||
|
boolean hasWater = false;
|
||||||
|
for (final Block block : lineOfSight) {
|
||||||
|
if (block.getType() == Material.WATER) {
|
||||||
|
hasWater = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(hasWater){
|
||||||
|
addWater(itemStack,player);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(event.getBlockFace() != BlockFace.UP) return;
|
||||||
|
|
||||||
|
if(CustomStack.byItemStack(event.getItem()) == null){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(event.getClickedBlock().getY() > config.getInt("config.height.max") || event.getClickedBlock().getY() < config.getInt("config.height.min")){
|
||||||
|
MessageManager.playerMessage(config.getString("messages.prefix") + config.getString("messages.not-a-good-place"),player);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Location location = event.getClickedBlock().getLocation();
|
||||||
|
|
||||||
|
if(CustomStack.byItemStack(event.getItem()).getNamespacedID().equalsIgnoreCase(config.getString("config.sprinkler-1-item"))){
|
||||||
|
if(MaxSprinklersPerChunk.maxSprinklersPerChunk(location)){
|
||||||
|
MessageManager.playerMessage(config.getString("messages.prefix")+config.getString("messages.reach-limit-sprinkler").replace("{Max}", config.getString("config.max-sprinklers")),player);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(player.getGameMode() != GameMode.CREATIVE){
|
||||||
|
itemStack.setAmount(itemStack.getAmount() -1);
|
||||||
|
}
|
||||||
|
IAFurniture.placeFurniture(config.getString("config.sprinkler-1"),location.clone().add(0,1,0));
|
||||||
|
SprinklerManager.putInstance(location.clone().add(0,1,0),"s1");
|
||||||
|
}else if(CustomStack.byItemStack(event.getItem()).getNamespacedID().equalsIgnoreCase(config.getString("config.sprinkler-2-item"))){
|
||||||
|
if(MaxSprinklersPerChunk.maxSprinklersPerChunk(location)){
|
||||||
|
MessageManager.playerMessage(config.getString("messages.prefix")+config.getString("messages.reach-limit-sprinkler").replace("{Max}", config.getString("config.max-sprinklers")),player);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(player.getGameMode() != GameMode.CREATIVE){
|
||||||
|
itemStack.setAmount(itemStack.getAmount() -1);
|
||||||
|
}
|
||||||
|
IAFurniture.placeFurniture(config.getString("config.sprinkler-2"),location.clone().add(0,1,0));
|
||||||
|
SprinklerManager.putInstance(location.clone().add(0,1,0),"s2");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private void addWater(ItemStack itemStack, Player player){
|
||||||
|
if(CustomStack.byItemStack(itemStack)!= null){
|
||||||
|
CustomStack customStack = CustomStack.byItemStack(itemStack);
|
||||||
|
if(customStack.getNamespacedID().equalsIgnoreCase(config.getString("config.watering-can-1")) ||
|
||||||
|
customStack.getNamespacedID().equalsIgnoreCase(config.getString("config.watering-can-2")) ||
|
||||||
|
customStack.getNamespacedID().equalsIgnoreCase(config.getString("config.watering-can-3")))
|
||||||
|
{
|
||||||
|
if(customStack.getMaxDurability() == customStack.getDurability()){
|
||||||
|
MessageManager.playerMessage(config.getString("messages.prefix") + config.getString("messages.can-full"),player);
|
||||||
|
}else {
|
||||||
|
customStack.setDurability(customStack.getDurability() + 1);
|
||||||
|
player.playSound(player, Sound.ITEM_BUCKET_FILL,1,1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,232 @@
|
|||||||
|
package net.momirealms.customcrops.listener;
|
||||||
|
|
||||||
|
import dev.lone.itemsadder.api.CustomBlock;
|
||||||
|
import dev.lone.itemsadder.api.CustomStack;
|
||||||
|
import dev.lone.itemsadder.api.Events.CustomBlockInteractEvent;
|
||||||
|
import net.momirealms.customcrops.CustomCrops;
|
||||||
|
import net.momirealms.customcrops.DataManager.CropManager;
|
||||||
|
import net.momirealms.customcrops.DataManager.MaxCropsPerChunk;
|
||||||
|
import net.momirealms.customcrops.MessageManager;
|
||||||
|
import org.bukkit.*;
|
||||||
|
import org.bukkit.block.Block;
|
||||||
|
import org.bukkit.block.BlockFace;
|
||||||
|
import org.bukkit.configuration.file.FileConfiguration;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.event.EventHandler;
|
||||||
|
import org.bukkit.event.Listener;
|
||||||
|
import org.bukkit.event.block.Action;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
public class RightClickCustomBlock implements Listener {
|
||||||
|
|
||||||
|
FileConfiguration config = CustomCrops.instance.getConfig();
|
||||||
|
|
||||||
|
@EventHandler
|
||||||
|
public void rightClickCustomCrop(CustomBlockInteractEvent event){
|
||||||
|
if (event.getAction() != Action.RIGHT_CLICK_BLOCK) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Block clickedBlock = event.getBlockClicked();
|
||||||
|
Location clickedBlockLocation = clickedBlock.getLocation();
|
||||||
|
CustomBlock clickedCustomBlock = CustomBlock.byAlreadyPlaced(clickedBlock);
|
||||||
|
if (event.getItem() == null) {
|
||||||
|
if (clickedCustomBlock.getNamespacedID().contains("stage")){
|
||||||
|
if(clickedCustomBlock.getNamespacedID().equalsIgnoreCase(config.getString("config.dead-crop"))) return;
|
||||||
|
String namespace = clickedCustomBlock.getNamespacedID().split(":")[0];
|
||||||
|
String[] cropNameList = clickedCustomBlock.getNamespacedID().split(":")[1].split("_");
|
||||||
|
int nextStage = Integer.parseInt(cropNameList[2]) + 1;
|
||||||
|
if (CustomBlock.getInstance(namespace + ":" + cropNameList[0] + "_" +cropNameList[1] +"_" + nextStage) == null) {
|
||||||
|
clickedCustomBlock.getLoot().forEach(itemStack -> {
|
||||||
|
clickedBlockLocation.getWorld().dropItem(clickedBlockLocation.clone().add(0.5,0.2,0.5),itemStack);
|
||||||
|
});
|
||||||
|
CustomBlock.remove(clickedBlockLocation);
|
||||||
|
if(config.getConfigurationSection("crops." + cropNameList[0]).getKeys(false).contains("return")){
|
||||||
|
CustomBlock.place(config.getString("crops." + cropNameList[0] + ".return"), clickedBlockLocation);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Player player = event.getPlayer();
|
||||||
|
World world = player.getWorld();
|
||||||
|
ItemStack mainHandItem = player.getInventory().getItemInMainHand();
|
||||||
|
|
||||||
|
|
||||||
|
if (CustomBlock.byAlreadyPlaced(world.getBlockAt(clickedBlockLocation.clone().subtract(0,1,0))) != null && clickedBlock.getType() == Material.TRIPWIRE) {
|
||||||
|
if(CustomBlock.byAlreadyPlaced(world.getBlockAt(clickedBlockLocation.clone().subtract(0,1,0))).getNamespacedID().equalsIgnoreCase(config.getString("config.pot"))) {
|
||||||
|
if (mainHandItem.getType() == Material.WATER_BUCKET) {
|
||||||
|
if(player.getGameMode() != GameMode.CREATIVE){
|
||||||
|
mainHandItem.setAmount(mainHandItem.getAmount() - 1);
|
||||||
|
player.getInventory().addItem(new ItemStack(Material.BUCKET));
|
||||||
|
}
|
||||||
|
CustomBlock.remove(clickedBlockLocation.clone().subtract(0, 1, 0));
|
||||||
|
CustomBlock.place(config.getString("config.watered-pot"), clickedBlockLocation.clone().subtract(0, 1, 0));
|
||||||
|
}else if(mainHandItem.getType() == Material.WOODEN_SWORD){
|
||||||
|
waterPot(mainHandItem,player,clickedBlockLocation.clone().subtract(0,1,0));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(CustomBlock.byAlreadyPlaced(world.getBlockAt(clickedBlockLocation.clone().subtract(0,1,0))).getNamespacedID().equalsIgnoreCase(config.getString("config.watered-pot"))){
|
||||||
|
if (mainHandItem.getType() == Material.BONE_MEAL){
|
||||||
|
if (clickedCustomBlock.getNamespacedID().contains("stage")){
|
||||||
|
String[] cropNameList = clickedCustomBlock.getNamespacedID().split("_");
|
||||||
|
int nextStage = Integer.parseInt(cropNameList[2]) + 1;
|
||||||
|
if (CustomBlock.getInstance(cropNameList[0] + "_" +cropNameList[1] +"_" + nextStage) != null){
|
||||||
|
if(player.getGameMode() != GameMode.CREATIVE){
|
||||||
|
mainHandItem.setAmount(mainHandItem.getAmount() - 1);
|
||||||
|
}
|
||||||
|
if (Math.random() < config.getDouble("config.bone-meal-chance")){
|
||||||
|
CustomBlock.remove(clickedBlockLocation);
|
||||||
|
CustomBlock.place(cropNameList[0] + "_" +cropNameList[1] +"_" + nextStage,clickedBlockLocation);
|
||||||
|
Particle particleSuccess = Particle.valueOf(config.getString("config.particle.success"));
|
||||||
|
world.spawnParticle(particleSuccess, clickedBlockLocation.clone().add(0.5, 0.1,0.5), 1 ,0,0,0,0);
|
||||||
|
if(config.getBoolean("config.bone-meal-consume-water")){
|
||||||
|
CustomBlock.remove(clickedBlockLocation.clone().subtract(0,1,0));
|
||||||
|
CustomBlock.place(config.getString("config.pot"), clickedBlockLocation.clone().subtract(0,1,0));
|
||||||
|
}
|
||||||
|
}else {
|
||||||
|
Particle particleFailure = Particle.valueOf(config.getString("config.particle.failure"));
|
||||||
|
world.spawnParticle(particleFailure, clickedBlockLocation.clone().add(0.5, 0.1,0.5), 1 ,0,0,0,0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (CustomBlock.byAlreadyPlaced(world.getBlockAt(clickedBlockLocation)) != null && event.getBlockFace() == BlockFace.UP){
|
||||||
|
if (CustomBlock.byAlreadyPlaced(world.getBlockAt(clickedBlockLocation)).getNamespacedID().equalsIgnoreCase(config.getString("config.pot"))){
|
||||||
|
if (mainHandItem.getType() == Material.WATER_BUCKET){
|
||||||
|
if(player.getGameMode() != GameMode.CREATIVE){
|
||||||
|
mainHandItem.setAmount(mainHandItem.getAmount() - 1);
|
||||||
|
player.getInventory().addItem(new ItemStack(Material.BUCKET));
|
||||||
|
}
|
||||||
|
CustomBlock.remove(clickedBlockLocation);
|
||||||
|
CustomBlock.place(config.getString("config.watered-pot"),clickedBlockLocation);
|
||||||
|
} else if (mainHandItem.getType() == Material.WOODEN_SWORD){
|
||||||
|
waterPot(mainHandItem, player,clickedBlockLocation);
|
||||||
|
} else {
|
||||||
|
tryPlantSeed(clickedBlockLocation, mainHandItem, player);
|
||||||
|
}
|
||||||
|
}else if(CustomBlock.byAlreadyPlaced(world.getBlockAt(clickedBlockLocation)).getNamespacedID().equalsIgnoreCase(config.getString("config.watered-pot"))){
|
||||||
|
|
||||||
|
tryPlantSeed(clickedBlockLocation, mainHandItem, player);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private void tryPlantSeed(Location clickedBlockLocation, ItemStack mainHandItem, Player player) {
|
||||||
|
if(CustomStack.byItemStack(mainHandItem) == null) return;
|
||||||
|
if (CustomStack.byItemStack(mainHandItem).getNamespacedID().toLowerCase().endsWith("_seeds")){
|
||||||
|
String namespaced_id = CustomStack.byItemStack(mainHandItem).getNamespacedID().toLowerCase();
|
||||||
|
String[] crop = CustomStack.byItemStack(mainHandItem).getNamespacedID().toLowerCase().replace("_seeds","").split(":");
|
||||||
|
if (clickedBlockLocation.getY() < config.getInt("config.height.min") || clickedBlockLocation.getY() > config.getInt("config.height.max")){
|
||||||
|
MessageManager.playerMessage(config.getString("messages.prefix") + config.getString("messages.not-a-good-place"),player);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Label_out:
|
||||||
|
if(config.getBoolean("enable-season")){
|
||||||
|
if(config.getBoolean("config.enable-greenhouse")){
|
||||||
|
for(int i = 1; i <= config.getInt("config.greenhouse-range"); i++){
|
||||||
|
Location tempLocation = clickedBlockLocation.clone().add(0,i+1,0);
|
||||||
|
if (CustomBlock.byAlreadyPlaced(clickedBlockLocation.getWorld().getBlockAt(tempLocation)) != null){
|
||||||
|
if(CustomBlock.byAlreadyPlaced(clickedBlockLocation.getWorld().getBlockAt(tempLocation)).getNamespacedID().equalsIgnoreCase(config.getString("config.greenhouse-glass"))){
|
||||||
|
break Label_out;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
String[] seasons = config.getString("crops."+crop[1]+".season").split(",");
|
||||||
|
boolean wrongSeason = true;
|
||||||
|
for(String season : seasons){
|
||||||
|
if(Objects.equals(season, config.getString("current-season"))){
|
||||||
|
wrongSeason = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(wrongSeason){
|
||||||
|
MessageManager.playerMessage(config.getString("messages.prefix")+config.getString("messages.wrong-season"),player);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(!config.contains("crops."+crop[1])){
|
||||||
|
MessageManager.playerMessage(config.getString("messages.prefix")+config.getString("messages.no-such-seed"),player);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(MaxCropsPerChunk.maxCropsPerChunk(clickedBlockLocation)){
|
||||||
|
MessageManager.playerMessage(config.getString("messages.prefix")+config.getString("messages.reach-limit-crop").replace("{Max}", config.getString("config.max-crops")),player);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(config.getBoolean("enable-season")){
|
||||||
|
CropManager.putInstance(clickedBlockLocation.clone().add(0,1,0), config.getString("crops."+crop[1]+".season"));
|
||||||
|
}else{
|
||||||
|
CropManager.putInstance(clickedBlockLocation.clone().add(0,1,0), "all");
|
||||||
|
}
|
||||||
|
if(player.getGameMode() != GameMode.CREATIVE){
|
||||||
|
mainHandItem.setAmount(mainHandItem.getAmount() -1);
|
||||||
|
}
|
||||||
|
CustomBlock.place(namespaced_id.replace("_seeds","_stage_1"),clickedBlockLocation.clone().add(0,1,0));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private void waterPot(ItemStack itemStack, Player player, Location location){
|
||||||
|
|
||||||
|
if(CustomStack.byItemStack(itemStack) == null) return;
|
||||||
|
|
||||||
|
CustomStack customStack = CustomStack.byItemStack(itemStack);
|
||||||
|
|
||||||
|
if(customStack.getDurability() > 0){
|
||||||
|
CustomStack.byItemStack(itemStack).setDurability(CustomStack.byItemStack(itemStack).getDurability() - 1);
|
||||||
|
}else return;
|
||||||
|
Bukkit.getScheduler().runTaskAsynchronously(CustomCrops.instance,()-> {
|
||||||
|
|
||||||
|
int x;
|
||||||
|
int z;
|
||||||
|
|
||||||
|
if (customStack.getNamespacedID().equalsIgnoreCase(config.getString("config.watering-can-1"))) {
|
||||||
|
x = 0;
|
||||||
|
z = 0;
|
||||||
|
} else if (customStack.getNamespacedID().equalsIgnoreCase(config.getString("config.watering-can-2"))) {
|
||||||
|
x = 2;
|
||||||
|
z = 2;
|
||||||
|
} else if (customStack.getNamespacedID().equalsIgnoreCase(config.getString("config.watering-can-3"))) {
|
||||||
|
x = 4;
|
||||||
|
z = 4;
|
||||||
|
} else return;
|
||||||
|
player.playSound(player,Sound.BLOCK_WATER_AMBIENT,1,1);
|
||||||
|
float yaw = player.getLocation().getYaw();
|
||||||
|
if (yaw <= 45 && yaw >= -135) {
|
||||||
|
if (yaw > -45) {
|
||||||
|
x = 0;
|
||||||
|
} else {
|
||||||
|
z = 0;
|
||||||
|
}
|
||||||
|
for (int i = 0; i <= x; i++) {
|
||||||
|
for (int j = 0; j <= z; j++) {
|
||||||
|
Location tempLoc = location.clone().add(i, 0, j);
|
||||||
|
canWaterPot(tempLoc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (yaw < 135 && yaw > 45) {
|
||||||
|
z= 0;
|
||||||
|
} else {
|
||||||
|
x= 0;
|
||||||
|
}
|
||||||
|
for (int i = 0; i <= x; i++) {
|
||||||
|
for (int j = 0; j <= z; j++) {
|
||||||
|
Location tempLoc = location.clone().subtract(i, 0, j);
|
||||||
|
canWaterPot(tempLoc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
private void canWaterPot(Location location){
|
||||||
|
if(CustomBlock.byAlreadyPlaced(location.getWorld().getBlockAt(location)) != null){
|
||||||
|
if(CustomBlock.byAlreadyPlaced(location.getWorld().getBlockAt(location)).getNamespacedID().equalsIgnoreCase(config.getString("config.pot"))){
|
||||||
|
Bukkit.getScheduler().callSyncMethod(CustomCrops.instance,()->{
|
||||||
|
CustomBlock.remove(location);
|
||||||
|
CustomBlock.place(config.getString("config.watered-pot"),location);
|
||||||
|
return null;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
95
src/main/resources/config-english.yml
Normal file
95
src/main/resources/config-english.yml
Normal file
@@ -0,0 +1,95 @@
|
|||||||
|
enable-season: true
|
||||||
|
# Current season
|
||||||
|
# Use command "/customcrops setseason" to change season
|
||||||
|
# You can experience season feature by using "CMI schedule" or other Season plugin
|
||||||
|
current-season: spring
|
||||||
|
|
||||||
|
config:
|
||||||
|
# The pot that crops can be planted in
|
||||||
|
# format: namespace:item_id
|
||||||
|
pot: customcrops:pot
|
||||||
|
# Crops can only grow on watered pot
|
||||||
|
watered-pot: customcrops:watered_pot
|
||||||
|
|
||||||
|
# Watering Can
|
||||||
|
# 1x1 range
|
||||||
|
watering-can-1: customcrops:watering_can_1
|
||||||
|
# 1x3 range
|
||||||
|
watering-can-2: customcrops:watering_can_2
|
||||||
|
# 1x5 range
|
||||||
|
watering-can-3: customcrops:watering_can_3
|
||||||
|
|
||||||
|
# enable greenhouse feature
|
||||||
|
# crops can be planted under greenhouse glass
|
||||||
|
enable-greenhouse: true
|
||||||
|
# effective range
|
||||||
|
greenhouse-range: 7
|
||||||
|
greenhouse-glass: customcrops:greenhouse_glass
|
||||||
|
|
||||||
|
# sprinkler furniture in ItemsAdder
|
||||||
|
# 3x3 range
|
||||||
|
sprinkler-1: customcrops:sprinkler_1
|
||||||
|
# sprinkler item in ItemsAdder
|
||||||
|
sprinkler-1-item: customcrops:sprinkler_1_item
|
||||||
|
|
||||||
|
# 5x5 range
|
||||||
|
sprinkler-2: customcrops:sprinkler_2
|
||||||
|
sprinkler-2-item: customcrops:sprinkler_2_item
|
||||||
|
|
||||||
|
# dead crops
|
||||||
|
dead-crop: customcrops:crop_stage_death
|
||||||
|
# The chance that crops grow every morning
|
||||||
|
grow-success-chance: 0.8
|
||||||
|
|
||||||
|
# The chance that using bone meal to skip one stage
|
||||||
|
bone-meal-chance: 0.5
|
||||||
|
# Will using bone meal consume water
|
||||||
|
bone-meal-consume-water: true
|
||||||
|
# Particle Effects
|
||||||
|
particle:
|
||||||
|
# Use bone meal
|
||||||
|
success: HEART
|
||||||
|
failure: VILLAGER_ANGRY
|
||||||
|
# The height where crops can grow
|
||||||
|
height:
|
||||||
|
min: 50
|
||||||
|
max: 100
|
||||||
|
# should we limit the max number of crops and spinklers in chunks?
|
||||||
|
# Maybe too many crops would cause lagggggggg
|
||||||
|
enable-limit: true
|
||||||
|
max-crops: 32
|
||||||
|
max-sprinklers: 4
|
||||||
|
# whitelist worlds where crops would grow
|
||||||
|
whitelist-worlds:
|
||||||
|
- world
|
||||||
|
# should we only alow crops in loaded chunks to grow?
|
||||||
|
# This is good for server performance
|
||||||
|
only-grow-in-loaded-chunks: true
|
||||||
|
|
||||||
|
messages:
|
||||||
|
prefix: '<gradient:#ccfbff:#ef96c5>[CustomCrops] </gradient>'
|
||||||
|
not-a-good-place: 'That place is too high/low. Just try another place!'
|
||||||
|
reload: 'Reloaded'
|
||||||
|
force-save: 'Successfully save cache data!'
|
||||||
|
no-such-seed: 'This seed is not configured in config.yml'
|
||||||
|
wrong-season: 'You can not plant this crop in this season'
|
||||||
|
season-set: 'Successfully change season to {Season}'
|
||||||
|
season-disabled: 'Season is not enabled in this server'
|
||||||
|
clean-cache: 'Successfully clean removed crops and sprinkler'
|
||||||
|
reach-limit-crop: 'Too many crops. The limit is {Max} per chunk!'
|
||||||
|
reach-limit-sprinkler: 'Too many sprinklers. The limit is {Max} per chunk!'
|
||||||
|
backup: 'Back up Successfully'
|
||||||
|
spring: 'spring'
|
||||||
|
summer: 'summer'
|
||||||
|
autumn: 'autumn'
|
||||||
|
winter: 'winter'
|
||||||
|
can-full: 'The watering can is already full!'
|
||||||
|
|
||||||
|
# Crops
|
||||||
|
crops:
|
||||||
|
tomato:
|
||||||
|
# Please name the crops with "_seeds" and "_stage_X"
|
||||||
|
# Otherwise they would not grow
|
||||||
|
# You can refer to the example configuration :)
|
||||||
|
season: spring,autumn
|
||||||
|
#return: customcrops:tomato_stage_3
|
||||||
95
src/main/resources/config.yml
Normal file
95
src/main/resources/config.yml
Normal file
@@ -0,0 +1,95 @@
|
|||||||
|
# 是否使用季节
|
||||||
|
# 非植物季节则无法耕种,过了季节则枯死
|
||||||
|
enable-season: true
|
||||||
|
# 当前季节
|
||||||
|
# 使用/customcrops setseason 来切换季节
|
||||||
|
current-season: spring
|
||||||
|
|
||||||
|
config:
|
||||||
|
# 植物的种植盆方块
|
||||||
|
pot: customcrops:pot
|
||||||
|
# 植物的浇过水的种植盆方块
|
||||||
|
watered-pot: customcrops:watered_pot
|
||||||
|
|
||||||
|
# 水壶
|
||||||
|
# 1x1
|
||||||
|
watering-can-1: customcrops:watering_can_1
|
||||||
|
# 1x3
|
||||||
|
watering-can-2: customcrops:watering_can_2
|
||||||
|
# 1x5
|
||||||
|
watering-can-3: customcrops:watering_can_3
|
||||||
|
|
||||||
|
# 温室玻璃,在温室玻璃正下方的方块可以无视季节种植
|
||||||
|
enable-greenhouse: true
|
||||||
|
# 温室玻璃有效范围
|
||||||
|
greenhouse-range: 7
|
||||||
|
# 温室玻璃方块
|
||||||
|
greenhouse-glass: customcrops:greenhouse_glass
|
||||||
|
|
||||||
|
# 洒水器的家具
|
||||||
|
sprinkler-1: customcrops:sprinkler_1
|
||||||
|
# 洒水器的方块的物品
|
||||||
|
sprinkler-1-item: customcrops:sprinkler_1_item
|
||||||
|
|
||||||
|
# 优质洒水器的家具
|
||||||
|
sprinkler-2: customcrops:sprinkler_2
|
||||||
|
# 优质洒水器的方块的物品
|
||||||
|
sprinkler-2-item: customcrops:sprinkler_2_item
|
||||||
|
|
||||||
|
# 骨粉催熟农作物进入下一阶段的概率(0-1)
|
||||||
|
bone-meal-chance: 0.5
|
||||||
|
# 使用骨粉是否会让种植盆从湿润转为干燥
|
||||||
|
bone-meal-consume-water: true
|
||||||
|
# 农作物枯萎后变成的方块,物品ID中请保留stage以保持其下方方块被破坏时,枯萎作物也被破坏的特性
|
||||||
|
dead-crop: customcrops:crop_stage_death
|
||||||
|
# 农作物每天成长一个阶段的概率(0-1)
|
||||||
|
grow-success-chance: 0.8
|
||||||
|
# 粒子效果
|
||||||
|
particle:
|
||||||
|
# 使用骨粉成功的粒子
|
||||||
|
success: HEART
|
||||||
|
# 使用骨粉失败的粒子
|
||||||
|
failure: VILLAGER_ANGRY
|
||||||
|
# 最低和最高Y坐标
|
||||||
|
height:
|
||||||
|
min: 50
|
||||||
|
max: 100
|
||||||
|
# 每个区块最大农作物数量和洒水器数量
|
||||||
|
# 检测范围为上一个height之间,事件无法异步,所以
|
||||||
|
# 若min与max相差越小,则种植农作物对性能的消耗越小
|
||||||
|
enable-limit: true
|
||||||
|
max-crops: 32
|
||||||
|
max-sprinklers: 4
|
||||||
|
# 生长生效的世界
|
||||||
|
whitelist-worlds:
|
||||||
|
- world
|
||||||
|
# 只在被加载的区块中生长和枯萎,对性能友好
|
||||||
|
only-grow-in-loaded-chunks: true
|
||||||
|
|
||||||
|
messages:
|
||||||
|
prefix: '<gradient:#ccfbff:#ef96c5>[CustomCrops] </gradient>'
|
||||||
|
not-a-good-place: 这个地方太高/太低了,请换个地方试试吧!
|
||||||
|
reload: 插件已重载
|
||||||
|
force-save: 成功强制保存缓存信息
|
||||||
|
no-such-seed: 此种子未在配置文件中配置!
|
||||||
|
wrong-season: 这个季节不适合这种农作物生长!
|
||||||
|
season-set: 成功设置季节为{Season}
|
||||||
|
season-disabled: 季节系统未启用.
|
||||||
|
clean-cache: 无效农作物和洒水器数据清除完毕!
|
||||||
|
reach-limit-crop: 农作物已到达最大区块上限{Max}!
|
||||||
|
reach-limit-sprinkler: 洒水器已到达最大区块上限{Max}!
|
||||||
|
backup: 备份完成
|
||||||
|
spring: 春
|
||||||
|
summer: 夏
|
||||||
|
autumn: 秋
|
||||||
|
winter: 冬
|
||||||
|
can-full: 水壶已满!
|
||||||
|
|
||||||
|
# 启用的农作物
|
||||||
|
crops:
|
||||||
|
tomato:
|
||||||
|
# 在IA配置文件中命名农作物时请以_seeds和_stage_X结尾,否则会报错
|
||||||
|
# 适宜的生长季节,若未启用季节系统可以无视此项目
|
||||||
|
season: spring,summer
|
||||||
|
# 空手收获后返回第几个生长状态
|
||||||
|
#return: customcrops:tomato_stage_3
|
||||||
10
src/main/resources/plugin.yml
Normal file
10
src/main/resources/plugin.yml
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
name: CustomCrops
|
||||||
|
version: '${project.version}'
|
||||||
|
main: net.momirealms.customcrops.CustomCrops
|
||||||
|
api-version: 1.18
|
||||||
|
depend: [ ItemsAdder , ProtocolLib ]
|
||||||
|
softdepend: [ PlaceholderAPI ]
|
||||||
|
authors: [ XiaoMoMi ]
|
||||||
|
commands:
|
||||||
|
customcrops:
|
||||||
|
permission-message: No Permission
|
||||||
Reference in New Issue
Block a user