9
0
mirror of https://github.com/Xiao-MoMi/Custom-Crops.git synced 2025-12-22 16:39:36 +00:00

1.4.0 beta

This commit is contained in:
Xiao-MoMi
2022-05-30 17:00:28 +08:00
parent 487a1a439e
commit 9542c91737
24 changed files with 597 additions and 704 deletions

View File

@@ -1,14 +1,14 @@
package net.momirealms.customcrops; package net.momirealms.customcrops;
import com.comphenix.protocol.ProtocolManager; import net.momirealms.customcrops.commands.CommandHandler;
import net.momirealms.customcrops.crops.CropTimer; import net.momirealms.customcrops.commands.CommandTabComplete;
import net.momirealms.customcrops.datamanager.BackUp; import net.momirealms.customcrops.datamanager.*;
import net.momirealms.customcrops.datamanager.CropManager; import net.momirealms.customcrops.listener.BreakCrops;
import net.momirealms.customcrops.datamanager.SprinklerManager; import net.momirealms.customcrops.timer.CropTimer;
import net.momirealms.customcrops.listener.BreakCustomBlock; import net.momirealms.customcrops.listener.BreakCustomBlock;
import net.momirealms.customcrops.listener.BreakFurniture;
import net.momirealms.customcrops.listener.RightClickBlock; import net.momirealms.customcrops.listener.RightClickBlock;
import net.momirealms.customcrops.listener.RightClickCustomBlock; import net.momirealms.customcrops.listener.RightClickCustomBlock;
import net.momirealms.customcrops.utils.Placeholders;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.configuration.file.YamlConfiguration;
@@ -21,7 +21,6 @@ import java.util.Objects;
public final class CustomCrops extends JavaPlugin { public final class CustomCrops extends JavaPlugin {
public static JavaPlugin instance; public static JavaPlugin instance;
public static ProtocolManager manager;
public static CropTimer timer; public static CropTimer timer;
public static CropManager cropManager; public static CropManager cropManager;
public static SprinklerManager sprinklerManager; public static SprinklerManager sprinklerManager;
@@ -40,7 +39,7 @@ public final class CustomCrops extends JavaPlugin {
Bukkit.getPluginManager().registerEvents(new RightClickCustomBlock(),this); Bukkit.getPluginManager().registerEvents(new RightClickCustomBlock(),this);
Bukkit.getPluginManager().registerEvents(new BreakCustomBlock(),this); Bukkit.getPluginManager().registerEvents(new BreakCustomBlock(),this);
Bukkit.getPluginManager().registerEvents(new RightClickBlock(),this); Bukkit.getPluginManager().registerEvents(new RightClickBlock(),this);
Bukkit.getPluginManager().registerEvents(new BreakFurniture(),this); Bukkit.getPluginManager().registerEvents(new BreakCrops(),this);
//开始计时任务 //开始计时任务
CustomCrops.timer = new CropTimer(); CustomCrops.timer = new CropTimer();
@@ -66,21 +65,17 @@ public final class CustomCrops extends JavaPlugin {
} }
//载入data数据 //载入data数据
FileConfiguration crop_data; CropManager.loadData();
FileConfiguration sprinkler_data; SprinklerManager.loadData();
crop_data = YamlConfiguration.loadConfiguration(crop_file);
sprinkler_data = YamlConfiguration.loadConfiguration(sprinkler_file);
CustomCrops.cropManager = new CropManager(crop_data);
CustomCrops.sprinklerManager = new SprinklerManager(sprinkler_data);
//检测papi依赖 //检测papi依赖
if(Bukkit.getPluginManager().getPlugin("PlaceholderAPI") != null){ if(Bukkit.getPluginManager().getPlugin("PlaceholderAPI") != null){
new Placeholders(this).register(); new Placeholders(this).register();
MessageManager.consoleMessage("&#ccfbff-#ef96c5&[CustomCrops] 检测到PlaceHolderAPI 已启用季节变量!",Bukkit.getConsoleSender()); MessageManager.consoleMessage("&#ccfbff-#ef96c5&[CustomCrops] 检测到PlaceHolderAPI 已启用季节变量!",Bukkit.getConsoleSender());
} }
//启动成功
MessageManager.consoleMessage("&#ccfbff-#ef96c5&[CustomCrops] 自定义农作物插件已启用!作者:小默米 QQ:3266959688",Bukkit.getConsoleSender()); MessageManager.consoleMessage("&#ccfbff-#ef96c5&[CustomCrops] 自定义农作物插件已启用!作者:小默米 QQ:3266959688",Bukkit.getConsoleSender());
//this.getLogger().info("自定义农作物插件已启用!作者:小默米 QQ:3266959688");
} }
@Override @Override

View File

@@ -1,5 +1,8 @@
package net.momirealms.customcrops; 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.BackUp;
import net.momirealms.customcrops.datamanager.CropManager; import net.momirealms.customcrops.datamanager.CropManager;
import net.momirealms.customcrops.datamanager.NextSeason; import net.momirealms.customcrops.datamanager.NextSeason;
@@ -117,11 +120,6 @@ public class CommandHandler implements CommandExecutor {
} }
return true; return true;
} }
if(args[0].equalsIgnoreCase("test")){
CropManager.testData_2();
SprinklerManager.testData_3();
return true;
}
return false; return false;
} }
} }

View File

@@ -1,4 +1,4 @@
package net.momirealms.customcrops; package net.momirealms.customcrops.commands;
import org.bukkit.command.Command; import org.bukkit.command.Command;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;

View File

