mirror of https://github.com/YatopiaMC/Yatopia.git
383 lines
15 KiB
Diff
383 lines
15 KiB
Diff
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
From: Paul Sauve <paul@technove.co>
|
|
Date: Wed, 20 Jan 2021 13:08:53 -0600
|
|
Subject: [PATCH] Airplane Configuration
|
|
|
|
Co-developed-by: Ben Kerllenevich <me@notom3ga.me>
|
|
|
|
Airplane
|
|
Copyright (C) 2020 Technove LLC
|
|
|
|
This program is free software: you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation, either version 3 of the License, or
|
|
(at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
diff --git a/src/main/java/gg/airplane/AirplaneCommand.java b/src/main/java/gg/airplane/AirplaneCommand.java
|
|
new file mode 100644
|
|
index 0000000000000000000000000000000000000000..1fa9b40e2f89272fa8bc9d927a9a852b5eb0db22
|
|
--- /dev/null
|
|
+++ b/src/main/java/gg/airplane/AirplaneCommand.java
|
|
@@ -0,0 +1,56 @@
|
|
+package gg.airplane;
|
|
+
|
|
+import net.md_5.bungee.api.ChatColor;
|
|
+import net.minecraft.server.MinecraftServer;
|
|
+import org.bukkit.Bukkit;
|
|
+import org.bukkit.Location;
|
|
+import org.bukkit.command.Command;
|
|
+import org.bukkit.command.CommandSender;
|
|
+
|
|
+import java.util.Collections;
|
|
+import java.util.List;
|
|
+import java.util.stream.Collectors;
|
|
+import java.util.stream.Stream;
|
|
+
|
|
+public class AirplaneCommand extends Command {
|
|
+
|
|
+ public AirplaneCommand() {
|
|
+ super("airplane");
|
|
+ this.description = "Airplane related commands";
|
|
+ this.usageMessage = "/airplane [reload | version]";
|
|
+ this.setPermission("bukkit.command.airplane");
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public List<String> tabComplete(CommandSender sender, String alias, String[] args, Location location) throws IllegalArgumentException {
|
|
+ if (args.length == 1) {
|
|
+ return Stream.of("reload", "version")
|
|
+ .filter(arg -> arg.startsWith(args[0].toLowerCase()))
|
|
+ .collect(Collectors.toList());
|
|
+ }
|
|
+ return Collections.emptyList();
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean execute(CommandSender sender, String commandLabel, String[] args) {
|
|
+ if (!testPermission(sender)) return true;
|
|
+ String prefix = ChatColor.of("#6a7eda") + "" + ChatColor.BOLD + "Airplane ✈ " + ChatColor.of("#e8ebf9");
|
|
+
|
|
+ if (args.length != 1) {
|
|
+ sender.sendMessage(prefix + "Usage: " + usageMessage);
|
|
+ args = new String[]{"version"};
|
|
+ }
|
|
+
|
|
+ if (args[0].equalsIgnoreCase("reload")) {
|
|
+ MinecraftServer console = MinecraftServer.getServer();
|
|
+ AirplaneConfig.load();
|
|
+ console.server.reloadCount++;
|
|
+
|
|
+ Command.broadcastCommandMessage(sender, prefix + "Airplane configuration has been reloaded.");
|
|
+ } else if (args[0].equalsIgnoreCase("version")) {
|
|
+ Command.broadcastCommandMessage(sender, prefix + "This server is running " + Bukkit.getName() + " version " + Bukkit.getVersion() + " (Implementing API version " + Bukkit.getBukkitVersion() + ")");
|
|
+ }
|
|
+
|
|
+ return true;
|
|
+ }
|
|
+}
|
|
diff --git a/src/main/java/gg/airplane/AirplaneConfig.java b/src/main/java/gg/airplane/AirplaneConfig.java
|
|
new file mode 100644
|
|
index 0000000000000000000000000000000000000000..4feb9686f45ce4ae9f474447496b8e0f6fcb7e31
|
|
--- /dev/null
|
|
+++ b/src/main/java/gg/airplane/AirplaneConfig.java
|
|
@@ -0,0 +1,46 @@
|
|
+package gg.airplane;
|
|
+
|
|
+import gg.airplane.manual.ManualParser;
|
|
+import net.minecraft.server.MinecraftServer;
|
|
+import org.apache.logging.log4j.Level;
|
|
+
|
|
+import java.io.File;
|
|
+import java.io.IOException;
|
|
+import java.lang.reflect.Method;
|
|
+import java.lang.reflect.Modifier;
|
|
+
|
|
+public class AirplaneConfig {
|
|
+
|
|
+ private static ManualParser manual;
|
|
+
|
|
+ public static void load() {
|
|
+ try {
|
|
+ manual = new ManualParser(new File("airplane.air"));
|
|
+ } catch (IOException e) {
|
|
+ e.printStackTrace();
|
|
+ }
|
|
+
|
|
+ manual.get("info.version", "1.0");
|
|
+ manual.setComment("info",
|
|
+ " Airplane Configuration",
|
|
+ " Please see https://airplane.gg/config for help.");
|
|
+
|
|
+ for (Method method : AirplaneConfig.class.getDeclaredMethods()) {
|
|
+ if (Modifier.isStatic(method.getModifiers()) && Modifier.isPrivate(method.getModifiers())) {
|
|
+ method.setAccessible(true);
|
|
+ try {
|
|
+ method.invoke(null);
|
|
+ } catch (Throwable t) {
|
|
+ MinecraftServer.LOGGER.log(Level.WARN, "Failed to load configuration option from " + method.getName(), t);
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+
|
|
+ try {
|
|
+ manual.save();
|
|
+ } catch (IOException e) {
|
|
+ e.printStackTrace();
|
|
+ }
|
|
+ }
|
|
+
|
|
+}
|
|
diff --git a/src/main/java/gg/airplane/commands/AirplaneCommands.java b/src/main/java/gg/airplane/commands/AirplaneCommands.java
|
|
new file mode 100644
|
|
index 0000000000000000000000000000000000000000..807cf274619b8f7be839e249cb62b9817876ca04
|
|
--- /dev/null
|
|
+++ b/src/main/java/gg/airplane/commands/AirplaneCommands.java
|
|
@@ -0,0 +1,10 @@
|
|
+package gg.airplane.commands;
|
|
+
|
|
+import gg.airplane.AirplaneCommand;
|
|
+import net.minecraft.server.MinecraftServer;
|
|
+
|
|
+public class AirplaneCommands {
|
|
+ public static void init() {
|
|
+ MinecraftServer.getServer().server.getCommandMap().register("airplane", "Airplane", new AirplaneCommand());
|
|
+ }
|
|
+}
|
|
diff --git a/src/main/java/gg/airplane/manual/ManualParser.java b/src/main/java/gg/airplane/manual/ManualParser.java
|
|
new file mode 100644
|
|
index 0000000000000000000000000000000000000000..ace29adb0f140d99a8d85ac824654beded4bf5b8
|
|
--- /dev/null
|
|
+++ b/src/main/java/gg/airplane/manual/ManualParser.java
|
|
@@ -0,0 +1,210 @@
|
|
+package gg.airplane.manual;
|
|
+
|
|
+import java.io.BufferedReader;
|
|
+import java.io.BufferedWriter;
|
|
+import java.io.File;
|
|
+import java.io.FileReader;
|
|
+import java.io.FileWriter;
|
|
+import java.io.IOException;
|
|
+import java.util.ArrayList;
|
|
+import java.util.Arrays;
|
|
+import java.util.LinkedHashMap;
|
|
+import java.util.List;
|
|
+import java.util.Map;
|
|
+import java.util.TreeMap;
|
|
+
|
|
+// todo make this cleaner and more ergonomic to use
|
|
+// also probably needs lists eventually
|
|
+public class ManualParser {
|
|
+
|
|
+ private final File file;
|
|
+ private final Map<String, Section> sections = new LinkedHashMap<>();
|
|
+
|
|
+ private static class ManualObject {
|
|
+ public final String key;
|
|
+ public final List<String> comments;
|
|
+
|
|
+ private ManualObject(String key, List<String> comments) {
|
|
+ this.key = key;
|
|
+ this.comments = comments == null ? new ArrayList<>() : comments;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ private static class Section extends ManualObject {
|
|
+ public final Map<String, Value> values;
|
|
+
|
|
+ private Section(String key, List<String> comments) {
|
|
+ super(key, comments);
|
|
+ this.values = new LinkedHashMap<>();
|
|
+ }
|
|
+
|
|
+ public void add(String key, Value value) {
|
|
+ this.values.put(key, value);
|
|
+ value.parent = this;
|
|
+ }
|
|
+
|
|
+ public Value get(String key) {
|
|
+ return this.values.computeIfAbsent(key, k -> {
|
|
+ Value value = new Value(k, null, null);
|
|
+ value.parent = this;
|
|
+ return value;
|
|
+ });
|
|
+ }
|
|
+ }
|
|
+
|
|
+ private static class Value extends ManualObject {
|
|
+ public Object value;
|
|
+ public Section parent;
|
|
+
|
|
+ private Value(String key, Object value, List<String> comments) {
|
|
+ super(key, comments);
|
|
+ this.value = value;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ public ManualParser(File file) throws IOException {
|
|
+ this.file = file;
|
|
+
|
|
+ if (!file.exists()) {
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ try (BufferedReader reader = new BufferedReader(new FileReader(file))) {
|
|
+ Section currentSection = null;
|
|
+ List<String> currentComment = new ArrayList<>();
|
|
+
|
|
+ String line;
|
|
+ while ((line = reader.readLine()) != null) {
|
|
+ line = line.trim();
|
|
+
|
|
+ if (line.length() == 0) {
|
|
+ continue; // empty line
|
|
+ }
|
|
+
|
|
+ if (line.startsWith("#")) {
|
|
+ currentComment.add(line.substring(1).trim());
|
|
+ } else if (line.startsWith("[")) {
|
|
+ if (!line.endsWith("]")) {
|
|
+ throw new IllegalArgumentException("Invalid configuration, section '" + line + "' does not end with ]");
|
|
+ }
|
|
+ if (line.length() < 3) {
|
|
+ throw new IllegalArgumentException("Invalid configuration, section '" + line + "' does not have a name");
|
|
+ }
|
|
+ String sectionName = line.substring(1, line.length() - 1);
|
|
+ Section newSection = new Section(sectionName, currentComment);
|
|
+ currentComment = new ArrayList<>();
|
|
+ currentSection = newSection;
|
|
+ this.sections.put(sectionName, newSection);
|
|
+ } else {
|
|
+ if (currentSection == null) {
|
|
+ throw new IllegalArgumentException("Invalid configuration, found value outside of section " + line);
|
|
+ }
|
|
+ int equals = line.indexOf("=");
|
|
+ if (equals <= 1 || equals == line.length() - 1) {
|
|
+ throw new IllegalArgumentException("Invalid configuration, assignment invalid " + line);
|
|
+ }
|
|
+
|
|
+ String key = line.substring(0, equals).trim();
|
|
+
|
|
+ String value = line.substring(equals + 1).trim();
|
|
+ if (value.length() == 0) {
|
|
+ throw new IllegalArgumentException("Invalid configuration, value does not exist " + line);
|
|
+ }
|
|
+ if (value.startsWith("\"")) {
|
|
+ if (!value.endsWith("\"")) {
|
|
+ throw new IllegalArgumentException("Invalid configuration, value has no ending quote " + line);
|
|
+ }
|
|
+ String stringValue = value.substring(1, value.length() - 1);
|
|
+ currentSection.add(key, new Value(key, stringValue, currentComment));
|
|
+ } else if (Character.isDigit(value.charAt(0))) {
|
|
+ if (value.contains(".")) {
|
|
+ double doubleValue = Double.parseDouble(value);
|
|
+ currentSection.add(key, new Value(key, doubleValue, currentComment));
|
|
+ } else {
|
|
+ int intValue = Integer.parseInt(value);
|
|
+ currentSection.add(key, new Value(key, intValue, currentComment));
|
|
+ }
|
|
+ } else if (value.equals("true") || value.equals("false")) {
|
|
+ boolean boolValue = Boolean.parseBoolean(value);
|
|
+ currentSection.add(key, new Value(key, boolValue, currentComment));
|
|
+ } else {
|
|
+ throw new IllegalArgumentException("Invalid configuration, unknown type for " + line);
|
|
+ }
|
|
+ currentComment = new ArrayList<>();
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+
|
|
+ public void save() throws IOException {
|
|
+ try (BufferedWriter writer = new BufferedWriter(new FileWriter(this.file))) {
|
|
+ for (Map.Entry<String, Section> entry : this.sections.entrySet()) {
|
|
+ Section section = entry.getValue();
|
|
+ if (section.comments != null) {
|
|
+ for (String comment : section.comments) {
|
|
+ writer.write("# " + comment + "\n");
|
|
+ }
|
|
+ }
|
|
+ writer.write("[" + section.key + "]" + "\n");
|
|
+ for (Value value : section.values.values()) {
|
|
+ if (value.comments != null) {
|
|
+ for (String comment : value.comments) {
|
|
+ writer.write(" # " + comment + "\n");
|
|
+ }
|
|
+ }
|
|
+ writer.write(" " + value.key + " = " + serialize(value.value) + "\n");
|
|
+ }
|
|
+ writer.write("\n");
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+
|
|
+ private ManualObject getObject(String key) {
|
|
+ String[] split = key.split("\\.", 2);
|
|
+ if (split.length == 1) {
|
|
+ return this.sections.computeIfAbsent(key, k -> new Section(k, null));
|
|
+ }
|
|
+ return this.sections.computeIfAbsent(split[0], k -> new Section(k, null)).get(split[1]);
|
|
+ }
|
|
+
|
|
+ public void setComment(String key, String... comment) {
|
|
+ ManualObject object = this.getObject(key);
|
|
+ object.comments.clear();
|
|
+ object.comments.addAll(Arrays.asList(comment));
|
|
+ }
|
|
+
|
|
+ public <T> T get(String key, T defaultValue, String... comment) {
|
|
+ String[] split = key.split("\\.", 2);
|
|
+ if (split.length == 1) {
|
|
+ throw new IllegalArgumentException("Key " + key + " does not include section");
|
|
+ }
|
|
+ Section section = this.sections.computeIfAbsent(split[0], k -> new Section(k, null));
|
|
+ if (!section.values.containsKey(split[1])) {
|
|
+ Value value = section.get(split[1]);
|
|
+ value.value = defaultValue;
|
|
+ value.comments.addAll(Arrays.asList(comment));
|
|
+ return defaultValue;
|
|
+ }
|
|
+ Value value = section.get(split[1]);
|
|
+ if (value.comments.isEmpty()) {
|
|
+ value.comments.addAll(Arrays.asList(comment));
|
|
+ }
|
|
+ return (T) value.value;
|
|
+ }
|
|
+
|
|
+ public void set(String key, Object value) {
|
|
+ ManualObject object = getObject(key);
|
|
+ if (!(object instanceof Value)) {
|
|
+ throw new IllegalArgumentException("Invalid key for value " + key);
|
|
+ }
|
|
+ ((Value) object).value = value;
|
|
+ }
|
|
+
|
|
+ private String serialize(Object object) {
|
|
+ if (object instanceof String) {
|
|
+ return "\"" + object + "\"";
|
|
+ }
|
|
+ return String.valueOf(object);
|
|
+ }
|
|
+
|
|
+}
|
|
diff --git a/src/main/java/net/minecraft/server/DedicatedServer.java b/src/main/java/net/minecraft/server/DedicatedServer.java
|
|
index e3721b53db68171665ba05201155d088ae3cb89f..b8a45c80b6691214e513286262f31b7b5b1dd5eb 100644
|
|
--- a/src/main/java/net/minecraft/server/DedicatedServer.java
|
|
+++ b/src/main/java/net/minecraft/server/DedicatedServer.java
|
|
@@ -185,6 +185,8 @@ public class DedicatedServer extends MinecraftServer implements IMinecraftServer
|
|
com.destroystokyo.paper.VersionHistoryManager.INSTANCE.getClass(); // load version history now
|
|
// Paper end
|
|
com.tuinity.tuinity.config.TuinityConfig.init((java.io.File) options.valueOf("tuinity-settings")); // Tuinity - Server Config
|
|
+ gg.airplane.AirplaneConfig.load(); // Airplane - config
|
|
+ gg.airplane.commands.AirplaneCommands.init(); // Airplane - command
|
|
|
|
this.setPVP(dedicatedserverproperties.pvp);
|
|
this.setAllowFlight(dedicatedserverproperties.allowFlight);
|