From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Allink Date: Sun, 10 Jul 2022 07:53:59 +0100 Subject: [PATCH] Add Scissors config & command diff --git a/src/main/java/co/aikar/timings/TimingsExport.java b/src/main/java/co/aikar/timings/TimingsExport.java index e29b0a90019b12bd6586ad0f7b5314f307e527ba..c6f19e178f8c5a03f9fb8b011f329ef81e4e35d8 100644 --- a/src/main/java/co/aikar/timings/TimingsExport.java +++ b/src/main/java/co/aikar/timings/TimingsExport.java @@ -23,6 +23,7 @@ */ package co.aikar.timings; +import com.github.atlasmediagroup.scissors.ScissorsConfig; import com.google.common.collect.Sets; import net.minecraft.server.MinecraftServer; import org.apache.commons.lang.StringUtils; @@ -228,7 +229,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)), + pair("scissors", mapAsJSON(ScissorsConfig.config, null)) // Scissors )); new TimingsExport(listeners, parent, history).start(); diff --git a/src/main/java/com/github/atlasmediagroup/scissors/ScissorsCommand.java b/src/main/java/com/github/atlasmediagroup/scissors/ScissorsCommand.java new file mode 100644 index 0000000000000000000000000000000000000000..f5202deac5b3a715a22d0d482f1302b6074b26ac --- /dev/null +++ b/src/main/java/com/github/atlasmediagroup/scissors/ScissorsCommand.java @@ -0,0 +1,150 @@ +package com.github.atlasmediagroup.scissors; + +import com.google.common.base.Functions; +import com.google.common.base.Joiner; +import com.google.common.collect.ImmutableSet; +import com.google.common.collect.Iterables; +import com.google.common.collect.Lists; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.server.MinecraftServer; +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.Location; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; + +import java.io.File; +import java.util.*; +import java.util.stream.Collectors; + +public class ScissorsCommand extends Command +{ + + private static final String BASE_PERM = "bukkit.command.scissors."; + private static final ImmutableSet SUBCOMMANDS = ImmutableSet.builder().add("reload", "version").build(); + + public ScissorsCommand(String name) + { + super(name); + this.description = "Scissors related commands"; + this.usageMessage = "/scissors [" + Joiner.on(" | ").join(SUBCOMMANDS) + "]"; + this.setPermission("bukkit.command.scissors;" + Joiner.on(';').join(SUBCOMMANDS.stream().map(s -> BASE_PERM + s).collect(Collectors.toSet()))); + } + + private static boolean testPermission(CommandSender commandSender, String permission) + { + if (commandSender.hasPermission(BASE_PERM + permission) || commandSender.hasPermission("bukkit.command.scissors")) + return true; + commandSender.sendMessage(Bukkit.getPermissionMessage()); // Sorry, kashike + return false; + } + + // Code from Mojang - copyright them + public static List getListMatchingLast(CommandSender sender, String[] args, String... matches) + { + return getListMatchingLast(sender, args, Arrays.asList(matches)); + } + + public static boolean matches(String s, String s1) + { + return s1.regionMatches(true, 0, s, 0, s.length()); + } + + public static List getListMatchingLast(CommandSender sender, String[] strings, Collection collection) + { + String last = strings[strings.length - 1]; + ArrayList results = Lists.newArrayList(); + + if (!collection.isEmpty()) + { + Iterator iterator = Iterables.transform(collection, Functions.toStringFunction()).iterator(); + + while (iterator.hasNext()) + { + String s1 = (String) iterator.next(); + + if (matches(last, s1) && (sender.hasPermission(BASE_PERM + s1) || sender.hasPermission("bukkit.command.scissors"))) + { + results.add(s1); + } + } + + if (results.isEmpty()) + { + iterator = collection.iterator(); + + while (iterator.hasNext()) + { + Object object = iterator.next(); + + if (object instanceof ResourceLocation && matches(last, ((ResourceLocation) object).getPath())) + { + results.add(String.valueOf(object)); + } + } + } + } + + return results; + } + + @Override + public List tabComplete(CommandSender sender, String alias, String[] args, Location location) throws IllegalArgumentException + { + if (args.length <= 1) + return getListMatchingLast(sender, args, SUBCOMMANDS); + + return Collections.emptyList(); + } + // 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; + } + if (SUBCOMMANDS.contains(args[0].toLowerCase(Locale.ENGLISH))) + { + if (!testPermission(sender, args[0].toLowerCase(Locale.ENGLISH))) return true; + } + switch (args[0].toLowerCase(Locale.ENGLISH)) + { + case "reload": + doReload(sender); + break; + case "ver": + if (!testPermission(sender, "version")) + break; // "ver" needs a special check because it's an alias. All other commands are checked up before the switch statement (because they are present in the SUBCOMMANDS set) + case "version": + Command ver = MinecraftServer.getServer().server.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 doReload(CommandSender sender) + { + Command.broadcastCommandMessage(sender, ChatColor.RED + "Please note that this command is not supported and may cause issues."); + Command.broadcastCommandMessage(sender, ChatColor.RED + "If you encounter any issues please use the /stop command to restart your server."); + + MinecraftServer console = MinecraftServer.getServer(); + ScissorsConfig.init((File) console.options.valueOf("scissors-settings")); + console.server.reloadCount++; + + Command.broadcastCommandMessage(sender, ChatColor.GREEN + "Scissors config reload complete."); + } +} diff --git a/src/main/java/com/github/atlasmediagroup/scissors/ScissorsConfig.java b/src/main/java/com/github/atlasmediagroup/scissors/ScissorsConfig.java new file mode 100644 index 0000000000000000000000000000000000000000..d0e2bcf4671d723d5893e0a9bc8c6e30a9b83be6 --- /dev/null +++ b/src/main/java/com/github/atlasmediagroup/scissors/ScissorsConfig.java @@ -0,0 +1,170 @@ +package com.github.atlasmediagroup.scissors; + +import com.google.common.base.Throwables; +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; + +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.logging.Level; +import java.util.regex.Pattern; + +public class ScissorsConfig +{ + + private static final String HEADER = """ + This is the main configuration file for Scissors. + As you can see, there's tons to configure. Some options may impact gameplay, so use + with caution, and make sure you know what each option does before configuring. + + If you need help with the configuration or have any questions related to Scissors, + join us in our Discord. + + Discord: https://discord.com/invite/mtVQcHn58h + Website: https://scissors.gg/\s + Docs: https://scissors.gg/javadoc/1.17.1/\s + """; + private static final Pattern SPACE = Pattern.compile(" "); + private static final Pattern NOT_NUMERIC = Pattern.compile("[^-\\d.]"); + /*========================================================================*/ + public static YamlConfiguration config; + static int version; + /*========================================================================*/ + static Map commands; + private static File CONFIG_FILE; + + 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 scissors.yml, please correct your syntax errors", ex); + throw Throwables.propagate(ex); + } + + commands = new HashMap<>(); + commands.put("scissors", new ScissorsCommand("scissors")); + + config.options().header(HEADER); + config.options().copyDefaults(true); + + version = getInt("config-version", 1); + set("config-version", 1); + readConfig(ScissorsConfig.class, null); + } + + protected static void logError(String s) + { + Bukkit.getLogger().severe(s); + } + + protected static void fatal(String s) + { + throw new RuntimeException("Fatal scissors.yml config error: " + s); + } + + public static void registerCommands() + { + for (Map.Entry entry : commands.entrySet()) + { + MinecraftServer.getServer().server.getCommandMap().register(entry.getKey(), "Scissors", 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); + } + } + } + } + saveConfig(); + } + + static void saveConfig() + { + try + { + config.save(CONFIG_FILE); + } + catch (IOException ex) + { + Bukkit.getLogger().log(Level.SEVERE, "Could not save " + CONFIG_FILE, ex); + } + } + + 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, def); + } + + private static int getInt(String path, int def) + { + config.addDefault(path, def); + return config.getInt(path, config.getInt(path)); + } + + private static List getList(String path, T def) + { + config.addDefault(path, def); + return 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)); + } +} diff --git a/src/main/java/net/minecraft/server/Main.java b/src/main/java/net/minecraft/server/Main.java index 6a00ee7f69bf44c5a9a329df26ac5640b368283b..3fed82a0b271234065767ec37c9ddd0a9f39da27 100644 --- a/src/main/java/net/minecraft/server/Main.java +++ b/src/main/java/net/minecraft/server/Main.java @@ -106,6 +106,7 @@ public class Main { org.bukkit.configuration.file.YamlConfiguration bukkitConfiguration = loadConfigFile((File) optionset.valueOf("bukkit-settings")); org.bukkit.configuration.file.YamlConfiguration spigotConfiguration = loadConfigFile((File) optionset.valueOf("spigot-settings")); org.bukkit.configuration.file.YamlConfiguration paperConfiguration = loadConfigFile((File) optionset.valueOf("paper-settings")); + org.bukkit.configuration.file.YamlConfiguration scissorsConfiguration = loadConfigFile((File) optionset.valueOf("scissors-settings")); // Scissors // Paper end Path path1 = Paths.get("eula.txt"); diff --git a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java index b6ee0e709b0f0529b99567bc9b8fb6bfd99bcd8e..4cd18a681dedea26b98002902a3c3b1f47966887 100644 --- a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java +++ b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java @@ -234,7 +234,15 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface io.papermc.paper.util.ObfHelper.INSTANCE.getClass(); // load mappings for stacktrace deobf and etc. io.papermc.paper.brigadier.PaperBrigadierProviderImpl.INSTANCE.getClass(); // init PaperBrigadierProvider // Paper end - + // Scissors start + try { + com.github.atlasmediagroup.scissors.ScissorsConfig.init((java.io.File) options.valueOf("scissors-settings")); + } catch (Exception e) { + DedicatedServer.LOGGER.error("Unable to load server configuration", e); + return false; + } + com.github.atlasmediagroup.scissors.ScissorsConfig.registerCommands(); + // Scissors end this.setPvpAllowed(dedicatedserverproperties.pvp); this.setFlightAllowed(dedicatedserverproperties.allowFlight); this.setResourcePack(dedicatedserverproperties.resourcePack, this.getPackHash()); diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java index cc797b45674163b5913e20031d110796d78b928b..bb5d6e5405c1781404bfd3d2af9c93026f9c86f0 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java @@ -924,6 +924,7 @@ public final class CraftServer implements Server { org.spigotmc.SpigotConfig.init((File) console.options.valueOf("spigot-settings")); // Spigot com.destroystokyo.paper.PaperConfig.init((File) console.options.valueOf("paper-settings")); // Paper + com.github.atlasmediagroup.scissors.ScissorsConfig.init(((File) console.options.valueOf("scissors-settings"))); // Scissors 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)) @@ -979,6 +980,7 @@ public final class CraftServer implements Server { this.reloadData(); org.spigotmc.SpigotConfig.registerCommands(); // Spigot com.destroystokyo.paper.PaperConfig.registerCommands(); // Paper + com.github.atlasmediagroup.scissors.ScissorsConfig.registerCommands(); // Scissors this.overrideAllCommandBlockCommands = this.commandsConfiguration.getStringList("command-block-overrides").contains("*"); this.ignoreVanillaPermissions = this.commandsConfiguration.getBoolean("ignore-vanilla-permissions"); @@ -2566,6 +2568,12 @@ public final class CraftServer implements Server { return com.destroystokyo.paper.PaperConfig.config; } + @Override + public YamlConfiguration getScissorsConfig() + { + return com.github.atlasmediagroup.scissors.ScissorsConfig.config; + } + @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 d033caf5dabbd2a240286c5623b3d287ae5cbdd9..facfcc3f478a21240fa2938c94de7dc599eeafd3 100644 --- a/src/main/java/org/bukkit/craftbukkit/Main.java +++ b/src/main/java/org/bukkit/craftbukkit/Main.java @@ -160,6 +160,14 @@ public class Main { .defaultsTo(new File[] {}) .describedAs("Jar file"); // Paper end + + // Scissors start + acceptsAll(asList("scissors", "scissors-settings"), "File for scissors settings") + .withRequiredArg() + .ofType(File.class) + .defaultsTo(new File("scissors.yml")) + .describedAs("Yml file"); + // Scissors end } };