--- a/net/minecraft/server/ServerFunctionManager.java
+++ b/net/minecraft/server/ServerFunctionManager.java
@@ -7,7 +7,9 @@
 import com.mojang.brigadier.exceptions.CommandSyntaxException;
 import java.util.Collection;
 import java.util.Deque;
+import java.util.Iterator;
 import java.util.List;
+import java.util.Objects;
 import java.util.Optional;
 import java.util.function.IntConsumer;
 import javax.annotation.Nullable;
@@ -17,9 +19,11 @@
 import net.minecraft.nbt.CompoundTag;
 import net.minecraft.network.chat.Component;
 import net.minecraft.resources.ResourceLocation;
+import net.minecraft.util.profiling.ProfilerFiller;
 import net.minecraft.world.level.GameRules;
 
 public class ServerFunctionManager {
+
     private static final Component NO_RECURSIVE_TRACES = Component.translatable("commands.debug.function.noRecursion");
     private static final ResourceLocation TICK_FUNCTION_TAG = new ResourceLocation("tick");
     private static final ResourceLocation LOAD_FUNCTION_TAG = new ResourceLocation("load");
@@ -41,24 +45,31 @@
     }
 
     public CommandDispatcher<CommandSourceStack> getDispatcher() {
-        return this.server.getCommands().getDispatcher();
+        return this.server.vanillaCommandDispatcher.getDispatcher(); // CraftBukkit
     }
 
     public void tick() {
         if (this.postReload) {
             this.postReload = false;
-            Collection<CommandFunction> collection = this.library.getTag(LOAD_FUNCTION_TAG);
-            this.executeTagFunctions(collection, LOAD_FUNCTION_TAG);
+            Collection<CommandFunction> collection = this.library.getTag(ServerFunctionManager.LOAD_FUNCTION_TAG);
+
+            this.executeTagFunctions(collection, ServerFunctionManager.LOAD_FUNCTION_TAG);
         }
 
-        this.executeTagFunctions(this.ticking, TICK_FUNCTION_TAG);
+        this.executeTagFunctions(this.ticking, ServerFunctionManager.TICK_FUNCTION_TAG);
     }
 
     private void executeTagFunctions(Collection<CommandFunction> functions, ResourceLocation label) {
-        this.server.getProfiler().push(label::toString);
+        ProfilerFiller gameprofilerfiller = this.server.getProfiler();
 
-        for(CommandFunction commandFunction : functions) {
-            this.execute(commandFunction, this.getGameLoopSender());
+        Objects.requireNonNull(label);
+        gameprofilerfiller.push(label::toString);
+        Iterator iterator = functions.iterator();
+
+        while (iterator.hasNext()) {
+            CommandFunction customfunction = (CommandFunction) iterator.next();
+
+            this.execute(customfunction, this.getGameLoopSender());
         }
 
         this.server.getProfiler().pop();
@@ -66,32 +77,34 @@
 
     public int execute(CommandFunction function, CommandSourceStack source) {
         try {
-            return this.execute(function, source, (ServerFunctionManager.TraceCallbacks)null, (CompoundTag)null);
-        } catch (FunctionInstantiationException var4) {
+            return this.execute(function, source, (ServerFunctionManager.TraceCallbacks) null, (CompoundTag) null);
+        } catch (FunctionInstantiationException functioninstantiationexception) {
             return 0;
         }
     }
 
     public int execute(CommandFunction function, CommandSourceStack source, @Nullable ServerFunctionManager.TraceCallbacks tracer, @Nullable CompoundTag arguments) throws FunctionInstantiationException {
-        CommandFunction commandFunction = function.instantiate(arguments, this.getDispatcher(), source);
+        CommandFunction customfunction1 = function.instantiate(arguments, this.getDispatcher(), source);
+
         if (this.context != null) {
             if (tracer != null) {
-                this.context.reportError(NO_RECURSIVE_TRACES.getString());
+                this.context.reportError(ServerFunctionManager.NO_RECURSIVE_TRACES.getString());
                 return 0;
             } else {
-                this.context.delayFunctionCall(commandFunction, source);
+                this.context.delayFunctionCall(customfunction1, source);
                 return 0;
             }
         } else {
-            int var6;
-            try {
+            int i;
+
+            try (co.aikar.timings.Timing timing = function.getTiming().startTiming()) { // Paper
                 this.context = new ServerFunctionManager.ExecutionContext(tracer);
-                var6 = this.context.runTopCommand(commandFunction, source);
+                i = this.context.runTopCommand(customfunction1, source);
             } finally {
                 this.context = null;
             }
 
-            return var6;
+            return i;
         }
     }
 
@@ -101,7 +114,7 @@
     }
 
     private void postReload(ServerFunctionLibrary loader) {
-        this.ticking = ImmutableList.copyOf(loader.getTag(TICK_FUNCTION_TAG));
+        this.ticking = ImmutableList.copyOf(loader.getTag(ServerFunctionManager.TICK_FUNCTION_TAG));
         this.postReload = true;
     }
 
@@ -125,7 +138,19 @@
         return this.library.getAvailableTags();
     }
 
-    class ExecutionContext {
+    public interface TraceCallbacks {
+
+        void onCommand(int depth, String command);
+
+        void onReturn(int depth, String command, int result);
+
+        void onError(int depth, String message);
+
+        void onCall(int depth, ResourceLocation function, int size);
+    }
+
+    private class ExecutionContext {
+
         private int depth;
         @Nullable
         private final ServerFunctionManager.TraceCallbacks tracer;
@@ -133,50 +158,61 @@
         private final List<ServerFunctionManager.QueuedCommand> nestedCalls = Lists.newArrayList();
         boolean abortCurrentDepth = false;
 
-        ExecutionContext(@Nullable ServerFunctionManager.TraceCallbacks tracer) {
-            this.tracer = tracer;
+        ExecutionContext(@Nullable ServerFunctionManager.TraceCallbacks customfunctiondata_tracecallbacks) {
+            this.tracer = customfunctiondata_tracecallbacks;
         }
 
         void delayFunctionCall(CommandFunction function, CommandSourceStack source) {
             int i = ServerFunctionManager.this.getCommandLimit();
-            CommandSourceStack commandSourceStack = this.wrapSender(source);
+            CommandSourceStack commandlistenerwrapper1 = this.wrapSender(source);
+
             if (this.commandQueue.size() + this.nestedCalls.size() < i) {
-                this.nestedCalls.add(new ServerFunctionManager.QueuedCommand(commandSourceStack, this.depth, new CommandFunction.FunctionEntry(function)));
+                this.nestedCalls.add(new ServerFunctionManager.QueuedCommand(commandlistenerwrapper1, this.depth, new CommandFunction.FunctionEntry(function)));
             }
 
         }
 
         private CommandSourceStack wrapSender(CommandSourceStack source) {
-            IntConsumer intConsumer = source.getReturnValueConsumer();
-            return intConsumer instanceof ServerFunctionManager.ExecutionContext.AbortingReturnValueConsumer ? source : source.withReturnValueConsumer(new ServerFunctionManager.ExecutionContext.AbortingReturnValueConsumer(intConsumer));
+            IntConsumer intconsumer = source.getReturnValueConsumer();
+
+            return intconsumer instanceof ServerFunctionManager.ExecutionContext.AbortingReturnValueConsumer ? source : source.withReturnValueConsumer(new ServerFunctionManager.ExecutionContext.AbortingReturnValueConsumer(intconsumer));
         }
 
         int runTopCommand(CommandFunction function, CommandSourceStack source) {
             int i = ServerFunctionManager.this.getCommandLimit();
-            CommandSourceStack commandSourceStack = this.wrapSender(source);
+            CommandSourceStack commandlistenerwrapper1 = this.wrapSender(source);
             int j = 0;
-            CommandFunction.Entry[] entrys = function.getEntries();
+            CommandFunction.Entry[] acustomfunction_d = function.getEntries();
 
-            for(int k = entrys.length - 1; k >= 0; --k) {
-                this.commandQueue.push(new ServerFunctionManager.QueuedCommand(commandSourceStack, 0, entrys[k]));
+            for (int k = acustomfunction_d.length - 1; k >= 0; --k) {
+                this.commandQueue.push(new ServerFunctionManager.QueuedCommand(commandlistenerwrapper1, 0, acustomfunction_d[k]));
             }
 
-            while(!this.commandQueue.isEmpty()) {
+            do {
+                if (this.commandQueue.isEmpty()) {
+                    return j;
+                }
+
                 try {
-                    ServerFunctionManager.QueuedCommand queuedCommand = this.commandQueue.removeFirst();
-                    ServerFunctionManager.this.server.getProfiler().push(queuedCommand::toString);
-                    this.depth = queuedCommand.depth;
-                    queuedCommand.execute(ServerFunctionManager.this, this.commandQueue, i, this.tracer);
-                    if (!this.abortCurrentDepth) {
-                        if (!this.nestedCalls.isEmpty()) {
-                            Lists.reverse(this.nestedCalls).forEach(this.commandQueue::addFirst);
-                        }
-                    } else {
-                        while(!this.commandQueue.isEmpty() && (this.commandQueue.peek()).depth >= this.depth) {
+                    ServerFunctionManager.QueuedCommand customfunctiondata_queuedcommand = (ServerFunctionManager.QueuedCommand) this.commandQueue.removeFirst();
+                    ProfilerFiller gameprofilerfiller = ServerFunctionManager.this.server.getProfiler();
+
+                    Objects.requireNonNull(customfunctiondata_queuedcommand);
+                    gameprofilerfiller.push(customfunctiondata_queuedcommand::toString);
+                    this.depth = customfunctiondata_queuedcommand.depth;
+                    customfunctiondata_queuedcommand.execute(ServerFunctionManager.this, this.commandQueue, i, this.tracer);
+                    if (this.abortCurrentDepth) {
+                        while (!this.commandQueue.isEmpty() && ((ServerFunctionManager.QueuedCommand) this.commandQueue.peek()).depth >= this.depth) {
                             this.commandQueue.removeFirst();
                         }
 
                         this.abortCurrentDepth = false;
+                    } else if (!this.nestedCalls.isEmpty()) {
+                        List list = Lists.reverse(this.nestedCalls);
+                        Deque deque = this.commandQueue;
+
+                        Objects.requireNonNull(this.commandQueue);
+                        list.forEach(deque::addFirst);
                     }
 
                     this.nestedCalls.clear();
@@ -185,10 +221,7 @@
                 }
 
                 ++j;
-                if (j >= i) {
-                    return j;
-                }
-            }
+            } while (j < i);
 
             return j;
         }
@@ -200,14 +233,14 @@
 
         }
 
-        class AbortingReturnValueConsumer implements IntConsumer {
+        private class AbortingReturnValueConsumer implements IntConsumer {
+
             private final IntConsumer wrapped;
 
-            AbortingReturnValueConsumer(IntConsumer delegate) {
-                this.wrapped = delegate;
+            AbortingReturnValueConsumer(IntConsumer intconsumer) {
+                this.wrapped = intconsumer;
             }
 
-            @Override
             public void accept(int i) {
                 this.wrapped.accept(i);
                 ExecutionContext.this.abortCurrentDepth = true;
@@ -216,6 +249,7 @@
     }
 
     public static class QueuedCommand {
+
         private final CommandSourceStack sender;
         final int depth;
         private final CommandFunction.Entry entry;
@@ -229,31 +263,20 @@
         public void execute(ServerFunctionManager manager, Deque<ServerFunctionManager.QueuedCommand> entries, int maxChainLength, @Nullable ServerFunctionManager.TraceCallbacks tracer) {
             try {
                 this.entry.execute(manager, this.sender, entries, maxChainLength, this.depth, tracer);
-            } catch (CommandSyntaxException var6) {
+            } catch (CommandSyntaxException commandsyntaxexception) {
                 if (tracer != null) {
-                    tracer.onError(this.depth, var6.getRawMessage().getString());
+                    tracer.onError(this.depth, commandsyntaxexception.getRawMessage().getString());
                 }
-            } catch (Exception var7) {
+            } catch (Exception exception) {
                 if (tracer != null) {
-                    tracer.onError(this.depth, var7.getMessage());
+                    tracer.onError(this.depth, exception.getMessage());
                 }
             }
 
         }
 
-        @Override
         public String toString() {
             return this.entry.toString();
         }
     }
-
-    public interface TraceCallbacks {
-        void onCommand(int depth, String command);
-
-        void onReturn(int depth, String command, int result);
-
-        void onError(int depth, String message);
-
-        void onCall(int depth, ResourceLocation function, int size);
-    }
 }
