9
0
mirror of https://github.com/Xiao-MoMi/Custom-Crops.git synced 2025-12-27 02:49:11 +00:00

1.5.0-SNAPSHOT

This commit is contained in:
Xiao-MoMi
2022-07-04 02:07:14 +08:00
parent f1a2bd6d1c
commit eda25b0bfc
74 changed files with 3379 additions and 5054 deletions

View File

@@ -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<Location, String> CROPS;
/*
开服的时候将文件的数据读入
*/
public static void loadData() {
private YamlConfiguration data;
private final CustomCrops plugin;
public static ConcurrentHashMap<Location, String> 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("<red>[CustomCrops] 农作物数据文件生成失败!</red>");
}
}
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<Map.Entry<Location, String>> en = CROPS.entrySet();
for(Map.Entry<Location, String> 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<Map.Entry<Location, String>> en = CROPS.entrySet();
for(Map.Entry<Location, String> 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("<red>[CustomCrops] crop.yml保存出错!</red>");
}
}
}
//将缓存内新数据更新到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("<red>[CustomCrops] 发现未知类型肥料,已自动清除错误数据!</red>");
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<String> 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;
});
}
}