From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: violetc <58360096+s-yh-china@users.noreply.github.com> Date: Fri, 29 Oct 2021 16:52:57 +0800 Subject: [PATCH] Leaves Server Config And Command diff --git a/src/main/java/co/aikar/timings/TimingsExport.java b/src/main/java/co/aikar/timings/TimingsExport.java index a2f71a6d1a9e98133dff6cd0f625da9435a8af14..45897b81a822b9523c16658ca46a507729f8d0d3 100644 --- a/src/main/java/co/aikar/timings/TimingsExport.java +++ b/src/main/java/co/aikar/timings/TimingsExport.java @@ -242,7 +242,8 @@ public class TimingsExport extends Thread { parent.put("config", createObject( pair("spigot", mapAsJSON(Bukkit.spigot().getSpigotConfig(), null)), pair("bukkit", mapAsJSON(Bukkit.spigot().getBukkitConfig(), null)), - pair("paper", mapAsJSON(Bukkit.spigot().getPaperConfig(), null)) + pair("paper", mapAsJSON(Bukkit.spigot().getPaperConfig(), null)), // Leaves - add config to timings report + pair("leaves", mapAsJSON(Bukkit.spigot().getLeavesConfig(), null)) // Leaves - add config to timings report )); new TimingsExport(listeners, parent, history).start(); diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java index 57e7f83345afa462d329cea515c96fa2aa48a5e3..2e7850a1e0da1f2978b585312aefb46bf0d039e9 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java @@ -1118,6 +1118,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop resourcekey, RegistryAccess iregistrycustom, Holder holder, Supplier supplier, boolean flag, boolean flag1, long i, int j, org.bukkit.generator.ChunkGenerator gen, org.bukkit.generator.BiomeProvider biomeProvider, org.bukkit.World.Environment env, java.util.function.Function paperWorldConfigCreator, java.util.concurrent.Executor executor) { // Paper - Async-Anti-Xray - Pass executor this.spigotConfig = new org.spigotmc.SpigotWorldConfig(((net.minecraft.world.level.storage.PrimaryLevelData) worlddatamutable).getLevelName()); // Spigot this.paperConfig = paperWorldConfigCreator.apply(this.spigotConfig); // Paper + this.leavesConfig = new top.leavesmc.leaves.LeavesConfig.WorldConfig(((net.minecraft.world.level.storage.PrimaryLevelData)worlddatamutable).getLevelName()); // Leaves - World Config this.generator = gen; this.world = new CraftWorld((ServerLevel) this, gen, biomeProvider, env); diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java index b1f34ee7a421c35eb3ee7ab112defe48d935c788..7623ebe3bfc508183f67b84e1f1815697ed98ba8 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java @@ -1053,6 +1053,7 @@ public final class CraftServer implements Server { org.spigotmc.SpigotConfig.init((File) console.options.valueOf("spigot-settings")); // Spigot this.console.paperConfigurations.reloadConfigs(this.console); + top.leavesmc.leaves.LeavesConfig.init((File) console.options.valueOf("leaves-settings")); // Leaves - Server Config for (ServerLevel world : this.console.getAllLevels()) { // world.serverLevelData.setDifficulty(config.difficulty); // Paper - per level difficulty world.setSpawnSettings(world.serverLevelData.getDifficulty() != Difficulty.PEACEFUL && config.spawnMonsters, config.spawnAnimals); // Paper - per level difficulty (from MinecraftServer#setDifficulty(ServerLevel, Difficulty, boolean)) @@ -1068,6 +1069,7 @@ public final class CraftServer implements Server { } } world.spigotConfig.init(); // Spigot + world.leavesConfig.init(); // Leaves - World Config } Plugin[] pluginClone = pluginManager.getPlugins().clone(); // Paper @@ -1083,6 +1085,7 @@ public final class CraftServer implements Server { this.reloadData(); org.spigotmc.SpigotConfig.registerCommands(); // Spigot io.papermc.paper.command.PaperCommands.registerCommands(this.console); // Paper + top.leavesmc.leaves.LeavesConfig.registerCommands(); // Leaves - Server Command this.overrideAllCommandBlockCommands = this.commandsConfiguration.getStringList("command-block-overrides").contains("*"); this.ignoreVanillaPermissions = this.commandsConfiguration.getBoolean("ignore-vanilla-permissions"); @@ -2849,6 +2852,14 @@ public final class CraftServer implements Server { { return CraftServer.this.console.paperConfigurations.createLegacyObject(CraftServer.this.console); } + + // Leaves start - add config to timings report + @Override + public YamlConfiguration getLeavesConfig() + { + return top.leavesmc.leaves.LeavesConfig.config; + } + /// Leaves end - add config to timings report @Override public void restart() { diff --git a/src/main/java/org/bukkit/craftbukkit/Main.java b/src/main/java/org/bukkit/craftbukkit/Main.java index a53514f2c510b29f596c361de7bc0b405c27e964..269c7ba0707db4fdc45a70000e0be892b6dfa31d 100644 --- a/src/main/java/org/bukkit/craftbukkit/Main.java +++ b/src/main/java/org/bukkit/craftbukkit/Main.java @@ -165,6 +165,14 @@ public class Main { .ofType(File.class) .defaultsTo(new File("paper.yml")) .describedAs("Yml file"); + + // Leaves start - Server Config + acceptsAll(asList("leaves", "leaves-settings"), "File for leaves settings") + .withRequiredArg() + .ofType(File.class) + .defaultsTo(new File("leaves.yml")) + .describedAs("Yml file"); + // Leaves end - Server Config acceptsAll(asList("add-plugin", "add-extra-plugin-jar"), "Specify paths to extra plugin jars to be loaded in addition to those in the plugins folder. This argument can be specified multiple times, once for each extra plugin jar path.") .withRequiredArg() diff --git a/src/main/java/top/leavesmc/leaves/LeavesConfig.java b/src/main/java/top/leavesmc/leaves/LeavesConfig.java new file mode 100644 index 0000000000000000000000000000000000000000..4d8063f34c91ec4fe5a926f9d46555ce0d5bd8d9 --- /dev/null +++ b/src/main/java/top/leavesmc/leaves/LeavesConfig.java @@ -0,0 +1,767 @@ +package top.leavesmc.leaves; + +import com.destroystokyo.paper.util.SneakyThrow; +import com.google.common.base.Throwables; +import net.minecraft.server.MinecraftServer; +import org.bukkit.Bukkit; +import org.bukkit.command.Command; +import org.bukkit.configuration.ConfigurationSection; +import org.bukkit.configuration.file.YamlConfiguration; + +import java.io.File; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.logging.Level; +import java.util.Random; + +// Powered by Tuinity(https://github.com/Tuinity/Tuinity) + +public final class LeavesConfig { + + public static final String CONFIG_HEADER = "Configuration file for Leaves."; + public static final int CURRENT_CONFIG_VERSION = 3; + + private static final Object[] EMPTY = new Object[0]; + + private static File configFile; + public static YamlConfiguration config; + private static int configVersion; + public static boolean createWorldSections = true; + static Map commands; + + public static void init(final File file) { + LeavesConfig.configFile = file; + config = new YamlConfiguration(); + config.options().header(CONFIG_HEADER); + config.options().copyDefaults(true); + + if (!file.exists()) { + try { + file.createNewFile(); + } catch (final Exception ex) { + Bukkit.getLogger().log(Level.SEVERE, "Failure to create leaves config", ex); + } + } else { + try { + config.load(file); + } catch (final Exception ex) { + Bukkit.getLogger().log(Level.SEVERE, "Failure to load leaves config", ex); + SneakyThrow.sneaky(ex); /* Rethrow, this is critical */ + throw new RuntimeException(ex); // unreachable + } + } + + if (config.contains("config-version-please-do-not-modify-me")) { + LeavesConfig.set("config-version-please-do-not-modify-me", null); + } + LeavesConfig.configVersion = LeavesConfig.getInt("config-version", CURRENT_CONFIG_VERSION); + LeavesConfig.set("config-version", CURRENT_CONFIG_VERSION); + + updateConfigVersion(config); + + LeavesConfig.load(config); + registerCarpetRules(); + + commands = new HashMap<>(); + } + + public static void load(final YamlConfiguration config) { + for (Method method : LeavesConfig.class.getDeclaredMethods()) { + if (Modifier.isPrivate(method.getModifiers())) { + if (method.getParameterTypes().length == 0 && method.getReturnType() == Void.TYPE) { + try { + method.setAccessible(true); + method.invoke(null); + } catch (InvocationTargetException ex) { + throw Throwables.propagate(ex.getCause()); + } catch (Exception ex) { + Bukkit.getLogger().log(Level.SEVERE, "Error invoking " + method, ex); + } + } + } + } + + /* We re-save to add new options */ + try { + config.save(LeavesConfig.configFile); + } catch (final Exception ex) { + Bukkit.getLogger().log(Level.SEVERE, "Unable to save leaves config", ex); + } + } + + private static void updateConfigVersion(final YamlConfiguration config) { + if (configVersion < CURRENT_CONFIG_VERSION) { + switch (configVersion) { + case 1 -> { + snowballAndEggCanKnockback = config.getBoolean("settings.snowball-and-egg-can-knockback-player", snowballAndEggCanKnockback); + fakeplayerSupport = config.getBoolean("settings.fakeplayer.enable", fakeplayerSupport); + unableFakeplayerNames = (List) config.getList("settings.fakeplayer.unable-fakeplayer-names", unableFakeplayerNames); + shearsInDispenserCanZeroAmount = config.getBoolean("settings.shears-in-dispenser-can-zero-amount", shearsInDispenserCanZeroAmount); + redstoneShearsWrench = config.getBoolean("settings.redstone-shears-wrench", redstoneShearsWrench); + buddingAmethystCanPushByPiston = config.getBoolean("settings.budding-amethyst-can-push-by-piston", buddingAmethystCanPushByPiston); + spectatorDontGetAdvancement = config.getBoolean("settings.spectator-dont-get-advancement", spectatorDontGetAdvancement); + stickChangeArmorStandArmStatus = config.getBoolean("settings.stick-change-armorstand-arm-status", stickChangeArmorStandArmStatus); + noChatSign = config.getBoolean("settings.no-chat-sign", noChatSign); + + config.set("settings.snowball-and-egg-can-knockback-player", null); + config.set("settings.player-can-edit-sign", null); + config.set("settings.fakeplayer", null); + config.set("settings.shears-in-dispenser-can-zero-amount", null); + config.set("settings.redstone-shears-wrench", null); + config.set("settings.budding-amethyst-can-push-by-piston", null); + config.set("settings.spectator-dont-get-advancement", null); + config.set("settings.stick-change-armorstand-arm-status", null); + config.set("settings.no-chat-sign", null); + } + + case 2 -> { + config.set("settings.modify.player-can-edit-sign", null); + config.set("settings.performance.skip-clone-loot-parameters", null); + } + } + } + } + + static void set(final String path, final Object value) { + LeavesConfig.config.set(path, value); + } + + public static void registerCommands() { + for (Map.Entry entry : commands.entrySet()) { + MinecraftServer.getServer().server.getCommandMap().register(entry.getKey(), "Leaves", entry.getValue()); + } + } + + static boolean getBoolean(final String path, final boolean dfl) { + LeavesConfig.config.addDefault(path, Boolean.valueOf(dfl)); + return LeavesConfig.config.getBoolean(path, dfl); + } + + static int getInt(final String path, final int dfl) { + LeavesConfig.config.addDefault(path, Integer.valueOf(dfl)); + return LeavesConfig.config.getInt(path, dfl); + } + + static long getLong(final String path, final long dfl) { + LeavesConfig.config.addDefault(path, Long.valueOf(dfl)); + return LeavesConfig.config.getLong(path, dfl); + } + + static double getDouble(final String path, final double dfl) { + LeavesConfig.config.addDefault(path, Double.valueOf(dfl)); + return LeavesConfig.config.getDouble(path, dfl); + } + + static String getString(final String path, final String dfl) { + LeavesConfig.config.addDefault(path, dfl); + return LeavesConfig.config.getString(path, dfl); + } + + static List getList(final String path, final List def) { + LeavesConfig.config.addDefault(path, def); + return (List) LeavesConfig.config.getList(path, config.getList(path)); + } + + public static boolean snowballAndEggCanKnockback = true; + private static void snowballAndEggCanKnockback() { + snowballAndEggCanKnockback = getBoolean("settings.modify.snowball-and-egg-can-knockback-player", snowballAndEggCanKnockback); + } + + public static boolean fakeplayerSupport = true; + public static List unableFakeplayerNames = List.of("player-name"); + public static int fakeplayerLimit = 10; + public static String fakeplayerPrefix = ""; + public static String fakeplayerSuffix = ""; + public static boolean alwaysSendFakeplayerData = true; + public static boolean fakeplayerResident = false; + public static boolean openFakeplayerInventory = false; + public static boolean fakeplayerSkipSleep = false; + private static void fakeplayer() { + fakeplayerSupport = getBoolean("settings.modify.fakeplayer.enable", fakeplayerSupport); + unableFakeplayerNames = getList("settings.modify.fakeplayer.unable-fakeplayer-names", unableFakeplayerNames); + fakeplayerLimit = getInt("settings.modify.fakeplayer.limit", fakeplayerLimit); + fakeplayerPrefix = getString("settings.modify.fakeplayer.prefix", fakeplayerPrefix); + fakeplayerSuffix = getString("settings.modify.fakeplayer.suffix", fakeplayerSuffix); + alwaysSendFakeplayerData = getBoolean("settings.modify.fakeplayer.always-send-data", alwaysSendFakeplayerData); + fakeplayerResident = getBoolean("settings.modify.fakeplayer.resident-fakeplayer", fakeplayerResident); + openFakeplayerInventory = getBoolean("settings.modify.fakeplayer.open-fakeplayer-inventory", openFakeplayerInventory); + fakeplayerSkipSleep = getBoolean("settings.modify.fakeplayer.skip-sleep-check", fakeplayerSkipSleep); + } + + public static boolean shearsInDispenserCanZeroAmount = false; + private static void shearsInDispenserCanZeroAmount() { + shearsInDispenserCanZeroAmount = getBoolean("settings.modify.shears-in-dispenser-can-zero-amount", shearsInDispenserCanZeroAmount); + } + + public static boolean redstoneShearsWrench = true; + private static void redstoneShearsWrench() { + redstoneShearsWrench = getBoolean("settings.modify.redstone-shears-wrench", redstoneShearsWrench); + } + + public static boolean buddingAmethystCanPushByPiston = false; + private static void buddingAmethystCanPushByPiston() { + buddingAmethystCanPushByPiston = getBoolean("settings.modify.budding-amethyst-can-push-by-piston", buddingAmethystCanPushByPiston); + } + + public static boolean spectatorDontGetAdvancement = false; + private static void spectatorDontGetAdvancement() { + spectatorDontGetAdvancement = getBoolean("settings.modify.spectator-dont-get-advancement", spectatorDontGetAdvancement); + } + + public static boolean stickChangeArmorStandArmStatus = true; + private static void stickChangeArmorStandHasArm() { + stickChangeArmorStandArmStatus = getBoolean("settings.modify.stick-change-armorstand-arm-status", stickChangeArmorStandArmStatus); + } + + public static boolean noChatSign = true; + private static void noChatSign() { + if (LeavesConfig.config.contains("settings.modify.no-chat-sign")) { + noChatSign = LeavesConfig.config.getBoolean("settings.modify.no-chat-sign"); + LeavesConfig.config.set("settings.modify.no-chat-sign", null); + } + noChatSign = getBoolean("settings.misc.no-chat-sign", noChatSign); + } + + public static boolean asyncMobSpawning = false; + private static boolean asyncMobSpawningLock = false; + private static void asyncMobSpawning() { + if (!asyncMobSpawningLock) { + asyncMobSpawning = getBoolean("settings.performance.async-mob-spawning", asyncMobSpawning); + asyncMobSpawningLock = true; + } + + if (asyncMobSpawning) { + asyncMobSpawning = false; + LeavesLogger.LOGGER.severe("Async MobSpawning is updating, it can't work"); + } + } + + public static boolean dontSendUselessEntityPackets = true; + private static void dontSendUselessEntityPackets() { + dontSendUselessEntityPackets = getBoolean("settings.performance.dont-send-useless-entity-packets", dontSendUselessEntityPackets); + } + + public static boolean asyncEntityTracker = false; + private static boolean asyncEntityTrackerLock = false; + private static void asyncEntityTracker() { + if (!asyncEntityTrackerLock) { + asyncEntityTracker = getBoolean("settings.performance.async-entity-tracker", asyncEntityTracker); + asyncEntityTrackerLock = true; + } + + if (asyncEntityTracker) { + asyncEntityTracker = false; + LeavesLogger.LOGGER.severe("Async EntityTracker is updating, it can't work"); + } + } + + public static boolean fixPaper6045 = true; + private static void fixPaper6045() { + fixPaper6045 = getBoolean("settings.performance.fix.fix-paper-6045", fixPaper6045); + } + + public static boolean optimizeEntityCoordinateKey = true; + private static void optimizeEntityCoordinateKey() { + optimizeEntityCoordinateKey = getBoolean("settings.performance.optimize-entity-coordinate-key", optimizeEntityCoordinateKey); + } + + public static boolean enableSuffocationOptimization = true; + private static void enableSuffocationOptimization() { + enableSuffocationOptimization = getBoolean("settings.performance.enable-suffocation-optimization", enableSuffocationOptimization); + } + + public static boolean entityStripRaytracing = true; + private static void entityStripRaytracing() { + entityStripRaytracing = getBoolean("settings.performance.strip-raytracing-for-entity", entityStripRaytracing); + } + + public static boolean checkSpookySeasonOnceAnHour = true; + private static void checkSpookySeasonOnceAnHour() { + checkSpookySeasonOnceAnHour = getBoolean("settings.performance.check-spooky-season-once-an-hour", checkSpookySeasonOnceAnHour); + } + + public static boolean optimizeChunkTicking = true; + private static boolean optimizeChunkTickingLock = false; + private static void optimizeChunkTicking() { + if (!optimizeChunkTickingLock) { + optimizeChunkTicking = getBoolean("settings.performance.optimize-chunk-ticking", optimizeChunkTicking); + optimizeChunkTickingLock = true; + } + } + + public static boolean skipPOIFindingInVehicle = true; + private static void skipPOIFindingInVehicle() { + skipPOIFindingInVehicle = getBoolean("settings.performance.skip-poi-find-in-vehicle", skipPOIFindingInVehicle); + } + + public static boolean entityTargetFindingOptimization = true; + private static void entityTargetFindingOptimization() { + entityTargetFindingOptimization = getBoolean("settings.performance.entity-target-find-optimization", entityTargetFindingOptimization); + } + + public static boolean useMoreThreadUnsafeRandom = true; + private static void useMoreThreadUnsafeRandom() { + useMoreThreadUnsafeRandom = getBoolean("settings.performance.use-more-thread-unsafe-random", useMoreThreadUnsafeRandom); + } + + public static boolean disableMethodProfiler = true; + private static void disableMethodProfiler() { + disableMethodProfiler = getBoolean("settings.misc.disable-method-profiler", disableMethodProfiler); + } + + public static boolean throttleInactiveGoalSelectorTick = false; + private static void throttleInactiveGoalSelectorTick() { + throttleInactiveGoalSelectorTick = getBoolean("settings.performance.inactive-goal-selector-disable", throttleInactiveGoalSelectorTick); + } + + public static boolean reduceEntityAllocations = true; + private static void reduceEntityAllocations() { + reduceEntityAllocations = getBoolean("settings.performance.reduce-entity-allocations", reduceEntityAllocations); + } + + public static boolean removeTickGuardLambda = true; + private static void removeTickGuardLambda() { + removeTickGuardLambda = getBoolean("settings.performance.remove.tick-guard-lambda", removeTickGuardLambda); + } + + public static boolean removeInventoryContainsIterators = true; + private static void removeInventoryContainsIterators() { + removeInventoryContainsIterators = getBoolean("settings.performance.remove.inventory-contains-iterators", removeInventoryContainsIterators); + } + + public static boolean removeGetNearPlayerStreams = true; + private static void removeGetNearPlayerStreams() { + removeGetNearPlayerStreams = getBoolean("settings.performance.remove.get-nearby-players-streams", removeGetNearPlayerStreams); + } + + public static boolean removeRangeCheckStreams = true; + private static void removeRangeCheckStreams() { + removeRangeCheckStreams = getBoolean("settings.performance.remove.range-check-streams-and-iterators", removeRangeCheckStreams); + } + + // only config now + public static boolean asyncPathfinding = false; + private static boolean asyncPathfindingLock = false; + private static void asyncPathfinding() { + if (!asyncPathfindingLock) { + asyncPathfinding = getBoolean("settings.performance.async-pathfinding", asyncPathfinding); + asyncPathfindingLock = true; + } + + if (asyncPathfinding) { + asyncPathfinding = false; + LeavesLogger.LOGGER.severe("Async Pathfinding is updating, it can't work"); + } + } + + public static boolean cacheClimbCheck = true; + private static void cacheClimbCheck() { + cacheClimbCheck = getBoolean("settings.performance.cache-climb-check", cacheClimbCheck); + } + + public static boolean biomeTemperaturesUseAgingCache = true; + private static boolean biomeTemperaturesUseAgingCacheLock = false; + private static void biomeTemperaturesUseAgingCache() { + if (!biomeTemperaturesUseAgingCacheLock) { + biomeTemperaturesUseAgingCache = getBoolean("settings.performance.biome-temperatures-use-aging-cache", biomeTemperaturesUseAgingCache); + biomeTemperaturesUseAgingCacheLock = true; + } + } + + public static boolean reduceEntityFluidLookup = true; + private static void reduceEntityFluidLookup() { + reduceEntityFluidLookup = getBoolean("settings.performance.reduce-entity-fluid-lookup", reduceEntityFluidLookup); + } + + public static boolean reduceChuckLoadAndLookup = true; + private static void reduceChuckLoadAndLookup() { + reduceChuckLoadAndLookup = getBoolean("settings.performance.reduce-chuck-load-and-lookup", reduceChuckLoadAndLookup); + } + + public static boolean simplerVanillaShapelessRecipes = true; + private static void simplerVanillaShapelessRecipes() { + simplerVanillaShapelessRecipes = getBoolean("settings.performance.simpler-vanilla-shapeless-recipes", simplerVanillaShapelessRecipes); + } + + public static boolean pcaSyncProtocol = false; + private static void pcaSyncProtocol() { + pcaSyncProtocol = getBoolean("settings.protocol.pca-sync-protocol", pcaSyncProtocol); + } + + public static String pcaSyncPlayerEntity = "OPS"; + private static final List pcaSyncPlayerEntityList = List.of("NOBODY", "BOT", "OPS", "OPS_AND_SELF", "EVERYONE"); + private static void pcaSyncPlayerEntity() { + pcaSyncPlayerEntity = getString("settings.protocol.pca-sync-player-entity", pcaSyncPlayerEntity); + if (!pcaSyncPlayerEntityList.contains(pcaSyncPlayerEntity)) { + pcaSyncPlayerEntity = "OPS"; + LeavesLogger.LOGGER.severe("pca-sync-player-entity value error, reset to OPS"); + } + } + + public static boolean bborProtocol = false; + private static void bborProtocol() { + bborProtocol = getBoolean("settings.protocol.bbor-protocol", bborProtocol); + } + + public static boolean instantBlockUpdaterReintroduced = false; + private static boolean instantBlockUpdaterReintroducedLock = false; + private static void instantBlockUpdaterReintroduced() { + if (!instantBlockUpdaterReintroducedLock) { + instantBlockUpdaterReintroduced = getBoolean("settings.modify.instant-block-updater-reintroduced", instantBlockUpdaterReintroduced); + instantBlockUpdaterReintroducedLock = true; + } + } + + public static boolean flattenTriangularDistribution = false; + private static void flattenTriangularDistribution() { + flattenTriangularDistribution = getBoolean("settings.modify.flatten-triangular-distribution", flattenTriangularDistribution); + } + + public static boolean jadeProtocol = false; + private static void jadeProtocol() { + jadeProtocol = getBoolean("settings.protocol.jade-protocol", jadeProtocol); + } + + public static boolean carpetAlternativeBlockPlacement = false; + private static void carpetAlternativeBlockPlacement() { + carpetAlternativeBlockPlacement = getBoolean("settings.protocol.carpet-alternative-block-placement", carpetAlternativeBlockPlacement); + } + + public static boolean playerOperationLimiter = false; + private static void playerOperationLimiter() { + playerOperationLimiter = getBoolean("settings.modify.player-operation-limiter", playerOperationLimiter); + } + + public static double renewableElytra = -1.0; + private static void renewableElytra() { + renewableElytra = getDouble("settings.modify.renewable-elytra", renewableElytra); + } + + public static int shulkerBoxStackSize = 1; + private static String stackableShulkerBoxes = "false"; + private static void stackableShulkerBoxes() { + stackableShulkerBoxes = getString("settings.modify.stackable-shulker-boxes", stackableShulkerBoxes); + stackableShulkerBoxes = MathUtils.isNumeric(stackableShulkerBoxes) ? stackableShulkerBoxes : stackableShulkerBoxes.equals("true") ? "2" : "1"; + shulkerBoxStackSize = Integer.parseInt(stackableShulkerBoxes); + } + + public static boolean improveFluidDirectionCaching = true; + private static boolean improveFluidDirectionCachingLock = false; + private static void improveFluidDirectionCaching() { + if (!improveFluidDirectionCachingLock) { + improveFluidDirectionCaching = getBoolean("settings.performance.improve-fluid-direction-caching", improveFluidDirectionCaching); + improveFluidDirectionCachingLock = true; + } + } + + public static boolean mcTechnicalMode = true; + private static void mcTechnicalMode() { + mcTechnicalMode = getBoolean("settings.modify.mc-technical-survival-mode", mcTechnicalMode); // TODO better name? + doMcTechnicalMode(); + } + + public static void doMcTechnicalMode() { + if (mcTechnicalMode) { + } + } + + public static boolean netherPortalFix = false; + private static void netherPortalFix() { + netherPortalFix = getBoolean("settings.modify.return-nether-portal-fix", netherPortalFix); + } + + public static boolean appleskinProtocol = false; + private static void appleskinProtocol() { + appleskinProtocol = getBoolean("settings.protocol.appleskin-protocol", appleskinProtocol); + } + + public static boolean xaeroMapProtocol = false; + public static int xaeroMapServerID = new Random().nextInt(); + private static void xaeroMapProtocol() { + xaeroMapProtocol = getBoolean("settings.protocol.xaero-map-protocol", xaeroMapProtocol); + xaeroMapServerID = getInt("settings.protocol.xaero-map-server-id", xaeroMapServerID); + } + + public static boolean extraYggdrasilService = false; + public static List extraYggdrasilServiceList = List.of("https://url.with.authlib-injector-yggdrasil"); + private static void extraYggdrasilService() { + extraYggdrasilService = getBoolean("settings.misc.extra-yggdrasil-service.enable", extraYggdrasilService); + extraYggdrasilServiceList = getList("settings.misc.extra-yggdrasil-service.urls", extraYggdrasilServiceList); + if (extraYggdrasilService) { + } + } + + public static boolean useVanillaRandom = false; + private static boolean useVanillaRandomLock = false; + private static void useVanillaRandom() { + if (!useVanillaRandomLock) { + useVanillaRandom = getBoolean("settings.modify.use-vanilla-random", useVanillaRandom); + useVanillaRandomLock = true; + } + } + + public static boolean updateSuppressionCrashFix = true; + private static void updateSuppressionCrashFix() { + updateSuppressionCrashFix = getBoolean("settings.modify.fix-update-suppression-crash", updateSuppressionCrashFix); + } + + public static boolean bedrockBreakList = false; + private static boolean bedrockBreakListLock = false; + private static void bedrockBreakList() { + if (!bedrockBreakListLock) { + bedrockBreakList = getBoolean("settings.modify.bedrock-break-list", bedrockBreakList); + bedrockBreakListLock = true; + } + } + + public static boolean syncmaticaProtocol = false; + public static boolean syncmaticaQuota = false; + public static int syncmaticaQuotaLimit = 40000000; + private static void syncmaticaProtocol() { + syncmaticaProtocol = getBoolean("settings.protocol.syncmatica.enable", syncmaticaProtocol); + syncmaticaQuota = getBoolean("settings.protocol.syncmatica.quota", syncmaticaQuota); + syncmaticaQuotaLimit = getInt("settings.protocol.syncmatica.quota-limit", syncmaticaQuotaLimit); + if (syncmaticaProtocol) { + } + } + + public static boolean disableDistanceCheckForUseItem = false; + private static void disableDistanceCheckForUseItem() { + disableDistanceCheckForUseItem = getBoolean("settings.modify.disable-distance-check-for-use-item", disableDistanceCheckForUseItem); + if (carpetAlternativeBlockPlacement) { + disableDistanceCheckForUseItem = true; + } + } + + public static boolean noFeatherFallingTrample = false; + private static void noFeatherFallingTrample() { + noFeatherFallingTrample = getBoolean("settings.modify.no-feather-falling-trample", noFeatherFallingTrample); + } + + public static boolean sharedVillagerDiscounts = false; + private static void sharedVillagerDiscounts() { + sharedVillagerDiscounts = getBoolean("settings.modify.shared-villager-discounts", sharedVillagerDiscounts); + } + + public static boolean redstoneDontCantOnTrapDoor = false; + private static void redstoneDontCantOnTrapDoor() { + redstoneDontCantOnTrapDoor = getBoolean("settings.modify.redstone-wire-dont-connect-if-on-trapdoor", redstoneDontCantOnTrapDoor); + } + + public static boolean disableCheckOutOfOrderCommand = false; + private static void disableCheckOutOfOrderCommand() { + disableCheckOutOfOrderCommand = getBoolean("settings.modify.disable-check-out-of-order-command", disableCheckOutOfOrderCommand); + } + + public static boolean despawnEndermanWithBlock = false; + private static void despawnEndermanWithBlock() { + despawnEndermanWithBlock = getBoolean("settings.modify.despawn-enderman-with-block", despawnEndermanWithBlock); + } + + public static boolean leavesCarpetSupport = false; + private static void leavesCarpetSupport() { + leavesCarpetSupport = getBoolean("settings.protocol.leaves-carpet-support", leavesCarpetSupport); + } + + public static void registerCarpetRules() { + } + + public static boolean creativeNoClip = false; + private static void creativeNoClip() { + creativeNoClip = getBoolean("settings.modify.creative-no-clip", creativeNoClip); + } + + public static boolean optimizedDragonRespawn = false; + private static void optimizedDragonRespawn() { + optimizedDragonRespawn = getBoolean("settings.performance.optimized-dragon-respawn", optimizedDragonRespawn); + } + + public static boolean mendingCompatibilityInfinity = false; + private static void mendingCompatibilityInfinity() { + mendingCompatibilityInfinity = getBoolean("settings.modify.mending-compatibility-infinity", mendingCompatibilityInfinity); + } + + public static boolean shaveSnowLayers = true; + private static void shaveSnowLayers() { + shaveSnowLayers = getBoolean("settings.modify.shave-snow-layers", shaveSnowLayers); + } + + public static final class WorldConfig { + + public final String worldName; + public String configPath; + ConfigurationSection worldDefaults; + + public WorldConfig(final String worldName) { + this.worldName = worldName; + this.init(); + } + + public void init() { + this.worldDefaults = LeavesConfig.config.getConfigurationSection("world-settings.default"); + if (this.worldDefaults == null) { + this.worldDefaults = LeavesConfig.config.createSection("world-settings.default"); + } + + String worldSectionPath = LeavesConfig.configVersion < CURRENT_CONFIG_VERSION ? this.worldName : "world-settings.".concat(this.worldName); + ConfigurationSection section = LeavesConfig.config.getConfigurationSection(worldSectionPath); + this.configPath = worldSectionPath; + if (LeavesConfig.createWorldSections) { + if (section == null) { + section = LeavesConfig.config.createSection(worldSectionPath); + } + LeavesConfig.config.set(worldSectionPath, section); + } + + this.load(); + } + + public void load() { + for (final Method method : LeavesConfig.WorldConfig.class.getDeclaredMethods()) { + if (method.getReturnType() != void.class || method.getParameterCount() != 0 || + !Modifier.isPrivate(method.getModifiers()) || Modifier.isStatic(method.getModifiers())) { + continue; + } + + try { + method.setAccessible(true); + method.invoke(this, EMPTY); + } catch (final Exception ex) { + SneakyThrow.sneaky(ex); /* Rethrow, this is critical */ + throw new RuntimeException(ex); // unreachable + } + } + + if (LeavesConfig.configVersion < CURRENT_CONFIG_VERSION) { + ConfigurationSection oldSection = LeavesConfig.config.getConfigurationSection(this.worldName); + LeavesConfig.config.set("world-settings.".concat(this.worldName), oldSection); + LeavesConfig.config.set(this.worldName, null); + } + + /* We re-save to add new options */ + try { + LeavesConfig.config.save(LeavesConfig.configFile); + } catch (final Exception ex) { + Bukkit.getLogger().log(Level.SEVERE, "Unable to save leaves config", ex); + } + } + + void set(final String path, final Object val) { + final ConfigurationSection config = LeavesConfig.config.getConfigurationSection(this.configPath); + this.worldDefaults.set(path, val); + if (config != null && config.get(path) != null) { + config.set(path, val); + } + } + + boolean getBoolean(final String path, final boolean dfl) { + final ConfigurationSection config = LeavesConfig.config.getConfigurationSection(this.configPath); + this.worldDefaults.addDefault(path, Boolean.valueOf(dfl)); + if (LeavesConfig.configVersion < CURRENT_CONFIG_VERSION) { + if (config != null && config.getBoolean(path) == dfl) { + config.set(path, null); + } + } + return config == null ? this.worldDefaults.getBoolean(path) : config.getBoolean(path, this.worldDefaults.getBoolean(path)); + } + + boolean getBooleanRaw(final String path, final boolean dfl) { + final ConfigurationSection config = LeavesConfig.config.getConfigurationSection(this.configPath); + if (LeavesConfig.configVersion < CURRENT_CONFIG_VERSION) { + if (config != null && config.getBoolean(path) == dfl) { + config.set(path, null); + } + } + return config == null ? this.worldDefaults.getBoolean(path, dfl) : config.getBoolean(path, this.worldDefaults.getBoolean(path, dfl)); + } + + int getInt(final String path, final int dfl) { + final ConfigurationSection config = LeavesConfig.config.getConfigurationSection(this.configPath); + this.worldDefaults.addDefault(path, Integer.valueOf(dfl)); + if (LeavesConfig.configVersion < CURRENT_CONFIG_VERSION) { + if (config != null && config.getInt(path) == dfl) { + config.set(path, null); + } + } + return config == null ? this.worldDefaults.getInt(path) : config.getInt(path, this.worldDefaults.getInt(path)); + } + + int getIntRaw(final String path, final int dfl) { + final ConfigurationSection config = LeavesConfig.config.getConfigurationSection(this.configPath); + if (LeavesConfig.configVersion < CURRENT_CONFIG_VERSION) { + if (config != null && config.getInt(path) == dfl) { + config.set(path, null); + } + } + return config == null ? this.worldDefaults.getInt(path, dfl) : config.getInt(path, this.worldDefaults.getInt(path, dfl)); + } + + long getLong(final String path, final long dfl) { + final ConfigurationSection config = LeavesConfig.config.getConfigurationSection(this.configPath); + this.worldDefaults.addDefault(path, Long.valueOf(dfl)); + if (LeavesConfig.configVersion < CURRENT_CONFIG_VERSION) { + if (config != null && config.getLong(path) == dfl) { + config.set(path, null); + } + } + return config == null ? this.worldDefaults.getLong(path) : config.getLong(path, this.worldDefaults.getLong(path)); + } + + long getLongRaw(final String path, final long dfl) { + final ConfigurationSection config = LeavesConfig.config.getConfigurationSection(this.configPath); + if (LeavesConfig.configVersion < CURRENT_CONFIG_VERSION) { + if (config != null && config.getLong(path) == dfl) { + config.set(path, null); + } + } + return config == null ? this.worldDefaults.getLong(path, dfl) : config.getLong(path, this.worldDefaults.getLong(path, dfl)); + } + + double getDouble(final String path, final double dfl) { + final ConfigurationSection config = LeavesConfig.config.getConfigurationSection(this.configPath); + this.worldDefaults.addDefault(path, Double.valueOf(dfl)); + if (LeavesConfig.configVersion < CURRENT_CONFIG_VERSION) { + if (config != null && config.getDouble(path) == dfl) { + config.set(path, null); + } + } + return config == null ? this.worldDefaults.getDouble(path) : config.getDouble(path, this.worldDefaults.getDouble(path)); + } + + double getDoubleRaw(final String path, final double dfl) { + final ConfigurationSection config = LeavesConfig.config.getConfigurationSection(this.configPath); + if (LeavesConfig.configVersion < CURRENT_CONFIG_VERSION) { + if (config != null && config.getDouble(path) == dfl) { + config.set(path, null); + } + } + return config == null ? this.worldDefaults.getDouble(path, dfl) : config.getDouble(path, this.worldDefaults.getDouble(path, dfl)); + } + + String getString(final String path, final String dfl) { + final ConfigurationSection config = LeavesConfig.config.getConfigurationSection(this.configPath); + this.worldDefaults.addDefault(path, dfl); + return config == null ? this.worldDefaults.getString(path) : config.getString(path, this.worldDefaults.getString(path)); + } + + String getStringRaw(final String path, final String dfl) { + final ConfigurationSection config = LeavesConfig.config.getConfigurationSection(this.configPath); + return config == null ? this.worldDefaults.getString(path, dfl) : config.getString(path, this.worldDefaults.getString(path, dfl)); + } + + List getList(final String path, final List dfl) { + final ConfigurationSection config = LeavesConfig.config.getConfigurationSection(this.configPath); + this.worldDefaults.addDefault(path, dfl); + return config == null ? this.worldDefaults.getList(path) : config.getList(path, this.worldDefaults.getList(path)); + } + + List getListRaw(final String path, final List dfl) { + final ConfigurationSection config = LeavesConfig.config.getConfigurationSection(this.configPath); + return config == null ? this.worldDefaults.getList(path, dfl) : config.getList(path, this.worldDefaults.getList(path, dfl)); + } + } +} diff --git a/src/main/java/top/leavesmc/leaves/command/CommandArgument.java b/src/main/java/top/leavesmc/leaves/command/CommandArgument.java new file mode 100644 index 0000000000000000000000000000000000000000..eadc6d168fb13299348b0c275ae352ee2f1e1ea2 --- /dev/null +++ b/src/main/java/top/leavesmc/leaves/command/CommandArgument.java @@ -0,0 +1,43 @@ +package top.leavesmc.leaves.command; + +import org.jetbrains.annotations.NotNull; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +public class CommandArgument { + + private final List> argumentTypes; + private final List> tabComplete; + + public CommandArgument(CommandArgumentType... argumentTypes) { + this.argumentTypes = List.of(argumentTypes); + this.tabComplete = new ArrayList<>(); + for (int i = 0; i < argumentTypes.length; i++) { + tabComplete.add(new ArrayList<>()); + } + } + + public List tabComplete(int n) { + if (tabComplete.size() > n) { + return tabComplete.get(n); + } else { + return List.of(); + } + } + + public CommandArgument setTabComplete(int index, List list) { + tabComplete.set(index, list); + return this; + } + + public CommandArgumentResult parse(int index, String @NotNull [] args) { + Object[] result = new Object[argumentTypes.size()]; + Arrays.fill(result, null); + for (int i = index, j = 0; i < args.length && j < result.length; i++, j++) { + result[j] = argumentTypes.get(j).pasre(args[i]); + } + return new CommandArgumentResult(new ArrayList<>(Arrays.asList(result))); + } +} diff --git a/src/main/java/top/leavesmc/leaves/command/CommandArgumentResult.java b/src/main/java/top/leavesmc/leaves/command/CommandArgumentResult.java new file mode 100644 index 0000000000000000000000000000000000000000..340eaca64c96180b895a075ce9e44402cd104eed --- /dev/null +++ b/src/main/java/top/leavesmc/leaves/command/CommandArgumentResult.java @@ -0,0 +1,62 @@ +package top.leavesmc.leaves.command; + +import net.minecraft.core.BlockPos; +import org.bukkit.util.Vector; + +import java.util.List; +import java.util.Objects; + +public class CommandArgumentResult { + + private final List result; + + public CommandArgumentResult(List result) { + this.result = result; + } + + public Integer readInt(int def) { + return Objects.requireNonNullElse(read(Integer.class), def); + } + + public Double readDouble(double def) { + return Objects.requireNonNullElse(read(Double.class), def); + } + + public String readString(String def) { + return Objects.requireNonNullElse(read(String.class), def); + } + + public BlockPos readPos() { + Integer[] pos = {read(Integer.class), read(Integer.class), read(Integer.class)}; + for (Integer po : pos) { + if (po == null) { + return null; + } + } + return new BlockPos(pos[0], pos[1], pos[2]); + } + + public Vector readVector() { + Double[] pos = {read(Double.class), read(Double.class), read(Double.class)}; + for (Double po : pos) { + if (po == null) { + return null; + } + } + return new Vector(pos[0], pos[1], pos[2]); + } + + public T read(Class tClass) { + if (result.isEmpty()) { + return null; + } + + Object obj = result.remove(0); + if (tClass.isInstance(obj)) { + return tClass.cast(obj); + } else { + return null; + } + } + +} diff --git a/src/main/java/top/leavesmc/leaves/command/CommandArgumentType.java b/src/main/java/top/leavesmc/leaves/command/CommandArgumentType.java new file mode 100644 index 0000000000000000000000000000000000000000..edf12195c7224ca2fb5d3c2ac3fcf485d3049d07 --- /dev/null +++ b/src/main/java/top/leavesmc/leaves/command/CommandArgumentType.java @@ -0,0 +1,37 @@ +package top.leavesmc.leaves.command; + +import org.jetbrains.annotations.NotNull; + +public abstract class CommandArgumentType { + + public static final CommandArgumentType INTEGER = new CommandArgumentType<>() { + @Override + public Integer pasre(@NotNull String arg) { + try { + return Integer.parseInt(arg); + } catch (NumberFormatException e) { + return null; + } + } + }; + + public static final CommandArgumentType DOUBLE = new CommandArgumentType<>() { + @Override + public Double pasre(@NotNull String arg) { + try { + return Double.parseDouble(arg); + } catch (NumberFormatException e) { + return null; + } + } + }; + + public static final CommandArgumentType STRING = new CommandArgumentType<>() { + @Override + public String pasre(@NotNull String arg) { + return arg; + } + }; + + public abstract E pasre(@NotNull String arg); +}