diff --git a/README.md b/README.md
deleted file mode 100644
index bd7aaad..0000000
--- a/README.md
+++ /dev/null
@@ -1,3 +0,0 @@
-MCBBS发布帖: https://www.mcbbs.net/thread-1342178-1-1.html
-
-MineDown: https://github.com/Phoenix616/MineDown
diff --git a/build.gradle b/build.gradle
new file mode 100644
index 0000000..cc05680
--- /dev/null
+++ b/build.gradle
@@ -0,0 +1,96 @@
+plugins {
+ id 'java'
+ id 'com.github.johnrengelman.shadow' version '7.1.2'
+}
+
+
+group = 'net.momirealms'
+version = '1.5.0-SNAPSHOT'
+
+repositories {
+ mavenCentral()
+ maven {
+ name = 'papermc-repo'
+ url = 'https://papermc.io/repo/repository/maven-public/'
+ }
+ maven {
+ name = 'sonatype'
+ url = 'https://oss.sonatype.org/content/groups/public/'
+ }
+ maven {
+ name = "sonatype-oss-snapshots1"
+ url = "https://s01.oss.sonatype.org/content/repositories/snapshots/"
+ }
+ maven {
+ name = "dmulloy2-repo"
+ url = "https://repo.dmulloy2.net/repository/public/"
+ }
+ maven {
+ name = "clip-repo"
+ url = 'https://repo.extendedclip.com/content/repositories/placeholderapi/'
+ }
+ maven {
+ name = "NBT-API"
+ url = "https://repo.codemc.org/repository/maven-public/"
+ }
+ maven {
+ name = "sk89q-repo"
+ url = "https://maven.enginehub.org/repo/"
+ }
+ maven {
+ name = "Lumine Releases"
+ url = "https://mvn.lumine.io/repository/maven-public"
+ }
+ maven {
+ name = "jitpack-repo"
+ url = "https://jitpack.io"
+ }
+}
+
+dependencies {
+ compileOnly 'com.destroystokyo.paper:paper-api:1.16.5-R0.1-SNAPSHOT'
+ compileOnly group: "com.comphenix.protocol", name: "ProtocolLib", version: "4.8.0"
+ compileOnly 'me.clip:placeholderapi:2.11.1'
+ compileOnly 'com.sk89q.worldguard:worldguard-bukkit:7.0.7'
+ compileOnly 'io.lumine:Mythic-Dist:5.0.3-SNAPSHOT'
+ compileOnly 'com.github.LoneDev6:api-itemsadder:3.2.0c-beta6'
+ compileOnly fileTree(dir:'libs',includes:['*jar'])
+ implementation("net.kyori:adventure-api:4.11.0")
+ implementation("net.kyori:adventure-platform-bukkit:4.1.1")
+ implementation("net.kyori:adventure-text-minimessage:4.11.0")
+ implementation 'de.tr7zw:item-nbt-api:2.10.0'
+}
+
+def targetJavaVersion = 16
+java {
+ def javaVersion = JavaVersion.toVersion(targetJavaVersion)
+ sourceCompatibility = javaVersion
+ targetCompatibility = javaVersion
+ if (JavaVersion.current() < javaVersion) {
+ toolchain.languageVersion = JavaLanguageVersion.of(targetJavaVersion)
+ }
+}
+
+tasks.withType(JavaCompile).configureEach {
+ if (targetJavaVersion >= 10 || JavaVersion.current().isJava10Compatible()) {
+ options.release = targetJavaVersion
+ }
+}
+
+processResources {
+ def props = [version: version]
+ inputs.properties props
+ filteringCharset 'UTF-8'
+ filesMatching('plugin.yml') {
+ expand props
+ }
+}
+
+tasks.withType(JavaCompile) {
+ options.encoding = "UTF-8"
+}
+
+shadowJar {
+ relocate 'net.kyori', 'libs.kyori'
+ relocate 'de.tr7zw', 'libs.tr7zw'
+}
\ No newline at end of file
diff --git a/gradle.properties b/gradle.properties
new file mode 100644
index 0000000..e69de29
diff --git a/gradlew b/gradlew
new file mode 100644
index 0000000..3da45c1
--- /dev/null
+++ b/gradlew
@@ -0,0 +1,234 @@
+#!/bin/sh
+
+#
+# Copyright ? 2015-2021 the original authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+##############################################################################
+#
+# Gradle start up script for POSIX generated by Gradle.
+#
+# Important for running:
+#
+# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
+# noncompliant, but you have some other compliant shell such as ksh or
+# bash, then to run this script, type that shell name before the whole
+# command line, like:
+#
+# ksh Gradle
+#
+# Busybox and similar reduced shells will NOT work, because this script
+# requires all of these POSIX shell features:
+# * functions;
+# * expansions ?$var?, ?${var}?, ?${var:-default}?, ?${var+SET}?,
+# ?${var#prefix}?, ?${var%suffix}?, and ?$( cmd )?;
+# * compound commands having a testable exit status, especially ?case?;
+# * various built-in commands including ?command?, ?set?, and ?ulimit?.
+#
+# Important for patching:
+#
+# (2) This script targets any POSIX shell, so it avoids extensions provided
+# by Bash, Ksh, etc; in particular arrays are avoided.
+#
+# The "traditional" practice of packing multiple parameters into a
+# space-separated string is a well documented source of bugs and security
+# problems, so this is (mostly) avoided, by progressively accumulating
+# options in "$@", and eventually passing that to Java.
+#
+# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
+# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
+# see the in-line comments for details.
+#
+# There are tweaks for specific operating systems such as AIX, CygWin,
+# Darwin, MinGW, and NonStop.
+#
+# (3) This script is generated from the Groovy template
+# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
+# within the Gradle project.
+#
+# You can find Gradle at https://github.com/gradle/gradle/.
+#
+##############################################################################
+
+# Attempt to set APP_HOME
+
+# Resolve links: $0 may be a link
+app_path=$0
+
+# Need this for daisy-chained symlinks.
+while
+ APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path
+ [ -h "$app_path" ]
+do
+ ls=$( ls -ld "$app_path" )
+ link=${ls#*' -> '}
+ case $link in #(
+ /*) app_path=$link ;; #(
+ *) app_path=$APP_HOME$link ;;
+ esac
+done
+
+APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
+
+APP_NAME="Gradle"
+APP_BASE_NAME=${0##*/}
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD=maximum
+
+warn () {
+ echo "$*"
+} >&2
+
+die () {
+ echo
+ echo "$*"
+ echo
+ exit 1
+} >&2
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+nonstop=false
+case "$( uname )" in #(
+ CYGWIN* ) cygwin=true ;; #(
+ Darwin* ) darwin=true ;; #(
+ MSYS* | MINGW* ) msys=true ;; #(
+ NONSTOP* ) nonstop=true ;;
+esac
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD=$JAVA_HOME/jre/sh/java
+ else
+ JAVACMD=$JAVA_HOME/bin/java
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD=java
+ which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
+ case $MAX_FD in #(
+ max*)
+ MAX_FD=$( ulimit -H -n ) ||
+ warn "Could not query maximum file descriptor limit"
+ esac
+ case $MAX_FD in #(
+ '' | soft) :;; #(
+ *)
+ ulimit -n "$MAX_FD" ||
+ warn "Could not set maximum file descriptor limit to $MAX_FD"
+ esac
+fi
+
+# Collect all arguments for the java command, stacking in reverse order:
+# * args from the command line
+# * the main class name
+# * -classpath
+# * -D...appname settings
+# * --module-path (only if needed)
+# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
+
+# For Cygwin or MSYS, switch paths to Windows format before running java
+if "$cygwin" || "$msys" ; then
+ APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
+ CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
+
+ JAVACMD=$( cygpath --unix "$JAVACMD" )
+
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ for arg do
+ if
+ case $arg in #(
+ -*) false ;; # don't mess with options #(
+ /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath
+ [ -e "$t" ] ;; #(
+ *) false ;;
+ esac
+ then
+ arg=$( cygpath --path --ignore --mixed "$arg" )
+ fi
+ # Roll the args list around exactly as many times as the number of
+ # args, so each arg winds up back in the position where it started, but
+ # possibly modified.
+ #
+ # NB: a `for` loop captures its iteration list before it begins, so
+ # changing the positional parameters here affects neither the number of
+ # iterations, nor the values presented in `arg`.
+ shift # remove old arg
+ set -- "$@" "$arg" # push replacement arg
+ done
+fi
+
+# Collect all arguments for the java command;
+# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of
+# shell script including quotes and variable substitutions, so put them in
+# double quotes to make sure that they get re-expanded; and
+# * put everything else in single quotes, so that it's not re-expanded.
+
+set -- \
+ "-Dorg.gradle.appname=$APP_BASE_NAME" \
+ -classpath "$CLASSPATH" \
+ org.gradle.wrapper.GradleWrapperMain \
+ "$@"
+
+# Use "xargs" to parse quoted args.
+#
+# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
+#
+# In Bash we could simply go:
+#
+# readarray ARGS < <( xargs -n1 <<<"$var" ) &&
+# set -- "${ARGS[@]}" "$@"
+#
+# but POSIX shell has neither arrays nor command substitution, so instead we
+# post-process each arg (as a line of input to sed) to backslash-escape any
+# character that might be a shell metacharacter, then use eval to reverse
+# that process (while maintaining the separation between arguments), and wrap
+# the whole thing up as a single "set" statement.
+#
+# This will of course break if any of these variables contains a newline or
+# an unmatched quote.
+#
+
+eval "set -- $(
+ printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
+ xargs -n1 |
+ sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
+ tr '\n' ' '
+ )" '"$@"'
+
+exec "$JAVACMD" "$@"
diff --git a/gradlew.bat b/gradlew.bat
new file mode 100644
index 0000000..107acd3
--- /dev/null
+++ b/gradlew.bat
@@ -0,0 +1,89 @@
+@rem
+@rem Copyright 2015 the original author or authors.
+@rem
+@rem Licensed under the Apache License, Version 2.0 (the "License");
+@rem you may not use this file except in compliance with the License.
+@rem You may obtain a copy of the License at
+@rem
+@rem https://www.apache.org/licenses/LICENSE-2.0
+@rem
+@rem Unless required by applicable law or agreed to in writing, software
+@rem distributed under the License is distributed on an "AS IS" BASIS,
+@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+@rem See the License for the specific language governing permissions and
+@rem limitations under the License.
+@rem
+
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Resolve any "." and ".." in APP_HOME to make it shorter.
+for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto execute
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto execute
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/pom.xml b/pom.xml
deleted file mode 100644
index ae6a5de..0000000
--- a/pom.xml
+++ /dev/null
@@ -1,96 +0,0 @@
-
-
- 4.0.0
-
- net.momirealms
- CustomCrops
- 1.0-SNAPSHOT
- jar
-
- CustomCrops
-
-
- 16
- UTF-8
-
-
-
-
- sk89q-repo
- https://maven.enginehub.org/repo/
-
-
- dmulloy2-repo
- https://repo.dmulloy2.net/repository/public/
-
-
- placeholderapi
- https://repo.extendedclip.com/content/repositories/placeholderapi/
-
-
- sonatype-oss-snapshots1
- https://s01.oss.sonatype.org/content/repositories/snapshots/
-
-
- papermc-repo
- https://papermc.io/repo/repository/maven-public/
-
-
- jitpack-repo
- https://jitpack.io
-
-
- sonatype
- https://oss.sonatype.org/content/groups/public/
-
-
-
-
-
- me.clip
- placeholderapi
- 2.11.1
- provided
-
-
- io.papermc.paper
- paper-api
- 1.17.1-R0.1-SNAPSHOT
- provided
-
-
- com.github.LoneDev6
- api-itemsadder
- 3.1.6
- provided
-
-
- com.sk89q.worldguard
- worldguard-bukkit
- 7.0.7
- provided
-
-
-
-
-
-
- org.apache.maven.plugins
- maven-compiler-plugin
- 3.8.1
-
- ${java.version}
- ${java.version}
-
-
-
-
-
- src/main/resources
- true
-
-
-
-
diff --git a/settings.gradle b/settings.gradle
new file mode 100644
index 0000000..d4b6e37
--- /dev/null
+++ b/settings.gradle
@@ -0,0 +1 @@
+rootProject.name = 'CustomCrops'
diff --git a/src/main/java/net/momirealms/customcrops/ConfigReader.java b/src/main/java/net/momirealms/customcrops/ConfigReader.java
new file mode 100644
index 0000000..4402765
--- /dev/null
+++ b/src/main/java/net/momirealms/customcrops/ConfigReader.java
@@ -0,0 +1,432 @@
+package net.momirealms.customcrops;
+
+import net.momirealms.customcrops.fertilizer.Fertilizer;
+import net.momirealms.customcrops.fertilizer.QualityCrop;
+import net.momirealms.customcrops.fertilizer.RetainingSoil;
+import net.momirealms.customcrops.fertilizer.SpeedGrow;
+import net.momirealms.customcrops.integrations.*;
+import net.momirealms.customcrops.requirements.Biome;
+import net.momirealms.customcrops.requirements.Permission;
+import net.momirealms.customcrops.requirements.Requirement;
+import net.momirealms.customcrops.requirements.YPos;
+import net.momirealms.customcrops.utils.*;
+import org.apache.commons.lang.StringUtils;
+import org.bukkit.Bukkit;
+import org.bukkit.World;
+import org.bukkit.configuration.file.FileConfiguration;
+import org.bukkit.configuration.file.YamlConfiguration;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Set;
+
+public class ConfigReader {
+
+ public static HashMap CROPS = new HashMap<>();
+ public static HashMap FERTILIZERS = new HashMap<>();
+ public static HashMap CANS = new HashMap<>();
+ public static HashMap SPRINKLERS = new HashMap<>();
+
+ private static YamlConfiguration getConfig(String configName) {
+ File file = new File(CustomCrops.instance.getDataFolder(), configName);
+ if (!file.exists()) {
+ CustomCrops.instance.saveResource(configName, false);
+ }
+ return YamlConfiguration.loadConfiguration(file);
+ }
+
+ public static void ReloadConfig(){
+ Config.loadConfig();
+ Message.loadMessage();
+ Basic.loadBasic();
+ Season.loadSeason();
+ cropLoad();
+ fertilizerLoad();
+ }
+
+ public static class Config{
+
+ public static List worlds;
+ public static List worldNames;
+ public static List cropGrowTimeList;
+ public static List integration;
+ public static boolean asyncCheck;
+// public static boolean useBoneMeal;
+// public static boolean consumeWater;
+// public static double boneMealChance;
+// public static String success;
+// public static String failure;
+ public static boolean enableLimit;
+ public static int cropLimit;
+ public static int sprinklerLimit;
+ public static int yMin;
+ public static int yMax;
+ public static int sprinklerRefill;
+ public static boolean logTime;
+ public static boolean onlyLoadedGrow;
+ public static boolean quality;
+ public static double quality_1;
+ public static double quality_2;
+
+ public static void loadConfig(){
+
+ //存读基本配置文件
+ CustomCrops.instance.saveDefaultConfig();
+ CustomCrops.instance.reloadConfig();
+ FileConfiguration config = CustomCrops.instance.getConfig();
+
+ //农作物生长时间点
+ cropGrowTimeList = config.getLongList("config.grow-time");
+ cropGrowTimeList.forEach(time -> {
+ if(time < 0 || time > 23999){
+ AdventureManager.consoleMessage("[CustomCrops] 农作物生长时间点必须位于0-23999之间");
+ cropGrowTimeList.remove(time);
+ }
+ });
+
+ //异步读取时间
+ asyncCheck = config.getBoolean("config.async-time-check",false);
+ logTime = config.getBoolean("config.log-time-consume",false);
+ onlyLoadedGrow = config.getBoolean("config.only-grow-in-loaded-chunks",true);
+
+ //骨粉设置(已废弃)
+// useBoneMeal = config.getBoolean("config.bone-meal.enable",false);
+// if (useBoneMeal){
+// boneMealChance = config.getDouble("config.bone-meal.chance");
+// consumeWater = config.getBoolean("config.bone-meal.consume-water");
+// success = config.getString("config.bone-meal.particle.success");
+// failure = config.getString("config.bone-meal.particle.failure");
+// }
+
+ //数量与高度限制
+ enableLimit = config.getBoolean("config.limit.enable",true);
+ if (enableLimit){
+ cropLimit = config.getInt("config.limit.crop",64);
+ sprinklerLimit = config.getInt("config.limit.sprinkler",16);
+ }
+ if (Bukkit.getServer().getClass().getPackage().getName().contains("16") || Bukkit.getServer().getClass().getPackage().getName().contains("17")){
+ yMin = 0;
+ yMax = 256;
+ }
+ if (Bukkit.getServer().getClass().getPackage().getName().contains("18") || Bukkit.getServer().getClass().getPackage().getName().contains("19")){
+ yMin = -64;
+ yMax = 320;
+ }
+
+ //农作物品质处理
+ quality = config.getBoolean("config.quality.enable");
+ if (quality){
+ String[] split = StringUtils.split(config.getString("config.quality.default-ratio"), "/");
+ double[] ratios = new double[3];
+ ratios[0] = Double.parseDouble(split[0]);
+ ratios[1] = Double.parseDouble(split[1]);
+ ratios[2] = Double.parseDouble(split[2]);
+ double total = ratios[0] + ratios[1] + ratios[2];
+ quality_1 = ratios[0]/total;
+ quality_2 = 1 - ratios[1]/total;
+ }
+
+ sprinklerRefill = config.getInt("config.sprinkler-refill",2);
+
+ //农作物生长的白名单世界
+ worlds = new ArrayList<>();
+ worldNames = config.getStringList("config.whitelist-worlds");
+ worldNames.forEach(worldName -> {
+ World world = Bukkit.getWorld(worldName);
+ if (world == null){
+ worldNames.remove(worldName);
+ AdventureManager.consoleMessage("[CustomCrops] 世界" + worldName + "" + "不存在");
+ }else {
+ worlds.add(world);
+ }
+ });
+
+ //处理插件兼容性
+ integration = new ArrayList<>();
+ if(config.getBoolean("config.integration.Residence",false)){
+ if(Bukkit.getPluginManager().getPlugin("Residence") == null){
+ CustomCrops.instance.getLogger().warning("未检测到插件 Residence!");
+ }else {
+ integration.add(new Residence());
+ AdventureManager.consoleMessage("[CustomCrops] 检测到 Residence 已启用保护!");
+ }
+ }
+ if(config.getBoolean("config.integration.Kingdoms",false)){
+ if(Bukkit.getPluginManager().getPlugin("Kingdoms") == null){
+ CustomCrops.instance.getLogger().warning("未检测到插件 Kingdoms!");
+ }else {
+ integration.add(new KingdomsX());
+ AdventureManager.consoleMessage("[CustomCrops] 检测到 KingdomsX 已启用保护!");
+ }
+ }
+ if(config.getBoolean("config.integration.WorldGuard",false)){
+ if(Bukkit.getPluginManager().getPlugin("WorldGuard") == null){
+ CustomCrops.instance.getLogger().warning("未检测到插件 WorldGuard!");
+ }else {
+ integration.add(new WorldGuard());
+ AdventureManager.consoleMessage("[CustomCrops] 检测到 WorldGuard 已启用保护!");
+ }
+ }
+ if(config.getBoolean("config.integration.GriefDefender",false)){
+ if(Bukkit.getPluginManager().getPlugin("GriefDefender") == null){
+ CustomCrops.instance.getLogger().warning("未检测到插件 GriefDefender!");
+ }else {
+ integration.add(new GriefDefender());
+ AdventureManager.consoleMessage("[CustomCrops] 检测到 GriefDefender 已启用保护!");
+ }
+ }
+ }
+ }
+
+ public static class Basic{
+
+ public static String pot;
+ public static String watered_pot;
+ public static String glass;
+ public static String sprinkler_1;
+ public static String sprinkler_2;
+ public static String sprinkler_1i;
+ public static String sprinkler_2i;
+ public static String dead;
+ public static String soilDetector;
+
+ public static void loadBasic(){
+ YamlConfiguration config = getConfig("basic.yml");
+ pot = config.getString("basic.pot");
+ watered_pot = config.getString("basic.watered-pot");
+ glass = config.getString("basic.greenhouse-glass");
+ sprinkler_1 = config.getString("basic.sprinkler-1");
+ sprinkler_2 = config.getString("basic.sprinkler-2");
+ sprinkler_1i = config.getString("basic.sprinkler-1-item");
+ sprinkler_2i = config.getString("basic.sprinkler-2-item");
+ dead = config.getString("basic.dead-crop");
+ soilDetector = StringUtils.split(config.getString("basic.soil-detector"),":")[1];
+
+ CANS.clear();
+ if (config.contains("water-can")){
+ config.getConfigurationSection("water-can").getKeys(false).forEach(key -> {
+ if (key.equals(StringUtils.split(config.getString("water-can." + key + ".item"),":")[1])){
+ int width = config.getInt("water-can." + key + ".width");
+ if (width % 2 == 0){
+ AdventureManager.consoleMessage("[CustomCrops] 水壶 " + key + " 的浇灌宽度必须为奇数!");
+ return;
+ }
+ WateringCan wateringCan = new WateringCan(config.getInt("water-can." + key + ".max"), width, config.getInt("water-can." + key + ".length"));
+ CANS.put(key, wateringCan);
+ }else {
+ AdventureManager.consoleMessage("[CustomCrops] 水壶 " + key + " 与ItemsAdder物品ID不一致");
+ }
+ });
+ }
+
+ SPRINKLERS.clear();
+ if (config.contains("sprinkler")){
+ config.getConfigurationSection("sprinkler").getKeys(false).forEach(key -> {
+ if (key.equals(StringUtils.split(config.getString("sprinkler." + key + ".3Ditem"),":")[1])){
+ Sprinkler sprinklerData = new Sprinkler(config.getInt("sprinkler." + key + ".range"), config.getInt("sprinkler." + key + ".max-water"));
+ sprinklerData.setNamespacedID_2(config.getString("sprinkler." + key + ".3Ditem"));
+ String twoD = config.getString("sprinkler." + key + ".2Ditem");
+ sprinklerData.setNamespacedID_1(twoD);
+ SPRINKLERS.put(key, sprinklerData);
+ SPRINKLERS.put(StringUtils.split(twoD,":")[1], sprinklerData);
+ }else {
+ AdventureManager.consoleMessage("[CustomCrops] 洒水器 " + key + " 与ItemsAdder物品ID不一致");
+ }
+ });
+ }
+ }
+ }
+
+ public static class Season{
+
+ public static boolean enable;
+ public static boolean greenhouse;
+ public static boolean seasonChange;
+ public static int range;
+ public static int duration;
+
+ public static void loadSeason(){
+ YamlConfiguration config = getConfig("season.yml");
+
+ enable = config.getBoolean("season.enable",false);
+ if (enable){
+ greenhouse = config.getBoolean("season.greenhouse.enable",false);
+ if (greenhouse) {
+ range = config.getInt("season.greenhouse.range",7);
+ }
+ seasonChange = config.getBoolean("season.auto-season-change.enable",false);
+ if (seasonChange) {
+ duration = config.getInt("season.auto-season-change.duration",28);
+ }
+ }
+ }
+ }
+
+ public static class Message{
+
+ public static String prefix;
+ public static String reload;
+ public static String lackArgs;
+ public static String noPerm;
+ public static String spring;
+ public static String summer;
+ public static String autumn;
+ public static String winter;
+ public static String sprinkler_limit;
+ public static String crop_limit;
+ public static String not_configed;
+ public static String badY;
+ public static String badBiome;
+ public static String badWorld;
+ public static String badPerm;
+ public static String badSeason;
+ public static String forceGrow;
+ public static String forceWater;
+ public static String backUp;
+ public static String setSeason;
+ public static String wrongArgs;
+ public static String forceSave;
+ public static boolean hasCropInfo;
+ public static boolean hasSprinklerInfo;
+ public static int cropTime;
+ public static int sprinklerTime;
+ public static String cropText;
+ public static String sprinklerLeft;
+ public static String sprinklerFull;
+ public static String sprinklerEmpty;
+ public static String sprinklerRight;
+ public static double cropOffset;
+ public static double sprinklerOffset;
+
+ public static void loadMessage(){
+ YamlConfiguration config = getConfig("messages.yml");
+ prefix = config.getString("messages.prefix");
+ reload = config.getString("messages.reload");
+ lackArgs = config.getString("messages.lack-args");
+ noPerm = config.getString("messages.no-perm");
+ spring = config.getString("messages.spring");
+ summer = config.getString("messages.summer");
+ autumn = config.getString("messages.autumn");
+ winter = config.getString("messages.winter");
+ sprinkler_limit = config.getString("messages.sprinkler-limit");
+ crop_limit = config.getString("messages.crop-limit");
+ not_configed = config.getString("messages.not-configed");
+ badY = config.getString("messages.bad-Y");
+ badBiome = config.getString("messages.bad-biome");
+ badWorld = config.getString("messages.bad-world");
+ badPerm = config.getString("messages.bad-perm");
+ badSeason = config.getString("messages.bad-season");
+ forceGrow = config.getString("messages.force-grow");
+ forceWater = config.getString("messages.force-water");
+ backUp = config.getString("messages.back-up");
+ setSeason = config.getString("messages.set-season");
+ wrongArgs = config.getString("messages.wrong-args");
+ forceSave = config.getString("messages.force-save");
+
+ hasCropInfo = config.getBoolean("hologram.grow-info.enable");
+ if (hasCropInfo){
+ cropTime = config.getInt("hologram.grow-info.duration");
+ cropText = config.getString("hologram.grow-info.text");
+ cropOffset = config.getDouble("hologram.grow-info.y-offset");
+ }
+ hasSprinklerInfo = config.getBoolean("hologram.sprinkler-info.enable");
+ if (hasSprinklerInfo){
+ sprinklerTime = config.getInt("hologram.sprinkler-info.duration");
+ sprinklerLeft = config.getString("hologram.sprinkler-info.left");
+ sprinklerFull = config.getString("hologram.sprinkler-info.full");
+ sprinklerEmpty = config.getString("hologram.sprinkler-info.empty");
+ sprinklerRight = config.getString("hologram.sprinkler-info.right");
+ sprinklerOffset = config.getDouble("hologram.sprinkler-info.y-offset");
+ }
+ }
+ }
+
+ public static void cropLoad(){
+ CROPS.clear();
+ YamlConfiguration config = getConfig("crops.yml");
+ Set keys = config.getConfigurationSection("crops").getKeys(false);
+ keys.forEach(key -> {
+ CropInstance cropInstance;
+ if (config.contains("crops." + key + ".amount")){
+ String[] split = StringUtils.split(config.getString("crops." + key + ".amount"),"~");
+ cropInstance = new CropInstance(Integer.parseInt(split[0]),Integer.parseInt(split[1]));
+ }else {
+ AdventureManager.consoleMessage("[CustomCrops] 未设置农作物 " + key +" 的产物数量!");
+ return;
+ }
+ if (config.contains("crops." + key + ".gigantic")){
+ cropInstance.setGiant(config.getString("crops." + key + ".gigantic.block"));
+ cropInstance.setGiantChance(config.getDouble("crops." + key + ".gigantic.chance"));
+ }
+ if (Season.enable && config.contains("crops." + key + ".season")){
+ cropInstance.setSeasons(config.getStringList("crops." + key + ".season"));
+ }
+ if (config.contains("crops." + key + ".return")){
+ cropInstance.setReturnStage(config.getString("crops." + key + ".return"));
+ }
+ if (config.contains("crops." + key + ".requirements")){
+ List requirements = new ArrayList<>();
+ config.getConfigurationSection("crops." + key + ".requirements").getValues(false).forEach((requirement, value) -> {
+ switch (requirement){
+ case "world" -> requirements.add(new net.momirealms.customcrops.requirements.World((List) value));
+ case "yPos" -> requirements.add(new YPos((List) value));
+ case "biome" -> requirements.add(new Biome((List) value));
+ case "permission" -> requirements.add(new Permission((String) value));
+ }
+ });
+ cropInstance.setRequirements(requirements);
+ }
+ if (Config.quality){
+ cropInstance.setQuality_1(config.getString("crops." + key + ".quality.1"));
+ cropInstance.setQuality_2(config.getString("crops." + key + ".quality.2"));
+ cropInstance.setQuality_3(config.getString("crops." + key + ".quality.3"));
+ }
+ CROPS.put(key, cropInstance);
+ });
+ }
+
+ public static void fertilizerLoad(){
+ FERTILIZERS.clear();
+ YamlConfiguration config = getConfig("fertilizer.yml");
+ if (config.contains("加速肥料")){
+ config.getConfigurationSection("加速肥料").getKeys(false).forEach(key -> {
+ if (StringUtils.split(config.getString("加速肥料." + key + ".item"), ":")[1].equals(key)){
+ SpeedGrow speedGrow = new SpeedGrow(key, config.getInt("加速肥料." + key + ".times"), config.getDouble("加速肥料." + key + ".chance"), config.getBoolean("加速肥料." + key + ".before-plant"));
+ speedGrow.setName(config.getString("加速肥料." + key + ".name"));
+ FERTILIZERS.put(key, speedGrow);
+ }else {
+ AdventureManager.consoleMessage("[CustomCrops] 肥料 " + key + " 与ItemsAdder物品ID不一致");
+ }
+ });
+ }
+ if (config.contains("保湿肥料")){
+ config.getConfigurationSection("保湿肥料").getKeys(false).forEach(key -> {
+ if (StringUtils.split(config.getString("保湿肥料." + key + ".item"), ":")[1].equals(key)){
+ RetainingSoil retainingSoil = new RetainingSoil(key, config.getInt("保湿肥料." + key + ".times"), config.getDouble("保湿肥料." + key + ".chance"), config.getBoolean("保湿肥料." + key + ".before-plant"));
+ retainingSoil.setName(config.getString("保湿肥料." + key + ".name"));
+ FERTILIZERS.put(key, retainingSoil);
+ }else {
+ AdventureManager.consoleMessage("[CustomCrops] 肥料 " + key + " 与ItemsAdder物品ID不一致");
+ }
+ });
+ }
+ if (config.contains("品质肥料")){
+ config.getConfigurationSection("品质肥料").getKeys(false).forEach(key -> {
+ if (StringUtils.split(config.getString("品质肥料." + key + ".item"), ":")[1].equals(key)){
+ String[] split = StringUtils.split(config.getString("品质肥料." + key + ".chance"), "/");
+ int[] weight = new int[3];
+ weight[0] = Integer.parseInt(split[0]);
+ weight[1] = Integer.parseInt(split[1]);
+ weight[2] = Integer.parseInt(split[2]);
+ QualityCrop qualityCrop = new QualityCrop(key, config.getInt("品质肥料." + key + ".times"), weight, config.getBoolean("品质肥料." + key + ".before-plant"));
+ qualityCrop.setName(config.getString("品质肥料." + key + ".name"));
+ FERTILIZERS.put(key, qualityCrop);
+ }else {
+ AdventureManager.consoleMessage("[CustomCrops] 肥料 " + key + " 与ItemsAdder物品ID不一致");
+ }
+ });
+ }
+ }
+}
diff --git a/src/main/java/net/momirealms/customcrops/CustomCrops.java b/src/main/java/net/momirealms/customcrops/CustomCrops.java
index fa72830..155db6c 100644
--- a/src/main/java/net/momirealms/customcrops/CustomCrops.java
+++ b/src/main/java/net/momirealms/customcrops/CustomCrops.java
@@ -1,89 +1,120 @@
package net.momirealms.customcrops;
-import net.momirealms.customcrops.commands.CommandHandler;
-import net.momirealms.customcrops.commands.CommandTabComplete;
+import net.kyori.adventure.platform.bukkit.BukkitAudiences;
+import net.momirealms.customcrops.commands.Executor;
+import net.momirealms.customcrops.commands.Completer;
import net.momirealms.customcrops.datamanager.*;
-import net.momirealms.customcrops.listener.BreakCrops;
+import net.momirealms.customcrops.listener.BreakBlock;
+import net.momirealms.customcrops.listener.InteractEntity;
+import net.momirealms.customcrops.listener.ItemSpawn;
+import net.momirealms.customcrops.listener.RightClick;
import net.momirealms.customcrops.timer.CropTimer;
-import net.momirealms.customcrops.listener.BreakCustomBlock;
-import net.momirealms.customcrops.listener.RightClickBlock;
-import net.momirealms.customcrops.listener.RightClickCustomBlock;
+import net.momirealms.customcrops.timer.CropTimerAsync;
+import net.momirealms.customcrops.utils.AdventureManager;
+import net.momirealms.customcrops.utils.BackUp;
+import net.momirealms.customcrops.utils.HoloUtil;
import net.momirealms.customcrops.utils.Placeholders;
import org.bukkit.Bukkit;
import org.bukkit.plugin.java.JavaPlugin;
-import java.io.File;
-import java.io.IOException;
import java.util.Objects;
public final class CustomCrops extends JavaPlugin {
public static JavaPlugin instance;
- public static CropTimer timer;
+ public static BukkitAudiences adventure;
+ private CropTimer cropTimer;
+ private CropTimerAsync cropTimerAsync;
+ private CropManager cropManager;
+ private SprinklerManager sprinklerManager;
+ private SeasonManager seasonManager;
+ private PotManager potManager;
@Override
public void onEnable() {
+
instance = this;
+ adventure = BukkitAudiences.create(this);
+
+ AdventureManager.consoleMessage("[CustomCrops] Running on " + Bukkit.getVersion());
//加载配置文件
- ConfigManager.Config.ReloadConfig();
+ ConfigReader.ReloadConfig();
+
+ //PAPI
+ if(Bukkit.getPluginManager().getPlugin("PlaceHolderAPI") != null){
+ new Placeholders().register();
+ AdventureManager.consoleMessage("[CustomCrops] 检测到 PlaceHolderAPI 已启用变量!");
+ }
//指令注册
- 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 BreakCrops(),this);
+ Objects.requireNonNull(Bukkit.getPluginCommand("customcrops")).setExecutor(new Executor(this));
+ Objects.requireNonNull(Bukkit.getPluginCommand("customcrops")).setTabCompleter(new Completer());
- //开始计时任务
- CustomCrops.timer = new CropTimer();
+ //注册事件
+ Bukkit.getPluginManager().registerEvents(new ItemSpawn(), this);
+ Bukkit.getPluginManager().registerEvents(new RightClick(), this);
+ Bukkit.getPluginManager().registerEvents(new BreakBlock(), this);
+ Bukkit.getPluginManager().registerEvents(new InteractEntity(this), this);
- //新建data文件
- 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();
- MessageManager.consoleMessage("&c[CustomCrops] 农作物数据文件生成失败!",Bukkit.getConsoleSender());
- }
- }
- if(!sprinkler_file.exists()){
- try {
- sprinkler_file.createNewFile();
- } catch (IOException e) {
- e.printStackTrace();
- MessageManager.consoleMessage("&c[CustomCrops] 洒水器数据文件生成失败!",Bukkit.getConsoleSender());
- }
+ //开始计时器
+ if(ConfigReader.Config.asyncCheck){
+ this.cropTimerAsync = new CropTimerAsync(this);
+ }else {
+ this.cropTimer = new CropTimer(this);
}
- //载入data数据
- CropManager.loadData();
- SprinklerManager.loadData();
-
- //检测papi依赖
- if(Bukkit.getPluginManager().getPlugin("PlaceholderAPI") != null){
- new Placeholders(this).register();
- MessageManager.consoleMessage("ccfbff-#ef96c5&[CustomCrops] &7检测到 &aPlaceHolderAPI &7已启用季节变量!",Bukkit.getConsoleSender());
+ //载入数据
+ if (ConfigReader.Season.enable){
+ this.seasonManager = new SeasonManager(this);
+ this.seasonManager.loadData();
}
- MessageManager.consoleMessage("ccfbff-#ef96c5&[CustomCrops] &7自定义农作物插件已启用!作者:小默米 QQ:3266959688",Bukkit.getConsoleSender());
+ this.cropManager = new CropManager(this);
+ this.cropManager.loadData();
+ this.sprinklerManager = new SprinklerManager(this);
+ this.sprinklerManager.loadData();
+ this.potManager = new PotManager(this);
+ this.potManager.loadData();
+
+ //启动完成
+ AdventureManager.consoleMessage("[CustomCrops] 插件已加载!作者:小默米 QQ:3266959688");
}
@Override
public void onDisable() {
- //关闭定时任务
- if (CustomCrops.timer != null) {
- CropTimer.stopTimer(CustomCrops.timer.getTaskID());
+
+ //保存数据
+ this.cropManager.saveData();
+ this.sprinklerManager.saveData();
+ this.potManager.saveData();
+ if (ConfigReader.Season.enable && !ConfigReader.Season.seasonChange){
+ this.seasonManager.saveData();
}
- //保存缓存中的数据
- CropManager.saveData();
- SprinklerManager.saveData();
+ //清除悬浮展示实体
+ HoloUtil.cache.keySet().forEach(player -> {
+ HoloUtil.cache.get(player).remove();
+ });
- //备份
+ //关闭计时器
+ if (cropTimer != null) {
+ this.cropTimer.stopTimer(cropTimer.getTaskID());
+ }
+ if (cropTimerAsync != null){
+ this.cropTimerAsync.stopTimer(cropTimerAsync.getTaskID());
+ }
+
+ //备份数据
+ AdventureManager.consoleMessage("[CustomCrops] 插件数据自动备份中...");
BackUp.backUpData();
- MessageManager.consoleMessage(("ccfbff-#ef96c5&[CustomCrops] &7自定义农作物插件已卸载!作者:小默米 QQ:3266959688"),Bukkit.getConsoleSender());
+ AdventureManager.consoleMessage("[CustomCrops] 备份已完成!");
+
+ //卸载完成
+ AdventureManager.consoleMessage("[CustomCrops] 插件已卸载!作者:小默米 QQ:3266959688");
}
+
+ public CropManager getCropManager() { return this.cropManager; }
+ public SprinklerManager getSprinklerManager() { return sprinklerManager; }
+ public SeasonManager getSeasonManager() { return seasonManager; }
+ public PotManager getPotManager() { return potManager; }
}
diff --git a/src/main/java/net/momirealms/customcrops/commands/CommandHandler.java b/src/main/java/net/momirealms/customcrops/commands/CommandHandler.java
deleted file mode 100644
index b22c8db..0000000
--- a/src/main/java/net/momirealms/customcrops/commands/CommandHandler.java
+++ /dev/null
@@ -1,123 +0,0 @@
-package net.momirealms.customcrops.commands;
-
-import net.momirealms.customcrops.datamanager.ConfigManager;
-import net.momirealms.customcrops.CustomCrops;
-import net.momirealms.customcrops.datamanager.MessageManager;
-import net.momirealms.customcrops.datamanager.BackUp;
-import net.momirealms.customcrops.datamanager.CropManager;
-import net.momirealms.customcrops.datamanager.NextSeason;
-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;
-
-public class CommandHandler implements CommandExecutor {
-
- @Override
- @ParametersAreNonnullByDefault
- public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
- if(args.length<1) return true;
- //重载插件
- if(args[0].equalsIgnoreCase("reload")){
-
- ConfigManager.Config.ReloadConfig();
-
- if(sender instanceof Player){
- MessageManager.playerMessage(ConfigManager.Config.prefix + ConfigManager.Config.reload, (Player) sender);
- }else {
- MessageManager.consoleMessage(ConfigManager.Config.prefix + ConfigManager.Config.reload, Bukkit.getConsoleSender());
- }
- return true;
- }
- //设置季节
- if(args[0].equalsIgnoreCase("setseason")){
- if(args.length<2) return true;
- if(ConfigManager.Config.season){
-
- FileConfiguration config = CustomCrops.instance.getConfig();
- config.set("current-season", args[1]);
- CustomCrops.instance.saveConfig();
- ConfigManager.Config.current = args[1];
-
- if(sender instanceof Player){
- MessageManager.playerMessage(ConfigManager.Config.prefix + ConfigManager.Config.season_set.replace("{Season}",args[1])
- .replace("spring", ConfigManager.Config.spring)
- .replace("summer", ConfigManager.Config.summer)
- .replace("autumn", ConfigManager.Config.autumn)
- .replace("winter", ConfigManager.Config.winter), (Player) sender);
- }else {
- MessageManager.consoleMessage(config.getString("messages.prefix") + ConfigManager.Config.season_set.replace("{Season}",args[1])
- .replace("spring", ConfigManager.Config.spring)
- .replace("summer", ConfigManager.Config.summer)
- .replace("autumn", ConfigManager.Config.autumn)
- .replace("winter", ConfigManager.Config.winter), Bukkit.getConsoleSender());
- }
-
- }else{
- if(sender instanceof Player){
- MessageManager.playerMessage(ConfigManager.Config.prefix + ConfigManager.Config.season_disabled, (Player) sender);
- }else {
- MessageManager.consoleMessage(ConfigManager.Config.prefix + ConfigManager.Config.season_disabled, Bukkit.getConsoleSender());
- }
- }
- return true;
- }
- //强制保存
- if(args[0].equalsIgnoreCase("forcesave")){
- CropManager.saveData();
- SprinklerManager.saveData();
- if(sender instanceof Player){
- MessageManager.playerMessage(ConfigManager.Config.prefix + ConfigManager.Config.force_save, (Player) sender);
- }else {
- MessageManager.consoleMessage(ConfigManager.Config.prefix + ConfigManager.Config.force_save, Bukkit.getConsoleSender());
- }
- return true;
- }
- //强制生长
- if(args[0].equalsIgnoreCase("forcegrow")){
- if(args.length<2) return true;
- Bukkit.getScheduler().runTaskAsynchronously(CustomCrops.instance, () -> CropManager.CropGrow(args[1]));
- if(sender instanceof Player){
- MessageManager.playerMessage(ConfigManager.Config.prefix + ConfigManager.Config.force_grow, (Player) sender);
- }else {
- MessageManager.consoleMessage(ConfigManager.Config.prefix + ConfigManager.Config.force_grow, Bukkit.getConsoleSender());
- }
- return true;
- }
- //强制洒水
- if(args[0].equalsIgnoreCase("forcewater")){
- if(args.length<2) return true;
- Bukkit.getScheduler().runTaskAsynchronously(CustomCrops.instance, () -> SprinklerManager.SprinklerWork(args[1]));
- if(sender instanceof Player){
- MessageManager.playerMessage(ConfigManager.Config.prefix + ConfigManager.Config.force_water, (Player) sender);
- }else {
- MessageManager.consoleMessage(ConfigManager.Config.prefix + ConfigManager.Config.force_water, Bukkit.getConsoleSender());
- }
- return true;
- }
- if(args[0].equalsIgnoreCase("backup")){
- BackUp.backUpData();
- if(sender instanceof Player){
- MessageManager.playerMessage(ConfigManager.Config.prefix + ConfigManager.Config.backup, (Player) sender);
- }else {
- MessageManager.consoleMessage(ConfigManager.Config.prefix + ConfigManager.Config.backup, Bukkit.getConsoleSender());
- }
- return true;
- }
- if(args[0].equalsIgnoreCase("nextseason")){
- NextSeason.changeSeason();
- if(sender instanceof Player){
- MessageManager.playerMessage(ConfigManager.Config.prefix + ConfigManager.Config.nextSeason, (Player) sender);
- }else {
- MessageManager.consoleMessage(ConfigManager.Config.prefix + ConfigManager.Config.nextSeason, Bukkit.getConsoleSender());
- }
- return true;
- }
- return false;
- }
-}
diff --git a/src/main/java/net/momirealms/customcrops/commands/CommandTabComplete.java b/src/main/java/net/momirealms/customcrops/commands/CommandTabComplete.java
deleted file mode 100644
index e7702ad..0000000
--- a/src/main/java/net/momirealms/customcrops/commands/CommandTabComplete.java
+++ /dev/null
@@ -1,29 +0,0 @@
-package net.momirealms.customcrops.commands;
-
-import net.momirealms.customcrops.datamanager.ConfigManager;
-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 onTabComplete(CommandSender sender, Command command, String alias, String[] args) {
- if (args.length == 1) {
- return Arrays.asList("backup" , "forcegrow", "forcesave", "forcewater", "reload", "setseason" , "nextseason");
- }
- if(args[0].equalsIgnoreCase("setseason")){
- return Arrays.asList("spring","summer","autumn","winter");
- }
- if(args[0].equalsIgnoreCase("forcegrow") || args[0].equalsIgnoreCase("forcewater")){
- return ConfigManager.Config.worlds;
- }
- return null;
- }
-}
diff --git a/src/main/java/net/momirealms/customcrops/commands/Completer.java b/src/main/java/net/momirealms/customcrops/commands/Completer.java
new file mode 100644
index 0000000..3b0359c
--- /dev/null
+++ b/src/main/java/net/momirealms/customcrops/commands/Completer.java
@@ -0,0 +1,46 @@
+package net.momirealms.customcrops.commands;
+
+import net.momirealms.customcrops.ConfigReader;
+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 Completer implements TabCompleter {
+
+ @Override
+ @ParametersAreNonnullByDefault
+ public @Nullable List onTabComplete(CommandSender sender, Command command, String alias, String[] args) {
+ if (!(sender.isOp() || sender.hasPermission("customcrops.admin"))){
+ return null;
+ }
+ if (args.length == 1) {
+ return Arrays.asList("backup", "forcegrow", "forcesave", "forcewater", "reload", "setseason");
+ }
+ if(args[0].equalsIgnoreCase("setseason") && args.length == 2){
+ return ConfigReader.Config.worldNames;
+ }
+ if(args[0].equalsIgnoreCase("forcesave") && args.length == 2){
+ if (ConfigReader.Season.enable){
+ if (ConfigReader.Season.seasonChange){
+ return Arrays.asList("all","crop","pot","sprinkler");
+ }else{
+ return Arrays.asList("all","crop","pot","season","sprinkler");
+ }
+ }else {
+ return Arrays.asList("all","crop","pot","sprinkler");
+ }
+ }
+ if(args[0].equalsIgnoreCase("setseason") && args.length == 3){
+ return Arrays.asList("spring","summer","autumn","winter");
+ }
+ if(args[0].equalsIgnoreCase("forcegrow") || args[0].equalsIgnoreCase("forcewater")){
+ return ConfigReader.Config.worldNames;
+ }
+ return null;
+ }
+}
diff --git a/src/main/java/net/momirealms/customcrops/commands/Executor.java b/src/main/java/net/momirealms/customcrops/commands/Executor.java
new file mode 100644
index 0000000..2fb79ba
--- /dev/null
+++ b/src/main/java/net/momirealms/customcrops/commands/Executor.java
@@ -0,0 +1,164 @@
+package net.momirealms.customcrops.commands;
+
+import net.momirealms.customcrops.utils.AdventureManager;
+import net.momirealms.customcrops.ConfigReader;
+import net.momirealms.customcrops.CustomCrops;
+import net.momirealms.customcrops.utils.BackUp;
+import org.bukkit.command.Command;
+import org.bukkit.command.CommandExecutor;
+import org.bukkit.command.CommandSender;
+import org.bukkit.entity.Player;
+
+import javax.annotation.ParametersAreNonnullByDefault;
+
+public class Executor implements CommandExecutor {
+
+ private final CustomCrops plugin;
+
+ public Executor(CustomCrops plugin){
+ this.plugin = plugin;
+ }
+
+ @Override
+ @ParametersAreNonnullByDefault
+ public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
+ //权限不足
+ if (!(sender.hasPermission("customcrops.admin") || sender.isOp())){
+ AdventureManager.playerMessage((Player) sender, ConfigReader.Message.prefix + ConfigReader.Message.noPerm);
+ return true;
+ }
+ //参数不足
+ if (args.length < 1) {
+ lackArgs(sender);
+ return true;
+ }
+ switch (args[0]){
+ case "reload" -> {
+ long time = System.currentTimeMillis();
+ ConfigReader.ReloadConfig();
+ if(sender instanceof Player){
+ AdventureManager.playerMessage((Player) sender,ConfigReader.Message.prefix + ConfigReader.Message.reload.replace("{time}", String.valueOf(System.currentTimeMillis() - time)));
+ }else {
+ AdventureManager.consoleMessage(ConfigReader.Message.prefix + ConfigReader.Message.reload.replace("{time}", String.valueOf(System.currentTimeMillis() - time)));
+ }
+ return true;
+ }
+ case "forcegrow" -> {
+ if (args.length < 2) {
+ lackArgs(sender);
+ return true;
+ }
+ plugin.getCropManager().cropGrow(args[1]);
+ if (sender instanceof Player player){
+ AdventureManager.playerMessage(player,ConfigReader.Message.prefix + ConfigReader.Message.forceGrow.replace("{world}",args[1]));
+ }else {
+ AdventureManager.consoleMessage(ConfigReader.Message.prefix + ConfigReader.Message.forceGrow.replace("{world}",args[1]));
+ }
+ return true;
+ }
+ case "forcewater" -> {
+ if (args.length < 2) {
+ lackArgs(sender);
+ return true;
+ }
+ plugin.getSprinklerManager().sprinklerWork(args[1]);
+ if (sender instanceof Player player){
+ AdventureManager.playerMessage(player,ConfigReader.Message.prefix + ConfigReader.Message.forceWater.replace("{world}",args[1]));
+ }else {
+ AdventureManager.consoleMessage(ConfigReader.Message.prefix + ConfigReader.Message.forceWater.replace("{world}",args[1]));
+ }
+ return true;
+ }
+ case "forcesave" -> {
+ if (args.length < 2) {
+ lackArgs(sender);
+ return true;
+ }
+ switch (args[1]){
+ case "all" -> {
+ plugin.getSprinklerManager().updateData();
+ plugin.getSprinklerManager().saveData();
+ if (ConfigReader.Season.enable && !ConfigReader.Season.seasonChange){
+ plugin.getSeasonManager().saveData();
+ }
+ plugin.getCropManager().updateData();
+ plugin.getCropManager().saveData();
+ plugin.getPotManager().saveData();
+ forceSave(sender);
+ }
+ case "crop" -> {
+ plugin.getCropManager().updateData();
+ plugin.getCropManager().saveData();
+ forceSave(sender);
+ }
+ case "pot" -> {
+ plugin.getPotManager().saveData();
+ forceSave(sender);
+ }
+ case "season" -> {
+ plugin.getSeasonManager().saveData();
+ forceSave(sender);
+ }
+ case "sprinkler" -> {
+ plugin.getSprinklerManager().updateData();
+ plugin.getSprinklerManager().saveData();
+ forceSave(sender);
+ }
+ }
+ }
+ case "backup" -> {
+ BackUp.backUpData();
+ if (sender instanceof Player player){
+ AdventureManager.playerMessage(player,ConfigReader.Message.prefix + ConfigReader.Message.backUp);
+ }else {
+ AdventureManager.consoleMessage(ConfigReader.Message.prefix + ConfigReader.Message.backUp);
+ }
+ return true;
+ }
+ case "setseason" -> {
+ if (args.length < 3) {
+ lackArgs(sender);
+ return true;
+ }
+ if (plugin.getSeasonManager().setSeason(args[1], args[2])){
+ if (sender instanceof Player player){
+ AdventureManager.playerMessage(player,ConfigReader.Message.prefix + ConfigReader.Message.setSeason.replace("{world}",args[1]).replace("{season}",args[2]));
+ }else {
+ AdventureManager.consoleMessage(ConfigReader.Message.prefix + ConfigReader.Message.setSeason.replace("{world}",args[1]).replace("{season}",args[2]));
+ }
+ }else {
+ if (sender instanceof Player player){
+ AdventureManager.playerMessage(player,ConfigReader.Message.prefix + ConfigReader.Message.wrongArgs);
+ }else {
+ AdventureManager.consoleMessage(ConfigReader.Message.prefix + ConfigReader.Message.wrongArgs);
+ }
+ }
+ return true;
+ }
+ default -> {
+ if (sender instanceof Player player){
+ AdventureManager.playerMessage(player,"");
+ }else {
+ AdventureManager.consoleMessage("");
+ }
+ }
+ }
+ return true;
+ }
+
+ private void lackArgs(CommandSender sender){
+ if (sender instanceof Player){
+ AdventureManager.playerMessage((Player) sender,ConfigReader.Message.prefix + ConfigReader.Message.lackArgs);
+ }else {
+ AdventureManager.consoleMessage(ConfigReader.Message.prefix + ConfigReader.Message.lackArgs);
+ }
+ }
+
+ private void forceSave(CommandSender sender){
+ if (sender instanceof Player player){
+ AdventureManager.playerMessage(player,ConfigReader.Message.prefix + ConfigReader.Message.forceSave);
+ }else {
+ AdventureManager.consoleMessage(ConfigReader.Message.prefix + ConfigReader.Message.forceSave);
+ }
+ }
+}
diff --git a/src/main/java/net/momirealms/customcrops/datamanager/ConfigManager.java b/src/main/java/net/momirealms/customcrops/datamanager/ConfigManager.java
deleted file mode 100644
index 9d8254c..0000000
--- a/src/main/java/net/momirealms/customcrops/datamanager/ConfigManager.java
+++ /dev/null
@@ -1,249 +0,0 @@
-package net.momirealms.customcrops.datamanager;
-
-import net.momirealms.customcrops.CustomCrops;
-import net.momirealms.customcrops.utils.Crop;
-import org.apache.commons.lang.StringUtils;
-import org.bukkit.Bukkit;
-import org.bukkit.configuration.file.FileConfiguration;
-import org.bukkit.configuration.file.YamlConfiguration;
-
-import java.io.File;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Set;
-
-public class ConfigManager {
-
- public static HashMap CONFIG;
- static {
- CONFIG = new HashMap<>();
- }
-
- public static class Config{
-
- public static boolean res;
- public static boolean wg;
- public static boolean king;
- public static boolean gd;
- public static boolean season;
- public static boolean need_water;
- public static boolean greenhouse;
- public static boolean limit;
- public static boolean log_time;
-
- public static List worlds;
- public static List cropGrowTimeList;
- public static List sprinklerWorkTimeList;
-
- public static String current;
- public static String prefix;
- public static String bad_place;
- public static String reload;
- public static String force_save;
- public static String nextSeason;
- public static String no_such_seed;
- public static String wrong_season;
- public static String season_set;
- public static String season_disabled;
- public static String force_grow;
- public static String force_water;
- public static String limit_crop;
- public static String limit_sprinkler;
- public static String backup;
- public static String spring;
- public static String summer;
- public static String autumn;
- public static String winter;
- public static String can_full;
- public static String pot;
- public static String watered_pot;
- public static String watering_can_1;
- public static String watering_can_2;
- public static String watering_can_3;
- public static String glass;
- public static String sprinkler_1;
- public static String sprinkler_2;
- public static String sprinkler_1i;
- public static String sprinkler_2i;
- public static String dead;
- public static String success;
- public static String failure;
-
- public static double bone_chance;
-
- public static int range;
- public static int maxh;
- public static int minh;
- public static int max_crop;
- public static int max_sprinkler;
-
- public static void ReloadConfig(){
- CustomCrops.instance.saveDefaultConfig();
- CustomCrops.instance.reloadConfig();
- FileConfiguration configuration = CustomCrops.instance.getConfig();
- //处理配置
- Config.res = configuration.getBoolean("config.integration.residence",false);
- Config.king = configuration.getBoolean("config.integration.kingdomsX",false);
- Config.wg = configuration.getBoolean("config.integration.worldguard",false);
- Config.gd = configuration.getBoolean("config.integration.griefdefender",false);
-
- if(res){
- if(Bukkit.getPluginManager().getPlugin("Residence") == null){
- CustomCrops.instance.getLogger().warning("未检测到插件Residence!");
- res = false;
- }else {
- MessageManager.consoleMessage("ccfbff-#ef96c5&[CustomCrops] &7检测到 &aResidence &7已启用领地保护!",Bukkit.getConsoleSender());
- }
- }
- if(king){
- if(Bukkit.getPluginManager().getPlugin("Kingdoms") == null){
- CustomCrops.instance.getLogger().warning("未检测到插件KingdomsX!");
- king = false;
- }else {
- MessageManager.consoleMessage("ccfbff-#ef96c5&[CustomCrops] &7检测到 &aKingdomsX &7已启用领地保护!",Bukkit.getConsoleSender());
- }
- }
- if(wg){
- if(Bukkit.getPluginManager().getPlugin("WorldGuard") == null){
- CustomCrops.instance.getLogger().warning("未检测到插件WorldGuard!");
- wg = false;
- }else {
- MessageManager.consoleMessage("ccfbff-#ef96c5&[CustomCrops] &7检测到 &aWorldGuard &7已启用区域保护!",Bukkit.getConsoleSender());
- }
- }
- if(gd){
- if(Bukkit.getPluginManager().getPlugin("GriefDefender") == null){
- CustomCrops.instance.getLogger().warning("未检测到插件GriefDefender!");
- gd = false;
- }else {
- MessageManager.consoleMessage("ccfbff-#ef96c5&[CustomCrops] &7检测到 &aGriefDefender &7已启用领地保护!",Bukkit.getConsoleSender());
- }
- }
-
- Config.season = configuration.getBoolean("enable-season");
- Config.need_water = configuration.getBoolean("config.bone-meal-consume-water");
- Config.greenhouse = configuration.getBoolean("config.enable-greenhouse");
- Config.limit = configuration.getBoolean("config.enable-limit");
- Config.log_time = configuration.getBoolean("config.log-time-consume", false);
-
- Config.bone_chance = configuration.getDouble("config.bone-meal-chance");
-
- Config.range = configuration.getInt("config.greenhouse-range");
- Config.maxh = configuration.getInt("config.height.max");
- Config.minh = configuration.getInt("config.height.min");
- Config.max_crop = configuration.getInt("config.max-crops");
- Config.max_sprinkler = configuration.getInt("config.max-sprinklers");
-
- Config.current = configuration.getString("current-season");
- Config.pot = configuration.getString("config.pot");
- Config.watered_pot = configuration.getString("config.watered-pot");
- Config.watering_can_1 = configuration.getString("config.watering-can-1");
- Config.watering_can_2 = configuration.getString("config.watering-can-2");
- Config.watering_can_3 = configuration.getString("config.watering-can-3");
- Config.glass = configuration.getString("config.greenhouse-glass");
- Config.sprinkler_1 = configuration.getString("config.sprinkler-1");
- Config.sprinkler_2 = configuration.getString("config.sprinkler-2");
- Config.sprinkler_1i = configuration.getString("config.sprinkler-1-item");
- Config.sprinkler_2i = configuration.getString("config.sprinkler-2-item");
- Config.dead = configuration.getString("config.dead-crop");
- Config.success = configuration.getString("config.particle.success");
- Config.failure = configuration.getString("config.particle.failure");
-
- Config.worlds = configuration.getStringList("config.whitelist-worlds");
- Config.cropGrowTimeList = configuration.getLongList("config.grow-time");
- Config.sprinklerWorkTimeList = configuration.getLongList("config.sprinkler-time");
-
- //处理消息
- Config.prefix = configuration.getString("messages.prefix");
- Config.bad_place = configuration.getString("messages.not-a-good-place");
- Config.reload = configuration.getString("messages.reload");
- Config.force_save = configuration.getString("messages.force-save");
- Config.nextSeason = configuration.getString("messages.nextseason");
- Config.no_such_seed = configuration.getString("messages.no-such-seed");
- Config.wrong_season = configuration.getString("messages.wrong-season");
- Config.season_set = configuration.getString("messages.season-set");
- Config.season_disabled = configuration.getString("messages.season-disabled");
- Config.force_grow = configuration.getString("messages.force-grow");
- Config.force_water = configuration.getString("messages.force-water");
- Config.limit_crop = configuration.getString("messages.reach-limit-crop");
- Config.limit_sprinkler = configuration.getString("messages.reach-limit-sprinkler");
- Config.can_full = configuration.getString("messages.can-full");
- Config.backup = configuration.getString("messages.backup");
- Config.spring = configuration.getString("messages.spring");
- Config.summer = configuration.getString("messages.summer");
- Config.autumn = configuration.getString("messages.autumn");
- Config.winter = configuration.getString("messages.winter");
-
- cropLoad();
- }
-
- /*
- 根据文件名获取配置文件
- */
- public static YamlConfiguration getConfig(String configName) {
-
- File file = new File(CustomCrops.instance.getDataFolder(), configName);
- //文件不存在则生成默认配置
- if (!file.exists()) {
- CustomCrops.instance.saveResource(configName, false);
- }
- return YamlConfiguration.loadConfiguration(file);
- }
-
- /*
- 加载农作物数据
- */
- public static void cropLoad(){
- try {
- CONFIG.clear();
- YamlConfiguration cropConfig = getConfig("crops.yml");
- Set keys = cropConfig.getConfigurationSection("crops").getKeys(false);
- keys.forEach(key -> {
- if(cropConfig.getConfigurationSection("crops."+key).contains("grow-chance")){
- double chance = cropConfig.getDouble("crops."+key+".grow-chance");
- Crop crop = new Crop(key, chance);
- if(cropConfig.getConfigurationSection("crops."+key).contains("return")){
- crop.setWillReturn(true);
- crop.setReturnStage(cropConfig.getString("crops."+key+".return"));
- }else {
- crop.setWillReturn(false);
- }
- if(Config.season){
- if(cropConfig.getConfigurationSection("crops."+key).contains("season")){
- crop.setSeasons(StringUtils.split( cropConfig.getString("crops."+key+".season"), ","));
- }else {
- MessageManager.consoleMessage("&c[CustomCrops] 错误!在启用季节模式的情况下未设置农作物 &f"+ key +" &c的生长季节!", Bukkit.getConsoleSender());
- return;
- }
- }
- if(cropConfig.getConfigurationSection("crops."+key).contains("gigantic")){
- crop.setWillGiant(true);
- crop.setGiant(cropConfig.getString("crops."+key+".gigantic"));
- if(cropConfig.getConfigurationSection("crops."+key).contains("gigantic-chance")){
- crop.setGiantChance(cropConfig.getDouble("crops."+key+".gigantic-chance"));
- }else {
- MessageManager.consoleMessage("&c[CustomCrops] 错误!未设置农作物 &f"+ key +" &c的巨大化概率!", Bukkit.getConsoleSender());
- return;
- }
- }else {
- crop.setWillGiant(false);
- }
- CONFIG.put(key, crop);
- }else {
- MessageManager.consoleMessage("&c[CustomCrops] 错误!未设置农作物 &f"+ key +" &c的生长概率!", Bukkit.getConsoleSender());
- }
- });
- if(keys.size() == CONFIG.size()){
- MessageManager.consoleMessage("ccfbff-#ef96c5&[CustomCrops] &7成功载入 &a" + CONFIG.size() + " &7种农作物", Bukkit.getConsoleSender());
- }else {
- MessageManager.consoleMessage("&c[CustomCrops] crops.yml配置存在错误,请根据上述提示仔细检查!", Bukkit.getConsoleSender());
- }
- }
- catch (Exception e) {
- e.printStackTrace();
- CustomCrops.instance.getLogger().warning("crops.yml加载失败!");
- }
- }
- }
-}
diff --git a/src/main/java/net/momirealms/customcrops/datamanager/CropManager.java b/src/main/java/net/momirealms/customcrops/datamanager/CropManager.java
index fc5a001..9d00b9e 100644
--- a/src/main/java/net/momirealms/customcrops/datamanager/CropManager.java
+++ b/src/main/java/net/momirealms/customcrops/datamanager/CropManager.java
@@ -1,249 +1,236 @@
package net.momirealms.customcrops.datamanager;
import dev.lone.itemsadder.api.CustomBlock;
+import net.momirealms.customcrops.fertilizer.QualityCrop;
+import net.momirealms.customcrops.utils.AdventureManager;
+import net.momirealms.customcrops.ConfigReader;
import net.momirealms.customcrops.CustomCrops;
-import net.momirealms.customcrops.utils.Crop;
+import net.momirealms.customcrops.fertilizer.Fertilizer;
+import net.momirealms.customcrops.fertilizer.RetainingSoil;
+import net.momirealms.customcrops.fertilizer.SpeedGrow;
+import net.momirealms.customcrops.utils.CropInstance;
import org.apache.commons.lang.StringUtils;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.World;
-import org.bukkit.block.Block;
-import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.configuration.file.YamlConfiguration;
-import org.bukkit.scheduler.BukkitScheduler;
import java.io.File;
import java.io.IOException;
-import java.util.*;
+import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
public class CropManager {
- public static ConcurrentHashMap CROPS;
- /*
- 开服的时候将文件的数据读入
- */
- public static void loadData() {
+ private YamlConfiguration data;
+ private final CustomCrops plugin;
+ public static ConcurrentHashMap Cache = new ConcurrentHashMap<>();
- File file = new File(CustomCrops.instance.getDataFolder(), "crop-data.yml");
- FileConfiguration data = YamlConfiguration.loadConfiguration(file);
+ public CropManager(CustomCrops plugin){
+ this.plugin = plugin;
+ }
- CROPS = new ConcurrentHashMap<>();
-
- for (String world : ConfigManager.Config.worlds) {
- //如果数据文件中有相应世界才进行读取
- if(data.contains(world)){
- for (String coordinate : data.getConfigurationSection(world).getKeys(false)) {
- Location tempLoc = new Location(Bukkit.getWorld(world), Integer.parseInt(coordinate.split(",")[0]), Integer.parseInt(coordinate.split(",")[1]), Integer.parseInt(coordinate.split(",")[2]));
- String cropName = data.getString(world + "." + coordinate);
- CROPS.put(tempLoc, cropName);
- }
+ //载入数据
+ public void loadData() {
+ File file = new File(CustomCrops.instance.getDataFolder(), "data" + File.separator + "crop.yml");
+ if(!file.exists()){
+ try {
+ file.getParentFile().mkdirs();
+ file.createNewFile();
+ } catch (IOException e) {
+ e.printStackTrace();
+ AdventureManager.consoleMessage("[CustomCrops] 农作物数据文件生成失败!");
}
}
+ this.data = YamlConfiguration.loadConfiguration(file);
}
- /*
- 保存数据
- */
- public static void saveData(){
-
- File file = new File(CustomCrops.instance.getDataFolder(), "crop-data.yml");
- FileConfiguration data;
- data = YamlConfiguration.loadConfiguration(file);
-
- Set> en = CROPS.entrySet();
- for(Map.Entry entry : en){
- Location loc = entry.getKey();
- data.set(loc.getWorld().getName()+"."+ loc.getBlockX() + "," + loc.getBlockY()+ ","+loc.getBlockZ(), entry.getValue());
- }
- try {
- data.save(file);
- }
- catch (IOException e) {
- e.printStackTrace();
- CustomCrops.instance.getLogger().warning("农作物数据保存出错");
- }
- }
- /*
- 生长部分
- */
- public static void CropGrow(String worldName) {
- /*
- 阶段1:更新数据
- */
- long start1 = System.currentTimeMillis();
- File file = new File(CustomCrops.instance.getDataFolder(), "crop-data.yml");
- FileConfiguration data = YamlConfiguration.loadConfiguration(file);
- BukkitScheduler bukkitScheduler = Bukkit.getScheduler();
- Set> en = CROPS.entrySet();
- for(Map.Entry entry : en){
- Location key = entry.getKey();
- data.set(key.getWorld().getName() + "." + key.getBlockX() + "," + key.getBlockY()+ ","+ key.getBlockZ(), entry.getValue());
- }
- long finish1 = System.currentTimeMillis();
- if (ConfigManager.Config.log_time){
- MessageManager.consoleMessage("ccfbff-#ef96c5&[CustomCrops] &7农作物数据更新耗时&a" + (finish1 - start1) + "&fms",Bukkit.getConsoleSender());
- }
- /*
- 阶段2:清理数据内无效的农作物并让有效农作物生长
- */
- long start2 = System.currentTimeMillis();
- if(data.contains(worldName)){
- World world = Bukkit.getWorld(worldName);
- data.getConfigurationSection(worldName).getKeys(false).forEach(key ->{
- String[] coordinate = StringUtils.split(key,",");
- //先判断区块是否加载,未加载则不进行下一步计算
- if (world.isChunkLoaded(Integer.parseInt(coordinate[0])/16, Integer.parseInt(coordinate[2])/16)){
- Location sLoc = new Location(world,Double.parseDouble(coordinate[0]),Double.parseDouble(coordinate[1]),Double.parseDouble(coordinate[2]));
- CustomBlock seedBlock = CustomBlock.byAlreadyPlaced(sLoc.getBlock());
- if(seedBlock == null){
- CROPS.remove(sLoc);
- data.set(worldName+"."+coordinate[0]+","+coordinate[1]+","+coordinate[2], null);
- }else{
- String namespacedID = seedBlock.getNamespacedID();
- /*
- 对之前旧版本的一些兼容
- 以及一些意料之外的情况,防止报错
- */
- if(namespacedID.equalsIgnoreCase(ConfigManager.Config.dead)){
- CROPS.remove(sLoc);
- data.set(worldName+"."+coordinate[0]+","+coordinate[1]+","+coordinate[2], null);
- return;
- }
- if(namespacedID.contains("_stage_")){
- Location potLoc = sLoc.clone().subtract(0,1,0);
- Block potBlock = potLoc.getBlock();
- CustomBlock pot = CustomBlock.byAlreadyPlaced(potBlock);
- if (pot != null){
- String potName = pot.getNamespacedID();
- /*
- 是湿润的种植盆吗
- */
- if (potName.equalsIgnoreCase(ConfigManager.Config.watered_pot)){
- String[] split = StringUtils.split(namespacedID,":");
- String[] cropNameList = StringUtils.split(split[1],"_");
- Crop crop = ConfigManager.CONFIG.get(cropNameList[0]);
- //季节判断
- Label_out:
- if(ConfigManager.Config.season){
- if(ConfigManager.Config.greenhouse){
- for(int i = 1; i <= ConfigManager.Config.range; i++){
- CustomBlock cb = CustomBlock.byAlreadyPlaced(sLoc.clone().add(0,i,0).getBlock());
- if (cb != null){
- if(cb.getNamespacedID().equalsIgnoreCase(ConfigManager.Config.glass)){
- break Label_out;
- }
- }
- }
- }
- boolean ws = true;
- for(String season : crop.getSeasons()){
- if (Objects.equals(season, ConfigManager.Config.current)) {
- ws = false;
- break;
- }
- }
- if(ws){
- CROPS.remove(sLoc);
- data.set(worldName+"."+coordinate[0]+","+coordinate[1]+","+coordinate[2], null);
- bukkitScheduler.callSyncMethod(CustomCrops.instance, () -> {
- CustomBlock.remove(sLoc);
- CustomBlock.place(ConfigManager.Config.dead, sLoc);
- return null;
- });
- return;
- }
- }
- //下一阶段判断
- int nextStage = Integer.parseInt(cropNameList[2]) + 1;
- if (CustomBlock.getInstance(split[0] +":"+cropNameList[0] + "_stage_" + nextStage) != null) {
- bukkitScheduler.callSyncMethod(CustomCrops.instance, () ->{
- CustomBlock.remove(potLoc);
- CustomBlock.place(ConfigManager.Config.pot, potLoc);
- if(Math.random()< crop.getChance()){
- CustomBlock.remove(sLoc);
- CustomBlock.place(split[0] + ":" + cropNameList[0] + "_stage_" + nextStage, sLoc);
- }
- return null;
- });
- }
- //巨大化判断
- else if(crop.getWillGiant()){
- bukkitScheduler.callSyncMethod(CustomCrops.instance, () ->{
- CustomBlock.remove(potLoc);
- CustomBlock.place(ConfigManager.Config.pot, potLoc);
- if(crop.getGiantChance() > Math.random()){
- CROPS.remove(sLoc);
- data.set(worldName+"."+coordinate[0]+","+coordinate[1]+","+coordinate[2], null);
- CustomBlock.remove(sLoc);
- CustomBlock.place(crop.getGiant(), sLoc);
- }
- return null;
- });
- }
- }
- /*
- 是干燥的种植盆吗
- */
- else if(potName.equalsIgnoreCase(ConfigManager.Config.pot)){
- if(ConfigManager.Config.season) {
- if(ConfigManager.Config.greenhouse){
- for(int i = 1; i <= ConfigManager.Config.range; i++){
- CustomBlock cb = CustomBlock.byAlreadyPlaced(sLoc.clone().add(0,i,0).getBlock());
- if (cb != null){
- if(cb.getNamespacedID().equalsIgnoreCase(ConfigManager.Config.glass)){
- return;
- }
- }
- }
- }
- boolean ws = true;
- Crop crop = ConfigManager.CONFIG.get(StringUtils.split(StringUtils.split(namespacedID,":")[1],"_")[0]);
- for (String season : crop.getSeasons()) {
- if (Objects.equals(season, ConfigManager.Config.current)) {
- ws = false;
- break;
- }
- }
- if (ws) {
- CROPS.remove(sLoc);
- data.set(worldName+"."+coordinate[0]+","+coordinate[1]+","+coordinate[2], null);
- bukkitScheduler.callSyncMethod(CustomCrops.instance, () -> {
- CustomBlock.remove(sLoc);
- CustomBlock.place(ConfigManager.Config.dead, sLoc);
- return null;
- });
- }
- }
- }
- }
- }
- else {
- CROPS.remove(sLoc);
- data.set(worldName+"."+coordinate[0]+","+coordinate[1]+","+coordinate[2], null);
- }
- }
- }
- });
- }
- long finish2 = System.currentTimeMillis();
- if (ConfigManager.Config.log_time){
- MessageManager.consoleMessage("ccfbff-#ef96c5&[CustomCrops] &7农作物生长耗时&a" + (finish2 - start2) + "&fms",Bukkit.getConsoleSender());
- }
-
- /*
- 阶段3:保存文件
- */
- long start3 = System.currentTimeMillis();
+ //保存数据
+ public void saveData() {
+ File file = new File(CustomCrops.instance.getDataFolder(), "data" + File.separator + "crop.yml");
try{
data.save(file);
}catch (IOException e){
e.printStackTrace();
- CustomCrops.instance.getLogger().warning("crop-data.yml保存出错!");
- }
- long finish3 = System.currentTimeMillis();
- if (ConfigManager.Config.log_time){
- MessageManager.consoleMessage("ccfbff-#ef96c5&[CustomCrops] &7农作物数据保存耗时&a" + (finish3 - start3) + "&fms",Bukkit.getConsoleSender());
+ AdventureManager.consoleMessage("[CustomCrops] crop.yml保存出错!");
}
}
-}
+
+ //将缓存内新数据更新到data内
+ public void updateData(){
+ Cache.forEach((location, String) -> {
+ int x = location.getBlockX();
+ int z = location.getBlockZ();
+ data.set(location.getWorld().getName() + "." + x / 16 + "," + z / 16 + "." + x + "," + location.getBlockY() + "," + z, String);
+ });
+ Cache.clear();
+ }
+
+ //农作物生长
+ public void cropGrow(String worldName){
+ Long time1 = System.currentTimeMillis();
+ updateData();
+ Long time2 = System.currentTimeMillis();
+ if(ConfigReader.Config.logTime){
+ AdventureManager.consoleMessage("性能监测: 农作物数据更新" + (time2-time1) + "ms");
+ }
+ if (data.contains(worldName)){
+ data.getConfigurationSection(worldName).getKeys(false).forEach(chunk ->{
+ String[] split = StringUtils.split(chunk,",");
+ World world = Bukkit.getWorld(worldName);
+ if (ConfigReader.Config.onlyLoadedGrow || world.isChunkLoaded(Integer.parseInt(split[0]), Integer.parseInt(split[1]))){
+ data.getConfigurationSection(worldName + "." + chunk).getValues(false).forEach((key, value) -> {
+ String[] coordinate = StringUtils.split(key, ",");
+ Location seedLocation = new Location(world,Double.parseDouble(coordinate[0]),Double.parseDouble(coordinate[1]),Double.parseDouble(coordinate[2]));
+ CustomBlock seedBlock = CustomBlock.byAlreadyPlaced(seedLocation.getBlock());
+ StringBuilder stringBuilder = new StringBuilder();
+ //需要修改
+ stringBuilder.append(worldName).append(".").append(chunk).append(".").append(key);
+ if(seedBlock == null) {
+ data.set(stringBuilder.toString(), null);
+ return;
+ }
+ String namespacedID = seedBlock.getNamespacedID();
+ String id = seedBlock.getId();
+ if(namespacedID.equals(ConfigReader.Basic.dead)) {
+ data.set(stringBuilder.toString(), null);
+ return;
+ }
+ if(!namespacedID.contains("_stage_")) {
+ data.set(stringBuilder.toString(), null);
+ return;
+ }
+ Location potLocation = seedLocation.clone().subtract(0,1,0);
+ CustomBlock pot = CustomBlock.byAlreadyPlaced(potLocation.getBlock());
+ if (pot == null) return;
+ String potNamespacedID = pot.getNamespacedID();
+ String[] cropNameList = StringUtils.split(id,"_");
+ CropInstance cropInstance = ConfigReader.CROPS.get(cropNameList[0]);
+ if (potNamespacedID.equals(ConfigReader.Basic.watered_pot)){
+ //如果启用季节限制且农作物有季节需求
+ if (ConfigReader.Season.enable && cropInstance.getSeasons() != null){
+ if (isWrongSeason(seedLocation, cropInstance.getSeasons(), worldName)){
+ data.set(stringBuilder.toString(), null);
+ Bukkit.getScheduler().callSyncMethod(CustomCrops.instance, () -> {
+ CustomBlock.remove(seedLocation);
+ CustomBlock.place(ConfigReader.Basic.dead, seedLocation);
+ return null;
+ });
+ return;
+ }
+ }
+ int nextStage = Integer.parseInt(cropNameList[2]) + 1;
+ if (CustomBlock.getInstance(StringUtils.chop(namespacedID) + nextStage) != null) {
+ Fertilizer fertilizer = PotManager.Cache.get(potLocation);
+ if (fertilizer != null){
+ int times = fertilizer.getTimes();
+ if (times > 0){
+ fertilizer.setTimes(times - 1);
+ if (fertilizer instanceof SpeedGrow speedGrow){
+ if (Math.random() < speedGrow.getChance() && CustomBlock.getInstance(StringUtils.chop(namespacedID) + (nextStage + 1)) != null){
+ addStage(potLocation, seedLocation, namespacedID, nextStage + 1);
+ }else {
+ addStage(potLocation, seedLocation, namespacedID, nextStage);
+ }
+ }else if(fertilizer instanceof RetainingSoil retainingSoil){
+ if (Math.random() < retainingSoil.getChance()){
+ addStage(seedLocation, namespacedID, nextStage);
+ }else {
+ addStage(potLocation, seedLocation, namespacedID, nextStage);
+ }
+ }else if(fertilizer instanceof QualityCrop){
+ addStage(potLocation, seedLocation, namespacedID, nextStage);
+ }else {
+ AdventureManager.consoleMessage("[CustomCrops] 发现未知类型肥料,已自动清除错误数据!");
+ PotManager.Cache.remove(potLocation);
+ }
+ }else {
+ PotManager.Cache.remove(potLocation);
+ }
+ }
+ else {
+ addStage(potLocation, seedLocation, namespacedID, nextStage);
+ }
+ }
+ else if(cropInstance.getGiant() != null){
+ Bukkit.getScheduler().callSyncMethod(CustomCrops.instance, () ->{
+ CustomBlock.remove(potLocation);
+ CustomBlock.place(ConfigReader.Basic.pot, potLocation);
+ if(cropInstance.getGiantChance() > Math.random()){
+ data.set(stringBuilder.toString(), null);
+ CustomBlock.remove(seedLocation);
+ CustomBlock.place(cropInstance.getGiant(), seedLocation);
+ }
+ return null;
+ });
+ }else {
+ if (cropInstance.getReturnStage() == null && !ConfigReader.Season.enable) data.set(stringBuilder.toString(), null);
+ Bukkit.getScheduler().callSyncMethod(CustomCrops.instance, () -> {
+ CustomBlock.remove(potLocation);
+ CustomBlock.place(ConfigReader.Basic.pot, potLocation);
+ return null;
+ });
+ }
+ }else if(potNamespacedID.equals(ConfigReader.Basic.pot)){
+ if(!ConfigReader.Season.enable || cropInstance.getSeasons() == null) return;
+ if(isWrongSeason(seedLocation, cropInstance.getSeasons(), worldName)){
+ data.set(stringBuilder.toString(), null);
+ Bukkit.getScheduler().callSyncMethod(CustomCrops.instance, () -> {
+ CustomBlock.remove(seedLocation);
+ CustomBlock.place(ConfigReader.Basic.dead, seedLocation);
+ return null;
+ });
+ }
+ }
+ });
+ }
+ });
+ }
+ Long time3 = System.currentTimeMillis();
+ if(ConfigReader.Config.logTime){
+ AdventureManager.consoleMessage("性能监测: 农作物生长过程" + (time3-time2) + "ms");
+ }
+ saveData();
+ Long time4 = System.currentTimeMillis();
+ if(ConfigReader.Config.logTime){
+ AdventureManager.consoleMessage("性能监测: 农作物数据保存" + (time4-time3) + "ms");
+ }
+ }
+
+ private boolean isWrongSeason(Location seedLocation, List seasons, String worldName){
+ if(ConfigReader.Season.greenhouse){
+ for(int i = 1; i <= ConfigReader.Season.range; i++){
+ CustomBlock customBlock = CustomBlock.byAlreadyPlaced(seedLocation.clone().add(0,i,0).getBlock());
+ if (customBlock != null){
+ if(customBlock.getNamespacedID().equals(ConfigReader.Basic.glass)){
+ return false;
+ }
+ }
+ }
+ }
+ for(String season : seasons){
+ if (season.equals(SeasonManager.SEASON.get(worldName))) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ private void addStage(Location potLocation, Location seedLocation, String namespacedID, int nextStage){
+ Bukkit.getScheduler().callSyncMethod(CustomCrops.instance, () ->{
+ CustomBlock.remove(potLocation);
+ CustomBlock.place(ConfigReader.Basic.pot, potLocation);
+ CustomBlock.remove(seedLocation);
+ CustomBlock.place(StringUtils.chop(namespacedID) + nextStage, seedLocation);
+ return null;
+ });
+ }
+
+ private void addStage(Location seedLocation, String namespacedID, int nextStage){
+ Bukkit.getScheduler().callSyncMethod(CustomCrops.instance, () ->{
+ CustomBlock.remove(seedLocation);
+ CustomBlock.place(StringUtils.chop(namespacedID) + nextStage, seedLocation);
+ return null;
+ });
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/net/momirealms/customcrops/datamanager/MessageManager.java b/src/main/java/net/momirealms/customcrops/datamanager/MessageManager.java
deleted file mode 100644
index 8a5550c..0000000
--- a/src/main/java/net/momirealms/customcrops/datamanager/MessageManager.java
+++ /dev/null
@@ -1,12 +0,0 @@
-package net.momirealms.customcrops.datamanager;
-
-import net.momirealms.customcrops.libs.minedown.MineDown;
-import org.bukkit.command.CommandSender;
-import org.bukkit.entity.Player;
-
-public class MessageManager {
- public static void consoleMessage(String s, CommandSender sender) { sender.spigot().sendMessage(MineDown.parse(s)); }
- public static void playerMessage(String s, Player player){
- player.spigot().sendMessage(MineDown.parse(s));
- }
-}
diff --git a/src/main/java/net/momirealms/customcrops/datamanager/NextSeason.java b/src/main/java/net/momirealms/customcrops/datamanager/NextSeason.java
deleted file mode 100644
index b63c72c..0000000
--- a/src/main/java/net/momirealms/customcrops/datamanager/NextSeason.java
+++ /dev/null
@@ -1,28 +0,0 @@
-package net.momirealms.customcrops.datamanager;
-
-import net.momirealms.customcrops.CustomCrops;
-import org.bukkit.configuration.file.FileConfiguration;
-
-import java.util.Objects;
-
-public class NextSeason {
-
- public static void changeSeason(){
- FileConfiguration config = CustomCrops.instance.getConfig();
- String currentSeason = ConfigManager.Config.current;
- String nextSeason = switch (Objects.requireNonNull(currentSeason)) {
- case "spring" -> "summer";
- case "summer" -> "autumn";
- case "autumn" -> "winter";
- case "winter" -> "spring";
- default -> null;
- };
- if(nextSeason != null){
- config.set("current-season", nextSeason);
- ConfigManager.Config.current = nextSeason;
- CustomCrops.instance.saveConfig();
- }else {
- CustomCrops.instance.getLogger().warning("季节出错!");
- }
- }
-}
\ No newline at end of file
diff --git a/src/main/java/net/momirealms/customcrops/datamanager/PotManager.java b/src/main/java/net/momirealms/customcrops/datamanager/PotManager.java
new file mode 100644
index 0000000..44e7124
--- /dev/null
+++ b/src/main/java/net/momirealms/customcrops/datamanager/PotManager.java
@@ -0,0 +1,81 @@
+package net.momirealms.customcrops.datamanager;
+
+import net.momirealms.customcrops.utils.AdventureManager;
+import net.momirealms.customcrops.ConfigReader;
+import net.momirealms.customcrops.CustomCrops;
+import net.momirealms.customcrops.fertilizer.Fertilizer;
+import net.momirealms.customcrops.fertilizer.QualityCrop;
+import net.momirealms.customcrops.fertilizer.RetainingSoil;
+import net.momirealms.customcrops.fertilizer.SpeedGrow;
+import org.apache.commons.lang.StringUtils;
+import org.bukkit.Bukkit;
+import org.bukkit.Location;
+import org.bukkit.configuration.MemorySection;
+import org.bukkit.configuration.file.YamlConfiguration;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.concurrent.ConcurrentHashMap;
+
+public class PotManager {
+
+ private CustomCrops plugin;
+ public static ConcurrentHashMap Cache = new ConcurrentHashMap<>();
+
+ public PotManager(CustomCrops plugin){
+ this.plugin = plugin;
+ }
+
+ public void loadData(){
+ File file = new File(CustomCrops.instance.getDataFolder(), "data" + File.separator + "pot.yml");
+ if(!file.exists()){
+ try {
+ file.getParentFile().mkdirs();
+ file.createNewFile();
+ } catch (IOException e) {
+ e.printStackTrace();
+ AdventureManager.consoleMessage("[CustomCrops] 种植盆数据文件生成失败!");
+ }
+ }
+ YamlConfiguration data = YamlConfiguration.loadConfiguration(file);
+ data.getKeys(false).forEach(worldName -> {
+ if (ConfigReader.Config.worldNames.contains(worldName)){
+ data.getConfigurationSection(worldName).getValues(false).forEach((key, value) ->{
+ String[] split = StringUtils.split(key, ",");
+ if (value instanceof MemorySection map){
+ String name = (String) map.get("fertilizer");
+ Fertilizer fertilizer = ConfigReader.FERTILIZERS.get(name);
+ if (fertilizer == null) return;
+ if (fertilizer instanceof SpeedGrow speedGrow){
+ Cache.put(new Location(Bukkit.getWorld(worldName), Double.parseDouble(split[0]), Double.parseDouble(split[1]), Double.parseDouble(split[2])), new SpeedGrow(name, (int) map.get("times"), speedGrow.getChance(), speedGrow.isBefore()));
+ }else if (fertilizer instanceof QualityCrop qualityCrop){
+ Cache.put(new Location(Bukkit.getWorld(worldName), Double.parseDouble(split[0]), Double.parseDouble(split[1]), Double.parseDouble(split[2])), new QualityCrop(name, (int) map.get("times"), qualityCrop.getChance(), qualityCrop.isBefore()));
+ }else if (fertilizer instanceof RetainingSoil retainingSoil){
+ Cache.put(new Location(Bukkit.getWorld(worldName), Double.parseDouble(split[0]), Double.parseDouble(split[1]), Double.parseDouble(split[2])), new RetainingSoil(name, (int) map.get("times"), retainingSoil.getChance(), retainingSoil.isBefore()));
+ }else {
+ AdventureManager.consoleMessage("[CustomCrops] 未知肥料类型错误!");
+ }
+ }
+ });
+ }
+ });
+ }
+
+ public void saveData(){
+ File file = new File(CustomCrops.instance.getDataFolder(), "data" + File.separator + "pot.yml");
+ YamlConfiguration data = new YamlConfiguration();
+ Cache.forEach(((location, fertilizer) -> {
+ String world = location.getWorld().getName();
+ int x = location.getBlockX();
+ int y = location.getBlockY();
+ int z = location.getBlockZ();
+ data.set(world + "." + x + "," + y + "," + z + ".fertilizer", fertilizer.getKey());
+ data.set(world + "." + x + "," + y + "," + z + ".times", fertilizer.getTimes());
+ }));
+ try {
+ data.save(file);
+ }catch (IOException e){
+ e.printStackTrace();
+ }
+ }
+}
diff --git a/src/main/java/net/momirealms/customcrops/datamanager/SeasonManager.java b/src/main/java/net/momirealms/customcrops/datamanager/SeasonManager.java
new file mode 100644
index 0000000..33de245
--- /dev/null
+++ b/src/main/java/net/momirealms/customcrops/datamanager/SeasonManager.java
@@ -0,0 +1,90 @@
+package net.momirealms.customcrops.datamanager;
+
+import net.momirealms.customcrops.utils.AdventureManager;
+import net.momirealms.customcrops.ConfigReader;
+import net.momirealms.customcrops.CustomCrops;
+import org.bukkit.Bukkit;
+import org.bukkit.World;
+import org.bukkit.configuration.file.YamlConfiguration;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Set;
+
+public record SeasonManager(CustomCrops plugin) {
+
+ public static HashMap SEASON = new HashMap<>();
+
+ private YamlConfiguration readData(File file) {
+ if (!file.exists()) {
+ try {
+ file.getParentFile().mkdirs();
+ file.createNewFile();
+ } catch (IOException e) {
+ e.printStackTrace();
+ AdventureManager.consoleMessage("[CustomCrops] 季节数据文件生成失败!");
+ }
+ }
+ return YamlConfiguration.loadConfiguration(file);
+ }
+
+ public void loadData() {
+ SEASON.clear();
+ YamlConfiguration data = readData(new File(CustomCrops.instance.getDataFolder(), "data" + File.separator + "season.yml"));
+ if (ConfigReader.Season.seasonChange) {
+ autoSeason();
+ } else {
+ Set set = data.getKeys(false);
+ ConfigReader.Config.worldNames.forEach(worldName -> {
+ if (set.contains(worldName)) {
+ SEASON.put(worldName, data.getString(worldName));
+ } else {
+ getSeason(Bukkit.getWorld(worldName));
+ }
+ });
+ }
+ }
+
+ public void autoSeason() {
+ ConfigReader.Config.worlds.forEach(this::getSeason);
+ }
+
+ public void getSeason(World world) {
+
+ int season = (int) ((world.getFullTime() / 24000L) % (ConfigReader.Season.duration * 4)) / ConfigReader.Season.duration;
+ switch (season) {
+ case 0 -> SEASON.put(world.getName(), "spring");
+ case 1 -> SEASON.put(world.getName(), "summer");
+ case 2 -> SEASON.put(world.getName(), "autumn");
+ case 3 -> SEASON.put(world.getName(), "winter");
+ default -> AdventureManager.consoleMessage("[CustomCrops] 自动季节计算错误!");
+ }
+ }
+
+ public void saveData() {
+ SEASON.forEach((key, value) -> {
+ File file = new File(CustomCrops.instance.getDataFolder(), "data" + File.separator + "season.yml");
+ YamlConfiguration data = readData(file);
+ data.set(key, value);
+ try {
+ data.save(file);
+ } catch (IOException e) {
+ e.printStackTrace();
+ AdventureManager.consoleMessage("[CustomCrops] season.yml保存出错!");
+ }
+ });
+ }
+
+ public boolean setSeason(String worldName, String season){
+ if (!ConfigReader.Config.worldNames.contains(worldName)){
+ return false;
+ }
+ if (!Arrays.asList("spring","summer","autumn","winter").contains(season)){
+ return false;
+ }
+ SEASON.put(worldName, season);
+ return true;
+ }
+}
diff --git a/src/main/java/net/momirealms/customcrops/datamanager/SprinklerManager.java b/src/main/java/net/momirealms/customcrops/datamanager/SprinklerManager.java
index 52a7906..b515b78 100644
--- a/src/main/java/net/momirealms/customcrops/datamanager/SprinklerManager.java
+++ b/src/main/java/net/momirealms/customcrops/datamanager/SprinklerManager.java
@@ -1,153 +1,124 @@
package net.momirealms.customcrops.datamanager;
import dev.lone.itemsadder.api.CustomBlock;
+import net.momirealms.customcrops.utils.AdventureManager;
+import net.momirealms.customcrops.ConfigReader;
import net.momirealms.customcrops.CustomCrops;
import net.momirealms.customcrops.utils.IAFurniture;
+import net.momirealms.customcrops.utils.Sprinkler;
import org.apache.commons.lang.StringUtils;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.World;
-import org.bukkit.configuration.file.FileConfiguration;
+import org.bukkit.configuration.MemorySection;
import org.bukkit.configuration.file.YamlConfiguration;
-import org.bukkit.scheduler.BukkitScheduler;
import java.io.File;
import java.io.IOException;
-import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
public class SprinklerManager {
- static ConcurrentHashMap SPRINKLERS;
- /*
- 开服的时候将文件的数据读入
- */
- public static void loadData(){
+ public YamlConfiguration data;
+ private final CustomCrops plugin;
+ public static ConcurrentHashMap Cache = new ConcurrentHashMap<>();
- SPRINKLERS = new ConcurrentHashMap<>();
+ public SprinklerManager(CustomCrops plugin){
+ this.plugin = plugin;
+ }
- File file = new File(CustomCrops.instance.getDataFolder(), "sprinkler-data.yml");
- FileConfiguration data = YamlConfiguration.loadConfiguration(file);
-
- for (String world : ConfigManager.Config.worlds) {
- 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);
- SPRINKLERS.put(tempLocation, type);
- }
+ public void loadData() {
+ File file = new File(CustomCrops.instance.getDataFolder(), "data" + File.separator + "sprinkler.yml");
+ if(!file.exists()){
+ try {
+ file.getParentFile().mkdirs();
+ file.createNewFile();
+ } catch (IOException e) {
+ e.printStackTrace();
+ AdventureManager.consoleMessage("[CustomCrops] 洒水器数据文件生成失败!");
}
}
+ this.data = YamlConfiguration.loadConfiguration(file);
}
- /*
- 保存数据
- */
- public static void saveData(){
- File file = new File(CustomCrops.instance.getDataFolder(), "sprinkler-data.yml");
- FileConfiguration data = YamlConfiguration.loadConfiguration(file);
-
- Set> en = SPRINKLERS.entrySet();
- for(Map.Entry entry : en){
- data.set(entry.getKey().getWorld().getName() + "." + entry.getKey().getBlockX() + "," + entry.getKey().getBlockY()+ ","+entry.getKey().getBlockZ(), entry.getValue());
- }
- try {
+ public void saveData(){
+ File file = new File(CustomCrops.instance.getDataFolder(), "data" + File.separator + "sprinkler.yml");
+ try{
data.save(file);
- }
- catch (IOException e) {
+ }catch (IOException e){
e.printStackTrace();
- CustomCrops.instance.getLogger().warning("洒水器数据保存出错");
+ AdventureManager.consoleMessage("[CustomCrops] sprinkler.yml保存出错!");
}
}
- public static void putInstance(Location location, String type) {
- SPRINKLERS.put(location, type);
+
+ public void updateData(){
+ Cache.forEach((location, sprinklerData) -> {
+ String world = location.getWorld().getName();
+ int x = location.getBlockX();
+ int z = location.getBlockZ();
+ StringBuilder stringBuilder = new StringBuilder().append(world).append(".").append(x/16).append(",").append(z/16).append(".").append(x).append(",").append(location.getBlockY()).append(",").append(z);
+ data.set(stringBuilder+".range", sprinklerData.getRange());
+ data.set(stringBuilder+".water", sprinklerData.getWater());
+ });
+ Cache.clear();
}
- public static void SprinklerWork(String worldName) {
- /*
- 阶段1:更新数据
- */
- long start1 = System.currentTimeMillis();
- File file = new File(CustomCrops.instance.getDataFolder(), "sprinkler-data.yml");
- FileConfiguration data;
- data = YamlConfiguration.loadConfiguration(file);
- BukkitScheduler bukkitScheduler = Bukkit.getScheduler();
-
- Set> en = SPRINKLERS.entrySet();
- for(Map.Entry entry : en){
- data.set(entry.getKey().getWorld().getName() + "." + entry.getKey().getBlockX() + "," + entry.getKey().getBlockY()+ ","+entry.getKey().getBlockZ(), entry.getValue());
+ public void sprinklerWork(String worldName){
+ Long time1 = System.currentTimeMillis();
+ updateData();
+ Long time2 = System.currentTimeMillis();
+ if (ConfigReader.Config.logTime){
+ AdventureManager.consoleMessage("性能监测: 洒水器数据更新" + (time2-time1) + "ms");
}
- long finish1 = System.currentTimeMillis();
- if (ConfigManager.Config.log_time){
- MessageManager.consoleMessage("ccfbff-#ef96c5&[CustomCrops] &7洒水器数据更新耗时&a" + (finish1-start1) + "&fms",Bukkit.getConsoleSender());
- }
- /*
- 阶段2:清理数据内无效的洒水器并工作
- */
- bukkitScheduler.callSyncMethod(CustomCrops.instance,()->{
- long start2 = System.currentTimeMillis();
- //检测碰撞体积需要同步
- if(data.contains(worldName)){
+ if (data.contains(worldName)){
+ data.getConfigurationSection(worldName).getKeys(false).forEach(chunk ->{
+ String[] split = StringUtils.split(chunk,",");
World world = Bukkit.getWorld(worldName);
- data.getConfigurationSection(worldName).getKeys(false).forEach(key ->{
- String[] coordinate = StringUtils.split(key,",");
- if (world.isChunkLoaded(Integer.parseInt(coordinate[0])/16, Integer.parseInt(coordinate[2])/16)){
- Location tempLoc = new Location(world,Double.parseDouble(coordinate[0])+0.5,Double.parseDouble(coordinate[1])+0.5,Double.parseDouble(coordinate[2])+0.5);
- if(!IAFurniture.getFromLocation(tempLoc, world)){
- SPRINKLERS.remove(tempLoc);
- data.set(worldName+"."+coordinate[0]+","+coordinate[1]+","+coordinate[2], null);
- }else {
- String type = data.getString(worldName + "." + coordinate[0] + "," + coordinate[1] + "," + coordinate[2]);
- if(type == null){
- MessageManager.consoleMessage("错误数据位于"+ worldName + coordinate[0] + "," + coordinate[1] + "," + coordinate[2], Bukkit.getConsoleSender());
- return;
- }
- if(type.equalsIgnoreCase("s1")){
- for(int i = -1; i <= 1;i++){
- for (int j = -1; j <= 1; j++){
- waterPot(tempLoc.clone().add(i,-1,j));
+ if (ConfigReader.Config.onlyLoadedGrow || world.isChunkLoaded(Integer.parseInt(split[0]), Integer.parseInt(split[1]))) {
+ data.getConfigurationSection(worldName + "." + chunk).getValues(false).forEach((key, value) -> {
+ String[] coordinate = StringUtils.split(key, ",");
+ Location location = new Location(world,Double.parseDouble(coordinate[0])+0.5,Double.parseDouble(coordinate[1])+0.5,Double.parseDouble(coordinate[2])+0.5);
+ if (value instanceof MemorySection map){
+ Bukkit.getScheduler().callSyncMethod(CustomCrops.instance, ()->{
+ int water = (int) map.get("water");
+ int range = (int) map.get("range");
+ if(!IAFurniture.getFromLocation(location, world)){
+ data.set(worldName + "." + chunk + "." + key, null);
+ return null;
+ }
+ if (range == 0) data.set(worldName + "." + chunk + "." + key, null);
+ if (water > 0){
+ data.set(worldName + "." + chunk + "." + key + ".water", water - 1);
+ for(int i = -range; i <= range; i++){
+ for (int j = -range; j <= range; j++){
+ waterPot(location.clone().add(i,-1,j));
+ }
}
}
- }else{
- for(int i = -2; i <= 2;i++){
- for (int j = -2; j <= 2; j++){
- waterPot(tempLoc.clone().add(i,-1,j));
- }
- }
- }
+ return null;
+ });
}
- }
- });
- }
- long finish2 = System.currentTimeMillis();
- if (ConfigManager.Config.log_time){
- MessageManager.consoleMessage("ccfbff-#ef96c5&[CustomCrops] &7洒水器工作耗时&a" + (finish2-start2) + "&fms",Bukkit.getConsoleSender());
- }
- bukkitScheduler.runTaskAsynchronously(CustomCrops.instance,()->{
- /*
- 阶段3:保存数据
- */
- long start3 = System.currentTimeMillis();
- try{
- data.save(file);
- }catch (IOException e){
- e.printStackTrace();
- CustomCrops.instance.getLogger().warning("sprinkler-data.yml保存出错!");
- }
- long finish3 = System.currentTimeMillis();
- if (ConfigManager.Config.log_time){
- MessageManager.consoleMessage("ccfbff-#ef96c5&[CustomCrops] &7洒水器数据保存耗时&a" + (finish3-start3) + "&fms",Bukkit.getConsoleSender());
+ });
}
});
- return null;
- });
+ }
+ Long time3 = System.currentTimeMillis();
+ if(ConfigReader.Config.logTime){
+ AdventureManager.consoleMessage("性能监测: 洒水器工作过程" + (time3-time2) + "ms");
+ }
+ saveData();
+ Long time4 = System.currentTimeMillis();
+ if(ConfigReader.Config.logTime){
+ AdventureManager.consoleMessage("性能监测: 洒水器数据保存" + (time4-time3) + "ms");
+ }
}
- private static void waterPot(Location tempLoc) {
- CustomBlock cb = CustomBlock.byAlreadyPlaced(tempLoc.getBlock());
+
+ private void waterPot(Location potLoc) {
+ CustomBlock cb = CustomBlock.byAlreadyPlaced(potLoc.getBlock());
if(cb != null){
- if(cb.getNamespacedID().equalsIgnoreCase(ConfigManager.Config.pot)){
- CustomBlock.remove(tempLoc);
- CustomBlock.place((ConfigManager.Config.watered_pot), tempLoc);
+ if(cb.getNamespacedID().equals(ConfigReader.Basic.pot)){
+ CustomBlock.remove(potLoc);
+ CustomBlock.place(ConfigReader.Basic.watered_pot, potLoc);
}
}
}
diff --git a/src/main/java/net/momirealms/customcrops/fertilizer/Fertilizer.java b/src/main/java/net/momirealms/customcrops/fertilizer/Fertilizer.java
new file mode 100644
index 0000000..e08b836
--- /dev/null
+++ b/src/main/java/net/momirealms/customcrops/fertilizer/Fertilizer.java
@@ -0,0 +1,9 @@
+package net.momirealms.customcrops.fertilizer;
+
+public interface Fertilizer {
+ String getKey();
+ int getTimes();
+ void setTimes(int times);
+ boolean isBefore();
+ String getName();
+}
diff --git a/src/main/java/net/momirealms/customcrops/fertilizer/QualityCrop.java b/src/main/java/net/momirealms/customcrops/fertilizer/QualityCrop.java
new file mode 100644
index 0000000..cf354b7
--- /dev/null
+++ b/src/main/java/net/momirealms/customcrops/fertilizer/QualityCrop.java
@@ -0,0 +1,58 @@
+package net.momirealms.customcrops.fertilizer;
+
+public class QualityCrop implements Fertilizer{
+
+ private int[] chance;
+ private String key;
+ private int times;
+ private boolean before;
+ private String name;
+
+ public QualityCrop(String key, int times, int[] chance, boolean before) {
+ this.chance = chance;
+ this.times = times;
+ this.before = before;
+ this.key = key;
+ }
+
+ @Override
+ public String getKey() {
+ return this.key;
+ }
+
+ @Override
+ public int getTimes() {
+ return this.times;
+ }
+
+ @Override
+ public void setTimes(int times) {
+ this.times = times;
+ }
+
+ @Override
+ public boolean isBefore() {
+ return this.before;
+ }
+
+ @Override
+ public String getName() {
+ return this.name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public void setChance(int[] chance) {
+ this.chance = chance;
+ }
+
+ public void setKey(String key) {
+ this.key = key;
+ }
+
+ public int[] getChance() {
+ return chance;
+ }
+}
diff --git a/src/main/java/net/momirealms/customcrops/fertilizer/RetainingSoil.java b/src/main/java/net/momirealms/customcrops/fertilizer/RetainingSoil.java
new file mode 100644
index 0000000..3168cc6
--- /dev/null
+++ b/src/main/java/net/momirealms/customcrops/fertilizer/RetainingSoil.java
@@ -0,0 +1,58 @@
+package net.momirealms.customcrops.fertilizer;
+
+public class RetainingSoil implements Fertilizer{
+
+ private double chance;
+ private String key;
+ private int times;
+ private boolean before;
+ public String name;
+
+ public RetainingSoil(String key, int times, double chance, boolean before){
+ this.times = times;
+ this.chance = chance;
+ this.before = before;
+ this.key = key;
+ }
+
+ @Override
+ public String getKey() {
+ return this.key;
+ }
+
+ @Override
+ public int getTimes() {
+ return this.times;
+ }
+
+ @Override
+ public void setTimes(int times) {
+ this.times = times;
+ }
+
+ @Override
+ public boolean isBefore() {
+ return this.before;
+ }
+
+ @Override
+ public String getName() {
+ return this.name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public void setChance(double chance) {
+ this.chance = chance;
+ }
+
+ public void setKey(String key) {
+ this.key = key;
+ }
+
+ public double getChance() {
+ return chance;
+ }
+}
diff --git a/src/main/java/net/momirealms/customcrops/fertilizer/SpeedGrow.java b/src/main/java/net/momirealms/customcrops/fertilizer/SpeedGrow.java
new file mode 100644
index 0000000..8bcde54
--- /dev/null
+++ b/src/main/java/net/momirealms/customcrops/fertilizer/SpeedGrow.java
@@ -0,0 +1,58 @@
+package net.momirealms.customcrops.fertilizer;
+
+public class SpeedGrow implements Fertilizer{
+
+ private double chance;
+ private String key;
+ private int times;
+ private boolean before;
+ private String name;
+
+ public SpeedGrow(String key, int times, double chance, boolean before){
+ this.chance = chance;
+ this.times = times;
+ this.before = before;
+ this.key = key;
+ }
+
+ @Override
+ public String getKey() {
+ return this.key;
+ }
+
+ @Override
+ public int getTimes() {
+ return this.times;
+ }
+
+ @Override
+ public void setTimes(int times) {
+ this.times = times;
+ }
+
+ @Override
+ public boolean isBefore() {
+ return this.before;
+ }
+
+ @Override
+ public String getName() {
+ return this.name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public double getChance() {
+ return chance;
+ }
+
+ public void setChance(double chance) {
+ this.chance = chance;
+ }
+
+ public void setKey(String key) {
+ this.key = key;
+ }
+}
diff --git a/src/main/java/net/momirealms/customcrops/integrations/GriefDefender.java b/src/main/java/net/momirealms/customcrops/integrations/GriefDefender.java
new file mode 100644
index 0000000..b24eb7e
--- /dev/null
+++ b/src/main/java/net/momirealms/customcrops/integrations/GriefDefender.java
@@ -0,0 +1,17 @@
+package net.momirealms.customcrops.integrations;
+
+import org.bukkit.Location;
+import org.bukkit.entity.Player;
+
+public record GriefDefender() implements Integration {
+
+ @Override
+ public boolean canBreak(Location location, Player player) {
+ return com.griefdefender.api.GriefDefender.getCore().getUser(player.getUniqueId()).canBreak(location);
+ }
+
+ @Override
+ public boolean canPlace(Location location, Player player) {
+ return com.griefdefender.api.GriefDefender.getCore().getUser(player.getUniqueId()).canPlace(player.getInventory().getItemInMainHand(), location);
+ }
+}
diff --git a/src/main/java/net/momirealms/customcrops/integrations/GriefDefenderIntegrations.java b/src/main/java/net/momirealms/customcrops/integrations/GriefDefenderIntegrations.java
deleted file mode 100644
index 709ac8a..0000000
--- a/src/main/java/net/momirealms/customcrops/integrations/GriefDefenderIntegrations.java
+++ /dev/null
@@ -1,16 +0,0 @@
-package net.momirealms.customcrops.integrations;
-
-import com.griefdefender.api.GriefDefender;
-import org.bukkit.Location;
-import org.bukkit.entity.Player;
-
-public class GriefDefenderIntegrations {
-
- public static boolean checkGDBreak(Location location, Player player){
- return GriefDefender.getCore().getUser(player.getUniqueId()).canBreak(location);
- }
-
- public static boolean checkGDBuild(Location location, Player player){
- return GriefDefender.getCore().getUser(player.getUniqueId()).canPlace(player.getInventory().getItemInMainHand(), location);
- }
-}
diff --git a/src/main/java/net/momirealms/customcrops/integrations/Integration.java b/src/main/java/net/momirealms/customcrops/integrations/Integration.java
new file mode 100644
index 0000000..8fcccde
--- /dev/null
+++ b/src/main/java/net/momirealms/customcrops/integrations/Integration.java
@@ -0,0 +1,9 @@
+package net.momirealms.customcrops.integrations;
+
+import org.bukkit.Location;
+import org.bukkit.entity.Player;
+
+public interface Integration {
+ boolean canBreak(Location location, Player player);
+ boolean canPlace(Location location, Player player);
+}
diff --git a/src/main/java/net/momirealms/customcrops/integrations/IntegrationCheck.java b/src/main/java/net/momirealms/customcrops/integrations/IntegrationCheck.java
deleted file mode 100644
index 843d915..0000000
--- a/src/main/java/net/momirealms/customcrops/integrations/IntegrationCheck.java
+++ /dev/null
@@ -1,57 +0,0 @@
-package net.momirealms.customcrops.integrations;
-
-import net.momirealms.customcrops.datamanager.ConfigManager;
-import org.bukkit.Location;
-import org.bukkit.entity.Player;
-
-public class IntegrationCheck {
-
- //收获权限检测
- public static boolean HarvestCheck(Location location, Player player){
- if(ConfigManager.Config.res){
- if(!ResidenceIntegrations.checkResHarvest(location, player)){
- return false;
- }
- }
- if(ConfigManager.Config.king){
- if(!KingdomsXIntegrations.checkKDBuild(location, player)){
- return false;
- }
- }
- if(ConfigManager.Config.wg){
- if(!WorldGuardIntegrations.checkWGHarvest(location, player)){
- return false;
- }
- }
- if(ConfigManager.Config.gd){
- if(!GriefDefenderIntegrations.checkGDBreak(location, player)){
- return false;
- }
- }
- return true;
- }
- //种植等权限检测
- public static boolean PlaceCheck(Location location, Player player){
- if(ConfigManager.Config.res){
- if(!ResidenceIntegrations.checkResBuild(location,player)){
- return false;
- }
- }
- if(ConfigManager.Config.king){
- if(!KingdomsXIntegrations.checkKDBuild(location,player)){
- return false;
- }
- }
- if(ConfigManager.Config.wg){
- if(!WorldGuardIntegrations.checkWGBuild(location, player)){
- return false;
- }
- }
- if(ConfigManager.Config.gd){
- if(!GriefDefenderIntegrations.checkGDBuild(location, player)){
- return false;
- }
- }
- return true;
- }
-}
\ No newline at end of file
diff --git a/src/main/java/net/momirealms/customcrops/integrations/KingdomsXIntegrations.java b/src/main/java/net/momirealms/customcrops/integrations/KingdomsX.java
similarity index 63%
rename from src/main/java/net/momirealms/customcrops/integrations/KingdomsXIntegrations.java
rename to src/main/java/net/momirealms/customcrops/integrations/KingdomsX.java
index 8f01ad9..a7f6c5e 100644
--- a/src/main/java/net/momirealms/customcrops/integrations/KingdomsXIntegrations.java
+++ b/src/main/java/net/momirealms/customcrops/integrations/KingdomsX.java
@@ -6,8 +6,19 @@ import org.kingdoms.constants.group.Kingdom;
import org.kingdoms.constants.land.Land;
import org.kingdoms.constants.player.KingdomPlayer;
-public class KingdomsXIntegrations {
- public static boolean checkKDBuild(Location location, Player player){
+public record KingdomsX() implements Integration {
+
+ @Override
+ public boolean canBreak(Location location, Player player) {
+ return kingdomsCheck(location, player);
+ }
+
+ @Override
+ public boolean canPlace(Location location, Player player) {
+ return kingdomsCheck(location, player);
+ }
+
+ private boolean kingdomsCheck(Location location, Player player) {
Land land = Land.getLand(location);
if (land == null) return true;
if (land.isClaimed()) {
@@ -16,7 +27,7 @@ public class KingdomsXIntegrations {
if (kp.getKingdom() != null) {
Kingdom kingdom = kp.getKingdom();
return kingdom != cropKingdom;
- }else {
+ } else {
return false;
}
}
diff --git a/src/main/java/net/momirealms/customcrops/integrations/ResidenceIntegrations.java b/src/main/java/net/momirealms/customcrops/integrations/Residence.java
similarity index 81%
rename from src/main/java/net/momirealms/customcrops/integrations/ResidenceIntegrations.java
rename to src/main/java/net/momirealms/customcrops/integrations/Residence.java
index f3bad98..90f7640 100644
--- a/src/main/java/net/momirealms/customcrops/integrations/ResidenceIntegrations.java
+++ b/src/main/java/net/momirealms/customcrops/integrations/Residence.java
@@ -6,8 +6,10 @@ import com.bekvon.bukkit.residence.protection.ResidencePermissions;
import org.bukkit.Location;
import org.bukkit.entity.Player;
-public class ResidenceIntegrations {
- public static boolean checkResBuild(Location location, Player player){
+public record Residence() implements Integration {
+
+ @Override
+ public boolean canBreak(Location location, Player player) {
ClaimedResidence res = com.bekvon.bukkit.residence.Residence.getInstance().getResidenceManager().getByLoc(location);
if(res!=null){
ResidencePermissions perms = res.getPermissions();
@@ -15,7 +17,9 @@ public class ResidenceIntegrations {
}
return true;
}
- public static boolean checkResHarvest(Location location, Player player){
+
+ @Override
+ public boolean canPlace(Location location, Player player) {
ClaimedResidence res = com.bekvon.bukkit.residence.Residence.getInstance().getResidenceManager().getByLoc(location);
if(res!=null){
ResidencePermissions perms = res.getPermissions();
diff --git a/src/main/java/net/momirealms/customcrops/integrations/WorldGuard.java b/src/main/java/net/momirealms/customcrops/integrations/WorldGuard.java
new file mode 100644
index 0000000..5c3fe53
--- /dev/null
+++ b/src/main/java/net/momirealms/customcrops/integrations/WorldGuard.java
@@ -0,0 +1,42 @@
+package net.momirealms.customcrops.integrations;
+
+import com.sk89q.worldedit.bukkit.BukkitAdapter;
+import com.sk89q.worldguard.LocalPlayer;
+import com.sk89q.worldguard.bukkit.WorldGuardPlugin;
+import com.sk89q.worldguard.protection.ApplicableRegionSet;
+import com.sk89q.worldguard.protection.flags.Flags;
+import com.sk89q.worldguard.protection.regions.RegionContainer;
+import com.sk89q.worldguard.protection.regions.RegionQuery;
+import org.bukkit.Location;
+import org.bukkit.entity.Player;
+
+public record WorldGuard() implements Integration {
+
+ @Override
+ public boolean canPlace(Location location, Player player) {
+ LocalPlayer localPlayer = WorldGuardPlugin.inst().wrapPlayer(player);
+ RegionContainer container = com.sk89q.worldguard.WorldGuard.getInstance().getPlatform().getRegionContainer();
+ RegionQuery query = container.createQuery();
+ ApplicableRegionSet set = query.getApplicableRegions(BukkitAdapter.adapt(location));
+ if (set != null){
+ System.out.println(set);
+ return query.testState(BukkitAdapter.adapt(location), localPlayer, Flags.BUILD);
+ }else {
+ return true;
+ }
+ }
+
+ @Override
+ public boolean canBreak(Location location, Player player) {
+ LocalPlayer localPlayer = WorldGuardPlugin.inst().wrapPlayer(player);
+ RegionContainer container = com.sk89q.worldguard.WorldGuard.getInstance().getPlatform().getRegionContainer();
+ RegionQuery query = container.createQuery();
+ ApplicableRegionSet set = query.getApplicableRegions(BukkitAdapter.adapt(location));
+ if (set != null){
+ System.out.println(set);
+ return query.testState(BukkitAdapter.adapt(location), localPlayer, Flags.BLOCK_BREAK);
+ }else {
+ return true;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/net/momirealms/customcrops/integrations/WorldGuardIntegrations.java b/src/main/java/net/momirealms/customcrops/integrations/WorldGuardIntegrations.java
deleted file mode 100644
index fc415e8..0000000
--- a/src/main/java/net/momirealms/customcrops/integrations/WorldGuardIntegrations.java
+++ /dev/null
@@ -1,26 +0,0 @@
-package net.momirealms.customcrops.integrations;
-
-import com.sk89q.worldedit.bukkit.BukkitAdapter;
-import com.sk89q.worldguard.LocalPlayer;
-import com.sk89q.worldguard.WorldGuard;
-import com.sk89q.worldguard.bukkit.WorldGuardPlugin;
-import com.sk89q.worldguard.protection.flags.Flags;
-import com.sk89q.worldguard.protection.regions.RegionContainer;
-import com.sk89q.worldguard.protection.regions.RegionQuery;
-import org.bukkit.Location;
-import org.bukkit.entity.Player;
-
-public class WorldGuardIntegrations {
- public static boolean checkWGBuild(Location loc,Player player){
- LocalPlayer localPlayer = WorldGuardPlugin.inst().wrapPlayer(player);
- RegionContainer container = WorldGuard.getInstance().getPlatform().getRegionContainer();
- RegionQuery query = container.createQuery();
- return query.testState(BukkitAdapter.adapt(loc), localPlayer, Flags.BUILD);
- }
- public static boolean checkWGHarvest(Location loc,Player player){
- LocalPlayer localPlayer = WorldGuardPlugin.inst().wrapPlayer(player);
- RegionContainer container = WorldGuard.getInstance().getPlatform().getRegionContainer();
- RegionQuery query = container.createQuery();
- return query.testState(BukkitAdapter.adapt(loc), localPlayer, Flags.BLOCK_BREAK);
- }
-}
\ No newline at end of file
diff --git a/src/main/java/net/momirealms/customcrops/libs/minedown/MineDown.java b/src/main/java/net/momirealms/customcrops/libs/minedown/MineDown.java
deleted file mode 100644
index 1e991aa..0000000
--- a/src/main/java/net/momirealms/customcrops/libs/minedown/MineDown.java
+++ /dev/null
@@ -1,499 +0,0 @@
-package net.momirealms.customcrops.libs.minedown;
-
-/*
- * Copyright (c) 2017 Max Lee (https://github.com/Phoenix616)
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-import net.md_5.bungee.api.ChatColor;
-import net.md_5.bungee.api.chat.BaseComponent;
-import net.md_5.bungee.api.chat.ClickEvent;
-import net.md_5.bungee.api.chat.HoverEvent;
-
-import java.util.Map;
-
-/**
- *
MineDown
- * A MarkDown inspired markup for Minecraft chat components
- *
- * This lets you convert string messages into chat components by using a custom mark up syntax
- * which is loosely based on MarkDown while still supporting legacy formatting codes.
- *
- *
- *
Inline Formatting
- *
Color legacy
&6Text
{@link ChatColor} codes
- *
Color
&gold&Text
{@link ChatColor} codes
- *
RGB Hex Color
&ff00ff&Text
Full hexadecimal format
- *
RGB Hex Color
&f0f&Text
Short format (equivalent to long one)
- *
Bold
**Text**
- *
Italic
##Text##
- *
Underlined
__Text__
- *
Strikethrough
~~Text~~
- *
Obfuscated
??Text??
- *
- *
- *
Events
- * You can define click and hover events with the commonly used MarkDown link syntax.
- *
- *
- *
Simple Syntax
- *
General syntax
[Text](text-color text-formatting... link hover text)
- * All advanced settings can be chained/included in a event definition.
- * You can't however add multiple different colors or click and hover actions!
- */
-public class MineDown {
- public static final String FONT_PREFIX = "font=";
- public static final String COLOR_PREFIX = "color=";
- public static final String FORMAT_PREFIX = "format=";
- public static final String HOVER_PREFIX = "hover=";
- public static final String INSERTION_PREFIX = "insert=";
-
- private String message;
- private final Replacer replacer = new Replacer();
- private final MineDownParser parser = new MineDownParser();
- private BaseComponent[] baseComponents = null;
- private boolean replaceFirst = Boolean.getBoolean("de.themoep.minedown.replacefirst");
-
- /**
- * Create a new MineDown builder with a certain message
- * @param message The message to parse
- */
- public MineDown(String message) {
- this.message = message;
- }
-
- /**
- * Parse a MineDown string to components
- * @param message The message to translate
- * @param replacements Optional placeholder replacements
- * @return The parsed components
- */
- public static BaseComponent[] parse(String message, String... replacements) {
- return new MineDown(message).replace(replacements).toComponent();
- }
-
- /**
- * Convert components to a MineDown string
- * @param components The components to convert
- * @return The components represented as a MineDown string
- */
- public static String stringify(BaseComponent[] components) {
- return new MineDownStringifier().stringify(components);
- }
-
- /**
- * Parse and convert the message to the component
- * @return The parsed component message
- */
- public BaseComponent[] toComponent() {
- if (baseComponents() == null) {
- if (replaceFirst()) {
- Replacer componentReplacer = new Replacer();
- for (Map.Entry entry : replacer().componentReplacements().entrySet()) {
- componentReplacer.replace(entry.getKey(), stringify(entry.getValue()));
- }
- baseComponents = parser().parse(componentReplacer.replaceIn(replacer().replaceIn(message()))).create();
- } else {
- baseComponents = replacer().replaceIn(parser().parse(message()).create());
- }
- }
- return baseComponents();
- }
-
- /**
- * Remove a cached component and re-parse the next time {@link #toComponent} is called
- */
- private void reset() {
- baseComponents = null;
- }
-
- /**
- * Set whether or not replacements should be replaced before or after the components are created.
- * When replacing first it will not replace any placeholders with component replacement values!
- * Default is after. (replaceFirst = false)
- * @param replaceFirst Whether or not to replace first or parse first
- * @return The MineDown instance
- */
- public MineDown replaceFirst(boolean replaceFirst) {
- reset();
- this.replaceFirst = replaceFirst;
- return this;
- }
-
- /**
- * Get whether or not replacements should be replaced before or after the components are created.
- * When replacing first it will not replace any placeholders with component replacement values!
- * Default is after. (replaceFirst = false)
- * @return Whether or not to replace first or parse first
- */
- public boolean replaceFirst() {
- return replaceFirst;
- }
-
- /**
- * Add an array with placeholders and values that should get replaced in the message
- * @param replacements The replacements, nth element is the placeholder, n+1th the value
- * @return The MineDown instance
- */
- public MineDown replace(String... replacements) {
- reset();
- replacer().replace(replacements);
- return this;
- }
-
- /**
- * Add a map with placeholders and values that should get replaced in the message
- * @param replacements The replacements mapped placeholder to value
- * @return The MineDown instance
- */
- public MineDown replace(Map replacements) {
- reset();
- replacer().replace(replacements);
- return this;
- }
-
- /**
- * Add a placeholder to component mapping that should get replaced in the message
- * @param placeholder The placeholder to replace
- * @param replacement The replacement components
- * @return The Replacer instance
- */
- public MineDown replace(String placeholder, BaseComponent... replacement) {
- reset();
- replacer().replace(placeholder,replacement);
- return this;
- }
-
- /**
- * Set the placeholder indicator for both prefix and suffix
- * @param placeholderIndicator The character to use as a placeholder indicator
- * @return The MineDown instance
- */
- public MineDown placeholderIndicator(String placeholderIndicator) {
- placeholderPrefix(placeholderIndicator);
- placeholderSuffix(placeholderIndicator);
- return this;
- }
-
- /**
- * Set the placeholder indicator's prefix character
- * @param placeholderPrefix The character to use as the placeholder indicator's prefix
- * @return The MineDown instance
- */
- public MineDown placeholderPrefix(String placeholderPrefix) {
- reset();
- replacer().placeholderPrefix(placeholderPrefix);
- return this;
- }
-
- /**
- * Get the placeholder indicator's prefix character
- * @return The placeholder indicator's prefix character
- */
- public String placeholderPrefix() {
- return replacer().placeholderPrefix();
- }
-
- /**
- * Set the placeholder indicator's suffix character
- * @param placeholderSuffix The character to use as the placeholder indicator's suffix
- * @return The MineDown instance
- */
- public MineDown placeholderSuffix(String placeholderSuffix) {
- reset();
- replacer().placeholderSuffix(placeholderSuffix);
- return this;
- }
-
- /**
- * Get the placeholder indicator's suffix character
- * @return The placeholder indicator's suffix character
- */
- public String placeholderSuffix() {
- return replacer().placeholderSuffix();
- }
-
- /**
- * Set whether or not the case of the placeholder should be ignored when replacing
- * @param ignorePlaceholderCase Whether or not to ignore the case of the placeholders
- * @return The MineDown instance
- */
- public MineDown ignorePlaceholderCase(boolean ignorePlaceholderCase) {
- reset();
- replacer().ignorePlaceholderCase(ignorePlaceholderCase);
- return this;
- }
-
- /**
- * Get whether or not the case of the placeholder should be ignored when replacing
- * @return Whether or not to ignore the case of the placeholders
- */
- public boolean ignorePlaceholderCase() {
- return replacer().ignorePlaceholderCase();
- }
-
- /**
- * Enable or disable the translation of legacy color codes
- * @param translateLegacyColors Whether or not to translate legacy color codes (Default: true)
- * @return The MineDown instance
- * @deprecated Use {@link #enable(MineDownParser.Option)} and {@link #disable(MineDownParser.Option)}
- */
- @Deprecated
- public MineDown translateLegacyColors(boolean translateLegacyColors) {
- reset();
- parser().translateLegacyColors(translateLegacyColors);
- return this;
- }
-
- /**
- * Detect urls in strings and add events to them? (Default: true)
- * @param enabled Whether or not to detect URLs and add events to them
- * @return The MineDown instance
- */
- public MineDown urlDetection(boolean enabled) {
- reset();
- parser().urlDetection(enabled);
- return this;
- }
-
- /**
- * Automatically add http to values of open_url when there doesn't exist any? (Default: true)
- * @param enabled Whether or not to automatically add http when missing
- * @return The MineDown instance
- */
- public MineDown autoAddUrlPrefix(boolean enabled) {
- reset();
- parser().autoAddUrlPrefix(enabled);
- return this;
- }
-
- /**
- * The text to display when hovering over an URL
- * @param text The text to display when hovering over an URL
- * @return The MineDown instance
- */
- public MineDown urlHoverText(String text) {
- reset();
- parser().urlHoverText(text);
- return this;
- }
-
- /**
- * Set the max width the hover text should have.
- * Minecraft itself will wrap after 60 characters.
- * Won't apply if the text already includes new lines.
- * @param hoverTextWidth The url hover text length
- * @return The MineDown instance
- */
- public MineDown hoverTextWidth(int hoverTextWidth) {
- reset();
- parser().hoverTextWidth(hoverTextWidth);
- return this;
- }
-
- /**
- * Enable an option. Unfilter it if you filtered it before.
- * @param option The option to enable
- * @return The MineDown instance
- */
- public MineDown enable(MineDownParser.Option option) {
- reset();
- parser().enable(option);
- return this;
- }
-
- /**
- * Disable an option. Disabling an option will stop the parser from replacing
- * this option's chars in the string. Use {@link #filter(MineDownParser.Option)} to completely
- * remove the characters used by this option from the message instead.
- * @param option The option to disable
- * @return The MineDown instance
- */
- public MineDown disable(MineDownParser.Option option) {
- reset();
- parser().disable(option);
- return this;
- }
-
- /**
- * Filter an option. This completely removes the characters of this option from
- * the string ignoring whether the option is enabled or not.
- * @param option The option to add to the filter
- * @return The MineDown instance
- */
- public MineDown filter(MineDownParser.Option option) {
- reset();
- parser().filter(option);
- return this;
- }
-
- /**
- * Unfilter an option. Does not enable it!
- * @param option The option to remove from the filter
- * @return The MineDown instance
- */
- public MineDown unfilter(MineDownParser.Option option) {
- reset();
- parser().unfilter(option);
- return this;
- }
-
- /**
- * Set a special character to replace color codes by if translating legacy colors is enabled.
- * @param colorChar The character to use as a special color code. (Default: ampersand &)
- * @return The MineDown instance
- */
- public MineDown colorChar(char colorChar) {
- reset();
- parser().colorChar(colorChar);
- return this;
- }
-
- /**
- * Get the set message that is to be parsed
- * @return The to be parsed message
- */
- public String message() {
- return this.message;
- }
-
- /**
- * Set the message that is to be parsed
- * @param message The message to be parsed
- * @return The MineDown instance
- */
- public MineDown message(String message) {
- this.message = message;
- reset();
- return this;
- }
-
- /**
- * Get the replacer instance that is currently used
- * @return The currently used replacer instance
- */
- public Replacer replacer() {
- return this.replacer;
- }
-
- /**
- * Get the parser instance that is currently used
- * @return The currently used parser instance
- */
- public MineDownParser parser() {
- return this.parser;
- }
-
- protected BaseComponent[] baseComponents() {
- return this.baseComponents;
- }
-
- /**
- * Copy all MineDown settings to a new instance
- * @return The new MineDown instance with all settings copied
- */
- public MineDown copy() {
- return new MineDown(message()).copy(this);
- }
-
- /**
- * Copy all MineDown settings from another one
- * @param from The MineDown to copy from
- * @return This MineDown instance
- */
- public MineDown copy(MineDown from) {
- replacer().copy(from.replacer());
- parser().copy(from.parser());
- return this;
- }
-
- /**
- * Get the string that represents the format in MineDown
- * @param format The format
- * @return The MineDown string or an empty one if it's not a format
- */
- public static String getFormatString(ChatColor format) {
- if (format == ChatColor.BOLD) {
- return "**";
- } else if (format == ChatColor.ITALIC) {
- return "##";
- } else if (format == ChatColor.UNDERLINE) {
- return "__";
- } else if (format == ChatColor.STRIKETHROUGH) {
- return "~~";
- } else if (format == ChatColor.MAGIC) {
- return "??";
- }
- return "";
- }
-
- /**
- * Get the ChatColor format from a MineDown string
- * @param c The character
- * @return The ChatColor of that format or null it none was found
- */
- public static ChatColor getFormatFromChar(char c) {
- switch (c) {
- case '~':
- return ChatColor.STRIKETHROUGH;
- case '_':
- return ChatColor.UNDERLINE;
- case '*':
- return ChatColor.BOLD;
- case '#':
- return ChatColor.ITALIC;
- case '?':
- return ChatColor.MAGIC;
- }
- return null;
- }
-
- /**
- * Escape all MineDown formatting in a string. This will escape backslashes too!
- * @param string The string to escape in
- * @return The string with formatting escaped
- */
- public static String escape(String string) {
- return new MineDown(string).parser().escape(string);
- }
-}
diff --git a/src/main/java/net/momirealms/customcrops/libs/minedown/MineDownParser.java b/src/main/java/net/momirealms/customcrops/libs/minedown/MineDownParser.java
deleted file mode 100644
index 7dc51fe..0000000
--- a/src/main/java/net/momirealms/customcrops/libs/minedown/MineDownParser.java
+++ /dev/null
@@ -1,1241 +0,0 @@
-package net.momirealms.customcrops.libs.minedown;
-
-/*
- * Copyright (c) 2017 Max Lee (https://github.com/Phoenix616)
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-import net.md_5.bungee.api.ChatColor;
-import net.md_5.bungee.api.chat.BaseComponent;
-import net.md_5.bungee.api.chat.ClickEvent;
-import net.md_5.bungee.api.chat.ComponentBuilder;
-import net.md_5.bungee.api.chat.HoverEvent;
-import net.md_5.bungee.api.chat.ItemTag;
-import net.md_5.bungee.api.chat.TextComponent;
-import net.md_5.bungee.api.chat.hover.content.Entity;
-import net.md_5.bungee.api.chat.hover.content.Item;
-import net.md_5.bungee.api.chat.hover.content.Text;
-
-import java.awt.Color;
-import java.lang.reflect.Field;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.EnumSet;
-import java.util.HashMap;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Locale;
-import java.util.Map;
-import java.util.PrimitiveIterator;
-import java.util.Set;
-import java.util.concurrent.atomic.AtomicInteger;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-import java.util.stream.Collectors;
-
-import static net.momirealms.customcrops.libs.minedown.MineDown.COLOR_PREFIX;
-import static net.momirealms.customcrops.libs.minedown.MineDown.FONT_PREFIX;
-import static net.momirealms.customcrops.libs.minedown.MineDown.FORMAT_PREFIX;
-import static net.momirealms.customcrops.libs.minedown.MineDown.HOVER_PREFIX;
-import static net.momirealms.customcrops.libs.minedown.MineDown.INSERTION_PREFIX;
-
-public class MineDownParser {
- private static final String RAINBOW = "rainbow";
-
- private static final boolean HAS_APPEND_SUPPORT = Util.hasMethod(ComponentBuilder.class, "append", BaseComponent[].class);
- private static final boolean HAS_RGB_SUPPORT = Util.hasMethod(ChatColor.class, "of", String.class);
- private static final boolean HAS_FONT_SUPPORT = Util.hasMethod(ComponentBuilder.class, "font", String.class);
- private static final boolean HAS_INSERTION_SUPPORT = Util.hasMethod(ComponentBuilder.class, "insertion", String.class);
- private static final boolean HAS_HOVER_CONTENT_SUPPORT = Util.hasMethod(HoverEvent.class, "getContents");
-
- /**
- * The character to use as a special color code. (Default: ampersand &)
- */
- private char colorChar = '&';
-
- /**
- * All enabled options
- */
- private Set