mirror of
https://github.com/AtlasMediaGroup/Scissors.git
synced 2024-11-01 04:37:09 +00:00
730 lines
32 KiB
Diff
730 lines
32 KiB
Diff
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
From: Allink <arclicious@vivaldi.net>
|
|
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 c07eb451a576811a39021f6f97103c77488fd001..b91d3ddf586a103770d63cdcf7ec590f95ee388f 100644
|
|
--- a/src/main/java/co/aikar/timings/TimingsExport.java
|
|
+++ b/src/main/java/co/aikar/timings/TimingsExport.java
|
|
@@ -25,6 +25,7 @@ package co.aikar.timings;
|
|
|
|
import com.google.common.collect.Sets;
|
|
import io.papermc.paper.adventure.PaperAdventure;
|
|
+import me.totalfreedom.scissors.ScissorsConfig;
|
|
import net.kyori.adventure.text.event.ClickEvent;
|
|
import net.kyori.adventure.text.format.NamedTextColor;
|
|
import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer;
|
|
@@ -242,7 +243,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/PositionUtility.java b/src/main/java/me/totalfreedom/scissors/PositionUtility.java
|
|
index 9e33ad84e50c7e2491aa883f905323f3ad2b070c..b085035794c91074205cb6994c73343283d274d5 100644
|
|
--- a/src/main/java/me/totalfreedom/scissors/PositionUtility.java
|
|
+++ b/src/main/java/me/totalfreedom/scissors/PositionUtility.java
|
|
@@ -8,7 +8,7 @@ import net.minecraft.world.phys.Vec3;
|
|
|
|
public class PositionUtility
|
|
{
|
|
- public static Vec3 getValidVec3(double x, double y, double z, Entity entity)
|
|
+ /*public static Vec3 getValidVec3(double x, double y, double z, Entity entity)
|
|
{
|
|
final Level level = entity.level;
|
|
|
|
@@ -37,7 +37,7 @@ public class PositionUtility
|
|
{ // If we throw some sort of exception due to the position being crazy, catch it
|
|
return new Vec3(0, 0, 0);
|
|
}
|
|
- }
|
|
+ }*/
|
|
|
|
public static Vec3 getValidVec3FromBlockPos(BlockPos blockPos, Entity entity)
|
|
{
|
|
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 cdbf10339a8e8846a8c364de483a0ccd95cd225a..3863684cdf3d613c39935e9f46fd4e7066f95eab 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 5c347c8ff0eb3eb500a7bd49d61fb19925d780ce..2549ff41d1d63ba0dbdaee3e526a44f953945b6d 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;
|
|
@@ -2377,6 +2378,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
|
|
}
|
|
@@ -2609,11 +2616,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 73e9be92c44ca7ae72d532e6f23d1f1c3504b35d..70f3448929acdb44d18187357402c5fd22aed189 100644
|
|
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
|
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
|
@@ -956,6 +956,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
|
|
@@ -987,6 +988,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");
|
|
|
|
@@ -2741,6 +2743,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 8bd5c9cd539fea052881df58ac9f5b5204391ab3..c5495e2f74d0009fa99c9c190dab1910df267af3 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
|