From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: NONPLAYT <76615486+NONPLAYT@users.noreply.github.com> Date: Sat, 15 Mar 2025 22:01:08 +0300 Subject: [PATCH] Command block parse results caching diff --git a/net/minecraft/world/level/BaseCommandBlock.java b/net/minecraft/world/level/BaseCommandBlock.java index 390d9cbe8050b90e4bd9327cf4d80571fbd8ece4..1398fb38edfc975dc716a5147159e9da0443ca83 100644 --- a/net/minecraft/world/level/BaseCommandBlock.java +++ b/net/minecraft/world/level/BaseCommandBlock.java @@ -35,6 +35,10 @@ public abstract class BaseCommandBlock { private String command = ""; @Nullable private Component customName; + // DivineMC start - Caching command block parse results + private String lastExecutedCommand; + private com.mojang.brigadier.ParseResults parseResultsCache; + // DivineMC end - Caching command block parse results // CraftBukkit start protected abstract org.bukkit.command.CommandSender getBukkitSender(CommandSourceStack wrapper); // CraftBukkit end @@ -115,13 +119,41 @@ public abstract class BaseCommandBlock { this.successCount++; } }); - // Paper start - ServerCommandEvent - org.bukkit.event.server.ServerCommandEvent event = new org.bukkit.event.server.ServerCommandEvent(commandSourceStack.getBukkitSender(), net.minecraft.commands.Commands.trimOptionalPrefix(this.command)); - if (!event.callEvent()) { - return true; + // DivineMC start - Command block parse results caching + if (org.bxteam.divinemc.config.DivineConfig.PerformanceCategory.commandBlockParseResultsCaching) { + String commandCache = this.command; + // noinspection DuplicatedCode + com.google.common.base.Joiner joiner = com.google.common.base.Joiner.on(" "); + + if (commandCache.startsWith("/")) { + commandCache = commandCache.substring(1); + } + + org.bukkit.event.server.ServerCommandEvent event = new org.bukkit.event.server.ServerCommandEvent(commandSourceStack.getBukkitSender(), commandCache); + org.bukkit.Bukkit.getPluginManager().callEvent(event); + if (!event.isCancelled()) { + commandCache = event.getCommand(); + String[] args = commandCache.split(" "); + + if (args.length != 0) { + String newCommand = joiner.join(args); + if (!newCommand.equals(lastExecutedCommand) || parseResultsCache == null) { + MinecraftServer.LOGGER.info("Recompiling parse results cache for command block at ({}, {}, {})", this.getPosition().x, this.getPosition().y, this.getPosition().z); + this.cache(server.getCommands().getDispatcher(), commandSourceStack, newCommand); + } + server.getCommands().performCommand(parseResultsCache, newCommand); + } + } + } else { + // Paper start - ServerCommandEvent + org.bukkit.event.server.ServerCommandEvent event = new org.bukkit.event.server.ServerCommandEvent(commandSourceStack.getBukkitSender(), net.minecraft.commands.Commands.trimOptionalPrefix(this.command)); + if (!event.callEvent()) { + return true; + } + server.getCommands().performPrefixedCommand(commandSourceStack, event.getCommand()); + // Paper end - ServerCommandEvent } - server.getCommands().performPrefixedCommand(commandSourceStack, event.getCommand()); - // Paper end - ServerCommandEvent + // DivineMC end - Command block parse results caching } } catch (Throwable var8) { CrashReport crashReport = CrashReport.forThrowable(var8, "Executing command block"); @@ -142,6 +174,13 @@ public abstract class BaseCommandBlock { } } + // DivineMC start - Command block parse results caching + private void cache(com.mojang.brigadier.CommandDispatcher dispatcher, CommandSourceStack commandSourceStack, String commandCache) { + this.parseResultsCache = dispatcher.parse(commandCache, commandSourceStack); + this.lastExecutedCommand = commandCache; + } + // DivineMC end - Command block parse results caching + public BaseCommandBlock.CloseableCommandBlockSource createSource() { // Paper - public, remove nullable return new BaseCommandBlock.CloseableCommandBlockSource(this.trackOutput); // Paper - add back source when output disabled }