mirror of
https://github.com/Xiao-MoMi/Custom-Crops.git
synced 2025-12-25 01:49:18 +00:00
3.0.1
This commit is contained in:
@@ -4,7 +4,7 @@ plugins {
|
||||
}
|
||||
|
||||
group = 'net.momirealms'
|
||||
version = '3.0.0'
|
||||
version = '3.0.1'
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
|
||||
@@ -716,8 +716,13 @@ public class PlatformManager extends Function {
|
||||
|
||||
WaterAmountHologram waterAmountHologram = potConfig.getWaterAmountHologram();
|
||||
if (waterAmountHologram != null && potData != null) {
|
||||
double offset = 0;
|
||||
StageConfig stageConfig = plugin.getCropManager().getStageConfig(plugin.getPlatformInterface().getAnyItemIDAt(location.clone().add(0,1,0)));
|
||||
if (stageConfig != null) {
|
||||
offset = stageConfig.getOffsetCorrection();
|
||||
}
|
||||
plugin.getHologramManager().showHologram(player,
|
||||
location.clone().add(0.5,waterAmountHologram.getOffset(),0.5),
|
||||
location.clone().add(0.5,waterAmountHologram.getOffset() + offset,0.5),
|
||||
AdventureUtils.getComponentFromMiniMessage(waterAmountHologram.getContent(potData.getWater(), potConfig.getMaxStorage())),
|
||||
waterAmountHologram.getDuration() * 1000,
|
||||
waterAmountHologram.getMode(),
|
||||
|
||||
@@ -56,6 +56,7 @@ public class ConfigManager extends Function {
|
||||
public static String referenceWorld;
|
||||
public static boolean enableLimitation;
|
||||
public static int maxCropPerChunk;
|
||||
public static int cacheSaveInterval;
|
||||
public static boolean setUpMode;
|
||||
|
||||
private final CustomCrops plugin;
|
||||
@@ -95,11 +96,12 @@ public class ConfigManager extends Function {
|
||||
}
|
||||
|
||||
private void loadScheduleSystem(ConfigurationSection section) {
|
||||
enableScheduleSystem = section.getBoolean("enable");
|
||||
enableScheduleSystem = section.getBoolean("default-schedule");
|
||||
pointGainInterval = section.getInt("point-gain-interval", 1000);
|
||||
corePoolSize = section.getInt("thread-pool-settings.corePoolSize", 2);
|
||||
maxPoolSize = section.getInt("thread-pool-settings.maximumPoolSize", 4);
|
||||
keepAliveTime = section.getInt("thread-pool-settings.keepAliveTime", 10);
|
||||
cacheSaveInterval = section.getInt("cache-save-interval", 7200);
|
||||
}
|
||||
|
||||
private void loadMechanic(ConfigurationSection section) {
|
||||
|
||||
@@ -18,7 +18,6 @@
|
||||
package net.momirealms.customcrops.api.object.world;
|
||||
|
||||
import net.momirealms.customcrops.CustomCrops;
|
||||
import net.momirealms.customcrops.api.object.CrowTask;
|
||||
import net.momirealms.customcrops.api.object.Function;
|
||||
import net.momirealms.customcrops.api.object.ItemMode;
|
||||
import net.momirealms.customcrops.api.object.action.Action;
|
||||
@@ -74,6 +73,7 @@ public class CCWorld extends Function {
|
||||
private long lastConsumeDay;
|
||||
private ScheduledFuture<?> timerTask;
|
||||
private int timer;
|
||||
private int cacheTimer;
|
||||
|
||||
public CCWorld(World world) {
|
||||
this.world = new WeakReference<>(world);
|
||||
@@ -93,6 +93,7 @@ public class CCWorld extends Function {
|
||||
this.consumeTaskPool.setMaxTotal(10);
|
||||
this.consumeTaskPool.setMinIdle(1);
|
||||
this.timer = 10;
|
||||
this.cacheTimer = ConfigManager.cacheSaveInterval;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -133,6 +134,10 @@ public class CCWorld extends Function {
|
||||
@SuppressWarnings("ResultOfMethodCallIgnored")
|
||||
public void disable() {
|
||||
closePool();
|
||||
saveCache();
|
||||
}
|
||||
|
||||
public void saveCache() {
|
||||
File chunks_folder = new File(CustomCrops.getInstance().getDataFolder().getParentFile().getParentFile(), ConfigManager.worldFolderPath + worldName + File.separator + "customcrops" + File.separator + "chunks");
|
||||
if (!chunks_folder.exists()) chunks_folder.mkdirs();
|
||||
for (Map.Entry<ChunkCoordinate, CCChunk> entry : chunkMap.entrySet()) {
|
||||
@@ -203,8 +208,17 @@ public class CCWorld extends Function {
|
||||
chunk.scheduleGrowTask(this);
|
||||
}
|
||||
}
|
||||
if (ConfigManager.cacheSaveInterval != -1) {
|
||||
cacheTimer--;
|
||||
if (cacheTimer <= 0) {
|
||||
if (ConfigManager.debug) Log.info("== Save cache ==");
|
||||
cacheTimer = ConfigManager.cacheSaveInterval;
|
||||
schedule.execute(this::saveCache);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
AdventureUtils.consoleMessage("<red>[CustomCrops] Unexpected world: " + worldName + " unloaded. Shutdown the schedule.");
|
||||
this.schedule.shutdown();
|
||||
}
|
||||
}, 1000, 1000L);
|
||||
|
||||
@@ -29,6 +29,7 @@ public class CustomCropsCommand extends AbstractMainCommand {
|
||||
regSubCommand(SetDateCommand.INSTANCE);
|
||||
regSubCommand(ForceCommand.INSTANCE);
|
||||
regSubCommand(MigrateCommand.INSTANCE);
|
||||
regSubCommand(ConvertCommand.INSTANCE);
|
||||
// regSubCommand(PerformanceTest.INSTANCE);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,183 @@
|
||||
package net.momirealms.customcrops.command.subcmd;
|
||||
|
||||
import net.momirealms.customcrops.CustomCrops;
|
||||
import net.momirealms.customcrops.api.util.AdventureUtils;
|
||||
import net.momirealms.customcrops.command.AbstractSubCommand;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
|
||||
public class ConvertCommand extends AbstractSubCommand {
|
||||
|
||||
public static final ConvertCommand INSTANCE = new ConvertCommand();
|
||||
|
||||
private final HashSet<String> confirm;
|
||||
|
||||
public ConvertCommand() {
|
||||
super("convert");
|
||||
confirm = new HashSet<>();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCommand(CommandSender sender, List<String> args) {
|
||||
if (lackArgs(sender, 1, args.size())) return true;
|
||||
|
||||
if (!confirm.contains(sender.getName())) {
|
||||
confirm.add(sender.getName());
|
||||
AdventureUtils.sendMessage(sender, "<gold>[CustomCrops] Type the command again to confirm.");
|
||||
return true;
|
||||
}
|
||||
|
||||
confirm.remove(sender.getName());
|
||||
|
||||
String mode = args.get(0).toUpperCase();
|
||||
|
||||
String platform = CustomCrops.getInstance().getPlatform().name().toLowerCase();
|
||||
YamlConfiguration oldConfig = YamlConfiguration.loadConfiguration(new File(CustomCrops.getInstance().getDataFolder(), "crops_" + platform + ".yml"));
|
||||
String namespace = oldConfig.getString("namespace", "");
|
||||
if (!namespace.equals("")) namespace = namespace + ":";
|
||||
|
||||
for (String crop : oldConfig.getKeys(false)) {
|
||||
|
||||
ConfigurationSection oldSection = oldConfig.getConfigurationSection(crop);
|
||||
if (oldSection == null) continue;
|
||||
int max_stage = oldSection.getInt("max-stage");
|
||||
|
||||
YamlConfiguration newConfig = new YamlConfiguration();
|
||||
ConfigurationSection newSection = newConfig.createSection(crop);
|
||||
newSection.set("type", mode);
|
||||
newSection.set("pot-whitelist", List.of("default"));
|
||||
newSection.set("seed", namespace + crop + "_seeds");
|
||||
newSection.set("max-points", max_stage -1);
|
||||
|
||||
ConfigurationSection pointSec = newSection.createSection("points");
|
||||
for (int i = 0; i < max_stage; i++) {
|
||||
pointSec.set(i + ".model", namespace + crop + "_stage_" + (i+1));
|
||||
}
|
||||
|
||||
if (oldSection.contains("gigantic-crop")) {
|
||||
newSection.set("max-points", max_stage);
|
||||
boolean isBlock = oldSection.contains("gigantic-crop.block");
|
||||
newSection.set("points." + max_stage + ".events.grow.action_gigantic.type", "variation");
|
||||
newSection.set("points." + max_stage + ".events.grow.action_gigantic.value.gigantic.item", isBlock ? oldSection.getString("gigantic-crop.block") : oldSection.getString("gigantic-crop.furniture"));
|
||||
newSection.set("points." + max_stage + ".events.grow.action_gigantic.value.gigantic.type", isBlock ? "TRIPWIRE" : "ITEM_FRAME");
|
||||
newSection.set("points." + max_stage + ".events.grow.action_gigantic.value.gigantic.chance", oldSection.getDouble("gigantic-crop.chance"));
|
||||
}
|
||||
|
||||
if (oldSection.contains("return")) {
|
||||
newSection.set("points." + (max_stage-1) + ".events.interact-by-hand.action_break.type", "break");
|
||||
newSection.set("points." + (max_stage-1) + ".events.interact-by-hand.action_break.value", true);
|
||||
newSection.set("points." + (max_stage-1) + ".events.interact-by-hand.action_replant.type", "replant");
|
||||
newSection.set("points." + (max_stage-1) + ".events.interact-by-hand.action_replant.value.point", Integer.parseInt(oldSection.getString("return", "1").substring(oldSection.getString("return", "1").length()-1)) - 1);
|
||||
newSection.set("points." + (max_stage-1) + ".events.interact-by-hand.action_replant.value.crop", crop);
|
||||
newSection.set("points." + (max_stage-1) + ".events.interact-by-hand.action_replant.value.model", oldSection.getString("return"));
|
||||
}
|
||||
|
||||
if (oldSection.contains("season")) {
|
||||
List<String> allSeason = new java.util.ArrayList<>(List.of("spring", "autumn", "summer", "winter"));
|
||||
for (String allow : oldSection.getStringList("season")) {
|
||||
allSeason.remove(allow.toLowerCase());
|
||||
}
|
||||
newSection.set("requirements.plant.requirement_season.type", "season");
|
||||
newSection.set("requirements.plant.requirement_season.value", oldSection.getStringList("season"));
|
||||
newSection.set("requirements.plant.requirement_season.message", "It's not a good season to plant " + crop);
|
||||
|
||||
newSection.set("death-conditions.unsuitable_season.model", namespace + "crop_stage_death");
|
||||
newSection.set("death-conditions.unsuitable_season.conditions.condition_season.type", "unsuitable_season");
|
||||
newSection.set("death-conditions.unsuitable_season.conditions.condition_season.value", allSeason);
|
||||
}
|
||||
|
||||
if (oldSection.contains("quality-loots")) {
|
||||
ConfigurationSection qualitySec = oldSection.getConfigurationSection("quality-loots");
|
||||
assert qualitySec != null;
|
||||
String[] split = qualitySec.getString("amount").split("~");
|
||||
int min = Integer.parseInt(split[0]);
|
||||
int max = Integer.parseInt(split[1]);
|
||||
newSection.set("points." + (max_stage-1) + ".events.break.action_drop.type", "drop-items");
|
||||
newSection.set("points." + (max_stage-1) + ".events.break.action_drop.value.quality-crops.min", min);
|
||||
newSection.set("points." + (max_stage-1) + ".events.break.action_drop.value.quality-crops.max", max);
|
||||
newSection.set("points." + (max_stage-1) + ".events.break.action_drop.value.quality-crops.items.1", qualitySec.getString("quality.1"));
|
||||
newSection.set("points." + (max_stage-1) + ".events.break.action_drop.value.quality-crops.items.2", qualitySec.getString("quality.2"));
|
||||
newSection.set("points." + (max_stage-1) + ".events.break.action_drop.value.quality-crops.items.3", qualitySec.getString("quality.3"));
|
||||
}
|
||||
|
||||
if (oldSection.contains("other-loots")) {
|
||||
ConfigurationSection lootSec = oldSection.getConfigurationSection("other-loots");
|
||||
assert lootSec != null;
|
||||
for (String loot_key : lootSec.getKeys(false)) {
|
||||
newSection.set("points." + (max_stage-1) + ".events.break.action_drop.value.other-items." + loot_key + ".item", lootSec.getString(loot_key + ".item"));
|
||||
newSection.set("points." + (max_stage-1) + ".events.break.action_drop.value.other-items." + loot_key + ".min", lootSec.getInt(loot_key + ".min_amount"));
|
||||
newSection.set("points." + (max_stage-1) + ".events.break.action_drop.value.other-items." + loot_key + ".max", lootSec.getInt(loot_key + ".max_amount"));
|
||||
newSection.set("points." + (max_stage-1) + ".events.break.action_drop.value.other-items." + loot_key + ".chance", lootSec.getDouble(loot_key + ".chance"));
|
||||
}
|
||||
}
|
||||
|
||||
if (oldSection.contains("harvest-actions.messages")) {
|
||||
newSection.set("points." + (max_stage-1) + ".events.break.action_message.type", "message");
|
||||
newSection.set("points." + (max_stage-1) + ".events.break.action_message.value", oldSection.getStringList("harvest-actions.messages"));
|
||||
newSection.set("points." + (max_stage-1) + ".events.break.action_message.chance", oldSection.getDouble("harvest-actions.messages-chance", 1));
|
||||
}
|
||||
|
||||
if (oldSection.contains("harvest-actions.commands")) {
|
||||
newSection.set("points." + (max_stage-1) + ".events.break.action_command.type", "command");
|
||||
newSection.set("points." + (max_stage-1) + ".events.break.action_command.value", oldSection.getStringList("harvest-actions.commands"));
|
||||
newSection.set("points." + (max_stage-1) + ".events.break.action_command.chance", oldSection.getDouble("harvest-actions.commands-chance", 1));
|
||||
}
|
||||
|
||||
if (oldSection.contains("harvest-actions.xp")) {
|
||||
newSection.set("points." + (max_stage-1) + ".events.break.action_exp.type", "exp");
|
||||
newSection.set("points." + (max_stage-1) + ".events.break.action_exp.value", oldSection.getInt("harvest-actions.xp"));
|
||||
newSection.set("points." + (max_stage-1) + ".events.break.action_exp.chance", oldSection.getDouble("harvest-actions.xp-chance", 1));
|
||||
}
|
||||
|
||||
if (oldSection.contains("harvest-actions.skill-xp")) {
|
||||
newSection.set("points." + (max_stage-1) + ".events.break.action_skill_xp.type", "skill-xp");
|
||||
newSection.set("points." + (max_stage-1) + ".events.break.action_skill_xp.value", oldSection.getInt("harvest-actions.skill-xp"));
|
||||
newSection.set("points." + (max_stage-1) + ".events.break.action_skill_xp.chance", oldSection.getDouble("harvest-actions.skill-xp-chance", 1));
|
||||
}
|
||||
|
||||
if (oldSection.contains("harvest-actions.job-xp")) {
|
||||
newSection.set("points." + (max_stage-1) + ".events.break.action_job_xp.type", "job-xp");
|
||||
newSection.set("points." + (max_stage-1) + ".events.break.action_job_xp.value", oldSection.getInt("harvest-actions.job-xp"));
|
||||
newSection.set("points." + (max_stage-1) + ".events.break.action_job_xp.chance", oldSection.getDouble("harvest-actions.job-xp-chance", 1));
|
||||
}
|
||||
|
||||
newSection.set("grow-conditions.||.condition_1.type", "water_more_than");
|
||||
newSection.set("grow-conditions.||.condition_1.value", 0);
|
||||
newSection.set("grow-conditions.||.condition_2.type", "random");
|
||||
newSection.set("grow-conditions.||.condition_2.value", 0.5);
|
||||
|
||||
newSection.set("custom-bone-meal.default.item", "BONE_MEAL");
|
||||
newSection.set("custom-bone-meal.default.particle", "VILLAGER_HAPPY");
|
||||
newSection.set("custom-bone-meal.default.sound", "minecraft:item.bone_meal.use");
|
||||
newSection.set("custom-bone-meal.default.chance.2", 0.2);
|
||||
newSection.set("custom-bone-meal.default.chance.1", 0.6);
|
||||
|
||||
File output = new File(CustomCrops.getInstance().getDataFolder(), "converted" + File.separator + crop + ".yml");
|
||||
if (!output.getParentFile().exists()) output.getParentFile().mkdirs();
|
||||
try {
|
||||
newConfig.save(output);
|
||||
} catch (IOException ignored) {
|
||||
}
|
||||
}
|
||||
|
||||
AdventureUtils.sendMessage(sender, "Converted! The result might not be 100% accurate.");
|
||||
AdventureUtils.sendMessage(sender, "Files are stored into /CustomCrops/converted/ folder");
|
||||
AdventureUtils.sendMessage(sender, "Please double check before put into production environment");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> onTabComplete(CommandSender sender, List<String> args) {
|
||||
if (args.size() == 1) {
|
||||
return List.of("tripwire", "item_frame");
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -39,6 +39,7 @@ import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileReader;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@@ -46,12 +47,23 @@ public class MigrateCommand extends AbstractSubCommand {
|
||||
|
||||
public static final MigrateCommand INSTANCE = new MigrateCommand();
|
||||
|
||||
private final HashSet<String> confirm;
|
||||
|
||||
public MigrateCommand() {
|
||||
super("migrate");
|
||||
confirm = new HashSet<>();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCommand(CommandSender sender, List<String> args) {
|
||||
|
||||
if (!confirm.contains(sender.getName())) {
|
||||
confirm.add(sender.getName());
|
||||
AdventureUtils.sendMessage(sender, "<red>[CustomCrops] Type the command again to confirm.");
|
||||
return true;
|
||||
}
|
||||
|
||||
confirm.remove(sender.getName());
|
||||
if (sender instanceof Player player) {
|
||||
AdventureUtils.playerMessage(player, "Migration started. See the console for more information.");
|
||||
}
|
||||
|
||||
@@ -21,10 +21,19 @@ worlds:
|
||||
- world
|
||||
|
||||
schedule-system:
|
||||
enable: true
|
||||
# Water amount and fertilizer use would be reduced at 6am
|
||||
# Sprinklers would work at 7am
|
||||
# if disabled, you can do that manually with command /customcrops force [consume/sprinklerwork]
|
||||
# 水分和肥料将在每天6点减少,洒水器将在7点工作
|
||||
# 如果禁用,你可以使用指令/customcrops force [consume/sprinklerwork]手动操作
|
||||
default-schedule: true
|
||||
# The average interval for a crop to gain one point (measured in seconds)
|
||||
# 平均每个农作物获得一生长点的时间间隔(秒)
|
||||
point-gain-interval: 1200
|
||||
# Save cache to file interval (seconds)
|
||||
# set "-1" to disable
|
||||
# 保存缓存的时间间隔 (秒)
|
||||
cache-save-interval: 7200
|
||||
# Thread pool settings
|
||||
# 线程池设置
|
||||
thread-pool-settings:
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
# https://docs.advntr.dev/minimessage/format.html
|
||||
messages:
|
||||
prefix: '<gradient:#ff206c:#fdee55>[CustomCrops] </gradient>'
|
||||
reload: '<white>¡Recargado! Tomó <green>{time}ms.'
|
||||
invalid-args: '<white>Argumentos invalidos.'
|
||||
no-console: '<white>Este comando solo puede ser ejecutado por un jugador'
|
||||
not-online: '<white>El jugador {player} no esta conectado'
|
||||
lack-args: '<white>Los argumentos son insuficientes'
|
||||
not-none-args: '<white>Este comando no tiene argumentos'
|
||||
before-plant: '<white>Este fertilizador debe ser usado antes de plantarlo'
|
||||
unsuitable-pot: "<white>No puedes plantar esta semilla en este pot"
|
||||
reach-crop-limit: '<white>El numero de crops ha llegado al limite'
|
||||
no-perm: "<red>No tienes permiso para esto"
|
||||
spring: 'Primavera'
|
||||
summer: 'Verano'
|
||||
autumn: 'Otoño'
|
||||
winter: 'Invierno'
|
||||
no-season: 'LAS TEMPORADAS ESTAN DESACTIVADAS EN ESTE MUNDO'
|
||||
set-season: "<white>Correctamente establecido {world}'s temporada a {season}."
|
||||
set-date: "<white>Correctamente establecido {world}'s fecha para {date}."
|
||||
world-not-exist: '<white>El mundo {world} no existe.'
|
||||
season-not-exist: '<white>Temporada {season} no existe.'
|
||||
force-sprinkler-work: "<white>Se forzo {world}'s sprinklers para trabajar"
|
||||
force-consume: "<white>Se forzo {world}'s pot para reducir la cantidad de consumo del agua y fertilizantes"
|
||||
@@ -51,6 +51,7 @@ permissions :
|
||||
customcrops.setseason: true
|
||||
customcrops.force: true
|
||||
customcrops.migrate: true
|
||||
customcrops.convert: true
|
||||
customcrops.reload:
|
||||
default: op
|
||||
customcrops.help:
|
||||
@@ -64,4 +65,6 @@ permissions :
|
||||
customcrops.force:
|
||||
default: op
|
||||
customcrops.migrate:
|
||||
default: op
|
||||
customcrops.convert:
|
||||
default: op
|
||||
Reference in New Issue
Block a user