From 731e657bf28c20f22e0efa05cf1cc9664374e9e8 Mon Sep 17 00:00:00 2001
From: Zach Brown <zach.brown@destroystokyo.com>
Date: Mon, 13 Apr 2015 15:47:15 -0500
Subject: [PATCH] Fix redstone lag issues


diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java
index d76b965..7624984 100644
--- a/src/main/java/net/minecraft/server/WorldServer.java
+++ b/src/main/java/net/minecraft/server/WorldServer.java
@@ -611,6 +611,8 @@ public class WorldServer extends World implements IAsyncTaskHandler {
             if (false) { // CraftBukkit
                 throw new IllegalStateException("TickNextTick list out of synch");
             } else {
+                // PaperSpigot start - No, stop doing this, it affects things like redstone
+                /*
                 if (i > 1000) {
                     // CraftBukkit start - If the server has too much to process over time, try to alleviate that
                     if (i > 20 * 1000) {
@@ -619,7 +621,11 @@ public class WorldServer extends World implements IAsyncTaskHandler {
                         i = 1000;
                     }
                     // CraftBukkit end
+                */
+                if (i > paperSpigotConfig.tickNextTickCap) {
+                    i = paperSpigotConfig.tickNextTickCap;
                 }
+                // PaperSpigot end
 
                 this.methodProfiler.a("cleaning");
 
@@ -636,6 +642,23 @@ public class WorldServer extends World implements IAsyncTaskHandler {
                     this.V.add(nextticklistentry);
                 }
 
+                // PaperSpigot start - Allow redstone ticks to bypass the tickNextTickListCap
+                if (paperSpigotConfig.tickNextTickListCapIgnoresRedstone) {
+                    Iterator<NextTickListEntry> iterator = this.M.iterator();
+                    while (iterator.hasNext()) {
+                        NextTickListEntry next = iterator.next();
+                        if (!flag && next.b > this.worldData.getTime()) {
+                            break;
+                        }
+
+                        if (next.a().isPowerSource() || next.a() instanceof IContainer) {
+                            iterator.remove();
+                            this.V.add(next);
+                        }
+                    }
+                }
+                // PaperSpigot end
+
                 this.methodProfiler.b();
                 this.methodProfiler.a("ticking");
                 Iterator iterator = this.V.iterator();
diff --git a/src/main/java/org/github/paperspigot/PaperSpigotWorldConfig.java b/src/main/java/org/github/paperspigot/PaperSpigotWorldConfig.java
index e0926a2..bcd8b65 100644
--- a/src/main/java/org/github/paperspigot/PaperSpigotWorldConfig.java
+++ b/src/main/java/org/github/paperspigot/PaperSpigotWorldConfig.java
@@ -234,4 +234,14 @@ public class PaperSpigotWorldConfig
     {
         netherVoidTopDamage = getBoolean( "nether-ceiling-void-damage", false );
     }
+
+    public int tickNextTickCap;
+    public boolean tickNextTickListCapIgnoresRedstone;
+    private void tickNextTickCap()
+    {
+        tickNextTickCap = getInt( "tick-next-tick-list-cap", 10000 ); // Higher values will be friendlier to vanilla style mechanics (to a point) but may hurt performance
+        tickNextTickListCapIgnoresRedstone = getBoolean( "tick-next-tick-list-cap-ignores-redstone", false ); // Redstone TickNextTicks will always bypass the preceding cap.
+        log( "WorldServer TickNextTick cap set at " + tickNextTickCap );
+        log( "WorldServer TickNextTickList cap always processes redstone: " + tickNextTickListCapIgnoresRedstone );
+    }
 }
-- 
1.9.5.msysgit.1