@@ -1,11 +1,25 @@
package net.momirealms.customcrops; 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.FileConfiguration;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.scheduler.BukkitScheduler;
import java.io.File;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Set;
public class ConfigManager { public class ConfigManager {
public static HashMap<String, Crop> CONFIG;
static {
CONFIG = new HashMap<>();
}
public static class Config{ public static class Config{
public static boolean res; public static boolean res;
@@ -14,7 +28,6 @@ public class ConfigManager {
public static boolean season; public static boolean season;
public static boolean need_water; public static boolean need_water;
public static boolean greenhouse; public static boolean greenhouse;
public static boolean big;
public static boolean limit; public static boolean limit;
public static List<String> worlds; public static List<String> worlds;
@@ -56,8 +69,6 @@ public class ConfigManager {
public static String failure; public static String failure;
public static double bone_chance; public static double bone_chance;
public static double grow_chance;
public static double big_chance;
public static int range; public static int range;
public static int maxh; public static int maxh;
@@ -69,6 +80,7 @@ public class ConfigManager {
CustomCrops.instance.reloadConfig(); CustomCrops.instance.reloadConfig();
FileConfiguration configuration = CustomCrops.instance.getConfig(); FileConfiguration configuration = CustomCrops.instance.getConfig();
cropLoad();
//处理配置 //处理配置
Config.res = configuration.getBoolean("integration.residence"); Config.res = configuration.getBoolean("integration.residence");
@@ -77,12 +89,9 @@ public class ConfigManager {
Config.season = configuration.getBoolean("enable-season"); Config.season = configuration.getBoolean("enable-season");
Config.need_water = configuration.getBoolean("config.bone-meal-consume-water"); Config.need_water = configuration.getBoolean("config.bone-meal-consume-water");
Config.greenhouse = configuration.getBoolean("config.enable-greenhouse"); Config.greenhouse = configuration.getBoolean("config.enable-greenhouse");
Config.big = configuration.getBoolean("config.gigantic.enable");
Config.limit = configuration.getBoolean("config.enable-limit"); Config.limit = configuration.getBoolean("config.enable-limit");
Config.bone_chance = configuration.getDouble("config.bone-meal-chance"); Config.bone_chance = configuration.getDouble("config.bone-meal-chance");
Config.grow_chance = configuration.getDouble("config.grow-success-chance");
Config.big_chance = configuration.getDouble("config.gigantic.chance");
Config.range = configuration.getInt("config.greenhouse-range"); Config.range = configuration.getInt("config.greenhouse-range");
Config.maxh = configuration.getInt("config.height.max"); Config.maxh = configuration.getInt("config.height.max");
@@ -130,5 +139,54 @@ public class ConfigManager {
Config.autumn = configuration.getString("messages.autumn"); Config.autumn = configuration.getString("messages.autumn");
Config.winter = configuration.getString("messages.winter"); Config.winter = configuration.getString("messages.winter");
} }
/*
根据文件名获取配置文件
*/
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<String> keys = cropConfig.getConfigurationSection("crops").getKeys(false);
keys.forEach(key -> {
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(cropConfig.getConfigurationSection("crops."+key).contains("season")){
crop.setSeasons(StringUtils.split( cropConfig.getString("crops."+key+".season"), ","));
}
if(cropConfig.getConfigurationSection("crops."+key).contains("gigantic")){
crop.setWillGiant(true);
crop.setGiant(cropConfig.getString("crops."+key+".gigantic"));
crop.setGiantChance(cropConfig.getDouble("crops."+key+".gigantic-chance"));
}else {
crop.setWillGiant(false);
}
CONFIG.put(key, crop);
});
}
catch (Exception e) {
e.printStackTrace();
CustomCrops.instance.getLogger().warning("crops.yml加载失败!");
}
}
} }
} }

View File

@@ -1,13 +1,11 @@
package net.momirealms.customcrops.datamanager; package net.momirealms.customcrops.datamanager;
import dev.lone.itemsadder.api.CustomBlock; import dev.lone.itemsadder.api.CustomBlock;
import net.momirealms.customcrops.ConfigManager;
import net.momirealms.customcrops.CustomCrops; import net.momirealms.customcrops.CustomCrops;
import net.momirealms.customcrops.MessageManager; import net.momirealms.customcrops.utils.Crop;
import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.StringUtils;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.World; import org.bukkit.World;
import org.bukkit.block.Block; import org.bukkit.block.Block;
import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.configuration.file.FileConfiguration;
@@ -21,90 +19,43 @@ import java.util.concurrent.ConcurrentHashMap;
public class CropManager { public class CropManager {
public static ConcurrentHashMap<Location, String> instances; public static ConcurrentHashMap<Location, String> CROPS;
/*
开服的时候将文件的数据读入
*/
public static void loadData() {
//4W性能测试
public static void testData_1(){
for(int i = -100; i < 100; i++){
for(int j = -100; j < 100; j++){
Location tempLoc = new Location(Bukkit.getWorld("world"),i,100,j);
String name = "spring";
instances.put(tempLoc, name);
}
}
}
//20W性能测试
public static void testData_2(){
for(int i = -100000; i < 100000; i++){
Location tempLoc = new Location(Bukkit.getWorld("world"),i,100,i);
String name = "spring";
instances.put(tempLoc, name);
}
}
//开服的时候将文件的数据读入
public CropManager(FileConfiguration data) {
FileConfiguration config = CustomCrops.instance.getConfig();
File file = new File(CustomCrops.instance.getDataFolder(), "crop-data.yml"); File file = new File(CustomCrops.instance.getDataFolder(), "crop-data.yml");
data = YamlConfiguration.loadConfiguration(file); FileConfiguration data = YamlConfiguration.loadConfiguration(file);
try {
for (String world : config.getStringList("config.whitelist-worlds")) { CROPS = new ConcurrentHashMap<>();
CropManager.instances = new ConcurrentHashMap<Location, String>();
if(data.getConfigurationSection(world) != null){ for (String world : ConfigManager.Config.worlds) {
for (String coordinate : data.getConfigurationSection(world).getKeys(false)) { //如果数据文件中有相应世界才进行读取
Location tempLocation = new Location(Bukkit.getWorld(world), (double)Integer.parseInt(coordinate.split(",")[0]), (double)Integer.parseInt(coordinate.split(",")[1]), (double)Integer.parseInt(coordinate.split(",")[2])); if(data.contains(world)){
String season = data.getString(world + "." + coordinate); for (String coordinate : data.getConfigurationSection(world).getKeys(false)) {
CropManager.instances.put(tempLocation, season); 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);
} }
} }
} }
catch (Exception e) {
CropManager.instances = new ConcurrentHashMap<Location, String>();
e.printStackTrace();
}
saveData();
} }
/* /*
//根据世界名获取所有的农作物 保存数据
public static List<Location> getCrops(World world){
FileConfiguration config = CustomCrops.instance.getConfig();
File file = new File(CustomCrops.instance.getDataFolder(), "crop-data.yml");
FileConfiguration data;
data = YamlConfiguration.loadConfiguration(file);
List<Location> locations = new ArrayList<Location>();
if (config.getStringList("config.whitelist-worlds").contains(world.getName())){
if(data.contains(world.getName())){
data.getConfigurationSection(world.getName()).getKeys(false).forEach(key ->{
String[] string_list = key.split(",");
if (config.getBoolean("config.only-grow-in-loaded-chunks")){
if (world.isChunkLoaded(Integer.parseInt(string_list[0])/16, Integer.parseInt(string_list[2])/16)){
locations.add(new Location(world, Double.parseDouble(string_list[0]),Double.parseDouble(string_list[1]),Double.parseDouble(string_list[2])));
}
}else {
locations.add(new Location(world, Double.parseDouble(string_list[0]),Double.parseDouble(string_list[1]),Double.parseDouble(string_list[2])));
}
});
}
}
return locations;
}
*/ */
//保存数据
public static void saveData(){ public static void saveData(){
File file = new File(CustomCrops.instance.getDataFolder(), "crop-data.yml"); File file = new File(CustomCrops.instance.getDataFolder(), "crop-data.yml");
FileConfiguration data; FileConfiguration data;
data = YamlConfiguration.loadConfiguration(file); data = YamlConfiguration.loadConfiguration(file);
if (CropManager.instances != null) {
//性能更高 //性能更高
Set<Map.Entry<Location, String>> en = instances.entrySet(); Set<Map.Entry<Location, String>> en = CROPS.entrySet();
for(Map.Entry<Location, String> entry : en){ for(Map.Entry<Location, String> entry : en){
data.set(entry.getKey().getWorld().getName() + "." + entry.getKey().getBlockX() + "," + entry.getKey().getBlockY()+ ","+entry.getKey().getBlockZ(), entry.getValue()); Location loc = entry.getKey();
} data.set(loc.getWorld().getName()+"."+ loc.getBlockX() + "," + loc.getBlockY()+ ","+loc.getBlockZ(), entry.getValue());
}
else {
CropManager.instances = new ConcurrentHashMap<Location, String>();
Bukkit.getConsoleSender().sendMessage("错误:空数据");
} }
try { try {
data.save(file); data.save(file);
@@ -114,209 +65,198 @@ public class CropManager {
CustomCrops.instance.getLogger().warning("农作物数据保存出错"); CustomCrops.instance.getLogger().warning("农作物数据保存出错");
} }
} }
public static void putInstance(Location location, String season) {
CropManager.instances.put(location, season); /*
添加农作物实例
*/
public static void putInstance(Location location, String crop) {
CROPS.put(location, crop);
} }
//清理无效的农作物并生长
/*
生长部分
*/
public static void CropGrow() { public static void CropGrow() {
/* /*
阶段1更新数据 阶段1更新数据
*/ */
long start1 = System.currentTimeMillis(); long start1 = System.currentTimeMillis();
FileConfiguration config = CustomCrops.instance.getConfig();
File file = new File(CustomCrops.instance.getDataFolder(), "crop-data.yml"); File file = new File(CustomCrops.instance.getDataFolder(), "crop-data.yml");
FileConfiguration data; FileConfiguration data = YamlConfiguration.loadConfiguration(file);
data = YamlConfiguration.loadConfiguration(file); BukkitScheduler bukkitScheduler = Bukkit.getScheduler();
if (CropManager.instances != null) {
//性能更高 Set<Map.Entry<Location, String>> en = CROPS.entrySet();
Set<Map.Entry<Location, String>> en = instances.entrySet(); for(Map.Entry<Location, String> entry : en){
for(Map.Entry<Location, String> entry : en){ Location key = entry.getKey();
Location key = entry.getKey(); data.set(key.getWorld().getName() + "." + key.getBlockX() + "," + key.getBlockY()+ ","+ key.getBlockZ(), entry.getValue());
data.set(key.getWorld().getName() + "." + key.getBlockX() + "," + key.getBlockY()+ ","+ key.getBlockZ(), entry.getValue());
}
} }
long finish1 = System.currentTimeMillis(); long finish1 = System.currentTimeMillis();
MessageManager.consoleMessage("&#ccfbff-#ef96c5&[CustomCrops|性能监测] &f农作物数据更新耗时&a" + String.valueOf(finish1-start1) + "&fms",Bukkit.getConsoleSender()); MessageManager.consoleMessage("&#ccfbff-#ef96c5&[CustomCrops] &7农作物数据更新耗时&a" + (finish1 - start1) + "&fms",Bukkit.getConsoleSender());
/* /*
阶段2清理数据内无效的农作物 阶段2清理数据内无效的农作物并让有效农作物生长
*/ */
long start2 = System.currentTimeMillis(); long start2 = System.currentTimeMillis();
List<Location> locations = new ArrayList<Location>();
ConfigManager.Config.worlds.forEach(worldName ->{ ConfigManager.Config.worlds.forEach(worldName ->{
if(data.contains(worldName)){ if(data.contains(worldName)){
World world = Bukkit.getWorld(worldName); World world = Bukkit.getWorld(worldName);
data.getConfigurationSection(worldName).getKeys(false).forEach(key ->{ data.getConfigurationSection(worldName).getKeys(false).forEach(key ->{
String[] string_list = StringUtils.split(key,",");
if (world.isChunkLoaded(Integer.parseInt(string_list[0])/16, Integer.parseInt(string_list[2])/16)){ String[] coordinate = StringUtils.split(key,",");
Location tempLoc = new Location(world,Double.parseDouble(string_list[0]),Double.parseDouble(string_list[1]),Double.parseDouble(string_list[2])); //先判断区块是否加载,未加载则不进行下一步计算
if(tempLoc.getBlock().getType() != Material.TRIPWIRE){ if (world.isChunkLoaded(Integer.parseInt(coordinate[0])/16, Integer.parseInt(coordinate[2])/16)){
CropManager.instances.remove(tempLoc);
data.set(worldName+"."+string_list[0]+","+string_list[1]+","+string_list[2], null); Location sLoc = new Location(world,Double.parseDouble(coordinate[0]),Double.parseDouble(coordinate[1]),Double.parseDouble(coordinate[2]));
}else { CustomBlock seedBlock = CustomBlock.byAlreadyPlaced(sLoc.getBlock());
locations.add(new Location(world, Double.parseDouble(string_list[0]),Double.parseDouble(string_list[1]),Double.parseDouble(string_list[2])));
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()){
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(); long finish2 = System.currentTimeMillis();
MessageManager.consoleMessage("&#ccfbff-#ef96c5&[CustomCrops|性能监测] &f农作物缓存清理耗时&a" + String.valueOf(finish2-start2) + "&fms",Bukkit.getConsoleSender()); MessageManager.consoleMessage("&#ccfbff-#ef96c5&[CustomCrops] &7农作物生长耗时&a" + (finish2 - start2) + "&fms",Bukkit.getConsoleSender());
/* /*
阶段3保存文件 阶段3保存文件
*/ */
try{
data.save(file);
}catch (IOException e){
e.printStackTrace();
CustomCrops.instance.getLogger().warning("农作物缓存清理保存出错!");
}
/*
阶段4农作物生长判断
*/
long start3 = System.currentTimeMillis(); long start3 = System.currentTimeMillis();
BukkitScheduler bukkitScheduler = Bukkit.getScheduler();
ConfigManager.Config.worlds.forEach(worldName -> {
World world = Bukkit.getWorld(worldName);
locations.forEach(seedLocation -> {
Location potLocation = seedLocation.clone().subtract(0,1,0);
Block seedBlock = seedLocation.getBlock();
Block potBlock = potLocation.getBlock();
String[] seasons = StringUtils.split(data.getString(worldName + "." + seedLocation.getBlockX() + "," + seedLocation.getBlockY() + "," + seedLocation.getBlockZ()),",");
if (CustomBlock.byAlreadyPlaced(potBlock) != null && CustomBlock.byAlreadyPlaced(seedBlock) != null){
String seedNamespace = CustomBlock.byAlreadyPlaced(seedBlock).getNamespacedID();
if (CustomBlock.byAlreadyPlaced(potBlock).getNamespacedID().equalsIgnoreCase(ConfigManager.Config.watered_pot) && seedNamespace.contains("stage")){
if (seedNamespace.equalsIgnoreCase(ConfigManager.Config.dead)){
return;
}
String[] split = StringUtils.split(seedNamespace,":");
String[] cropNameList = StringUtils.split(split[1],"_");
Label_out:
if(ConfigManager.Config.season){
if(ConfigManager.Config.greenhouse){
for(int i = 1; i <= ConfigManager.Config.range; i++){
Location tempLocation = seedLocation.clone().add(0,i,0);
if (CustomBlock.byAlreadyPlaced(tempLocation.getBlock()) != null){
if(CustomBlock.byAlreadyPlaced(tempLocation.getBlock()).getNamespacedID().equalsIgnoreCase(ConfigManager.Config.glass)){
break Label_out;
}
}
}
}
boolean wrongSeason = true;
for(String season : seasons){
if (Objects.equals(season, ConfigManager.Config.current)) {
wrongSeason = false;
break;
}
}
if(wrongSeason){
bukkitScheduler.callSyncMethod(CustomCrops.instance, () -> {
CustomBlock.remove(seedLocation);
CustomBlock.place(ConfigManager.Config.dead, seedLocation);
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(potLocation);
CustomBlock.place(ConfigManager.Config.pot, potLocation);
if(Math.random()< ConfigManager.Config.grow_chance){
CustomBlock.remove(seedLocation);
CustomBlock.place(split[0] + ":" + cropNameList[0] + "_stage_" + nextStage,seedLocation);
}
return null;
});
}else if(ConfigManager.Config.big){
//农作物巨大化
if(config.getConfigurationSection("crops." + cropNameList[0]).getKeys(false).contains("gigantic")){
bukkitScheduler.callSyncMethod(CustomCrops.instance, () ->{
CustomBlock.remove(potLocation);
CustomBlock.place(ConfigManager.Config.pot, potLocation);
if(ConfigManager.Config.big_chance > Math.random()){
CustomBlock.remove(seedLocation);
CustomBlock.place(config.getString("crops." + cropNameList[0] + ".gigantic"),seedLocation);
}
return null;
});
}
}
}else if(CustomBlock.byAlreadyPlaced(potBlock).getNamespacedID().equalsIgnoreCase(ConfigManager.Config.pot) && seedNamespace.contains("stage")){
if (seedNamespace.equalsIgnoreCase(ConfigManager.Config.dead)){
return;
}
if(ConfigManager.Config.season) {
if(ConfigManager.Config.greenhouse){
for(int i = 1; i <= ConfigManager.Config.range; i++){
Location tempLocation = seedLocation.clone().add(0,i,0);
if (CustomBlock.byAlreadyPlaced(tempLocation.getBlock()) != null){
if(CustomBlock.byAlreadyPlaced(tempLocation.getBlock()).getNamespacedID().equalsIgnoreCase(ConfigManager.Config.glass)){
return;
}
}
}
}
boolean wrongSeason = true;
for (String season : seasons) {
if (Objects.equals(season, ConfigManager.Config.current)) {
wrongSeason = false;
break;
}
}
if (wrongSeason) {
bukkitScheduler.callSyncMethod(CustomCrops.instance, () -> {
CustomBlock.remove(seedLocation);
CustomBlock.place(ConfigManager.Config.dead, seedLocation);
return null;
});
}
}
}
}
});
});
long finish3 = System.currentTimeMillis();
MessageManager.consoleMessage("&#ccfbff-#ef96c5&[CustomCrops|性能监测] &f农作物生长判断耗时&a" + String.valueOf(finish3-start3) + "&fms",Bukkit.getConsoleSender());
}
/*
//清理无效的农作物
public static void cleanLoadedCache() {
File file = new File(CustomCrops.instance.getDataFolder(), "crop-data.yml");
FileConfiguration data;
data = YamlConfiguration.loadConfiguration(file);
ConfigManager.Config.worlds.forEach(worldName ->{
if(data.contains(worldName)){
World world = Bukkit.getWorld(worldName);
data.getConfigurationSection(worldName).getKeys(false).forEach(key ->{
String[] string_list = StringUtils.split(key,",");
if (world.isChunkLoaded(Integer.parseInt(string_list[0])/16, Integer.parseInt(string_list[2])/16)){
Location tempLoc = new Location(world,Double.parseDouble(string_list[0]),Double.parseDouble(string_list[1]),Double.parseDouble(string_list[2]));
if(world.getBlockAt(tempLoc).getType() != Material.TRIPWIRE){
CropManager.instances.remove(tempLoc);
data.set(worldName+"."+string_list[0]+","+string_list[1]+","+string_list[2], null);
}
}
});
}
});
try{ try{
data.save(file); data.save(file);
}catch (IOException e){ }catch (IOException e){
e.printStackTrace(); e.printStackTrace();
CustomCrops.instance.getLogger().warning("农作物缓存清理保存出错!"); CustomCrops.instance.getLogger().warning("农作物缓存清理保存出错!");
} }
long finish3 = System.currentTimeMillis();
MessageManager.consoleMessage("&#ccfbff-#ef96c5&[CustomCrops] &7农作物数据保存耗时&a" + (finish3 - start3) + "&fms",Bukkit.getConsoleSender());
} }
*/
} }

View File

@@ -1,13 +1,11 @@
package net.momirealms.customcrops; package net.momirealms.customcrops.datamanager;
import net.momirealms.customcrops.Libs.minedown.MineDown; import net.momirealms.customcrops.Libs.minedown.MineDown;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
public class MessageManager { public class MessageManager {
public static void consoleMessage(String s, CommandSender sender) { public static void consoleMessage(String s, CommandSender sender) { sender.spigot().sendMessage(MineDown.parse(s)); }
sender.spigot().sendMessage(MineDown.parse(s));
}
public static void playerMessage(String s, Player player){ public static void playerMessage(String s, Player player){
player.spigot().sendMessage(MineDown.parse(s)); player.spigot().sendMessage(MineDown.parse(s));
} }

View File

@@ -1,6 +1,5 @@
package net.momirealms.customcrops.datamanager; package net.momirealms.customcrops.datamanager;
import net.momirealms.customcrops.ConfigManager;
import net.momirealms.customcrops.CustomCrops; import net.momirealms.customcrops.CustomCrops;
import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.configuration.file.FileConfiguration;
@@ -8,7 +7,6 @@ import java.util.Objects;
public class NextSeason { public class NextSeason {
public static void changeSeason(){ public static void changeSeason(){
FileConfiguration config = CustomCrops.instance.getConfig(); FileConfiguration config = CustomCrops.instance.getConfig();
String currentSeason = ConfigManager.Config.current; String currentSeason = ConfigManager.Config.current;
String nextSeason = switch (Objects.requireNonNull(currentSeason)) { String nextSeason = switch (Objects.requireNonNull(currentSeason)) {
@@ -26,4 +24,4 @@ public class NextSeason {
CustomCrops.instance.getLogger().warning("季节配置文件出错!"); CustomCrops.instance.getLogger().warning("季节配置文件出错!");
} }
} }
} }

View File

@@ -1,16 +1,15 @@
package net.momirealms.customcrops.datamanager; package net.momirealms.customcrops.datamanager;
import dev.lone.itemsadder.api.CustomBlock; import dev.lone.itemsadder.api.CustomBlock;
import net.momirealms.customcrops.ConfigManager;
import net.momirealms.customcrops.CustomCrops; import net.momirealms.customcrops.CustomCrops;
import net.momirealms.customcrops.IAFurniture; import net.momirealms.customcrops.utils.IAFurniture;
import net.momirealms.customcrops.MessageManager;
import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.StringUtils;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.World; import org.bukkit.World;
import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.scheduler.BukkitScheduler;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
@@ -19,83 +18,38 @@ import java.util.concurrent.ConcurrentHashMap;
public class SprinklerManager { public class SprinklerManager {
public static ConcurrentHashMap<Location, String> instances; public static ConcurrentHashMap<Location, String> SPRINKLERS;
/*
开服的时候将文件的数据读入
*/
public static void loadData(){
//10W性能测试 SPRINKLERS = new ConcurrentHashMap<>();
public static void testData_3(){
for(int i = -50000; i < 50000; i++){
Location tempLoc = new Location(Bukkit.getWorld("world"),i,100,i);
String name = "s1";
instances.put(tempLoc, name);
}
}
//开服的时候将文件的数据读入
public SprinklerManager(FileConfiguration data) {
FileConfiguration config = CustomCrops.instance.getConfig();
File file = new File(CustomCrops.instance.getDataFolder(), "sprinkler-data.yml"); File file = new File(CustomCrops.instance.getDataFolder(), "sprinkler-data.yml");
data = YamlConfiguration.loadConfiguration(file); FileConfiguration data = YamlConfiguration.loadConfiguration(file);
try { for (String world : ConfigManager.Config.worlds) {
for (String world : config.getStringList("config.whitelist-worlds")) { if(data.getConfigurationSection(world) != null){
SprinklerManager.instances = new ConcurrentHashMap<Location, String>(); for (String coordinate : data.getConfigurationSection(world).getKeys(false)) {
if(data.getConfigurationSection(world) != null){ Location tempLocation = new Location(Bukkit.getWorld(world), Integer.parseInt(coordinate.split(",")[0]), Integer.parseInt(coordinate.split(",")[1]), Integer.parseInt(coordinate.split(",")[2]));
for (String coordinate : data.getConfigurationSection(world).getKeys(false)) { String type = data.getString(world + "." + coordinate);
Location tempLocation = new Location(Bukkit.getWorld(world), Integer.parseInt(coordinate.split(",")[0]), Integer.parseInt(coordinate.split(",")[1]), Integer.parseInt(coordinate.split(",")[2])); SPRINKLERS.put(tempLocation, type);
String type = data.getString(world + "." + coordinate);
SprinklerManager.instances.put(tempLocation, type);
}
} }
} }
} }
catch (Exception e) {
SprinklerManager.instances = new ConcurrentHashMap<Location, String>();
e.printStackTrace();
}
saveData();
} }
/* /*
//根据世界名获取所有的洒水器 保存数据
public static List<Location> getSprinklers(World world){ */
FileConfiguration config = CustomCrops.instance.getConfig();
File file = new File(CustomCrops.instance.getDataFolder(), "sprinkler-data.yml");
FileConfiguration data;
data = YamlConfiguration.loadConfiguration(file);
List<Location> locations = new ArrayList<Location>();
if (config.getStringList("config.whitelist-worlds").contains(world.getName())){
if(data.contains(world.getName())){
data.getConfigurationSection(world.getName()).getKeys(false).forEach(key ->{
String[] string_list = key.split(",");
//只返回被加载的区块中的洒水器坐标
if (config.getBoolean("config.only-grow-in-loaded-chunks")){
if (world.isChunkLoaded(Integer.parseInt(string_list[0])/16, Integer.parseInt(string_list[2])/16)){
locations.add(new Location(world, Double.parseDouble(string_list[0]),Double.parseDouble(string_list[1]),Double.parseDouble(string_list[2])));
}
}else {
locations.add(new Location(world, Double.parseDouble(string_list[0]),Double.parseDouble(string_list[1]),Double.parseDouble(string_list[2])));
}
});
}
}
return locations;
}
*/
//保存数据
public static void saveData(){ public static void saveData(){
File file = new File(CustomCrops.instance.getDataFolder(), "sprinkler-data.yml"); File file = new File(CustomCrops.instance.getDataFolder(), "sprinkler-data.yml");
FileConfiguration data; FileConfiguration data = YamlConfiguration.loadConfiguration(file);
data = YamlConfiguration.loadConfiguration(file);
if (SprinklerManager.instances != null) { Set<Map.Entry<Location, String>> en = SPRINKLERS.entrySet();
//性能更高 for(Map.Entry<Location, String> entry : en){
Set<Map.Entry<Location, String>> en = instances.entrySet(); data.set(entry.getKey().getWorld().getName() + "." + entry.getKey().getBlockX() + "," + entry.getKey().getBlockY()+ ","+entry.getKey().getBlockZ(), entry.getValue());
for(Map.Entry<Location, String> entry : en){
data.set(entry.getKey().getWorld().getName() + "." + entry.getKey().getBlockX() + "," + entry.getKey().getBlockY()+ ","+entry.getKey().getBlockZ(), entry.getValue());
}
}
else {
SprinklerManager.instances = new ConcurrentHashMap<Location, String>();
Bukkit.getConsoleSender().sendMessage("错误:空数据");
} }
try { try {
data.save(file); data.save(file);
@@ -106,8 +60,9 @@ public class SprinklerManager {
} }
} }
public static void putInstance(Location location, String type) { public static void putInstance(Location location, String type) {
SprinklerManager.instances.put(location, type); SPRINKLERS.put(location, type);
} }
public static void SprinklerWork() { public static void SprinklerWork() {
/* /*
阶段1更新数据 阶段1更新数据
@@ -116,100 +71,71 @@ public class SprinklerManager {
File file = new File(CustomCrops.instance.getDataFolder(), "sprinkler-data.yml"); File file = new File(CustomCrops.instance.getDataFolder(), "sprinkler-data.yml");
FileConfiguration data; FileConfiguration data;
data = YamlConfiguration.loadConfiguration(file); data = YamlConfiguration.loadConfiguration(file);
if (SprinklerManager.instances != null) { BukkitScheduler bukkitScheduler = Bukkit.getScheduler();
//性能更高
Set<Map.Entry<Location, String>> en = instances.entrySet(); Set<Map.Entry<Location, String>> en = SPRINKLERS.entrySet();
for(Map.Entry<Location, String> entry : en){ for(Map.Entry<Location, String> entry : en){
data.set(entry.getKey().getWorld().getName() + "." + entry.getKey().getBlockX() + "," + entry.getKey().getBlockY()+ ","+entry.getKey().getBlockZ(), entry.getValue()); data.set(entry.getKey().getWorld().getName() + "." + entry.getKey().getBlockX() + "," + entry.getKey().getBlockY()+ ","+entry.getKey().getBlockZ(), entry.getValue());
}
} }
long finish1 = System.currentTimeMillis(); long finish1 = System.currentTimeMillis();
MessageManager.consoleMessage("&#ccfbff-#ef96c5&[CustomCrops|性能监测] &f洒水器数据更新耗时&a" + String.valueOf(finish1-start1) + "&fms",Bukkit.getConsoleSender()); MessageManager.consoleMessage("&#ccfbff-#ef96c5&[CustomCrops] &7洒水器数据更新耗时&a" + String.valueOf(finish1-start1) + "&fms",Bukkit.getConsoleSender());
/* /*
阶段2清理数据内无效的农作物 阶段2清理数据内无效的洒水器并工作
*/ */
Bukkit.getScheduler().callSyncMethod(CustomCrops.instance,()->{ bukkitScheduler.callSyncMethod(CustomCrops.instance,()->{
long start2 = System.currentTimeMillis(); long start2 = System.currentTimeMillis();
//map不能一边循环一边删除
//创建一个新的HashSet,用作循环
//检测碰撞体积需要同步 //检测碰撞体积需要同步
List<Location> locations = new ArrayList<Location>();
ConfigManager.Config.worlds.forEach(worldName ->{ ConfigManager.Config.worlds.forEach(worldName ->{
if(data.contains(worldName)){ if(data.contains(worldName)){
World world = Bukkit.getWorld(worldName); World world = Bukkit.getWorld(worldName);
data.getConfigurationSection(worldName).getKeys(false).forEach(key ->{ data.getConfigurationSection(worldName).getKeys(false).forEach(key ->{
String[] string_list = StringUtils.split(key,","); String[] coordinate = StringUtils.split(key,",");
if (world.isChunkLoaded(Integer.parseInt(string_list[0])/16, Integer.parseInt(string_list[2])/16)){ if (world.isChunkLoaded(Integer.parseInt(coordinate[0])/16, Integer.parseInt(coordinate[2])/16)){
Location tempLoc = new Location(world,Double.parseDouble(string_list[0])+0.5,Double.parseDouble(string_list[1])+0.5,Double.parseDouble(string_list[2])+0.5); 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)){ if(!IAFurniture.getFromLocation(tempLoc, world)){
SprinklerManager.instances.remove(tempLoc); SPRINKLERS.remove(tempLoc);
data.set(worldName+"."+string_list[0]+","+string_list[1]+","+string_list[2], null); data.set(worldName+"."+coordinate[0]+","+coordinate[1]+","+coordinate[2], null);
}else { }else {
locations.add(new Location(world, Double.parseDouble(string_list[0]),Double.parseDouble(string_list[1]),Double.parseDouble(string_list[2]))); String type = data.getString(worldName + "." + coordinate[0] + "," + coordinate[1] + "," + coordinate[2]);
if(type.equals("s1")){
for(int i = -1; i <= 1;i++){
for (int j = -1; j <= 1; j++){
waterPot(tempLoc.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));
}
}
}
} }
} }
}); });
} }
}); });
/*
Set<Location> key = new HashSet(instances.keySet());
for(Location u_key : key) {
if (!IAFurniture.getFromLocation(u_key.clone().add(0.5,0.5,0.5), u_key.getWorld())){
SprinklerManager.instances.remove(u_key);
data.set(u_key.getWorld().getName()+"."+u_key.getBlockX()+","+u_key.getBlockY()+","+u_key.getBlockZ(), null);
}else {
locations.add(new Location(world, Double.parseDouble(string_list[0]),Double.parseDouble(string_list[1]),Double.parseDouble(string_list[2])));
}
}
*/
long finish2 = System.currentTimeMillis(); long finish2 = System.currentTimeMillis();
MessageManager.consoleMessage("&#ccfbff-#ef96c5&[CustomCrops|性能监测] &f洒水器缓存清理耗时&a" + String.valueOf(finish2-start2) + "&fms",Bukkit.getConsoleSender()); MessageManager.consoleMessage("&#ccfbff-#ef96c5&[CustomCrops] &7洒水器工作耗时&a" + String.valueOf(finish2-start2) + "&fms",Bukkit.getConsoleSender());
Bukkit.getScheduler().runTaskAsynchronously(CustomCrops.instance,()->{ bukkitScheduler.runTaskAsynchronously(CustomCrops.instance,()->{
/* /*
阶段3保存数据 阶段3保存数据
*/ */
long start3 = System.currentTimeMillis();
try{ try{
data.save(file); data.save(file);
}catch (IOException e){ }catch (IOException e){
e.printStackTrace(); e.printStackTrace();
CustomCrops.instance.getLogger().warning("洒水器缓存清理保存出错!"); CustomCrops.instance.getLogger().warning("洒水器数据保存出错!");
} }
/*
阶段4洒水器工作
*/
long start3 = System.currentTimeMillis();
ConfigManager.Config.worlds.forEach(worldName -> {
World world = Bukkit.getWorld(worldName);
locations.forEach(location -> {
String type = data.getString(worldName + "." + location.getBlockX() + "," + location.getBlockY() + "," + location.getBlockZ());
if(type.equals("s1")){
for(int i = -1; i <= 1;i++){
for (int j = -1; j <= 1; j++){
Location tempLoc = location.clone().add(i,-1,j);
waterPot(tempLoc, world);
}
}
}else{
for(int i = -2; i <= 2;i++){
for (int j = -2; j <= 2; j++){
Location tempLoc = location.clone().add(i,-1,j);
waterPot(tempLoc, world);
}
}
}
});
});
long finish3 = System.currentTimeMillis(); long finish3 = System.currentTimeMillis();
MessageManager.consoleMessage("&#ccfbff-#ef96c5&[CustomCrops|性能监测] &f洒水器工作耗时&a" + String.valueOf(finish3-start3) + "&fms",Bukkit.getConsoleSender()); MessageManager.consoleMessage("&#ccfbff-#ef96c5&[CustomCrops] &7洒水器数据保存耗时&a" + String.valueOf(finish3-start3) + "&fms",Bukkit.getConsoleSender());
}); });
return null; return null;
}); });
} }
private static void waterPot(Location tempLoc, World world) { private static void waterPot(Location tempLoc) {
if(CustomBlock.byAlreadyPlaced(tempLoc.getBlock()) != null){ if(CustomBlock.byAlreadyPlaced(tempLoc.getBlock()) != null){
if(CustomBlock.byAlreadyPlaced(tempLoc.getBlock()).getNamespacedID().equalsIgnoreCase(ConfigManager.Config.pot)){ if(CustomBlock.byAlreadyPlaced(tempLoc.getBlock()).getNamespacedID().equalsIgnoreCase(ConfigManager.Config.pot)){
Bukkit.getScheduler().callSyncMethod(CustomCrops.instance,()->{ Bukkit.getScheduler().callSyncMethod(CustomCrops.instance,()->{

View File

@@ -1,6 +1,6 @@
package net.momirealms.customcrops.integrations; package net.momirealms.customcrops.integrations;
import net.momirealms.customcrops.ConfigManager; import net.momirealms.customcrops.datamanager.ConfigManager;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;

View File

@@ -12,19 +12,15 @@ import org.bukkit.entity.Player;
public class WorldGuardIntegrations { public class WorldGuardIntegrations {
public static boolean checkWGBuild(Location loc,Player player){ public static boolean checkWGBuild(Location loc,Player player){
LocalPlayer localPlayer = WorldGuardPlugin.inst().wrapPlayer(player); LocalPlayer localPlayer = WorldGuardPlugin.inst().wrapPlayer(player);
RegionContainer container = WorldGuard.getInstance().getPlatform().getRegionContainer(); RegionContainer container = WorldGuard.getInstance().getPlatform().getRegionContainer();
RegionQuery query = container.createQuery(); RegionQuery query = container.createQuery();
return !query.testState(BukkitAdapter.adapt(loc), localPlayer, Flags.BUILD); return !query.testState(BukkitAdapter.adapt(loc), localPlayer, Flags.BUILD);
} }
public static boolean checkWGHarvest(Location loc,Player player){ public static boolean checkWGHarvest(Location loc,Player player){
LocalPlayer localPlayer = WorldGuardPlugin.inst().wrapPlayer(player); LocalPlayer localPlayer = WorldGuardPlugin.inst().wrapPlayer(player);
RegionContainer container = WorldGuard.getInstance().getPlatform().getRegionContainer(); RegionContainer container = WorldGuard.getInstance().getPlatform().getRegionContainer();
RegionQuery query = container.createQuery(); RegionQuery query = container.createQuery();
return !query.testState(BukkitAdapter.adapt(loc), localPlayer, Flags.BLOCK_BREAK); return !query.testState(BukkitAdapter.adapt(loc), localPlayer, Flags.BLOCK_BREAK);
} }
} }

View File

@@ -1,7 +1,7 @@
package net.momirealms.customcrops.datamanager; package net.momirealms.customcrops.limits;
import dev.lone.itemsadder.api.CustomBlock; import dev.lone.itemsadder.api.CustomBlock;
import net.momirealms.customcrops.ConfigManager; import net.momirealms.customcrops.datamanager.ConfigManager;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.block.Block; import org.bukkit.block.Block;
@@ -28,7 +28,7 @@ public class MaxCropsPerChunk {
square.add(0.0, 1.0, 0.0); square.add(0.0, 1.0, 0.0);
Block b = square.getBlock(); Block b = square.getBlock();
if(CustomBlock.byAlreadyPlaced(b)!= null){ if(CustomBlock.byAlreadyPlaced(b)!= null){
if (CustomBlock.byAlreadyPlaced(b).getNamespacedID().contains("stage")) { if (CustomBlock.byAlreadyPlaced(b).getNamespacedID().contains("_stage_")) {
if (n++ > maxAmount) { if (n++ > maxAmount) {
break Label_out; break Label_out;
} }

View File

@@ -1,7 +1,7 @@
package net.momirealms.customcrops.datamanager; package net.momirealms.customcrops.limits;
import net.momirealms.customcrops.ConfigManager; import net.momirealms.customcrops.datamanager.ConfigManager;
import net.momirealms.customcrops.IAFurniture; import net.momirealms.customcrops.utils.IAFurniture;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.World; import org.bukkit.World;

View File

@@ -1,17 +1,17 @@
package net.momirealms.customcrops.listener; package net.momirealms.customcrops.listener;
import dev.lone.itemsadder.api.CustomStack; import dev.lone.itemsadder.api.CustomStack;
import net.momirealms.customcrops.ConfigManager; import net.momirealms.customcrops.datamanager.ConfigManager;
import org.bukkit.entity.Entity; import org.bukkit.entity.Entity;
import org.bukkit.entity.Item; import org.bukkit.entity.Item;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener; import org.bukkit.event.Listener;
import org.bukkit.event.entity.EntitySpawnEvent; import org.bukkit.event.entity.EntitySpawnEvent;
public class BreakFurniture implements Listener { public class BreakCrops implements Listener {
@EventHandler @EventHandler
public void breakFurniture(EntitySpawnEvent event){ public void breakCrops(EntitySpawnEvent event){
Entity entity = event.getEntity(); Entity entity = event.getEntity();
if(!(entity instanceof Item)) return; if(!(entity instanceof Item)) return;
if(CustomStack.byItemStack(((Item) entity).getItemStack()) != null){ if(CustomStack.byItemStack(((Item) entity).getItemStack()) != null){
@@ -27,4 +27,4 @@ public class BreakFurniture implements Listener {
} }
} }
} }
} }

View File

@@ -2,7 +2,7 @@ package net.momirealms.customcrops.listener;
import dev.lone.itemsadder.api.CustomBlock; import dev.lone.itemsadder.api.CustomBlock;
import dev.lone.itemsadder.api.Events.CustomBlockBreakEvent; import dev.lone.itemsadder.api.Events.CustomBlockBreakEvent;
import net.momirealms.customcrops.ConfigManager; import net.momirealms.customcrops.datamanager.ConfigManager;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.World; import org.bukkit.World;
@@ -17,24 +17,29 @@ public class BreakCustomBlock implements Listener {
@EventHandler @EventHandler
public void breakCustomBlock(CustomBlockBreakEvent event){ public void breakCustomBlock(CustomBlockBreakEvent event){
Player player =event.getPlayer();
Location location = event.getBlock().getLocation();
String namespacedId = event.getNamespacedID(); String namespacedId = event.getNamespacedID();
if(namespacedId.contains("stage")){ //用于防止玩家使用精准采集获取生长阶段物品
if(namespacedId.contains("_stage_")){
Player player =event.getPlayer();
if(player.getInventory().getItemInMainHand().containsEnchantment(Enchantment.SILK_TOUCH) || player.getInventory().getItemInMainHand().getType() == Material.SHEARS){ if(player.getInventory().getItemInMainHand().containsEnchantment(Enchantment.SILK_TOUCH) || player.getInventory().getItemInMainHand().getType() == Material.SHEARS){
event.setCancelled(true); event.setCancelled(true);
Location location = event.getBlock().getLocation();
CustomBlock.place(namespacedId, location); CustomBlock.place(namespacedId, location);
CustomBlock.byAlreadyPlaced(location.getBlock()).getLoot().forEach(itemStack -> { CustomBlock.byAlreadyPlaced(location.getBlock()).getLoot().forEach(itemStack -> {
location.getWorld().dropItem(location.clone().add(0.5,0.2,0.5), itemStack); location.getWorld().dropItem(location.clone().add(0.5,0.2,0.5), itemStack);
CustomBlock.remove(location); CustomBlock.remove(location);
}); });
} }
}else if(namespacedId.equalsIgnoreCase(ConfigManager.Config.watered_pot) || namespacedId.equalsIgnoreCase(ConfigManager.Config.pot)){ }
//玩家破坏种植盆也会使得农作物掉落
else if(namespacedId.equalsIgnoreCase(ConfigManager.Config.watered_pot) || namespacedId.equalsIgnoreCase(ConfigManager.Config.pot)){
Location location = event.getBlock().getLocation();
World world = location.getWorld(); World world = location.getWorld();
Block blockUp = location.add(0,1,0).getBlock(); Block blockUp = location.add(0,1,0).getBlock();
if(CustomBlock.byAlreadyPlaced(blockUp) != null){ if(CustomBlock.byAlreadyPlaced(blockUp) != null){
if(CustomBlock.byAlreadyPlaced(blockUp).getNamespacedID().contains("stage")){ if(CustomBlock.byAlreadyPlaced(blockUp).getNamespacedID().contains("_stage_")){
for (ItemStack itemStack : CustomBlock.byAlreadyPlaced(blockUp).getLoot()) { for (ItemStack itemStack : CustomBlock.byAlreadyPlaced(blockUp).getLoot()) {
world.dropItem(location.clone().add(0.5, 0.2, 0.5), itemStack); world.dropItem(location.clone().add(0.5, 0.2, 0.5), itemStack);
} }

View File

@@ -1,12 +1,12 @@
package net.momirealms.customcrops.listener; package net.momirealms.customcrops.listener;
import dev.lone.itemsadder.api.CustomStack; import dev.lone.itemsadder.api.CustomStack;
import net.momirealms.customcrops.ConfigManager; import net.momirealms.customcrops.datamanager.ConfigManager;
import net.momirealms.customcrops.datamanager.MaxSprinklersPerChunk; import net.momirealms.customcrops.limits.MaxSprinklersPerChunk;
import net.momirealms.customcrops.datamanager.SprinklerManager; import net.momirealms.customcrops.datamanager.SprinklerManager;
import net.momirealms.customcrops.IAFurniture; import net.momirealms.customcrops.utils.IAFurniture;
import net.momirealms.customcrops.integrations.IntegrationCheck; import net.momirealms.customcrops.integrations.IntegrationCheck;
import net.momirealms.customcrops.MessageManager; import net.momirealms.customcrops.datamanager.MessageManager;
import org.bukkit.GameMode; import org.bukkit.GameMode;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.Material; import org.bukkit.Material;
@@ -49,13 +49,13 @@ public class RightClickBlock implements Listener {
if(hasWater){ if(hasWater){
if(namespacedId.equalsIgnoreCase(ConfigManager.Config.watering_can_1) || if(namespacedId.equalsIgnoreCase(ConfigManager.Config.watering_can_1) ||
namespacedId.equalsIgnoreCase(ConfigManager.Config.watering_can_2) || namespacedId.equalsIgnoreCase(ConfigManager.Config.watering_can_2) ||
namespacedId.equalsIgnoreCase(ConfigManager.Config.watering_can_3)) { namespacedId.equalsIgnoreCase(ConfigManager.Config.watering_can_3)) {
if(customStack.getMaxDurability() == customStack.getDurability()){ if(customStack.getMaxDurability() == customStack.getDurability()){
MessageManager.playerMessage(ConfigManager.Config.prefix + ConfigManager.Config.can_full,player); MessageManager.playerMessage(ConfigManager.Config.prefix + ConfigManager.Config.can_full, player);
}else { }else {
customStack.setDurability(customStack.getDurability() + 1); customStack.setDurability(customStack.getDurability() + 1);
player.getWorld().playSound(player.getLocation(),Sound.ITEM_BUCKET_FILL,1,1); player.getWorld().playSound(player.getLocation(),Sound.ITEM_BUCKET_FILL,1,1);
} }
} }
} }

View File

@@ -3,17 +3,17 @@ package net.momirealms.customcrops.listener;
import dev.lone.itemsadder.api.CustomBlock; import dev.lone.itemsadder.api.CustomBlock;
import dev.lone.itemsadder.api.CustomStack; import dev.lone.itemsadder.api.CustomStack;
import dev.lone.itemsadder.api.Events.CustomBlockInteractEvent; import dev.lone.itemsadder.api.Events.CustomBlockInteractEvent;
import net.momirealms.customcrops.ConfigManager; import net.momirealms.customcrops.datamanager.ConfigManager;
import net.momirealms.customcrops.CustomCrops; import net.momirealms.customcrops.CustomCrops;
import net.momirealms.customcrops.datamanager.CropManager; import net.momirealms.customcrops.datamanager.CropManager;
import net.momirealms.customcrops.datamanager.MaxCropsPerChunk; import net.momirealms.customcrops.limits.MaxCropsPerChunk;
import net.momirealms.customcrops.integrations.IntegrationCheck; import net.momirealms.customcrops.integrations.IntegrationCheck;
import net.momirealms.customcrops.MessageManager; import net.momirealms.customcrops.datamanager.MessageManager;
import net.momirealms.customcrops.utils.Crop;
import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.StringUtils;
import org.bukkit.*; import org.bukkit.*;
import org.bukkit.block.Block; import org.bukkit.block.Block;
import org.bukkit.block.BlockFace; import org.bukkit.block.BlockFace;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener; import org.bukkit.event.Listener;
@@ -25,36 +25,32 @@ import java.util.Objects;
public class RightClickCustomBlock implements Listener { public class RightClickCustomBlock implements Listener {
BukkitScheduler bukkitScheduler = Bukkit.getScheduler();
@EventHandler @EventHandler
public void rightClickCustomCrop(CustomBlockInteractEvent event){ public void rightClickCustomBlock(CustomBlockInteractEvent event){
if (event.getAction() != Action.RIGHT_CLICK_BLOCK) { if (event.getAction() != Action.RIGHT_CLICK_BLOCK) return;
return;
}
//获取配置文件
Player player = event.getPlayer();
Block clickedBlock = event.getBlockClicked(); Block clickedBlock = event.getBlockClicked();
Location clickedBlockLocation = clickedBlock.getLocation(); Location clickedBlockLocation = clickedBlock.getLocation();
/* /*
手里无物品,则进行收获判断 手里无物品,则进行收获判断
手里有物品,则进行浇水,骨粉,种植判断 手里有物品,则进行浇水,骨粉,种植判断
*/ */
//手无物品部分 //手部分
if (event.getItem() == null) { if (event.getItem() == null) {
CustomBlock clickedCustomBlock = CustomBlock.byAlreadyPlaced(clickedBlock); CustomBlock clickedCustomBlock = CustomBlock.byAlreadyPlaced(clickedBlock);
if(clickedCustomBlock == null) return; Player player = event.getPlayer();
//兼容性检测 //兼容性检测
if(!IntegrationCheck.HarvestCheck(clickedBlockLocation, player)){ if(!IntegrationCheck.HarvestCheck(clickedBlockLocation, player)){
//获取点击方块的命名空间与ID //获取点击方块的命名空间与ID
String namespacedID = clickedCustomBlock.getNamespacedID(); String namespacedID = event.getNamespacedID();
//如果ID内有stage则进行下一步 //如果ID内有stage则进行下一步
if (namespacedID.contains("stage")){ if (namespacedID.contains("_stage_")){
//是否为枯萎植物 //是否为枯萎植物
if(namespacedID.equalsIgnoreCase(ConfigManager.Config.dead)) return; if(namespacedID.equalsIgnoreCase(ConfigManager.Config.dead)) return;
//String namespace = clickedCustomBlock.getNamespacedID().split(":")[0];
String[] split = StringUtils.split(namespacedID,":"); String[] split = StringUtils.split(namespacedID,":");
//String[] cropNameList = clickedCustomBlock.getNamespacedID().split(":")[1].split("_");
String[] cropNameList = StringUtils.split(split[1],"_"); String[] cropNameList = StringUtils.split(split[1],"_");
int nextStage = Integer.parseInt(cropNameList[2]) + 1; int nextStage = Integer.parseInt(cropNameList[2]) + 1;
//农作物是否存在下一阶段 //农作物是否存在下一阶段
if (CustomBlock.getInstance(split[0] + ":" + cropNameList[0] + "_stage_" + nextStage) == null) { if (CustomBlock.getInstance(split[0] + ":" + cropNameList[0] + "_stage_" + nextStage) == null) {
@@ -63,33 +59,27 @@ public class RightClickCustomBlock implements Listener {
clickedCustomBlock.getLoot().forEach(itemStack -> clickedBlockLocation.getWorld().dropItem(clickedBlockLocation.clone().add(0.5,0.2,0.5),itemStack)); clickedCustomBlock.getLoot().forEach(itemStack -> clickedBlockLocation.getWorld().dropItem(clickedBlockLocation.clone().add(0.5,0.2,0.5),itemStack));
CustomBlock.remove(clickedBlockLocation); CustomBlock.remove(clickedBlockLocation);
//如果配置文件中有return项目则放置方块 //如果配置文件中有return项目则放置方块
FileConfiguration config = CustomCrops.instance.getConfig(); Crop crop = ConfigManager.CONFIG.get(cropNameList[0]);
if(crop.getWillReturn()){
if(config.getConfigurationSection("crops." + cropNameList[0]).getKeys(false).contains("return")){ CustomBlock.place(crop.getReturnStage(), clickedBlockLocation);
CustomBlock.place(config.getString("crops." + cropNameList[0] + ".return"), clickedBlockLocation);
} }
} }
} }
} }
}else{ }else{
//非空手状态
//右键的不是自定义方块返回
CustomBlock clickedCustomBlock = CustomBlock.byAlreadyPlaced(clickedBlock);
if(clickedCustomBlock == null) return;
//获取右键物品的namespaceID //获取右键物品的namespaceID
String namespacedId = clickedCustomBlock.getNamespacedID(); String namespacedId = event.getNamespacedID();
/* /*
右键的是特殊作物吗 右键的是特殊作物吗
*/ */
if (namespacedId.contains("stage")) { if (namespacedId.contains("stage")) {
//下方方块不是自定义方块则返回 //下方方块不是自定义方块则返回
World world = player.getWorld(); Player player = event.getPlayer();
Block blockUnder = clickedBlockLocation.clone().subtract(0,1,0).getBlock(); Block blockUnder = clickedBlockLocation.clone().subtract(0,1,0).getBlock();
if (CustomBlock.byAlreadyPlaced(blockUnder) == null) return; CustomBlock cb = CustomBlock.byAlreadyPlaced(blockUnder);
if (cb == null) return;
//检测右键的方块下方是否为干燥的种植盆方块 //检测右键的方块下方是否为干燥的种植盆方块
if (CustomBlock.byAlreadyPlaced(blockUnder).getNamespacedID().equalsIgnoreCase(ConfigManager.Config.pot)) { if (cb.getNamespacedID().equalsIgnoreCase(ConfigManager.Config.pot)) {
//获取手中的物品 //获取手中的物品
ItemStack mainHandItem = player.getInventory().getItemInMainHand(); ItemStack mainHandItem = player.getInventory().getItemInMainHand();
Location locUnder = clickedBlockLocation.clone().subtract(0,1,0); Location locUnder = clickedBlockLocation.clone().subtract(0,1,0);
@@ -107,18 +97,14 @@ public class RightClickCustomBlock implements Listener {
} }
} }
//检测右键的方块下方是否为湿润的种植盆方块 //检测右键的方块下方是否为湿润的种植盆方块
else if(CustomBlock.byAlreadyPlaced(blockUnder).getNamespacedID().equalsIgnoreCase(ConfigManager.Config.watered_pot)){ else if(cb.getNamespacedID().equalsIgnoreCase(ConfigManager.Config.watered_pot)){
//获取手中的物品 //获取手中的物品
ItemStack mainHandItem = player.getInventory().getItemInMainHand(); ItemStack mainHandItem = player.getInventory().getItemInMainHand();
//如果是骨粉 //如果是骨粉
if (mainHandItem.getType() == Material.BONE_MEAL){ if (mainHandItem.getType() == Material.BONE_MEAL){
//植物是否具有stage属性 //植物是否具有stage属性
if (clickedCustomBlock.getNamespacedID().contains("stage")){ if (namespacedId.contains("_stage_")){
//获取点击方块的命名空间与ID String[] split = StringUtils.split(namespacedId,":");
String namespacedID = clickedCustomBlock.getNamespacedID();
//String namespace = clickedCustomBlock.getNamespacedID().split(":")[0];
String[] split = StringUtils.split(namespacedID,":");
//String[] cropNameList = clickedCustomBlock.getNamespacedID().split(":")[1].split("_");
String[] cropNameList = StringUtils.split(split[1],"_"); String[] cropNameList = StringUtils.split(split[1],"_");
//下一生长阶段 //下一生长阶段
int nextStage = Integer.parseInt(cropNameList[2]) + 1; int nextStage = Integer.parseInt(cropNameList[2]) + 1;
@@ -127,6 +113,7 @@ public class RightClickCustomBlock implements Listener {
if(player.getGameMode() != GameMode.CREATIVE){ if(player.getGameMode() != GameMode.CREATIVE){
mainHandItem.setAmount(mainHandItem.getAmount() - 1); mainHandItem.setAmount(mainHandItem.getAmount() - 1);
} }
World world = player.getWorld();
//骨粉的成功率 //骨粉的成功率
if (Math.random() < ConfigManager.Config.bone_chance){ if (Math.random() < ConfigManager.Config.bone_chance){
CustomBlock.remove(clickedBlockLocation); CustomBlock.remove(clickedBlockLocation);
@@ -147,130 +134,125 @@ public class RightClickCustomBlock implements Listener {
} }
} }
} }
/* /*
右键的是种植盆吗 右键的是种植盆吗
*/ */
else if (event.getBlockFace() == BlockFace.UP){ else if (event.getBlockFace() == BlockFace.UP){
//获取手中的物品 //获取手中的物品
ItemStack mainHandItem = player.getInventory().getItemInMainHand(); ItemStack item = event.getItem();
Player player = event.getPlayer();
//检测右键的方块是否为干燥的种植盆方块 //检测右键的方块是否为干燥的种植盆方块
if (namespacedId.equalsIgnoreCase(ConfigManager.Config.pot)){ if (namespacedId.equalsIgnoreCase(ConfigManager.Config.pot)){
//如果手中的是水桶,那么转干为湿 //如果手中的是水桶,那么转干为湿
if (item.getType() == Material.WATER_BUCKET){
if (mainHandItem.getType() == Material.WATER_BUCKET){
//扣除水桶 //扣除水桶
if(player.getGameMode() != GameMode.CREATIVE){ if(player.getGameMode() != GameMode.CREATIVE){
mainHandItem.setAmount(mainHandItem.getAmount() - 1); item.setAmount(item.getAmount() - 1);
player.getInventory().addItem(new ItemStack(Material.BUCKET)); player.getInventory().addItem(new ItemStack(Material.BUCKET));
} }
CustomBlock.remove(clickedBlockLocation); CustomBlock.remove(clickedBlockLocation);
CustomBlock.place(ConfigManager.Config.watered_pot,clickedBlockLocation); CustomBlock.place(ConfigManager.Config.watered_pot,clickedBlockLocation);
} else if (mainHandItem.getType() == Material.WOODEN_SWORD){ return;
waterPot(mainHandItem, player,clickedBlockLocation); }
} else { CustomStack customStack = CustomStack.byItemStack(item);
tryPlantSeed(clickedBlockLocation, mainHandItem, player); if (customStack != null){
String namespacedID = customStack.getNamespacedID();
if (namespacedID.endsWith("_seeds")){
if(tryPlantSeed(clickedBlockLocation, namespacedID, player)){
if(player.getGameMode() != GameMode.CREATIVE){
item.setAmount(item.getAmount() -1);
}
}
}else {
waterPot(item, player, clickedBlockLocation);
}
} }
} }
//检测右键的方块是否为湿润的种植盆方块 //检测右键的方块是否为湿润的种植盆方块
else if(namespacedId.equalsIgnoreCase(ConfigManager.Config.watered_pot)){ else if(namespacedId.equalsIgnoreCase(ConfigManager.Config.watered_pot)){
tryPlantSeed(clickedBlockLocation, mainHandItem, player); CustomStack customStack = CustomStack.byItemStack(item);
if (customStack != null){
String namespacedID = customStack.getNamespacedID();
if (namespacedID.endsWith("_seeds")){
if(tryPlantSeed(clickedBlockLocation, namespacedID, player)){
if(player.getGameMode() != GameMode.CREATIVE){
item.setAmount(item.getAmount() -1);
}
}
}
}
} }
} }
} }
} }
//尝试种植植物 //尝试种植植物
private void tryPlantSeed(Location clickedBlockLocation, ItemStack mainHandItem, Player player) { private boolean tryPlantSeed(Location clickedBlockLocation, String namespacedID, Player player) {
//是否为IA物品 //获取农作物名
if(CustomStack.byItemStack(mainHandItem) == null) return; String key = StringUtils.split(namespacedID.replace("_seeds",""),":")[1];
//获取命名空间名与ID //检测上方为空气
String namespaced_id = CustomStack.byItemStack(mainHandItem).getNamespacedID(); if(clickedBlockLocation.clone().add(0, 1, 0).getBlock().getType() != Material.AIR){
//是否为种子 return false;
if (namespaced_id.endsWith("_seeds")){ }
//获取农作物名 //该种子是否存在于配置文件中
String cropName = StringUtils.split(namespaced_id.replace("_seeds",""),":")[1]; if(!ConfigManager.CONFIG.containsKey(key)){
//String[] crop = CustomStack.byItemStack(mainHandItem).getNamespacedID().toLowerCase().replace("_seeds","").split(":"); MessageManager.playerMessage(ConfigManager.Config.prefix + ConfigManager.Config.no_such_seed,player);
return false;
//检测上方为空气 }
if(clickedBlockLocation.clone().add(0, 1, 0).getBlock().getType() != Material.AIR){ //是否超高超低
return; if (clickedBlockLocation.getY() < ConfigManager.Config.minh || clickedBlockLocation.getY() > ConfigManager.Config.maxh){
} MessageManager.playerMessage(ConfigManager.Config.prefix + ConfigManager.Config.bad_place,player);
FileConfiguration config = CustomCrops.instance.getConfig(); return false;
//该种子是否存在于配置文件中 }
if(!config.getConfigurationSection("crops").getKeys(false).contains(cropName)){ Location locUp = clickedBlockLocation.clone().add(0,1,0);
MessageManager.playerMessage(ConfigManager.Config.prefix + ConfigManager.Config.no_such_seed,player); //是否启用了季节
return; Label_out:
} if(ConfigManager.Config.season){
//是否超高超低 if(ConfigManager.Config.greenhouse){
if (clickedBlockLocation.getY() < ConfigManager.Config.minh || clickedBlockLocation.getY() > ConfigManager.Config.maxh){ int range = ConfigManager.Config.range;
MessageManager.playerMessage(ConfigManager.Config.prefix + ConfigManager.Config.bad_place,player); for(int i = 1; i <= range; i++){
return; CustomBlock cb = CustomBlock.byAlreadyPlaced(locUp.clone().add(0,i,0).getBlock());
} if (cb != null){
Location locUp = clickedBlockLocation.clone().add(0,1,0); if(cb.getNamespacedID().equalsIgnoreCase(ConfigManager.Config.glass)){
//是否启用了季节 break Label_out;
Label_out:
if(ConfigManager.Config.season){
if(ConfigManager.Config.greenhouse){
int range = ConfigManager.Config.range;
World world = player.getWorld();
for(int i = 1; i <= range; i++){
Location tempLocation = locUp.clone().add(0,i,0);
if (CustomBlock.byAlreadyPlaced(tempLocation.getBlock()) != null){
if(CustomBlock.byAlreadyPlaced(tempLocation.getBlock()).getNamespacedID().equalsIgnoreCase(ConfigManager.Config.glass)){
break Label_out;
}
} }
} }
} }
//获取种子适宜生长的季节 }
String[] seasons = config.getString("crops."+cropName+".season").split(","); //获取种子适宜生长的季节
boolean wrongSeason = true; boolean ws = true;
for(String season : seasons){ Crop crop = ConfigManager.CONFIG.get(key);
if (Objects.equals(season, ConfigManager.Config.current)) { for(String season : crop.getSeasons()){
wrongSeason = false; if (Objects.equals(season, ConfigManager.Config.current)) {
break; ws = false;
} break;
}
if(wrongSeason){
MessageManager.playerMessage(ConfigManager.Config.prefix + ConfigManager.Config.wrong_season,player);
return;
} }
} }
//是否到达区块上限 if(ws){
if(MaxCropsPerChunk.maxCropsPerChunk(clickedBlockLocation)){ MessageManager.playerMessage(ConfigManager.Config.prefix + ConfigManager.Config.wrong_season,player);
MessageManager.playerMessage(ConfigManager.Config.prefix + ConfigManager.Config.limit_crop.replace("{Max}", String.valueOf(ConfigManager.Config.max_crop)),player); return false;
return;
} }
//添加到缓存中
if(ConfigManager.Config.season){
CropManager.putInstance(locUp, config.getString("crops."+cropName+".season"));
}else{
CropManager.putInstance(locUp, "all");
}
//减少种子数量
if(player.getGameMode() != GameMode.CREATIVE){
mainHandItem.setAmount(mainHandItem.getAmount() -1);
}
//放置自定义农作物
CustomBlock.place(namespaced_id.replace("_seeds","_stage_1"),locUp);
} }
//是否到达区块上限
if(MaxCropsPerChunk.maxCropsPerChunk(clickedBlockLocation)){
MessageManager.playerMessage(ConfigManager.Config.prefix + ConfigManager.Config.limit_crop.replace("{Max}", String.valueOf(ConfigManager.Config.max_crop)),player);
return false;
}
//添加到缓存中
CropManager.putInstance(locUp, key);
//放置自定义农作物
CustomBlock.place(namespacedID.replace("_seeds","_stage_1"),locUp);
return true;
} }
private void waterPot(ItemStack itemStack, Player player, Location location){ private void waterPot(ItemStack itemStack, Player player, Location location){
//是否为IA物品 //是否为IA物品
if(CustomStack.byItemStack(itemStack) == null) return; if(CustomStack.byItemStack(itemStack) == null) return;
BukkitScheduler bukkitScheduler = Bukkit.getScheduler();
bukkitScheduler.runTaskAsynchronously(CustomCrops.instance,()-> { bukkitScheduler.runTaskAsynchronously(CustomCrops.instance,()-> {
//获取IA物品 //获取IA物品
CustomStack customStack = CustomStack.byItemStack(itemStack); CustomStack customStack = CustomStack.byItemStack(itemStack);
String namespacedId = customStack.getNamespacedID(); String namespacedId = customStack.getNamespacedID();
World world = player.getWorld(); World world = player.getWorld();
int x; int x;
int z; int z;
if (namespacedId.equalsIgnoreCase(ConfigManager.Config.watering_can_1)) { if (namespacedId.equalsIgnoreCase(ConfigManager.Config.watering_can_1)) {
x = 0; x = 0;
z = 0; z = 0;
@@ -281,19 +263,14 @@ public class RightClickCustomBlock implements Listener {
x = 4; x = 4;
z = 4; z = 4;
} else return; } else return;
//判断耐久度
if(customStack.getDurability() > 0){ if(customStack.getDurability() > 0){
CustomStack.byItemStack(itemStack).setDurability(CustomStack.byItemStack(itemStack).getDurability() - 1); CustomStack.byItemStack(itemStack).setDurability(CustomStack.byItemStack(itemStack).getDurability() - 1);
}else return; }else return;
//播放洒水音效 //播放洒水音效
world.playSound(player.getLocation(),Sound.BLOCK_WATER_AMBIENT,1,1); world.playSound(player.getLocation(),Sound.BLOCK_WATER_AMBIENT,1,1);
//获取玩家朝向 //获取玩家朝向
float yaw = player.getLocation().getYaw(); float yaw = player.getLocation().getYaw();
String wateredPot = ConfigManager.Config.watered_pot;
String pot = ConfigManager.Config.pot;
//根据朝向确定浇水方向 //根据朝向确定浇水方向
if (yaw <= 45 && yaw >= -135) { if (yaw <= 45 && yaw >= -135) {
if (yaw > -45) { if (yaw > -45) {
@@ -304,12 +281,13 @@ public class RightClickCustomBlock implements Listener {
for (int i = 0; i <= x; i++) { for (int i = 0; i <= x; i++) {
for (int j = 0; j <= z; j++) { for (int j = 0; j <= z; j++) {
Location tempLoc = location.clone().add(i, 0, j); Location tempLoc = location.clone().add(i, 0, j);
if(CustomBlock.byAlreadyPlaced(tempLoc.getBlock()) != null){ CustomBlock cb = CustomBlock.byAlreadyPlaced(tempLoc.getBlock());
if(CustomBlock.byAlreadyPlaced(tempLoc.getBlock()).getNamespacedID().equalsIgnoreCase(pot)){ if(cb != null){
if(cb.getNamespacedID().equalsIgnoreCase(ConfigManager.Config.pot)){
//同步替换方块 //同步替换方块
bukkitScheduler.callSyncMethod(CustomCrops.instance,()->{ bukkitScheduler.callSyncMethod(CustomCrops.instance,()->{
CustomBlock.remove(tempLoc); CustomBlock.remove(tempLoc);
CustomBlock.place(wateredPot,tempLoc); CustomBlock.place(ConfigManager.Config.watered_pot,tempLoc);
return null; return null;
}); });
} }
@@ -325,12 +303,13 @@ public class RightClickCustomBlock implements Listener {
for (int i = 0; i <= x; i++) { for (int i = 0; i <= x; i++) {
for (int j = 0; j <= z; j++) { for (int j = 0; j <= z; j++) {
Location tempLoc = location.clone().subtract(i, 0, j); Location tempLoc = location.clone().subtract(i, 0, j);
if(CustomBlock.byAlreadyPlaced(tempLoc.getBlock()) != null){ CustomBlock cb = CustomBlock.byAlreadyPlaced(tempLoc.getBlock());
if(CustomBlock.byAlreadyPlaced(tempLoc.getBlock()).getNamespacedID().equalsIgnoreCase(pot)){ if(cb != null){
if(cb.getNamespacedID().equalsIgnoreCase(ConfigManager.Config.pot)){
//同步替换方块 //同步替换方块
bukkitScheduler.callSyncMethod(CustomCrops.instance,()->{ bukkitScheduler.callSyncMethod(CustomCrops.instance,()->{
CustomBlock.remove(tempLoc); CustomBlock.remove(tempLoc);
CustomBlock.place(wateredPot,tempLoc); CustomBlock.place(ConfigManager.Config.watered_pot,tempLoc);
return null; return null;
}); });
} }

View File

@@ -1,4 +1,4 @@
package net.momirealms.customcrops.crops; package net.momirealms.customcrops.timer;
import net.momirealms.customcrops.CustomCrops; import net.momirealms.customcrops.CustomCrops;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;

View File

@@ -1,6 +1,6 @@
package net.momirealms.customcrops.crops; package net.momirealms.customcrops.timer;
import net.momirealms.customcrops.ConfigManager; import net.momirealms.customcrops.datamanager.ConfigManager;
import net.momirealms.customcrops.CustomCrops; import net.momirealms.customcrops.CustomCrops;
import net.momirealms.customcrops.datamanager.CropManager; import net.momirealms.customcrops.datamanager.CropManager;
import net.momirealms.customcrops.datamanager.SprinklerManager; import net.momirealms.customcrops.datamanager.SprinklerManager;

View File

@@ -0,0 +1,45 @@
package net.momirealms.customcrops.utils;
public class Crop {
private final String key;
private final double chance;
private double giantChance;
private String[] seasons;
private boolean willReturn;
private String returnStage;
private boolean willGiant;
private String giant;
public Crop(String key, double chance){
this.key = key;
this.chance = chance;
}
public String getReturnStage(){
return this.returnStage;
}
public String getGiant(){
return this.giant;
}
public boolean getWillReturn(){
return this.willReturn;
}
public boolean getWillGiant(){
return this.willGiant;
}
public String[] getSeasons() {return this.seasons;}
public double getChance() {return this.chance;}
public double getGiantChance() { return this.giantChance; }
public void setWillReturn(boolean b){
this.willReturn = b;
}
public void setReturnStage(String stage){
this.returnStage = stage;
}
public void setSeasons(String[] seasons) { this.seasons = seasons; }
public void setWillGiant(boolean b) { this.willGiant = b; }
public void setGiant(String giant) {this.giant = giant; }
public void setGiantChance(double giantChance) { this.giantChance = giantChance; }
}

View File

@@ -1,6 +1,7 @@
package net.momirealms.customcrops; package net.momirealms.customcrops.utils;
import dev.lone.itemsadder.api.CustomFurniture; import dev.lone.itemsadder.api.CustomFurniture;
import net.momirealms.customcrops.CustomCrops;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.World; import org.bukkit.World;
import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.configuration.file.FileConfiguration;

View File

@@ -1,6 +1,8 @@
package net.momirealms.customcrops; package net.momirealms.customcrops.utils;
import me.clip.placeholderapi.expansion.PlaceholderExpansion; import me.clip.placeholderapi.expansion.PlaceholderExpansion;
import net.momirealms.customcrops.datamanager.ConfigManager;
import net.momirealms.customcrops.CustomCrops;
import org.bukkit.OfflinePlayer; import org.bukkit.OfflinePlayer;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;

View File

@@ -1,132 +1,96 @@
# ###################### #是否使用季节
# 季节设置 # #非植物季节则无法耕种,过了季节则枯死
# ###################### enable-season: false
# 是否使用季节 #当前季节
# 非植物季节则无法耕种,过了季节则枯死 #使用/customcrops setseason 来切换季节
enable-season: true #使用/customcrops nextseason 进入下一季节
# 当前季节
# 使用/customcrops setseason 来切换季节
# 使用/customcrops nextseason 进入下一季节
current-season: spring current-season: spring
config: config:
# ###################### #植物生长的可能时间点,你可以在一天设置多个时间点判断生长
# 基础设置 # #为了防止植物生长过快你可以适当调低生长一个阶段的概率
# ###################### #请尽量在植物生长后200ticks以上设置洒水器工作点如果生长和洒水时间靠太近可能会带来一些不必要的麻烦例如数据太多植物还没来得及生长完洒水器就开始工作
# 植物生长的可能时间点,你可以在一天设置多个时间点判断生长 #mc的时间范围为0-23999ticks1秒=20ticks
# 为了防止植物生长过快你可以适当调低生长一个阶段的概率
# 你设置的时间节点越多,则服务器计算量也越大
# 请尽量在植物生长后200ticks以上设置洒水器工作点如果生长和洒水时间靠太近可能会带来一些不必要的麻烦例如数据太多植物还没来得及生长完洒水器就开始工作
# mc的时间范围为0-23999ticks1秒=20ticks
# 生长时间点 #生长时间点
grow-time: grow-time:
- 0 - 0
# - 12000 - 12000
# 洒水器工作点 #洒水器工作点
sprinkler-time: sprinkler-time:
- 200 - 200
# - 12200 - 12200
# 生长生效的世界 #生长生效的世界
whitelist-worlds: whitelist-worlds:
- world - world
# 农作物每次成长一个阶段的概率0-1
grow-success-chance: 0.8
#骨粉催熟农作物进入下一阶段的概率0-1
# ######################
# 骨粉设置 #
# ######################
# 骨粉催熟农作物进入下一阶段的概率0-1
bone-meal-chance: 0.5 bone-meal-chance: 0.5
# 使用骨粉是否会让种植盆从湿润转为干燥 #使用骨粉是否会让种植盆从湿润转为干燥
bone-meal-consume-water: true bone-meal-consume-water: true
# 粒子效果 #粒子效果
particle: particle:
# 使用骨粉成功的粒子 #使用骨粉成功的粒子
success: HEART success: HEART
# 使用骨粉失败的粒子 #使用骨粉失败的粒子
failure: VILLAGER_ANGRY failure: VILLAGER_ANGRY
# ###################### #温室系统,在温室玻璃正下方的方块可以无视季节种植
# 温室系统 #
# ######################
# 温室玻璃,在温室玻璃正下方的方块可以无视季节种植
enable-greenhouse: true enable-greenhouse: true
# 温室玻璃有效范围 #温室玻璃有效范围
greenhouse-range: 7 greenhouse-range: 7
# ###################### #植物的种植盆方块
# IA物品 #
# ######################
# 植物的种植盆方块
pot: customcrops:pot pot: customcrops:pot
# 植物的浇过水的种植盆方块 #植物的浇过水的种植盆方块
watered-pot: customcrops:watered_pot watered-pot: customcrops:watered_pot
# 水壶1x1 #水壶1x1
watering-can-1: customcrops:watering_can_1 watering-can-1: customcrops:watering_can_1
# 水壶1x3 #水壶1x3
watering-can-2: customcrops:watering_can_2 watering-can-2: customcrops:watering_can_2
# 水壶1x5 #水壶1x5
watering-can-3: customcrops:watering_can_3 watering-can-3: customcrops:watering_can_3
# 温室玻璃方块 #温室玻璃方块
greenhouse-glass: customcrops:greenhouse_glass greenhouse-glass: customcrops:greenhouse_glass
# 洒水器的家具 #洒水器的家具
sprinkler-1: customcrops:sprinkler_1 sprinkler-1: customcrops:sprinkler_1
# 洒水器的方块的物品请以_item结尾 #洒水器的方块的物品请以_item结尾
sprinkler-1-item: customcrops:sprinkler_1_item sprinkler-1-item: customcrops:sprinkler_1_item
# 优质洒水器的家具 #优质洒水器的家具
sprinkler-2: customcrops:sprinkler_2 sprinkler-2: customcrops:sprinkler_2
# 优质洒水器的方块的物品请以_item结尾 #优质洒水器的方块的物品请以_item结尾
sprinkler-2-item: customcrops:sprinkler_2_item sprinkler-2-item: customcrops:sprinkler_2_item
# 农作物枯萎后变成的方块,物品ID中请保留stage以保持其下方方块被破坏时枯萎作物也被破坏的特性 #农作物枯萎后变成的方块,物品ID中请保留stage以保持其下方方块被破坏时枯萎作物也被破坏的特性
dead-crop: customcrops:crop_stage_death dead-crop: customcrops:crop_stage_death
# ###################### #种植的最低和最高Y坐标
# 优化限制 #
# ######################
# 种植的最低和最高Y坐标
height: height:
min: 50 min: 50
max: 100 max: 100
# 每个区块最大农作物数量和洒水器数量 #每个区块最大农作物数量和洒水器数量
# 是否启用限制 #是否启用限制
enable-limit: true enable-limit: true
max-crops: 32 max-crops: 32
max-sprinklers: 4 max-sprinklers: 4
# ######################
# 巨大植物 #
# ######################
gigantic:
# 是否启用巨大植物
enable: true
# 农作物巨大化的概率
chance: 0.01
#插件兼容
# ######################
# 插件兼容 #
# ######################
integration: integration:
# 收获权限为harvest 浇水种植权限为build #收获flag为harvest 浇水种植flag为build
residence: false residence: false
# 收获flag为BLOCK-BREAK 浇水种植flag为BUILD #收获flag为BLOCK-BREAK 浇水种植flag为BUILD
worldguard: false worldguard: false
# 王国成员可以破坏和种植 #只有王国成员可以破坏浇水和种植
kingdomsX: false kingdomsX: false
# ###################### #MineDown格式Wiki
# 消息文件 # #https://github.com/Phoenix616/MineDown
# ######################
# MineDown格式Wiki
# https://github.com/Phoenix616/MineDown
messages: messages:
prefix: '&#ccfbff-#ef96c5&[CustomCrops] ' prefix: '&#ccfbff-#ef96c5&[CustomCrops] '
not-a-good-place: '&f这个地方太高/太低了,请换个地方试试吧!' not-a-good-place: '&f这个地方太高/太低了,请换个地方试试吧!'
@@ -141,43 +105,9 @@ messages:
force-water: '&f已强制洒水!' force-water: '&f已强制洒水!'
reach-limit-crop: '&f农作物已到达最大区块上限{Max}!' reach-limit-crop: '&f农作物已到达最大区块上限{Max}!'
reach-limit-sprinkler: '&f洒水器已到达最大区块上限{Max}!' reach-limit-sprinkler: '&f洒水器已到达最大区块上限{Max}!'
can-full: '&f水壶已满'
backup: '&f备份完成' backup: '&f备份完成'
spring: '&f春' spring: '&f春'
summer: '&f夏' summer: '&f夏'
autumn: '&f秋' autumn: '&f秋'
winter: '&f冬' winter: '&f冬'
can-full: '&f水壶已满'
# ######################
# 农作物 #
# ######################
crops:
tomato:
# 在IA配置文件中命名农作物时请以_seeds和_stage_X结尾否则会无法生长和种植
# 适宜的生长季节,若未启用季节系统可以无视此项目
season: spring,summer
# 空手收获后返回第几个生长状态
# return: customcrops:tomato_stage_3
# 巨大化植物
# gigantic: customcrops:gigantic_tomato
# ######################
# 果树 #
# ######################
# 果树系统还未写,以下配置无效
trees:
lemon:
# 生长季节与结果季节
season: spring,summer
# 果树每天成长一个阶段的概率
chance: 0.2
# 果树的果实
result: customcrops:lemon
# 果实数量,可选范围
amount: 1-4
# 收获后返回第几阶段
return: customcrops:lemon_tree_5
# 若在当前季节无法及时结果是否返回上一个return的状态
force-return: true

View File

@@ -0,0 +1,22 @@
crops:
tomato:
#在IA配置文件中命名农作物时请以_seeds和_stage_X结尾否则会无法生长和种植
#只要遵循正确的命名规则,你可以无限自定义农作物阶段数量
#每个生长点生长一个阶段的概率
#此项目必填0-1
grow-chance: 0.4
#适宜的生长季节,若未启用季节系统可以无视此项目
#若启用季节则必须填写此项目
#季节之间用逗号分隔
#可用的季节类型spring,summer,autumn,winter
#season: spring,summer
#空手收获后返回第几个生长状态
#不填写此项目则无法重复收获
#return: customcrops:tomato_stage_1
#巨大化植物,以极低的概率生长为另一种形态
#gigantic: customcrops:gigantic_tomato
#gigantic-chance: 0.01

View File

@@ -1,5 +1,5 @@
name: CustomCrops name: CustomCrops
version: '1.3.0' version: '1.4.0'
main: net.momirealms.customcrops.CustomCrops main: net.momirealms.customcrops.CustomCrops
api-version: 1.16 api-version: 1.16
depend: [ ItemsAdder , ProtocolLib ] depend: [ ItemsAdder , ProtocolLib ]