mirror of
https://github.com/YatopiaMC/Yatopia.git
synced 2024-11-26 20:55:30 +01:00
e1a085de4c
Fixes #145
470 lines
19 KiB
Diff
470 lines
19 KiB
Diff
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
From: tr7zw <tr7zw@live.de>
|
|
Date: Wed, 5 Aug 2020 08:05:10 -0500
|
|
Subject: [PATCH] Add config Yatopia command and basic settings
|
|
|
|
|
|
diff --git a/src/main/java/co/aikar/timings/TimingsExport.java b/src/main/java/co/aikar/timings/TimingsExport.java
|
|
index b67f05f290db653cf75a89e85bd3decb5044a1e0..11758b6b158d971b9beb1b609d7513dab46be525 100644
|
|
--- a/src/main/java/co/aikar/timings/TimingsExport.java
|
|
+++ b/src/main/java/co/aikar/timings/TimingsExport.java
|
|
@@ -232,6 +232,7 @@ public class TimingsExport extends Thread {
|
|
pair("paper", mapAsJSON(Bukkit.spigot().getPaperConfig(), null)), // Tuinity - add config to timings report
|
|
pair("tuinity", mapAsJSON(Bukkit.spigot().getTuinityConfig(), null)) // Tuinity - add config to timings report
|
|
, pair("purpur", mapAsJSON(Bukkit.spigot().getPurpurConfig(), null)) // Purpur - add config to timings report
|
|
+ , pair("yatopia", mapAsJSON(Bukkit.spigot().getYatopiaConfig(), null)) // Yatopia - add config to timings report
|
|
));
|
|
|
|
new TimingsExport(listeners, parent, history).start();
|
|
diff --git a/src/main/java/dev/tr7zw/yatopia/YatopiaCommand.java b/src/main/java/dev/tr7zw/yatopia/YatopiaCommand.java
|
|
new file mode 100644
|
|
index 0000000000000000000000000000000000000000..0ada1657122fd973bbb8ec8b7c7be83de0bd4a00
|
|
--- /dev/null
|
|
+++ b/src/main/java/dev/tr7zw/yatopia/YatopiaCommand.java
|
|
@@ -0,0 +1,141 @@
|
|
+package dev.tr7zw.yatopia;
|
|
+
|
|
+import com.google.common.base.Preconditions;
|
|
+import com.google.common.collect.Lists;
|
|
+import java.io.File;
|
|
+import java.util.Arrays;
|
|
+import java.util.Collection;
|
|
+import java.util.Collections;
|
|
+import java.util.List;
|
|
+import java.util.Locale;
|
|
+import java.util.function.Function;
|
|
+import net.minecraft.server.MinecraftKey;
|
|
+import net.minecraft.server.MinecraftServer;
|
|
+import net.minecraft.server.World;
|
|
+import net.minecraft.server.WorldDataServer;
|
|
+import org.bukkit.Bukkit;
|
|
+import org.bukkit.ChatColor;
|
|
+import org.bukkit.Location;
|
|
+import org.bukkit.command.Command;
|
|
+import org.bukkit.command.CommandSender;
|
|
+import org.spigotmc.TicksPerSecondCommand;
|
|
+
|
|
+public class YatopiaCommand extends Command {
|
|
+
|
|
+ public YatopiaCommand(String name) {
|
|
+ super(name);
|
|
+ this.description = "Yatopia related commands";
|
|
+ this.usageMessage = "/yatopia [help | reload | info | version]";
|
|
+ this.setPermission("bukkit.command.yatopia");
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public List<String> tabComplete(CommandSender sender, String alias, String[] args, Location location) throws IllegalArgumentException {
|
|
+ if (args.length <= 1) {
|
|
+ return getListMatchingLast(args, "help", "info", "reload", "version");
|
|
+ }
|
|
+ return Collections.emptyList();
|
|
+ }
|
|
+
|
|
+ // Code from Mojang - copyright them
|
|
+ public static List<String> getListMatchingLast(String[] args, String... matches) {
|
|
+ return getListMatchingLast(args, Arrays.asList(matches));
|
|
+ }
|
|
+
|
|
+ public static boolean matches(String s, String s1) {
|
|
+ return s1.regionMatches(true, 0, s, 0, s.length());
|
|
+ }
|
|
+
|
|
+ public static List<String> getListMatchingLast(String[] strings, Collection<?> collection) {
|
|
+ String last = strings[strings.length - 1];
|
|
+ List<String> results = Lists.newArrayList();
|
|
+
|
|
+ if (!collection.isEmpty()) {
|
|
+ Function<Object, String> toStringFunction = (o) -> {
|
|
+ Preconditions.checkNotNull(o);
|
|
+ return o.toString();
|
|
+ };
|
|
+ for (Object c : collection) {
|
|
+ String value = toStringFunction.apply(c);
|
|
+ if (matches(last, value)) {
|
|
+ results.add(value);
|
|
+ }
|
|
+ }
|
|
+
|
|
+ if (results.isEmpty()) {
|
|
+ for (Object c : collection) {
|
|
+ if (c instanceof MinecraftKey) {
|
|
+ MinecraftKey key = (MinecraftKey) c;
|
|
+ if (matches(last, key.getKey())) {
|
|
+ results.add(key.toString());
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+
|
|
+ return results;
|
|
+ }
|
|
+ // end copy stuff
|
|
+
|
|
+ @Override
|
|
+ public boolean execute(CommandSender sender, String commandLabel, String[] args) {
|
|
+ if (!testPermission(sender)) return true;
|
|
+
|
|
+ if (args.length == 0) {
|
|
+ sender.sendMessage(ChatColor.RED + "Usage: " + usageMessage);
|
|
+ return false;
|
|
+ }
|
|
+
|
|
+ switch (args[0].toLowerCase(Locale.ENGLISH)) {
|
|
+ case "info":
|
|
+ doInfo(sender);
|
|
+ break;
|
|
+ case "reload":
|
|
+ doReload(sender);
|
|
+ break;
|
|
+ case "ver":
|
|
+ case "version":
|
|
+ Command ver = org.bukkit.Bukkit.getServer().getCommandMap().getCommand("version");
|
|
+ if (ver != null) {
|
|
+ ver.execute(sender, commandLabel, new String[0]);
|
|
+ break;
|
|
+ }
|
|
+ // else - fall through to default
|
|
+ default:
|
|
+ sender.sendMessage(ChatColor.RED + "Usage: " + usageMessage);
|
|
+ return false;
|
|
+ }
|
|
+
|
|
+ return true;
|
|
+ }
|
|
+
|
|
+ private void doInfo(CommandSender sender) {
|
|
+ broadcastMessage(sender, ChatColor.GOLD + "Last tick took " + TicksPerSecondCommand.format(Bukkit.getLastTickMs()));
|
|
+ for (World world : MinecraftServer.getServer().getWorlds()) {
|
|
+ String name = ((WorldDataServer) world.worldData).getName();
|
|
+ broadcastMessage(sender, ChatColor.GOLD + "Entities in world " +
|
|
+ ChatColor.YELLOW + "\"" + name + "\"" +
|
|
+ ChatColor.GOLD + ": " + ChatColor.YELLOW + world.getWorld().getEntityCount());
|
|
+ broadcastMessage(sender, ChatColor.GOLD + "Chunks loaded in world " +
|
|
+ ChatColor.YELLOW + "\"" + name + "\"" +
|
|
+ ChatColor.GOLD + ": " + ChatColor.YELLOW + world.getWorld().getChunkCount());
|
|
+ }
|
|
+ }
|
|
+
|
|
+ private void doReload(CommandSender sender) {
|
|
+ broadcastMessage(sender, ChatColor.RED + "Please note that this command is not supported and may cause issues.");
|
|
+ broadcastMessage(sender, ChatColor.RED + "If you encounter any issues please use the /stop command to restart your server.");
|
|
+
|
|
+ MinecraftServer console = MinecraftServer.getServer();
|
|
+ dev.tr7zw.yatopia.YatopiaConfig.init((File) console.options.valueOf("yatopia-settings"));
|
|
+ console.server.reloadCount++;
|
|
+
|
|
+ broadcastMessage(sender, ChatColor.GREEN + "Yatopia config reload complete.");
|
|
+ }
|
|
+
|
|
+ // utility method
|
|
+ private void broadcastMessage(CommandSender sender, String message) {
|
|
+ Command.broadcastCommandMessage(sender, message);
|
|
+ }
|
|
+}
|
|
diff --git a/src/main/java/dev/tr7zw/yatopia/YatopiaConfig.java b/src/main/java/dev/tr7zw/yatopia/YatopiaConfig.java
|
|
new file mode 100644
|
|
index 0000000000000000000000000000000000000000..b67a82569747fb8f4a349b7f81fe502cc4e2a792
|
|
--- /dev/null
|
|
+++ b/src/main/java/dev/tr7zw/yatopia/YatopiaConfig.java
|
|
@@ -0,0 +1,213 @@
|
|
+package dev.tr7zw.yatopia;
|
|
+
|
|
+import com.google.common.base.Throwables;
|
|
+import java.io.File;
|
|
+import java.io.IOException;
|
|
+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.concurrent.TimeUnit;
|
|
+import java.util.logging.Level;
|
|
+import java.util.regex.Pattern;
|
|
+import net.minecraft.server.MinecraftServer;
|
|
+import org.bukkit.Bukkit;
|
|
+import org.bukkit.command.Command;
|
|
+import org.bukkit.configuration.InvalidConfigurationException;
|
|
+import org.bukkit.configuration.file.YamlConfiguration;
|
|
+
|
|
+public class YatopiaConfig {
|
|
+
|
|
+ public static File CONFIG_FILE;
|
|
+ private static final String HEADER = "This is the main configuration file for Yatopia.\n"
|
|
+ + "Yatopia contains many breaking changes and settings, so know what you are doing!\n"
|
|
+ + "You have been warned!\n";
|
|
+ /*========================================================================*/
|
|
+ public static YamlConfiguration config;
|
|
+ public static int version; // since we're remapping sidestreams' configs we need this public
|
|
+ static Map<String, Command> commands;
|
|
+ public static boolean verbose; // since we're remapping sidestreams' configs we need this public
|
|
+ private static boolean fatalError;
|
|
+ /*========================================================================*/
|
|
+ private static boolean metricsStarted;
|
|
+
|
|
+ public static void init(File configFile) {
|
|
+ CONFIG_FILE = configFile;
|
|
+ config = new YamlConfiguration();
|
|
+ try {
|
|
+ config.load(CONFIG_FILE);
|
|
+ } catch (IOException ex) {
|
|
+ } catch (InvalidConfigurationException ex) {
|
|
+ Bukkit.getLogger().log(Level.SEVERE, "Could not load yatopia.yml, please correct your syntax errors", ex);
|
|
+ throw Throwables.propagate(ex);
|
|
+ }
|
|
+ config.options().header(HEADER);
|
|
+ config.options().copyDefaults(true);
|
|
+ verbose = getBoolean("verbose", false);
|
|
+
|
|
+ commands = new HashMap<String, Command>();
|
|
+ commands.put("yatopia", new YatopiaCommand("yatopia"));
|
|
+
|
|
+ version = getInt("config-version", 1);
|
|
+ set("config-version", 1);
|
|
+ removeLeftovers();
|
|
+ readConfig(YatopiaConfig.class, null);
|
|
+ }
|
|
+
|
|
+ private static void removeLeftovers() {
|
|
+ // this method is only to remove non-used values in the config
|
|
+
|
|
+ // leftover from akarin / rainforest
|
|
+ if (config.get("world-settings") != null) {
|
|
+ set("world-settings", null);
|
|
+ }
|
|
+ // unused settings getting removed
|
|
+ if (config.get("settings.disablePlayerOutOfWorldBorderCheck") != null) {
|
|
+ set("settings.disablePlayerOutOfWorldBorderCheck", null);
|
|
+ }
|
|
+ if (config.get("settings.disableEntityCollisions") != null) {
|
|
+ set("settings.disableEntityCollisions", null);
|
|
+ }
|
|
+ if (config.get("settings.onlyPlayerCollisions") != null) {
|
|
+ set("settings.onlyPlayerCollisions", null);
|
|
+ }
|
|
+ if (config.get("settings.disableEntityCollisionboxes") != null) {
|
|
+ set("settings.disableEntityCollisionboxes", null);
|
|
+ }
|
|
+ }
|
|
+
|
|
+ protected static void logError(String s) {
|
|
+ Bukkit.getLogger().severe(s);
|
|
+ }
|
|
+
|
|
+ protected static void fatal(String s) {
|
|
+ fatalError = true;
|
|
+ throw new RuntimeException("Fatal yatopia.yml config error: " + s);
|
|
+ }
|
|
+
|
|
+ protected static void log(String s) {
|
|
+ if (verbose) {
|
|
+ Bukkit.getLogger().info(s);
|
|
+ }
|
|
+ }
|
|
+
|
|
+ public static void registerCommands() {
|
|
+ for (Map.Entry<String, Command> entry : commands.entrySet()) {
|
|
+ MinecraftServer.getServer().server.getCommandMap().register(entry.getKey(), "Yatopia", entry.getValue());
|
|
+ }
|
|
+ }
|
|
+
|
|
+ static void readConfig(Class<?> clazz, Object instance) {
|
|
+ for (Method method : clazz.getDeclaredMethods()) {
|
|
+ if (Modifier.isPrivate(method.getModifiers())) {
|
|
+ if (method.getParameterTypes().length == 0 && method.getReturnType() == Void.TYPE) {
|
|
+ try {
|
|
+ method.setAccessible(true);
|
|
+ method.invoke(instance);
|
|
+ } catch (InvocationTargetException ex) {
|
|
+ throw Throwables.propagate(ex.getCause());
|
|
+ } catch (Exception ex) {
|
|
+ Bukkit.getLogger().log(Level.SEVERE, "Error invoking " + method, ex);
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+
|
|
+ try {
|
|
+ config.save(CONFIG_FILE);
|
|
+ } catch (IOException ex) {
|
|
+ Bukkit.getLogger().log(Level.SEVERE, "Could not save " + CONFIG_FILE, ex);
|
|
+ }
|
|
+ }
|
|
+
|
|
+ private static final Pattern SPACE = Pattern.compile(" ");
|
|
+ private static final Pattern NOT_NUMERIC = Pattern.compile("[^-\\d.]");
|
|
+
|
|
+ public static int getSeconds(String str) {
|
|
+ str = SPACE.matcher(str).replaceAll("");
|
|
+ final char unit = str.charAt(str.length() - 1);
|
|
+ str = NOT_NUMERIC.matcher(str).replaceAll("");
|
|
+ double num;
|
|
+ try {
|
|
+ num = Double.parseDouble(str);
|
|
+ } catch (Exception e) {
|
|
+ num = 0D;
|
|
+ }
|
|
+ switch (unit) {
|
|
+ case 'd':
|
|
+ num *= (double) 60 * 60 * 24;
|
|
+ break;
|
|
+ case 'h':
|
|
+ num *= (double) 60 * 60;
|
|
+ break;
|
|
+ case 'm':
|
|
+ num *= 60;
|
|
+ break;
|
|
+ default:
|
|
+ case 's':
|
|
+ break;
|
|
+ }
|
|
+ return (int) num;
|
|
+ }
|
|
+
|
|
+ protected static String timeSummary(int seconds) {
|
|
+ String time = "";
|
|
+
|
|
+ if (seconds > 60 * 60 * 24) {
|
|
+ time += TimeUnit.SECONDS.toDays(seconds) + "d";
|
|
+ seconds %= 60 * 60 * 24;
|
|
+ }
|
|
+
|
|
+ if (seconds > 60 * 60) {
|
|
+ time += TimeUnit.SECONDS.toHours(seconds) + "h";
|
|
+ seconds %= 60 * 60;
|
|
+ }
|
|
+
|
|
+ if (seconds > 0) {
|
|
+ time += TimeUnit.SECONDS.toMinutes(seconds) + "m";
|
|
+ }
|
|
+ return time;
|
|
+ }
|
|
+
|
|
+ private static void set(String path, Object val) {
|
|
+ config.set(path, val);
|
|
+ }
|
|
+
|
|
+ private static boolean getBoolean(String path, boolean def) {
|
|
+ config.addDefault(path, def);
|
|
+ return config.getBoolean(path, config.getBoolean(path));
|
|
+ }
|
|
+
|
|
+ private static double getDouble(String path, double def) {
|
|
+ config.addDefault(path, def);
|
|
+ return config.getDouble(path, config.getDouble(path));
|
|
+ }
|
|
+
|
|
+ private static float getFloat(String path, float def) {
|
|
+ // TODO: Figure out why getFloat() always returns the default value.
|
|
+ return (float) getDouble(path, (double) def);
|
|
+ }
|
|
+
|
|
+ private static int getInt(String path, int def) {
|
|
+ config.addDefault(path, def);
|
|
+ return config.getInt(path, config.getInt(path));
|
|
+ }
|
|
+
|
|
+ private static <T> List<T> getList(String path, List<T> def) {
|
|
+ config.addDefault(path, def);
|
|
+ return (List<T>) config.getList(path, config.getList(path));
|
|
+ }
|
|
+
|
|
+ private static String getString(String path, String def) {
|
|
+ config.addDefault(path, def);
|
|
+ return config.getString(path, config.getString(path));
|
|
+ }
|
|
+
|
|
+ public static boolean disableEntityStuckChecks = false;
|
|
+ private static void disableEntityStuckChecks() {
|
|
+ disableEntityStuckChecks = getBoolean("settings.disableEntityStuckChecks", false);
|
|
+ }
|
|
+
|
|
+}
|
|
diff --git a/src/main/java/net/minecraft/server/DedicatedServer.java b/src/main/java/net/minecraft/server/DedicatedServer.java
|
|
index a60634fc455e8a59399020689b70eb64b6824d12..cb4a89940cf02de5c3eefc5c746397a931c96b7a 100644
|
|
--- a/src/main/java/net/minecraft/server/DedicatedServer.java
|
|
+++ b/src/main/java/net/minecraft/server/DedicatedServer.java
|
|
@@ -181,6 +181,15 @@ public class DedicatedServer extends MinecraftServer implements IMinecraftServer
|
|
// Paper end
|
|
com.tuinity.tuinity.config.TuinityConfig.init((java.io.File) options.valueOf("tuinity-settings")); // Tuinity - Server Config
|
|
|
|
+ // Yatopia start
|
|
+ try {
|
|
+ dev.tr7zw.yatopia.YatopiaConfig.init((java.io.File) options.valueOf("yatopia-settings"));
|
|
+ } catch (Exception e) {
|
|
+ DedicatedServer.LOGGER.error("Unable to load server configuration", e);
|
|
+ return false;
|
|
+ }
|
|
+ dev.tr7zw.yatopia.YatopiaConfig.registerCommands();
|
|
+ // Yatopia end
|
|
this.setPVP(dedicatedserverproperties.pvp);
|
|
this.setAllowFlight(dedicatedserverproperties.allowFlight);
|
|
this.setResourcePack(dedicatedserverproperties.resourcePack, this.aZ());
|
|
diff --git a/src/main/java/net/minecraft/server/EntityLiving.java b/src/main/java/net/minecraft/server/EntityLiving.java
|
|
index f24f7f1230a380f46112e886fb5dff7c33edb2ce..88f4c30a03e9139b0284ff1a545ad80941dbd46c 100644
|
|
--- a/src/main/java/net/minecraft/server/EntityLiving.java
|
|
+++ b/src/main/java/net/minecraft/server/EntityLiving.java
|
|
@@ -266,6 +266,7 @@ public abstract class EntityLiving extends Entity {
|
|
//this.world.getMethodProfiler().enter("livingEntityBaseTick"); // Akarin - remove caller
|
|
boolean flag = this instanceof EntityHuman;
|
|
|
|
+ if (dev.tr7zw.yatopia.YatopiaConfig.disableEntityStuckChecks) { // Yatopia
|
|
if (this.isAlive()) {
|
|
if (this.inBlock()) {
|
|
this.damageEntity(DamageSource.STUCK, 1.0F);
|
|
@@ -281,6 +282,7 @@ public abstract class EntityLiving extends Entity {
|
|
}
|
|
}
|
|
}
|
|
+ } // Yatopia
|
|
|
|
if (this.isFireProof() || this.world.isClientSide) {
|
|
this.extinguish();
|
|
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
|
index 2d32ab02d7edee9a964dc2d9248c0c769e7dcac8..9f9bbd1c7830a93da3fcbd399bb2e402b7698ec3 100644
|
|
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
|
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
|
@@ -844,6 +844,7 @@ public final class CraftServer implements Server {
|
|
net.pl3x.purpur.PurpurConfig.init((File) console.options.valueOf("purpur-settings")); // Purpur
|
|
com.proximyst.rainforest.RainforestConfig.init((File) console.options.valueOf("rainforest-settings")); // Rainforest
|
|
de.minebench.origami.OrigamiConfig.init((File) console.options.valueOf("origami-settings")); // Origami
|
|
+ dev.tr7zw.yatopia.YatopiaConfig.init((File) console.options.valueOf("yatopia-settings")); // Yatopia
|
|
for (WorldServer world : console.getWorlds()) {
|
|
world.worldDataServer.setDifficulty(config.difficulty);
|
|
world.setSpawnFlags(config.spawnMonsters, config.spawnAnimals);
|
|
@@ -2271,6 +2272,13 @@ public final class CraftServer implements Server {
|
|
}
|
|
// Origami end
|
|
|
|
+ // Yatopia start
|
|
+ @Override
|
|
+ public YamlConfiguration getYatopiaConfig() {
|
|
+ return dev.tr7zw.yatopia.YatopiaConfig.config;
|
|
+ }
|
|
+ // Yatopia end
|
|
+
|
|
@Override
|
|
public void restart() {
|
|
org.spigotmc.RestartCommand.restart();
|
|
diff --git a/src/main/java/org/bukkit/craftbukkit/Main.java b/src/main/java/org/bukkit/craftbukkit/Main.java
|
|
index 132ad379242d9aa2defc639f79764050b73c572d..5387a50e4a24e2eb49693368c5342a69b8d14b69 100644
|
|
--- a/src/main/java/org/bukkit/craftbukkit/Main.java
|
|
+++ b/src/main/java/org/bukkit/craftbukkit/Main.java
|
|
@@ -169,6 +169,14 @@ public class Main {
|
|
.describedAs("Yml file");
|
|
// Origami end
|
|
|
|
+ // Yatopia start
|
|
+ acceptsAll(asList("yatopia", "yatopia-settings"), "File for yatopia settings")
|
|
+ .withRequiredArg()
|
|
+ .ofType(File.class)
|
|
+ .defaultsTo(new File("yatopia.yml"))
|
|
+ .describedAs("Yml file");
|
|
+ // Yatopia end
|
|
+
|
|
// Paper start
|
|
acceptsAll(asList("server-name"), "Name of the server")
|
|
.withRequiredArg()
|