Remove NextTickList processing whilst we look into an issue.
http://www.spigotmc.org/threads/lwc-locks-randomly-going-missing-after-using-1249.10505/ Catch stalling on corrupted map data / NBT arrays.
This commit is contained in:
parent
6c36e5eff0
commit
a0deef28ee
3 changed files with 310 additions and 310 deletions
|
@ -1,4 +1,4 @@
|
||||||
From 728698cfb07683d5ce15c07ea8cf32591cc4c95c Mon Sep 17 00:00:00 2001
|
From 1d5b81555def55b67178090ba0e5f3ecf27f5bda Mon Sep 17 00:00:00 2001
|
||||||
From: md_5 <md_5@live.com.au>
|
From: md_5 <md_5@live.com.au>
|
||||||
Date: Sun, 1 Dec 2013 15:10:48 +1100
|
Date: Sun, 1 Dec 2013 15:10:48 +1100
|
||||||
Subject: [PATCH] mc-dev imports
|
Subject: [PATCH] mc-dev imports
|
||||||
|
@ -1187,6 +1187,281 @@ index 0000000..90a2a80
|
||||||
+ c.put(ChunkCoordinates.class, Integer.valueOf(6));
|
+ c.put(ChunkCoordinates.class, Integer.valueOf(6));
|
||||||
+ }
|
+ }
|
||||||
+}
|
+}
|
||||||
|
diff --git a/src/main/java/net/minecraft/server/NBTBase.java b/src/main/java/net/minecraft/server/NBTBase.java
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000..6e7c3a2
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/src/main/java/net/minecraft/server/NBTBase.java
|
||||||
|
@@ -0,0 +1,129 @@
|
||||||
|
+package net.minecraft.server;
|
||||||
|
+
|
||||||
|
+import java.io.DataInput;
|
||||||
|
+import java.io.DataOutput;
|
||||||
|
+import java.io.IOException;
|
||||||
|
+
|
||||||
|
+public abstract class NBTBase {
|
||||||
|
+
|
||||||
|
+ public static final String[] a = new String[] { "END", "BYTE", "SHORT", "INT", "LONG", "FLOAT", "DOUBLE", "BYTE[]", "STRING", "LIST", "COMPOUND", "INT[]"};
|
||||||
|
+
|
||||||
|
+ abstract void write(DataOutput dataoutput) throws IOException;
|
||||||
|
+
|
||||||
|
+ abstract void load(DataInput datainput, int i) throws IOException;
|
||||||
|
+
|
||||||
|
+ public abstract String toString();
|
||||||
|
+
|
||||||
|
+ public abstract byte getTypeId();
|
||||||
|
+
|
||||||
|
+ protected NBTBase() {}
|
||||||
|
+
|
||||||
|
+ protected static NBTBase createTag(byte b0) {
|
||||||
|
+ switch (b0) {
|
||||||
|
+ case 0:
|
||||||
|
+ return new NBTTagEnd();
|
||||||
|
+
|
||||||
|
+ case 1:
|
||||||
|
+ return new NBTTagByte();
|
||||||
|
+
|
||||||
|
+ case 2:
|
||||||
|
+ return new NBTTagShort();
|
||||||
|
+
|
||||||
|
+ case 3:
|
||||||
|
+ return new NBTTagInt();
|
||||||
|
+
|
||||||
|
+ case 4:
|
||||||
|
+ return new NBTTagLong();
|
||||||
|
+
|
||||||
|
+ case 5:
|
||||||
|
+ return new NBTTagFloat();
|
||||||
|
+
|
||||||
|
+ case 6:
|
||||||
|
+ return new NBTTagDouble();
|
||||||
|
+
|
||||||
|
+ case 7:
|
||||||
|
+ return new NBTTagByteArray();
|
||||||
|
+
|
||||||
|
+ case 8:
|
||||||
|
+ return new NBTTagString();
|
||||||
|
+
|
||||||
|
+ case 9:
|
||||||
|
+ return new NBTTagList();
|
||||||
|
+
|
||||||
|
+ case 10:
|
||||||
|
+ return new NBTTagCompound();
|
||||||
|
+
|
||||||
|
+ case 11:
|
||||||
|
+ return new NBTTagIntArray();
|
||||||
|
+
|
||||||
|
+ default:
|
||||||
|
+ return null;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ public static String getTagName(int i) {
|
||||||
|
+ switch (i) {
|
||||||
|
+ case 0:
|
||||||
|
+ return "TAG_End";
|
||||||
|
+
|
||||||
|
+ case 1:
|
||||||
|
+ return "TAG_Byte";
|
||||||
|
+
|
||||||
|
+ case 2:
|
||||||
|
+ return "TAG_Short";
|
||||||
|
+
|
||||||
|
+ case 3:
|
||||||
|
+ return "TAG_Int";
|
||||||
|
+
|
||||||
|
+ case 4:
|
||||||
|
+ return "TAG_Long";
|
||||||
|
+
|
||||||
|
+ case 5:
|
||||||
|
+ return "TAG_Float";
|
||||||
|
+
|
||||||
|
+ case 6:
|
||||||
|
+ return "TAG_Double";
|
||||||
|
+
|
||||||
|
+ case 7:
|
||||||
|
+ return "TAG_Byte_Array";
|
||||||
|
+
|
||||||
|
+ case 8:
|
||||||
|
+ return "TAG_String";
|
||||||
|
+
|
||||||
|
+ case 9:
|
||||||
|
+ return "TAG_List";
|
||||||
|
+
|
||||||
|
+ case 10:
|
||||||
|
+ return "TAG_Compound";
|
||||||
|
+
|
||||||
|
+ case 11:
|
||||||
|
+ return "TAG_Int_Array";
|
||||||
|
+
|
||||||
|
+ case 99:
|
||||||
|
+ return "Any Numeric Tag";
|
||||||
|
+
|
||||||
|
+ default:
|
||||||
|
+ return "UNKNOWN";
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ public abstract NBTBase clone();
|
||||||
|
+
|
||||||
|
+ public boolean equals(Object object) {
|
||||||
|
+ if (!(object instanceof NBTBase)) {
|
||||||
|
+ return false;
|
||||||
|
+ } else {
|
||||||
|
+ NBTBase nbtbase = (NBTBase) object;
|
||||||
|
+
|
||||||
|
+ return this.getTypeId() == nbtbase.getTypeId();
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ public int hashCode() {
|
||||||
|
+ return this.getTypeId();
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ protected String a_() {
|
||||||
|
+ return this.toString();
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
diff --git a/src/main/java/net/minecraft/server/NBTTagByteArray.java b/src/main/java/net/minecraft/server/NBTTagByteArray.java
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000..916d935
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/src/main/java/net/minecraft/server/NBTTagByteArray.java
|
||||||
|
@@ -0,0 +1,56 @@
|
||||||
|
+package net.minecraft.server;
|
||||||
|
+
|
||||||
|
+import java.io.DataInput;
|
||||||
|
+import java.io.DataOutput;
|
||||||
|
+import java.io.IOException;
|
||||||
|
+import java.util.Arrays;
|
||||||
|
+
|
||||||
|
+public class NBTTagByteArray extends NBTBase {
|
||||||
|
+
|
||||||
|
+ private byte[] data;
|
||||||
|
+
|
||||||
|
+ NBTTagByteArray() {}
|
||||||
|
+
|
||||||
|
+ public NBTTagByteArray(byte[] abyte) {
|
||||||
|
+ this.data = abyte;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ void write(DataOutput dataoutput) throws IOException {
|
||||||
|
+ dataoutput.writeInt(this.data.length);
|
||||||
|
+ dataoutput.write(this.data);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ void load(DataInput datainput, int i) throws IOException {
|
||||||
|
+ int j = datainput.readInt();
|
||||||
|
+
|
||||||
|
+ this.data = new byte[j];
|
||||||
|
+ datainput.readFully(this.data);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ public byte getTypeId() {
|
||||||
|
+ return (byte) 7;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ public String toString() {
|
||||||
|
+ return "[" + this.data.length + " bytes]";
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ public NBTBase clone() {
|
||||||
|
+ byte[] abyte = new byte[this.data.length];
|
||||||
|
+
|
||||||
|
+ System.arraycopy(this.data, 0, abyte, 0, this.data.length);
|
||||||
|
+ return new NBTTagByteArray(abyte);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ public boolean equals(Object object) {
|
||||||
|
+ return super.equals(object) ? Arrays.equals(this.data, ((NBTTagByteArray) object).data) : false;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ public int hashCode() {
|
||||||
|
+ return super.hashCode() ^ Arrays.hashCode(this.data);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ public byte[] c() {
|
||||||
|
+ return this.data;
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
diff --git a/src/main/java/net/minecraft/server/NBTTagIntArray.java b/src/main/java/net/minecraft/server/NBTTagIntArray.java
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000..49b3f14
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/src/main/java/net/minecraft/server/NBTTagIntArray.java
|
||||||
|
@@ -0,0 +1,72 @@
|
||||||
|
+package net.minecraft.server;
|
||||||
|
+
|
||||||
|
+import java.io.DataInput;
|
||||||
|
+import java.io.DataOutput;
|
||||||
|
+import java.io.IOException;
|
||||||
|
+import java.util.Arrays;
|
||||||
|
+
|
||||||
|
+public class NBTTagIntArray extends NBTBase {
|
||||||
|
+
|
||||||
|
+ private int[] data;
|
||||||
|
+
|
||||||
|
+ NBTTagIntArray() {}
|
||||||
|
+
|
||||||
|
+ public NBTTagIntArray(int[] aint) {
|
||||||
|
+ this.data = aint;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ void write(DataOutput dataoutput) throws IOException {
|
||||||
|
+ dataoutput.writeInt(this.data.length);
|
||||||
|
+
|
||||||
|
+ for (int i = 0; i < this.data.length; ++i) {
|
||||||
|
+ dataoutput.writeInt(this.data[i]);
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ void load(DataInput datainput, int i) throws IOException {
|
||||||
|
+ int j = datainput.readInt();
|
||||||
|
+
|
||||||
|
+ this.data = new int[j];
|
||||||
|
+
|
||||||
|
+ for (int k = 0; k < j; ++k) {
|
||||||
|
+ this.data[k] = datainput.readInt();
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ public byte getTypeId() {
|
||||||
|
+ return (byte) 11;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ public String toString() {
|
||||||
|
+ String s = "[";
|
||||||
|
+ int[] aint = this.data;
|
||||||
|
+ int i = aint.length;
|
||||||
|
+
|
||||||
|
+ for (int j = 0; j < i; ++j) {
|
||||||
|
+ int k = aint[j];
|
||||||
|
+
|
||||||
|
+ s = s + k + ",";
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return s + "]";
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ public NBTBase clone() {
|
||||||
|
+ int[] aint = new int[this.data.length];
|
||||||
|
+
|
||||||
|
+ System.arraycopy(this.data, 0, aint, 0, this.data.length);
|
||||||
|
+ return new NBTTagIntArray(aint);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ public boolean equals(Object object) {
|
||||||
|
+ return super.equals(object) ? Arrays.equals(this.data, ((NBTTagIntArray) object).data) : false;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ public int hashCode() {
|
||||||
|
+ return super.hashCode() ^ Arrays.hashCode(this.data);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ public int[] c() {
|
||||||
|
+ return this.data;
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
diff --git a/src/main/java/net/minecraft/server/NextTickListEntry.java b/src/main/java/net/minecraft/server/NextTickListEntry.java
|
diff --git a/src/main/java/net/minecraft/server/NextTickListEntry.java b/src/main/java/net/minecraft/server/NextTickListEntry.java
|
||||||
new file mode 100644
|
new file mode 100644
|
||||||
index 0000000..06934a1
|
index 0000000..06934a1
|
||||||
|
@ -2282,5 +2557,5 @@ index 0000000..c0db754
|
||||||
+ }
|
+ }
|
||||||
+}
|
+}
|
||||||
--
|
--
|
||||||
1.8.4.msysgit.0
|
1.8.3.2
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,33 @@
|
||||||
|
From 51cc9fc818ece90ca3349895c2d8d7d7f210b99e Mon Sep 17 00:00:00 2001
|
||||||
|
From: md_5 <git@md-5.net>
|
||||||
|
Date: Mon, 20 Jan 2014 13:44:07 +1100
|
||||||
|
Subject: [PATCH] Catch stalling on corrupted map data / NBT arrays.
|
||||||
|
|
||||||
|
|
||||||
|
diff --git a/src/main/java/net/minecraft/server/NBTTagByteArray.java b/src/main/java/net/minecraft/server/NBTTagByteArray.java
|
||||||
|
index 916d935..3fa9c1a 100644
|
||||||
|
--- a/src/main/java/net/minecraft/server/NBTTagByteArray.java
|
||||||
|
+++ b/src/main/java/net/minecraft/server/NBTTagByteArray.java
|
||||||
|
@@ -22,6 +22,7 @@ public class NBTTagByteArray extends NBTBase {
|
||||||
|
|
||||||
|
void load(DataInput datainput, int i) throws IOException {
|
||||||
|
int j = datainput.readInt();
|
||||||
|
+ com.google.common.base.Preconditions.checkArgument( i < 1 << 24);
|
||||||
|
|
||||||
|
this.data = new byte[j];
|
||||||
|
datainput.readFully(this.data);
|
||||||
|
diff --git a/src/main/java/net/minecraft/server/NBTTagIntArray.java b/src/main/java/net/minecraft/server/NBTTagIntArray.java
|
||||||
|
index 49b3f14..6c33462 100644
|
||||||
|
--- a/src/main/java/net/minecraft/server/NBTTagIntArray.java
|
||||||
|
+++ b/src/main/java/net/minecraft/server/NBTTagIntArray.java
|
||||||
|
@@ -25,6 +25,7 @@ public class NBTTagIntArray extends NBTBase {
|
||||||
|
|
||||||
|
void load(DataInput datainput, int i) throws IOException {
|
||||||
|
int j = datainput.readInt();
|
||||||
|
+ com.google.common.base.Preconditions.checkArgument( i < 1 << 24);
|
||||||
|
|
||||||
|
this.data = new int[j];
|
||||||
|
|
||||||
|
--
|
||||||
|
1.8.3.2
|
||||||
|
|
|
@ -1,308 +0,0 @@
|
||||||
From dc7f9783926c0f66e83fcca98161f4d513dccf04 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Mike Primm <mike@primmhome.com>
|
|
||||||
Date: Sat, 18 Jan 2014 13:54:38 -0600
|
|
||||||
Subject: [PATCH] Optimize NextTickList processing
|
|
||||||
|
|
||||||
|
|
||||||
diff --git a/src/main/java/net/minecraft/server/NextTickListEntry.java b/src/main/java/net/minecraft/server/NextTickListEntry.java
|
|
||||||
index 06934a1..d90acfc 100644
|
|
||||||
--- a/src/main/java/net/minecraft/server/NextTickListEntry.java
|
|
||||||
+++ b/src/main/java/net/minecraft/server/NextTickListEntry.java
|
|
||||||
@@ -30,7 +30,7 @@ public class NextTickListEntry implements Comparable {
|
|
||||||
}
|
|
||||||
|
|
||||||
public int hashCode() {
|
|
||||||
- return (this.a * 1024 * 1024 + this.c * 1024 + this.b) * 256;
|
|
||||||
+ return (this.a * 257) ^ this.b ^ (this.c * 60217); // Spigot - better hash
|
|
||||||
}
|
|
||||||
|
|
||||||
public NextTickListEntry a(long i) {
|
|
||||||
diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java
|
|
||||||
index 9672508..74a3294 100644
|
|
||||||
--- a/src/main/java/net/minecraft/server/WorldServer.java
|
|
||||||
+++ b/src/main/java/net/minecraft/server/WorldServer.java
|
|
||||||
@@ -29,8 +29,8 @@ public class WorldServer extends World implements org.bukkit.BlockChangeDelegate
|
|
||||||
private final MinecraftServer server;
|
|
||||||
public EntityTracker tracker; // CraftBukkit - private final -> public
|
|
||||||
private final PlayerChunkMap manager;
|
|
||||||
- private Set M;
|
|
||||||
- private TreeSet N;
|
|
||||||
+ private org.bukkit.craftbukkit.util.LongObjectHashMap<Set<NextTickListEntry>> tickEntriesByChunk; // Spigot - switch to something better for chunk-wise access
|
|
||||||
+ private TreeSet<NextTickListEntry> tickEntryQueue; // Spigot public ChunkProviderServer chunkProviderServer;
|
|
||||||
public ChunkProviderServer chunkProviderServer;
|
|
||||||
public boolean savingDisabled;
|
|
||||||
private boolean O;
|
|
||||||
@@ -40,7 +40,8 @@ public class WorldServer extends World implements org.bukkit.BlockChangeDelegate
|
|
||||||
private NoteDataList[] S = new NoteDataList[] { new NoteDataList((EmptyClass2) null), new NoteDataList((EmptyClass2) null)};
|
|
||||||
private int T;
|
|
||||||
private static final StructurePieceTreasure[] U = new StructurePieceTreasure[] { new StructurePieceTreasure(Items.STICK, 0, 1, 3, 10), new StructurePieceTreasure(Item.getItemOf(Blocks.WOOD), 0, 1, 3, 10), new StructurePieceTreasure(Item.getItemOf(Blocks.LOG), 0, 1, 3, 10), new StructurePieceTreasure(Items.STONE_AXE, 0, 1, 1, 3), new StructurePieceTreasure(Items.WOOD_AXE, 0, 1, 1, 5), new StructurePieceTreasure(Items.STONE_PICKAXE, 0, 1, 1, 3), new StructurePieceTreasure(Items.WOOD_PICKAXE, 0, 1, 1, 5), new StructurePieceTreasure(Items.APPLE, 0, 2, 3, 5), new StructurePieceTreasure(Items.BREAD, 0, 2, 3, 3), new StructurePieceTreasure(Item.getItemOf(Blocks.LOG2), 0, 1, 3, 10)};
|
|
||||||
- private List V = new ArrayList();
|
|
||||||
+ private ArrayList<NextTickListEntry> pendingTickEntries = new ArrayList<NextTickListEntry>(); // Spigot
|
|
||||||
+ private int nextPendingTickEntry; // Spigot
|
|
||||||
private IntHashMap entitiesById;
|
|
||||||
|
|
||||||
// CraftBukkit start
|
|
||||||
@@ -59,13 +60,15 @@ public class WorldServer extends World implements org.bukkit.BlockChangeDelegate
|
|
||||||
this.entitiesById = new IntHashMap();
|
|
||||||
}
|
|
||||||
|
|
||||||
- if (this.M == null) {
|
|
||||||
- this.M = new HashSet();
|
|
||||||
+ // Spigot start
|
|
||||||
+ if (this.tickEntriesByChunk == null) {
|
|
||||||
+ this.tickEntriesByChunk = new org.bukkit.craftbukkit.util.LongObjectHashMap<Set<NextTickListEntry>>();
|
|
||||||
}
|
|
||||||
|
|
||||||
- if (this.N == null) {
|
|
||||||
- this.N = new TreeSet();
|
|
||||||
+ if (this.tickEntryQueue == null) {
|
|
||||||
+ this.tickEntryQueue = new TreeSet<NextTickListEntry>();
|
|
||||||
}
|
|
||||||
+ // Spigot end
|
|
||||||
|
|
||||||
this.Q = new org.bukkit.craftbukkit.CraftTravelAgent(this); // CraftBukkit
|
|
||||||
this.scoreboard = new ScoreboardServer(minecraftserver);
|
|
||||||
@@ -445,9 +448,16 @@ public class WorldServer extends World implements org.bukkit.BlockChangeDelegate
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean a(int i, int j, int k, Block block) {
|
|
||||||
- NextTickListEntry nextticklistentry = new NextTickListEntry(i, j, k, block);
|
|
||||||
-
|
|
||||||
- return this.V.contains(nextticklistentry);
|
|
||||||
+ // Spigot start
|
|
||||||
+ int te_cnt = this.pendingTickEntries.size();
|
|
||||||
+ for (int idx = this.nextPendingTickEntry; idx < te_cnt; idx++) {
|
|
||||||
+ NextTickListEntry ent = this.pendingTickEntries.get(idx);
|
|
||||||
+ if ((ent.a == i) && (ent.b == j) && (ent.c == k) && Block.a(ent.a(), block)) {
|
|
||||||
+ return true;
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+ return false;
|
|
||||||
+ // Spigot end
|
|
||||||
}
|
|
||||||
|
|
||||||
public void a(int i, int j, int k, Block block, int l) {
|
|
||||||
@@ -481,10 +491,9 @@ public class WorldServer extends World implements org.bukkit.BlockChangeDelegate
|
|
||||||
nextticklistentry.a(i1);
|
|
||||||
}
|
|
||||||
|
|
||||||
- if (!this.M.contains(nextticklistentry)) {
|
|
||||||
- this.M.add(nextticklistentry);
|
|
||||||
- this.N.add(nextticklistentry);
|
|
||||||
- }
|
|
||||||
+ // Spigot start
|
|
||||||
+ addNextTickIfNeeded(nextticklistentry);
|
|
||||||
+ // Spigot end
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -496,10 +505,9 @@ public class WorldServer extends World implements org.bukkit.BlockChangeDelegate
|
|
||||||
nextticklistentry.a((long) l + this.worldData.getTime());
|
|
||||||
}
|
|
||||||
|
|
||||||
- if (!this.M.contains(nextticklistentry)) {
|
|
||||||
- this.M.add(nextticklistentry);
|
|
||||||
- this.N.add(nextticklistentry);
|
|
||||||
- }
|
|
||||||
+ // Spigot start
|
|
||||||
+ addNextTickIfNeeded(nextticklistentry);
|
|
||||||
+ // Spigot end
|
|
||||||
}
|
|
||||||
|
|
||||||
public void tickEntities() {
|
|
||||||
@@ -519,11 +527,11 @@ public class WorldServer extends World implements org.bukkit.BlockChangeDelegate
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean a(boolean flag) {
|
|
||||||
- int i = this.N.size();
|
|
||||||
-
|
|
||||||
- if (i != this.M.size()) {
|
|
||||||
- throw new IllegalStateException("TickNextTick list out of synch");
|
|
||||||
- } else {
|
|
||||||
+ // Spigot start
|
|
||||||
+ int i = this.tickEntryQueue.size();
|
|
||||||
+ this.nextPendingTickEntry = 0;
|
|
||||||
+ {
|
|
||||||
+ // Spigot end
|
|
||||||
if (i > 1000) {
|
|
||||||
// CraftBukkit start - If the server has too much to process over time, try to alleviate that
|
|
||||||
if (i > 20 * 1000) {
|
|
||||||
@@ -539,23 +547,24 @@ public class WorldServer extends World implements org.bukkit.BlockChangeDelegate
|
|
||||||
NextTickListEntry nextticklistentry;
|
|
||||||
|
|
||||||
for (int j = 0; j < i; ++j) {
|
|
||||||
- nextticklistentry = (NextTickListEntry) this.N.first();
|
|
||||||
+ nextticklistentry = (NextTickListEntry) this.tickEntryQueue.first(); // Spigot
|
|
||||||
if (!flag && nextticklistentry.d > this.worldData.getTime()) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
- this.N.remove(nextticklistentry);
|
|
||||||
- this.M.remove(nextticklistentry);
|
|
||||||
- this.V.add(nextticklistentry);
|
|
||||||
+ // Spigot start
|
|
||||||
+ this.removeNextTickIfNeeded(nextticklistentry);
|
|
||||||
+ this.pendingTickEntries.add(nextticklistentry);
|
|
||||||
+ // Spigot end
|
|
||||||
}
|
|
||||||
|
|
||||||
this.methodProfiler.b();
|
|
||||||
this.methodProfiler.a("ticking");
|
|
||||||
- Iterator iterator = this.V.iterator();
|
|
||||||
-
|
|
||||||
- while (iterator.hasNext()) {
|
|
||||||
- nextticklistentry = (NextTickListEntry) iterator.next();
|
|
||||||
- iterator.remove();
|
|
||||||
+ // Spigot start
|
|
||||||
+ for (int j = 0, te_cnt = this.pendingTickEntries.size(); j < te_cnt; j++) {
|
|
||||||
+ nextticklistentry = pendingTickEntries.get(j);
|
|
||||||
+ this.nextPendingTickEntry = j + 1; // treat this as dequeued
|
|
||||||
+ // Spigot end
|
|
||||||
byte b0 = 0;
|
|
||||||
|
|
||||||
if (this.b(nextticklistentry.a - b0, nextticklistentry.b - b0, nextticklistentry.c - b0, nextticklistentry.a + b0, nextticklistentry.b + b0, nextticklistentry.c + b0)) {
|
|
||||||
@@ -586,50 +595,18 @@ public class WorldServer extends World implements org.bukkit.BlockChangeDelegate
|
|
||||||
}
|
|
||||||
|
|
||||||
this.methodProfiler.b();
|
|
||||||
- this.V.clear();
|
|
||||||
- return !this.N.isEmpty();
|
|
||||||
+ // Spigot start
|
|
||||||
+ this.pendingTickEntries.clear();
|
|
||||||
+ this.nextPendingTickEntry = 0;
|
|
||||||
+ return !this.tickEntryQueue.isEmpty();
|
|
||||||
+ // Spigot end
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public List a(Chunk chunk, boolean flag) {
|
|
||||||
- ArrayList arraylist = null;
|
|
||||||
- ChunkCoordIntPair chunkcoordintpair = chunk.l();
|
|
||||||
- int i = (chunkcoordintpair.x << 4) - 2;
|
|
||||||
- int j = i + 16 + 2;
|
|
||||||
- int k = (chunkcoordintpair.z << 4) - 2;
|
|
||||||
- int l = k + 16 + 2;
|
|
||||||
-
|
|
||||||
- for (int i1 = 0; i1 < 2; ++i1) {
|
|
||||||
- Iterator iterator;
|
|
||||||
-
|
|
||||||
- if (i1 == 0) {
|
|
||||||
- iterator = this.N.iterator();
|
|
||||||
- } else {
|
|
||||||
- iterator = this.V.iterator();
|
|
||||||
- if (!this.V.isEmpty()) {
|
|
||||||
- a.debug("toBeTicked = " + this.V.size());
|
|
||||||
- }
|
|
||||||
- }
|
|
||||||
-
|
|
||||||
- while (iterator.hasNext()) {
|
|
||||||
- NextTickListEntry nextticklistentry = (NextTickListEntry) iterator.next();
|
|
||||||
-
|
|
||||||
- if (nextticklistentry.a >= i && nextticklistentry.a < j && nextticklistentry.c >= k && nextticklistentry.c < l) {
|
|
||||||
- if (flag) {
|
|
||||||
- this.M.remove(nextticklistentry);
|
|
||||||
- iterator.remove();
|
|
||||||
- }
|
|
||||||
-
|
|
||||||
- if (arraylist == null) {
|
|
||||||
- arraylist = new ArrayList();
|
|
||||||
- }
|
|
||||||
-
|
|
||||||
- arraylist.add(nextticklistentry);
|
|
||||||
- }
|
|
||||||
- }
|
|
||||||
- }
|
|
||||||
-
|
|
||||||
- return arraylist;
|
|
||||||
+ // Spigot start
|
|
||||||
+ return this.getNextTickEntriesForChunk(chunk, flag);
|
|
||||||
+ // Spigot end
|
|
||||||
}
|
|
||||||
|
|
||||||
/* CraftBukkit start - We prevent spawning in general, so this butchering is not needed
|
|
||||||
@@ -701,13 +678,15 @@ public class WorldServer extends World implements org.bukkit.BlockChangeDelegate
|
|
||||||
this.entitiesById = new IntHashMap();
|
|
||||||
}
|
|
||||||
|
|
||||||
- if (this.M == null) {
|
|
||||||
- this.M = new HashSet();
|
|
||||||
+ // Spigot start
|
|
||||||
+ if (this.tickEntriesByChunk == null) {
|
|
||||||
+ this.tickEntriesByChunk = new org.bukkit.craftbukkit.util.LongObjectHashMap<Set<NextTickListEntry>>();
|
|
||||||
}
|
|
||||||
|
|
||||||
- if (this.N == null) {
|
|
||||||
- this.N = new TreeSet();
|
|
||||||
+ if (this.tickEntryQueue == null) {
|
|
||||||
+ this.tickEntryQueue = new TreeSet<NextTickListEntry>();
|
|
||||||
}
|
|
||||||
+ // Spigot end
|
|
||||||
|
|
||||||
this.b(worldsettings);
|
|
||||||
super.a(worldsettings);
|
|
||||||
@@ -1037,4 +1016,62 @@ public class WorldServer extends World implements org.bukkit.BlockChangeDelegate
|
|
||||||
return Block.b(getType(x, y, z));
|
|
||||||
}
|
|
||||||
// CraftBukkit end
|
|
||||||
+ // Spigot start
|
|
||||||
+ private void addNextTickIfNeeded(NextTickListEntry ent) {
|
|
||||||
+ long coord = LongHash.toLong(ent.a >> 4, ent.c >> 4);
|
|
||||||
+ Set<NextTickListEntry> chunkset = this.tickEntriesByChunk.get(coord);
|
|
||||||
+ if (chunkset == null) {
|
|
||||||
+ chunkset = new HashSet<NextTickListEntry>();
|
|
||||||
+ this.tickEntriesByChunk.put(coord, chunkset);
|
|
||||||
+ } else if (chunkset.contains(ent)) {
|
|
||||||
+ return;
|
|
||||||
+ }
|
|
||||||
+ chunkset.add(ent);
|
|
||||||
+ this.tickEntryQueue.add(ent);
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ private void removeNextTickIfNeeded(NextTickListEntry ent) {
|
|
||||||
+ long coord = LongHash.toLong(ent.a >> 4, ent.c >> 4);
|
|
||||||
+ Set<NextTickListEntry> chunkset = this.tickEntriesByChunk.get(coord);
|
|
||||||
+ if (chunkset != null) {
|
|
||||||
+ chunkset.remove(ent);
|
|
||||||
+ if (chunkset.isEmpty()) {
|
|
||||||
+ this.tickEntriesByChunk.remove(coord);
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+ this.tickEntryQueue.remove(ent);
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ private List<NextTickListEntry> getNextTickEntriesForChunk(Chunk chunk, boolean remove) {
|
|
||||||
+ long coord = LongHash.toLong(chunk.locX, chunk.locZ);
|
|
||||||
+ Set<NextTickListEntry> chunkset = this.tickEntriesByChunk.get(coord);
|
|
||||||
+ List<NextTickListEntry> list = null;
|
|
||||||
+ if (chunkset != null) {
|
|
||||||
+ list = new ArrayList<NextTickListEntry>(chunkset);
|
|
||||||
+ if (remove) {
|
|
||||||
+ this.tickEntriesByChunk.remove(coord);
|
|
||||||
+ this.tickEntryQueue.removeAll(list);
|
|
||||||
+ chunkset.clear();
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+ // See if any on list of ticks being processed now
|
|
||||||
+ if (this.nextPendingTickEntry < this.pendingTickEntries.size()) {
|
|
||||||
+ int xmin = (chunk.locX << 4);
|
|
||||||
+ int xmax = xmin + 16;
|
|
||||||
+ int zmin = (chunk.locZ << 4);
|
|
||||||
+ int zmax = zmin + 16;
|
|
||||||
+ int te_cnt = this.pendingTickEntries.size();
|
|
||||||
+ for (int i = this.nextPendingTickEntry; i < te_cnt; i++) {
|
|
||||||
+ NextTickListEntry ent = this.pendingTickEntries.get(i);
|
|
||||||
+ if ((ent.a >= xmin) && (ent.a < xmax) && (ent.c >= zmin) && (ent.c < zmax)) {
|
|
||||||
+ if (list == null) {
|
|
||||||
+ list = new ArrayList<NextTickListEntry>();
|
|
||||||
+ }
|
|
||||||
+ list.add(ent);
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+ return list;
|
|
||||||
+ }
|
|
||||||
+ // Spigot end
|
|
||||||
}
|
|
||||||
--
|
|
||||||
1.8.3.4 (Apple Git-47)
|
|
||||||
|
|
Loading…
Reference in a new issue