mirror of
https://github.com/AtlasMediaGroup/Scissors.git
synced 2024-11-16 18:46:12 +00:00
Telesphoreo
f8e15546d6
These were all related to the Scissors config, and it's easier to fixup the patch and add stuff specifically related to the config file rather than having it spread across multiple patches
700 lines
30 KiB
Diff
700 lines
30 KiB
Diff
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
From: Telesphoreo <me@telesphoreo.me>
|
|
Date: Wed, 15 Mar 2023 23:13:56 -0500
|
|
Subject: [PATCH] Add Scissors configuration file & command
|
|
|
|
|
|
diff --git a/src/main/java/co/aikar/timings/TimingsExport.java b/src/main/java/co/aikar/timings/TimingsExport.java
|
|
index 06bff37e4c1fddd3be6343049a66787c63fb420c..f6667c193e1c52dd954acb90d09748251976dd42 100644
|
|
--- a/src/main/java/co/aikar/timings/TimingsExport.java
|
|
+++ b/src/main/java/co/aikar/timings/TimingsExport.java
|
|
@@ -241,7 +241,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/me/totalfreedom/scissors/ScissorsCommand.java b/src/main/java/me/totalfreedom/scissors/ScissorsCommand.java
|
|
new file mode 100644
|
|
index 0000000000000000000000000000000000000000..797677d892d83cf54d9a60af1e277b67ed3d6e95
|
|
--- /dev/null
|
|
+++ b/src/main/java/me/totalfreedom/scissors/ScissorsCommand.java
|
|
@@ -0,0 +1,150 @@
|
|
+package me.totalfreedom.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<String> SUBCOMMANDS = ImmutableSet.<String>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<String> 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<String> getListMatchingLast(CommandSender sender, String[] strings, Collection<?> collection)
|
|
+ {
|
|
+ String last = strings[strings.length - 1];
|
|
+ ArrayList<String> 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<String> 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/me/totalfreedom/scissors/ScissorsConfig.java b/src/main/java/me/totalfreedom/scissors/ScissorsConfig.java
|
|
new file mode 100644
|
|
index 0000000000000000000000000000000000000000..9f2a51fddb692f5152c32dcbe1f5a6ba150634e4
|
|
--- /dev/null
|
|
+++ b/src/main/java/me/totalfreedom/scissors/ScissorsConfig.java
|
|
@@ -0,0 +1,213 @@
|
|
+package me.totalfreedom.scissors;
|
|
+
|
|
+
|
|
+import com.google.common.base.Throwables;
|
|
+import net.minecraft.server.MinecraftServer;
|
|
+import net.minecraft.server.dedicated.DedicatedServer;
|
|
+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.nio.file.Files;
|
|
+import java.nio.file.Path;
|
|
+import java.util.HashMap;
|
|
+import java.util.List;
|
|
+import java.util.Map;
|
|
+import java.util.logging.Level;
|
|
+import java.util.regex.Pattern;
|
|
+
|
|
+// TODO - Migrate to new format
|
|
+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.19.4/\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<String, Command> commands;
|
|
+ private static File CONFIG_FILE;
|
|
+
|
|
+ public static void init(File configFile)
|
|
+ {
|
|
+ final File configFolder = (File) DedicatedServer.getServer().options.valueOf("scissors-settings" + "-directory");
|
|
+ final Path configFolderPath = configFolder.toPath();
|
|
+ final Path oldConfigFilePath = configFile.toPath();
|
|
+ final Path newConfigFilePath = configFolderPath.resolve(configFile.toPath());
|
|
+
|
|
+ if (configFile.exists())
|
|
+ {
|
|
+ try
|
|
+ {
|
|
+ Files.move(oldConfigFilePath, newConfigFilePath);
|
|
+ }
|
|
+ catch (IOException e)
|
|
+ {
|
|
+ throw new RuntimeException("Error migrating configuration file to new directory!", e);
|
|
+ }
|
|
+ }
|
|
+
|
|
+ CONFIG_FILE = newConfigFilePath.toFile();
|
|
+ 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", 3);
|
|
+ set("config-version", 3);
|
|
+ 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<String, Command> 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);
|
|
+ }
|
|
+ }
|
|
+
|
|
+ public static boolean runCommandsInBooks = false;
|
|
+
|
|
+ private static void runCommandsInBooks()
|
|
+ {
|
|
+ runCommandsInBooks = getBoolean("runCommandsInBooks", false);
|
|
+ }
|
|
+
|
|
+ // people still may want them to bypass permissions for warps
|
|
+ public static boolean commandSignsBypassPermissions = false;
|
|
+ private static void commandSignsBypassPermissions()
|
|
+ {
|
|
+ commandSignsBypassPermissions = getBoolean("commandSignsBypassPermissions", false);
|
|
+ }
|
|
+
|
|
+ public static boolean chatSignaturesEnabled = true;
|
|
+ private static void chatSignaturesEnabled()
|
|
+ {
|
|
+ chatSignaturesEnabled = getBoolean("chatSignaturesEnabled", true);
|
|
+ }
|
|
+
|
|
+ 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 <T> 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/network/chat/OutgoingChatMessage.java b/src/main/java/net/minecraft/network/chat/OutgoingChatMessage.java
|
|
index 74cf1c043beef03cfd5adf481414a5ee78bef2a6..182f68359a7a8c0b331acd103ed3952ea3c33b93 100644
|
|
--- a/src/main/java/net/minecraft/network/chat/OutgoingChatMessage.java
|
|
+++ b/src/main/java/net/minecraft/network/chat/OutgoingChatMessage.java
|
|
@@ -1,5 +1,6 @@
|
|
package net.minecraft.network.chat;
|
|
|
|
+import me.totalfreedom.scissors.ScissorsConfig;
|
|
import net.minecraft.server.level.ServerPlayer;
|
|
|
|
public interface OutgoingChatMessage {
|
|
@@ -42,12 +43,16 @@ public interface OutgoingChatMessage {
|
|
}
|
|
public void sendToPlayer(ServerPlayer sender, boolean filterMaskEnabled, ChatType.Bound params, @javax.annotation.Nullable Component unsigned) {
|
|
// Paper end
|
|
+ // Scissors start - Add configuration option to disable chat signatures
|
|
PlayerChatMessage playerChatMessage = this.message.filter(filterMaskEnabled);
|
|
playerChatMessage = unsigned != null ? playerChatMessage.withUnsignedContent(unsigned) : playerChatMessage; // Paper
|
|
- if (!playerChatMessage.isFullyFiltered()) {
|
|
+ if (!playerChatMessage.isFullyFiltered() && /* Scissors */ ScissorsConfig.chatSignaturesEnabled) {
|
|
sender.connection.sendPlayerChatMessage(playerChatMessage, params);
|
|
+ return;
|
|
}
|
|
|
|
+ sender.connection.sendDisguisedChatMessage(playerChatMessage.decoratedContent(), params);
|
|
+ // Scissors end
|
|
}
|
|
}
|
|
}
|
|
diff --git a/src/main/java/net/minecraft/server/Main.java b/src/main/java/net/minecraft/server/Main.java
|
|
index c6fa6bcd66d61359124a8426b919493c6ec43f06..0b44304fa7f6c2856f9dd18ffc1239058c1de0a8 100644
|
|
--- a/src/main/java/net/minecraft/server/Main.java
|
|
+++ b/src/main/java/net/minecraft/server/Main.java
|
|
@@ -136,6 +136,7 @@ public class Main {
|
|
// Paper start - load config files for access below if needed
|
|
org.bukkit.configuration.file.YamlConfiguration bukkitConfiguration = io.papermc.paper.configuration.PaperConfigurations.loadLegacyConfigFile((File) optionset.valueOf("bukkit-settings"));
|
|
org.bukkit.configuration.file.YamlConfiguration spigotConfiguration = io.papermc.paper.configuration.PaperConfigurations.loadLegacyConfigFile((File) optionset.valueOf("spigot-settings"));
|
|
+ org.bukkit.configuration.file.YamlConfiguration scissorsConfiguration = io.papermc.paper.configuration.PaperConfigurations.loadLegacyConfigFile((File) optionset.valueOf("scissors-settings")); // Scissors - TODO Change this
|
|
// Paper end
|
|
|
|
if (optionset.has("initSettings")) { // CraftBukkit
|
|
diff --git a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java
|
|
index a7e133f3495e9132a5fdae2c24f225e7b026295a..16f0daad2456ce23f8d73389f62aac9f10235100 100644
|
|
--- a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java
|
|
+++ b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java
|
|
@@ -222,6 +222,16 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface
|
|
io.papermc.paper.brigadier.PaperBrigadierProviderImpl.INSTANCE.getClass(); // init PaperBrigadierProvider
|
|
// Paper end
|
|
|
|
+ // Scissors start
|
|
+ try {
|
|
+ me.totalfreedom.scissors.ScissorsConfig.init((java.io.File) options.valueOf("scissors-settings"));
|
|
+ } catch (Exception e) {
|
|
+ DedicatedServer.LOGGER.error("Unable to load server configuration", e);
|
|
+ return false;
|
|
+ }
|
|
+ me.totalfreedom.scissors.ScissorsConfig.registerCommands();
|
|
+ // Scissors end
|
|
+
|
|
this.setPvpAllowed(dedicatedserverproperties.pvp);
|
|
this.setFlightAllowed(dedicatedserverproperties.allowFlight);
|
|
this.setMotd(dedicatedserverproperties.motd);
|
|
diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
|
index c15c5855dca11cd69f316c42783d32b800a93bd7..1ec1cc90c7e698036f6ae446f0dab97f03ebb064 100644
|
|
--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
|
+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
|
@@ -1,5 +1,6 @@
|
|
package net.minecraft.server.network;
|
|
|
|
+import me.totalfreedom.scissors.ScissorsConfig;
|
|
import me.totalfreedom.scissors.event.player.SpectatorTeleportEvent;
|
|
import com.google.common.collect.Lists;
|
|
import com.google.common.primitives.Floats;
|
|
@@ -2360,6 +2361,12 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic
|
|
Optional<LastSeenMessages> optional = this.lastSeenMessages.applyUpdate(acknowledgment);
|
|
|
|
if (optional.isEmpty()) {
|
|
+ // Scissors start - Add configuration option to disable chat signatures
|
|
+ if (!ScissorsConfig.chatSignaturesEnabled)
|
|
+ {
|
|
+ return optional;
|
|
+ }
|
|
+ // Scissors end
|
|
ServerGamePacketListenerImpl.LOGGER.warn("Failed to validate message acknowledgements from {}", this.player.getName().getString());
|
|
this.disconnect(ServerGamePacketListenerImpl.CHAT_VALIDATION_FAILED, org.bukkit.event.player.PlayerKickEvent.Cause.CHAT_VALIDATION_FAILED); // Paper - kick event causes
|
|
}
|
|
@@ -2592,11 +2599,16 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic
|
|
@Override
|
|
public void handleChatAck(ServerboundChatAckPacket packet) {
|
|
LastSeenMessagesValidator lastseenmessagesvalidator = this.lastSeenMessages;
|
|
-
|
|
- synchronized (this.lastSeenMessages) {
|
|
if (!this.lastSeenMessages.applyOffset(packet.offset())) {
|
|
- ServerGamePacketListenerImpl.LOGGER.warn("Failed to validate message acknowledgements from {}", this.player.getName().getString());
|
|
- this.disconnect(ServerGamePacketListenerImpl.CHAT_VALIDATION_FAILED, org.bukkit.event.player.PlayerKickEvent.Cause.CHAT_VALIDATION_FAILED); // Paper - kick event causes
|
|
+ synchronized (this.lastSeenMessages) {
|
|
+ // Scissors start - Add configuration option to disable chat signatures
|
|
+ if (!ScissorsConfig.chatSignaturesEnabled)
|
|
+ {
|
|
+ return;
|
|
+ }
|
|
+ // Scissors end
|
|
+ ServerGamePacketListenerImpl.LOGGER.warn("Failed to validate message acknowledgements from {}", this.player.getName().getString());
|
|
+ this.disconnect(ServerGamePacketListenerImpl.CHAT_VALIDATION_FAILED, org.bukkit.event.player.PlayerKickEvent.Cause.CHAT_VALIDATION_FAILED); // Paper - kick event causes
|
|
}
|
|
|
|
}
|
|
diff --git a/src/main/java/net/minecraft/world/item/WrittenBookItem.java b/src/main/java/net/minecraft/world/item/WrittenBookItem.java
|
|
index 31911c09fe15753ae32fa39417bdc9e9de552a88..97ce45c6e44b1400b8d60b52397617038f8fe911 100644
|
|
--- a/src/main/java/net/minecraft/world/item/WrittenBookItem.java
|
|
+++ b/src/main/java/net/minecraft/world/item/WrittenBookItem.java
|
|
@@ -2,6 +2,8 @@ package net.minecraft.world.item;
|
|
|
|
import java.util.List;
|
|
import javax.annotation.Nullable;
|
|
+
|
|
+import me.totalfreedom.scissors.ScissorsConfig;
|
|
import net.minecraft.ChatFormatting;
|
|
import net.minecraft.commands.CommandSourceStack;
|
|
import net.minecraft.core.BlockPos;
|
|
@@ -9,8 +11,7 @@ import net.minecraft.nbt.CompoundTag;
|
|
import net.minecraft.nbt.ListTag;
|
|
import net.minecraft.nbt.StringTag;
|
|
import net.minecraft.nbt.Tag;
|
|
-import net.minecraft.network.chat.Component;
|
|
-import net.minecraft.network.chat.ComponentUtils;
|
|
+import net.minecraft.network.chat.*;
|
|
import net.minecraft.stats.Stats;
|
|
import net.minecraft.util.StringUtil;
|
|
import net.minecraft.world.InteractionHand;
|
|
@@ -111,8 +112,7 @@ public class WrittenBookItem extends Item {
|
|
|
|
public static boolean resolveBookComponents(ItemStack book, @Nullable CommandSourceStack commandSource, @Nullable Player player) {
|
|
CompoundTag compoundTag = book.getTag();
|
|
- if (io.papermc.paper.configuration.GlobalConfiguration.get().itemValidation.resolveSelectorsInBooks && compoundTag != null && !compoundTag.getBoolean("resolved")) { // Paper
|
|
- compoundTag.putBoolean("resolved", true);
|
|
+ if (compoundTag != null) { // Paper
|
|
if (!makeSureTagIsValid(compoundTag)) {
|
|
return false;
|
|
} else {
|
|
@@ -161,8 +161,42 @@ public class WrittenBookItem extends Item {
|
|
component2 = Component.literal(text);
|
|
}
|
|
|
|
- return Component.Serializer.toJson(component2);
|
|
+ return Component.Serializer.toJson(!ScissorsConfig.runCommandsInBooks ? sanitize(component2, 0) : component2); // Scissors - Allow server owners to disable run command in books
|
|
+ }
|
|
+
|
|
+ // Scissors start - Allow server owners to disable run command in books
|
|
+ public static Component sanitize(Component component, int depth)
|
|
+ {
|
|
+ if (depth > 128)
|
|
+ {
|
|
+ return Component.nullToEmpty("Sanitization function depth limit exceeded");
|
|
+ }
|
|
+
|
|
+ MutableComponent component2 = component.copy();
|
|
+
|
|
+ final Style style = component2.getStyle();
|
|
+ final ClickEvent clickEvent = style.getClickEvent();
|
|
+
|
|
+ if (clickEvent != null && clickEvent.getAction().equals(ClickEvent.Action.RUN_COMMAND))
|
|
+ {
|
|
+ final String clickEventValue = clickEvent.getValue();
|
|
+
|
|
+ component2 = component2.copy().setStyle(style
|
|
+ .withClickEvent(null)
|
|
+ .withHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, Component.nullToEmpty("Would've " + (clickEventValue.startsWith("/") ? "ran" : "said") + ": " + clickEvent.getValue())))
|
|
+ );
|
|
+ }
|
|
+
|
|
+ final List<Component> processedExtra = component2.getSiblings()
|
|
+ .stream()
|
|
+ .map(comp -> sanitize(comp, depth + 1))
|
|
+ .toList();
|
|
+ component2.getSiblings().clear();
|
|
+ component2.getSiblings().addAll(processedExtra);
|
|
+
|
|
+ return component2;
|
|
}
|
|
+ // Scissors end
|
|
|
|
@Override
|
|
public boolean isFoil(ItemStack stack) {
|
|
diff --git a/src/main/java/net/minecraft/world/level/block/entity/SignBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/SignBlockEntity.java
|
|
index 4da4edae517a0efec6e03a719ec47b700509dab1..837b20be528bc33f62c0c675d90afebd0a781b6f 100644
|
|
--- a/src/main/java/net/minecraft/world/level/block/entity/SignBlockEntity.java
|
|
+++ b/src/main/java/net/minecraft/world/level/block/entity/SignBlockEntity.java
|
|
@@ -4,8 +4,11 @@ import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
|
import java.util.UUID;
|
|
import java.util.function.Function;
|
|
import javax.annotation.Nullable;
|
|
+
|
|
+import me.totalfreedom.scissors.ScissorsConfig;
|
|
import net.minecraft.commands.CommandSource;
|
|
import net.minecraft.commands.CommandSourceStack;
|
|
+import net.minecraft.commands.Commands;
|
|
import net.minecraft.core.BlockPos;
|
|
import net.minecraft.nbt.CompoundTag;
|
|
import net.minecraft.network.chat.ClickEvent;
|
|
@@ -15,6 +18,7 @@ import net.minecraft.network.chat.ComponentUtils;
|
|
import net.minecraft.network.chat.MutableComponent;
|
|
import net.minecraft.network.chat.Style;
|
|
import net.minecraft.network.protocol.game.ClientboundBlockEntityDataPacket;
|
|
+import net.minecraft.server.MinecraftServer;
|
|
import net.minecraft.server.level.ServerLevel;
|
|
import net.minecraft.server.level.ServerPlayer;
|
|
import net.minecraft.util.FormattedCharSequence;
|
|
@@ -24,6 +28,8 @@ import net.minecraft.world.item.DyeColor;
|
|
import net.minecraft.world.level.block.state.BlockState;
|
|
import net.minecraft.world.phys.Vec2;
|
|
import net.minecraft.world.phys.Vec3;
|
|
+import org.bukkit.craftbukkit.CraftServer;
|
|
+import org.bukkit.craftbukkit.entity.CraftPlayer;
|
|
|
|
public class SignBlockEntity extends BlockEntity implements CommandSource { // CraftBukkit - implements
|
|
private static final boolean CONVERT_LEGACY_SIGNS = Boolean.getBoolean("convertLegacySigns"); // Paper
|
|
@@ -272,6 +278,21 @@ public class SignBlockEntity extends BlockEntity implements CommandSource { // C
|
|
}
|
|
player.getServer().getCommands().performPrefixedCommand(this.createCommandSourceStack(((org.bukkit.craftbukkit.entity.CraftPlayer) event.getPlayer()).getHandle()), event.getMessage());
|
|
// Paper end
|
|
+ // Scissors start - Add optional permissions to command signs
|
|
+ final MinecraftServer vanillaServer = player.getServer();
|
|
+ final CraftServer craftServer = vanillaServer.server;
|
|
+ final CraftPlayer craftPlayer = player.getBukkitEntity();
|
|
+ final Commands commands = vanillaServer.getCommands();
|
|
+
|
|
+ if (ScissorsConfig.commandSignsBypassPermissions)
|
|
+ {
|
|
+ commands.performPrefixedCommand(this.createCommandSourceStack(((org.bukkit.craftbukkit.entity.CraftPlayer) event.getPlayer()).getHandle()), event.getMessage());
|
|
+ }
|
|
+ else
|
|
+ {
|
|
+ craftServer.dispatchCommand(craftPlayer, command.substring(1));
|
|
+ }
|
|
+ // Scissors end
|
|
}
|
|
}
|
|
|
|
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
|
index ccc578bf2d7edfe866a5892978ce9e116787c4b4..4cb94d9e1f4ec56e01289b25c952c00df25f71a1 100644
|
|
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
|
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
|
@@ -955,6 +955,7 @@ public final class CraftServer implements Server {
|
|
}
|
|
|
|
org.spigotmc.SpigotConfig.init((File) console.options.valueOf("spigot-settings")); // Spigot
|
|
+ me.totalfreedom.scissors.ScissorsConfig.init(((File) console.options.valueOf("scissors-settings"))); // Scissors
|
|
this.console.paperConfigurations.reloadConfigs(this.console);
|
|
for (ServerLevel world : this.console.getAllLevels()) {
|
|
// world.serverLevelData.setDifficulty(config.difficulty); // Paper - per level difficulty
|
|
@@ -986,6 +987,7 @@ public final class CraftServer implements Server {
|
|
this.reloadData();
|
|
org.spigotmc.SpigotConfig.registerCommands(); // Spigot
|
|
io.papermc.paper.command.PaperCommands.registerCommands(this.console); // Paper
|
|
+ me.totalfreedom.scissors.ScissorsConfig.registerCommands(); // Scissors
|
|
this.overrideAllCommandBlockCommands = this.commandsConfiguration.getStringList("command-block-overrides").contains("*");
|
|
this.ignoreVanillaPermissions = this.commandsConfiguration.getBoolean("ignore-vanilla-permissions");
|
|
|
|
@@ -2744,6 +2746,12 @@ public final class CraftServer implements Server {
|
|
return CraftServer.this.console.paperConfigurations.createLegacyObject(CraftServer.this.console);
|
|
}
|
|
|
|
+ @Override
|
|
+ public YamlConfiguration getScissorsConfig()
|
|
+ {
|
|
+ return me.totalfreedom.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 cd87e192ff09e77538521bbde38416c52daa22b8..1bc7a99a457d0dd8befecfcd11da39a6b76291f1 100644
|
|
--- a/src/main/java/org/bukkit/craftbukkit/Main.java
|
|
+++ b/src/main/java/org/bukkit/craftbukkit/Main.java
|
|
@@ -180,9 +180,27 @@ public class Main {
|
|
.defaultsTo("Unknown Server")
|
|
.describedAs("Name");
|
|
// Paper end
|
|
+
|
|
+ // Scissors start
|
|
+ acceptsAll(asList("scissors-dir", "scissors-settings-directory"), "Directory for Scissors settings")
|
|
+ .withRequiredArg()
|
|
+ .ofType(File.class)
|
|
+ .defaultsTo(new File(io.papermc.paper.configuration.PaperConfigurations.CONFIG_DIR))
|
|
+ .describedAs("Config directory");
|
|
+ // Scissors end
|
|
+
|
|
+ // Scissors start
|
|
+ acceptsAll(asList("scissors", "scissors-settings"), "File for Scissors settings")
|
|
+ .withRequiredArg()
|
|
+ .ofType(File.class)
|
|
+ .defaultsTo(new File("scissors.yml"))
|
|
+ .describedAs("YAML file");
|
|
+ // Scissors end
|
|
}
|
|
};
|
|
|
|
+
|
|
+
|
|
OptionSet options = null;
|
|
|
|
// Paper start - preload logger classes to avoid plugins mixing versions
|