9
0
mirror of https://github.com/Xiao-MoMi/Custom-Crops.git synced 2025-12-25 09:59:20 +00:00
This commit is contained in:
Xiao-MoMi
2023-04-20 17:20:16 +08:00
parent 8a4042d9da
commit 4f92c268e6
10 changed files with 258 additions and 5 deletions

View File

@@ -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(),

View File

@@ -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) {

View File

@@ -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);

View File

@@ -29,6 +29,7 @@ public class CustomCropsCommand extends AbstractMainCommand {
regSubCommand(SetDateCommand.INSTANCE);
regSubCommand(ForceCommand.INSTANCE);
regSubCommand(MigrateCommand.INSTANCE);
regSubCommand(ConvertCommand.INSTANCE);
// regSubCommand(PerformanceTest.INSTANCE);
}
}

View File

@@ -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;
}
}

View File

@@ -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.");
}

View File

@@ -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:

View File

@@ -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"

View File

@@ -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