3
0

Finally fix #67

This commit is contained in:
Prototik 2015-06-27 16:32:21 +07:00
parent 9fdf330495
commit 8c50b9899f
19 changed files with 737 additions and 704 deletions

View File

@ -73,7 +73,7 @@
if (this.players.isEmpty()) if (this.players.isEmpty())
{ {
+ if (this.theWorldServer.loadedEntityList.size() == 0 || this.theWorldServer.theChunkProviderServer.loadedChunkHashMap.size() == 0) + if (this.theWorldServer.loadedEntityList.size() == 0 || this.theWorldServer.theChunkProviderServer.loadedChunkHashMap_KC.size() == 0)
+ { + {
+ return; // CraftBukkit - Only do unload when we go from non-empty to empty + return; // CraftBukkit - Only do unload when we go from non-empty to empty
+ } + }

View File

@ -67,11 +67,11 @@
- public List loadedChunks = new ArrayList(); - public List loadedChunks = new ArrayList();
+ public boolean loadChunkOnProvideRequest = MinecraftServer.getServer().cauldronConfig.loadChunkOnRequest.getValue(); // Cauldron - if true, allows mods to force load chunks. to disable, set load-chunk-on-request in cauldron.yml to false + public boolean loadChunkOnProvideRequest = MinecraftServer.getServer().cauldronConfig.loadChunkOnRequest.getValue(); // Cauldron - if true, allows mods to force load chunks. to disable, set load-chunk-on-request in cauldron.yml to false
+ public int initialTick; // Cauldron counter to keep track of when this loader was created + public int initialTick; // Cauldron counter to keep track of when this loader was created
+ public TLongObjectMap<Chunk> loadedChunkHashMap = new TSynchronizedLongObjectMap<Chunk>(new TLongObjectHashMap<Chunk>()); + public TLongObjectMap<Chunk> loadedChunkHashMap_KC = new TSynchronizedLongObjectMap<Chunk>(new TLongObjectHashMap<Chunk>());
+ public List loadedChunks = new ArrayList(); // Cauldron - vanilla compatibility + public List loadedChunks = new ArrayList(); // Cauldron - vanilla compatibility
public WorldServer worldObj; public WorldServer worldObj;
private Set<Long> loadingChunks = com.google.common.collect.Sets.newHashSet(); private Set<Long> loadingChunks = com.google.common.collect.Sets.newHashSet();
+ public LongHashMap loadedChunkHashMap_vanilla = new LongHashMap(); // Cauldron - vanilla/mystcraft compatibility + public LongHashMap loadedChunkHashMap = new kcauldron.wrapper.VanillaChunkHashMap(loadedChunkHashMap_KC); // KCauldron - vanilla/mystcraft compatibility
private static final String __OBFID = "CL_00001436"; private static final String __OBFID = "CL_00001436";
public ChunkProviderServer(WorldServer p_i1520_1_, IChunkLoader p_i1520_2_, IChunkProvider p_i1520_3_) public ChunkProviderServer(WorldServer p_i1520_1_, IChunkLoader p_i1520_2_, IChunkProvider p_i1520_3_)
@ -85,7 +85,7 @@
public boolean chunkExists(int p_73149_1_, int p_73149_2_) public boolean chunkExists(int p_73149_1_, int p_73149_2_)
{ {
- return this.loadedChunkHashMap.containsItem(ChunkCoordIntPair.chunkXZ2Int(p_73149_1_, p_73149_2_)); - return this.loadedChunkHashMap.containsItem(ChunkCoordIntPair.chunkXZ2Int(p_73149_1_, p_73149_2_));
+ return this.loadedChunkHashMap.containsKey(LongHash.toLong(p_73149_1_, p_73149_2_)); // CraftBukkit + return this.loadedChunkHashMap_KC.containsKey(LongHash.toLong(p_73149_1_, p_73149_2_)); // CraftBukkit
} }
- public List func_152380_a() - public List func_152380_a()
@ -102,7 +102,7 @@
{ {
- this.chunksToUnload.add(Long.valueOf(ChunkCoordIntPair.chunkXZ2Int(p_73241_1_, p_73241_2_))); - this.chunksToUnload.add(Long.valueOf(ChunkCoordIntPair.chunkXZ2Int(p_73241_1_, p_73241_2_)));
+ this.chunksToUnload.add(p_73241_1_, p_73241_2_); + this.chunksToUnload.add(p_73241_1_, p_73241_2_);
+ Chunk c = this.loadedChunkHashMap.get(LongHash.toLong(p_73241_1_, p_73241_2_)); + Chunk c = this.loadedChunkHashMap_KC.get(LongHash.toLong(p_73241_1_, p_73241_2_));
+ +
+ if (c != null) + if (c != null)
+ { + {
@ -118,7 +118,7 @@
- this.chunksToUnload.add(Long.valueOf(ChunkCoordIntPair.chunkXZ2Int(p_73241_1_, p_73241_2_))); - this.chunksToUnload.add(Long.valueOf(ChunkCoordIntPair.chunkXZ2Int(p_73241_1_, p_73241_2_)));
+ // CraftBukkit start + // CraftBukkit start
+ this.chunksToUnload.add(p_73241_1_, p_73241_2_); + this.chunksToUnload.add(p_73241_1_, p_73241_2_);
+ Chunk c = this.loadedChunkHashMap.get(LongHash.toLong(p_73241_1_, p_73241_2_)); + Chunk c = this.loadedChunkHashMap_KC.get(LongHash.toLong(p_73241_1_, p_73241_2_));
+ +
+ if (c != null) + if (c != null)
+ { + {
@ -138,7 +138,7 @@
- Chunk chunk = (Chunk)iterator.next(); - Chunk chunk = (Chunk)iterator.next();
- this.unloadChunksIfNotNearSpawn(chunk.xPosition, chunk.zPosition); - this.unloadChunksIfNotNearSpawn(chunk.xPosition, chunk.zPosition);
- } - }
+ this.loadedChunkHashMap.forEachValue(new TObjectProcedure<Chunk>() { + this.loadedChunkHashMap_KC.forEachValue(new TObjectProcedure<Chunk>() {
+ @Override + @Override
+ public boolean execute(Chunk chunk) { + public boolean execute(Chunk chunk) {
+ unloadChunksIfNotNearSpawn(chunk.xPosition, chunk.zPosition); + unloadChunksIfNotNearSpawn(chunk.xPosition, chunk.zPosition);
@ -156,7 +156,7 @@
- this.chunksToUnload.remove(Long.valueOf(k)); - this.chunksToUnload.remove(Long.valueOf(k));
- Chunk chunk = (Chunk)this.loadedChunkHashMap.getValueByKey(k); - Chunk chunk = (Chunk)this.loadedChunkHashMap.getValueByKey(k);
+ this.chunksToUnload.remove(par1, par2); + this.chunksToUnload.remove(par1, par2);
+ Chunk chunk = (Chunk) this.loadedChunkHashMap.get(LongHash.toLong(par1, par2)); + Chunk chunk = (Chunk) this.loadedChunkHashMap_KC.get(LongHash.toLong(par1, par2));
+ boolean newChunk = false; + boolean newChunk = false;
AnvilChunkLoader loader = null; AnvilChunkLoader loader = null;
@ -178,7 +178,7 @@
- this.chunksToUnload.remove(Long.valueOf(k)); - this.chunksToUnload.remove(Long.valueOf(k));
- Chunk chunk = (Chunk)this.loadedChunkHashMap.getValueByKey(k); - Chunk chunk = (Chunk)this.loadedChunkHashMap.getValueByKey(k);
+ this.chunksToUnload.remove(p_73158_1_, p_73158_2_); + this.chunksToUnload.remove(p_73158_1_, p_73158_2_);
+ Chunk chunk = (Chunk) this.loadedChunkHashMap.get(LongHash.toLong(p_73158_1_, p_73158_2_)); + Chunk chunk = (Chunk) this.loadedChunkHashMap_KC.get(LongHash.toLong(p_73158_1_, p_73158_2_));
+ boolean newChunk = false; // CraftBukkit + boolean newChunk = false; // CraftBukkit
if (chunk == null) if (chunk == null)
@ -195,7 +195,7 @@
if (chunk == null) if (chunk == null)
{ {
chunk = this.safeLoadChunk(p_73158_1_, p_73158_2_); chunk = this.safeLoadChunk(p_73158_1_, p_73158_2_);
@@ -176,18 +235,40 @@ @@ -176,18 +235,39 @@
CrashReport crashreport = CrashReport.makeCrashReport(throwable, "Exception generating new chunk"); CrashReport crashreport = CrashReport.makeCrashReport(throwable, "Exception generating new chunk");
CrashReportCategory crashreportcategory = crashreport.makeCategory("Chunk to be generated"); CrashReportCategory crashreportcategory = crashreport.makeCategory("Chunk to be generated");
crashreportcategory.addCrashSection("Location", String.format("%d,%d", new Object[] {Integer.valueOf(p_73158_1_), Integer.valueOf(p_73158_2_)})); crashreportcategory.addCrashSection("Location", String.format("%d,%d", new Object[] {Integer.valueOf(p_73158_1_), Integer.valueOf(p_73158_2_)}));
@ -213,9 +213,8 @@
- this.loadedChunks.add(chunk); - this.loadedChunks.add(chunk);
- loadingChunks.remove(k); - loadingChunks.remove(k);
- chunk.onChunkLoad(); - chunk.onChunkLoad();
+ this.loadedChunkHashMap.put(LongHash.toLong(p_73158_1_, p_73158_2_), chunk); // CraftBukkit + this.loadedChunkHashMap_KC.put(LongHash.toLong(p_73158_1_, p_73158_2_), chunk); // CraftBukkit
+ this.loadedChunks.add(chunk); // Cauldron - vanilla compatibility + this.loadedChunks.add(chunk); // Cauldron - vanilla compatibility
+ this.loadedChunkHashMap_vanilla.add(ChunkCoordIntPair.chunkXZ2Int(p_73158_1_, p_73158_2_), chunk); // Cauldron - vanilla/mystcraft compatibility
+ loadingChunks.remove(LongHash.toLong(p_73158_1_, p_73158_2_)); // Cauldron - LongHash + loadingChunks.remove(LongHash.toLong(p_73158_1_, p_73158_2_)); // Cauldron - LongHash
+ +
+ if (chunk != null) + if (chunk != null)
@ -241,14 +240,14 @@
} }
return chunk; return chunk;
@@ -195,11 +276,29 @@ @@ -195,11 +275,29 @@
public Chunk provideChunk(int p_73154_1_, int p_73154_2_) public Chunk provideChunk(int p_73154_1_, int p_73154_2_)
{ {
- Chunk chunk = (Chunk)this.loadedChunkHashMap.getValueByKey(ChunkCoordIntPair.chunkXZ2Int(p_73154_1_, p_73154_2_)); - Chunk chunk = (Chunk)this.loadedChunkHashMap.getValueByKey(ChunkCoordIntPair.chunkXZ2Int(p_73154_1_, p_73154_2_));
- return chunk == null ? (!this.worldObj.findingSpawnPoint && !this.loadChunkOnProvideRequest ? this.defaultEmptyChunk : this.loadChunk(p_73154_1_, p_73154_2_)) : chunk; - return chunk == null ? (!this.worldObj.findingSpawnPoint && !this.loadChunkOnProvideRequest ? this.defaultEmptyChunk : this.loadChunk(p_73154_1_, p_73154_2_)) : chunk;
+ // CraftBukkit start + // CraftBukkit start
+ Chunk chunk = (Chunk) this.loadedChunkHashMap.get(LongHash.toLong(p_73154_1_, p_73154_2_)); + Chunk chunk = (Chunk) this.loadedChunkHashMap_KC.get(LongHash.toLong(p_73154_1_, p_73154_2_));
+ chunk = chunk == null ? (shouldLoadChunk() ? this.loadChunk(p_73154_1_, p_73154_2_) : this.defaultEmptyChunk) : chunk; // Cauldron handle forge server tick events and load the chunk within 5 seconds of the world being loaded (for chunk loaders) + chunk = chunk == null ? (shouldLoadChunk() ? this.loadChunk(p_73154_1_, p_73154_2_) : this.defaultEmptyChunk) : chunk; // Cauldron handle forge server tick events and load the chunk within 5 seconds of the world being loaded (for chunk loaders)
+ +
+ if (chunk == this.defaultEmptyChunk) + if (chunk == this.defaultEmptyChunk)
@ -274,7 +273,7 @@
{ {
if (this.currentChunkLoader == null) if (this.currentChunkLoader == null)
{ {
@@ -209,6 +308,7 @@ @@ -209,6 +307,7 @@
{ {
try try
{ {
@ -282,7 +281,7 @@
Chunk chunk = this.currentChunkLoader.loadChunk(this.worldObj, p_73239_1_, p_73239_2_); Chunk chunk = this.currentChunkLoader.loadChunk(this.worldObj, p_73239_1_, p_73239_2_);
if (chunk != null) if (chunk != null)
@@ -217,8 +317,11 @@ @@ -217,8 +316,11 @@
if (this.currentChunkProvider != null) if (this.currentChunkProvider != null)
{ {
@ -294,7 +293,7 @@
} }
return chunk; return chunk;
@@ -231,7 +334,7 @@ @@ -231,7 +333,7 @@
} }
} }
@ -303,7 +302,7 @@
{ {
if (this.currentChunkLoader != null) if (this.currentChunkLoader != null)
{ {
@@ -246,7 +349,7 @@ @@ -246,7 +348,7 @@
} }
} }
@ -312,7 +311,7 @@
{ {
if (this.currentChunkLoader != null) if (this.currentChunkLoader != null)
{ {
@@ -254,15 +357,18 @@ @@ -254,15 +356,18 @@
{ {
p_73242_1_.lastSaveTime = this.worldObj.getTotalWorldTime(); p_73242_1_.lastSaveTime = this.worldObj.getTotalWorldTime();
this.currentChunkLoader.saveChunk(this.worldObj, p_73242_1_); this.currentChunkLoader.saveChunk(this.worldObj, p_73242_1_);
@ -332,7 +331,7 @@
} }
} }
@@ -277,6 +383,35 @@ @@ -277,6 +382,35 @@
if (this.currentChunkProvider != null) if (this.currentChunkProvider != null)
{ {
this.currentChunkProvider.populate(p_73153_1_, p_73153_2_, p_73153_3_); this.currentChunkProvider.populate(p_73153_1_, p_73153_2_, p_73153_3_);
@ -368,7 +367,7 @@
GameRegistry.generateWorld(p_73153_2_, p_73153_3_, worldObj, currentChunkProvider, p_73153_1_); GameRegistry.generateWorld(p_73153_2_, p_73153_3_, worldObj, currentChunkProvider, p_73153_1_);
chunk.setChunkModified(); chunk.setChunkModified();
} }
@@ -286,11 +421,13 @@ @@ -286,11 +420,13 @@
public boolean saveChunks(boolean p_73151_1_, IProgressUpdate p_73151_2_) public boolean saveChunks(boolean p_73151_1_, IProgressUpdate p_73151_2_)
{ {
int i = 0; int i = 0;
@ -385,7 +384,7 @@
if (p_73151_1_) if (p_73151_1_)
{ {
@@ -325,36 +462,61 @@ @@ -325,36 +461,60 @@
{ {
if (!this.worldObj.levelSaving) if (!this.worldObj.levelSaving)
{ {
@ -408,7 +407,7 @@
{ {
- if (!this.chunksToUnload.isEmpty()) - if (!this.chunksToUnload.isEmpty())
+ long chunkcoordinates = this.chunksToUnload.popFirst(); + long chunkcoordinates = this.chunksToUnload.popFirst();
+ Chunk chunk = this.loadedChunkHashMap.get(chunkcoordinates); + Chunk chunk = this.loadedChunkHashMap_KC.get(chunkcoordinates);
+ +
+ if (chunk == null) + if (chunk == null)
{ {
@ -451,11 +450,10 @@
+ this.safeSaveChunk(chunk); + this.safeSaveChunk(chunk);
+ this.safeSaveExtraChunkData(chunk); + this.safeSaveExtraChunkData(chunk);
+ // this.unloadQueue.remove(olong); + // this.unloadQueue.remove(olong);
+ this.loadedChunkHashMap.remove(chunkcoordinates); // CraftBukkit + this.loadedChunkHashMap_KC.remove(chunkcoordinates); // CraftBukkit
+ this.loadedChunks.remove(chunk); // Cauldron - vanilla compatibility + this.loadedChunks.remove(chunk); // Cauldron - vanilla compatibility
+ this.loadedChunkHashMap_vanilla.remove(ChunkCoordIntPair.chunkXZ2Int(LongHash.msw(chunkcoordinates), LongHash.lsw(chunkcoordinates))); // Cauldron - vanilla/mystcraft compatibility
+ ForgeChunkManager.putDormantChunk(chunkcoordinates, chunk); + ForgeChunkManager.putDormantChunk(chunkcoordinates, chunk);
+ if(this.loadedChunkHashMap.size() == 0 && ForgeChunkManager.getPersistentChunksFor(this.worldObj).size() == 0 && !DimensionManager.shouldLoadSpawn(this.worldObj.provider.dimensionId)){ + if(this.loadedChunkHashMap_KC.size() == 0 && ForgeChunkManager.getPersistentChunksFor(this.worldObj).size() == 0 && !DimensionManager.shouldLoadSpawn(this.worldObj.provider.dimensionId)){
+ DimensionManager.unloadWorld(this.worldObj.provider.dimensionId); + DimensionManager.unloadWorld(this.worldObj.provider.dimensionId);
+ return currentChunkProvider.unloadQueuedChunks(); + return currentChunkProvider.unloadQueuedChunks();
+ } + }
@ -467,21 +465,21 @@
if (this.currentChunkLoader != null) if (this.currentChunkLoader != null)
{ {
this.currentChunkLoader.chunkTick(); this.currentChunkLoader.chunkTick();
@@ -371,7 +533,7 @@ @@ -371,7 +531,7 @@
public String makeString() public String makeString()
{ {
- return "ServerChunkCache: " + this.loadedChunkHashMap.getNumHashElements() + " Drop: " + this.chunksToUnload.size(); - return "ServerChunkCache: " + this.loadedChunkHashMap.getNumHashElements() + " Drop: " + this.chunksToUnload.size();
+ return "ServerChunkCache: " + this.loadedChunkHashMap.size() + " Drop: " + this.chunksToUnload.size(); // Cauldron + return "ServerChunkCache: " + this.loadedChunkHashMap_KC.size() + " Drop: " + this.chunksToUnload.size(); // Cauldron
} }
public List getPossibleCreatures(EnumCreatureType p_73155_1_, int p_73155_2_, int p_73155_3_, int p_73155_4_) public List getPossibleCreatures(EnumCreatureType p_73155_1_, int p_73155_2_, int p_73155_3_, int p_73155_4_)
@@ -386,8 +548,31 @@ @@ -386,8 +546,31 @@
public int getLoadedChunkCount() public int getLoadedChunkCount()
{ {
- return this.loadedChunkHashMap.getNumHashElements(); - return this.loadedChunkHashMap.getNumHashElements();
+ return this.loadedChunkHashMap.size(); // Cauldron + return this.loadedChunkHashMap_KC.size(); // Cauldron
} }
public void recreateStructures(int p_82695_1_, int p_82695_2_) {} public void recreateStructures(int p_82695_1_, int p_82695_2_) {}
@ -498,8 +496,8 @@
+ public long lastAccessed(int x, int z) + public long lastAccessed(int x, int z)
+ { + {
+ long chunkHash = LongHash.toLong(x, z); + long chunkHash = LongHash.toLong(x, z);
+ if (!loadedChunkHashMap.containsKey(chunkHash)) return 0; + if (!loadedChunkHashMap_KC.containsKey(chunkHash)) return 0;
+ return loadedChunkHashMap.get(chunkHash).lastAccessedTick; + return loadedChunkHashMap_KC.get(chunkHash).lastAccessedTick;
+ } + }
+ +
+ /*private boolean shouldUnloadChunk(Chunk chunk) + /*private boolean shouldUnloadChunk(Chunk chunk)

View File

@ -10,14 +10,13 @@
class ChunkIOProvider implements AsynchronousExecutor.CallBackProvider<QueuedChunk, net.minecraft.world.chunk.Chunk, Runnable, RuntimeException> { class ChunkIOProvider implements AsynchronousExecutor.CallBackProvider<QueuedChunk, net.minecraft.world.chunk.Chunk, Runnable, RuntimeException> {
private final AtomicInteger threadNumber = new AtomicInteger(1); private final AtomicInteger threadNumber = new AtomicInteger(1);
@@ -41,13 +44,21 @@ @@ -41,13 +44,20 @@
queuedChunk.loader.loadEntities(queuedChunk.world, queuedChunk.compound.getCompoundTag("Level"), chunk); queuedChunk.loader.loadEntities(queuedChunk.world, queuedChunk.compound.getCompoundTag("Level"), chunk);
MinecraftForge.EVENT_BUS.post(new ChunkDataEvent.Load(chunk, queuedChunk.compound)); // Don't call ChunkDataEvent.Load async MinecraftForge.EVENT_BUS.post(new ChunkDataEvent.Load(chunk, queuedChunk.compound)); // Don't call ChunkDataEvent.Load async
chunk.lastSaveTime = queuedChunk.provider.worldObj.getTotalWorldTime(); chunk.lastSaveTime = queuedChunk.provider.worldObj.getTotalWorldTime();
- queuedChunk.provider.loadedChunkHashMap.add(ChunkCoordIntPair.chunkXZ2Int(queuedChunk.x, queuedChunk.z), chunk); - queuedChunk.provider.loadedChunkHashMap.add(ChunkCoordIntPair.chunkXZ2Int(queuedChunk.x, queuedChunk.z), chunk);
+ queuedChunk.provider.loadedChunkHashMap.put(LongHash.toLong(queuedChunk.x, queuedChunk.z), chunk); + queuedChunk.provider.loadedChunkHashMap_KC.put(LongHash.toLong(queuedChunk.x, queuedChunk.z), chunk);
queuedChunk.provider.loadedChunks.add(chunk); queuedChunk.provider.loadedChunks.add(chunk);
+ queuedChunk.provider.loadedChunkHashMap_vanilla.add(ChunkCoordIntPair.chunkXZ2Int(queuedChunk.x, queuedChunk.z), chunk); // Cauldron - vanilla/mystcraft compatibility
chunk.onChunkLoad(); chunk.onChunkLoad();
if (queuedChunk.provider.currentChunkProvider != null) { if (queuedChunk.provider.currentChunkProvider != null) {

View File

@ -9,96 +9,96 @@ import java.util.Properties;
import org.spigotmc.RestartCommand; import org.spigotmc.RestartCommand;
public class KCauldron { public class KCauldron {
private static boolean sManifestParsed = false; private static boolean sManifestParsed = false;
private static void parseManifest() { private static void parseManifest() {
if (sManifestParsed) if (sManifestParsed)
return; return;
sManifestParsed = true; sManifestParsed = true;
try { try {
Enumeration<URL> resources = KCauldron.class.getClassLoader() Enumeration<URL> resources = KCauldron.class.getClassLoader()
.getResources("META-INF/MANIFEST.MF"); .getResources("META-INF/MANIFEST.MF");
Properties manifest = new Properties(); Properties manifest = new Properties();
while (resources.hasMoreElements()) { while (resources.hasMoreElements()) {
URL url = resources.nextElement(); URL url = resources.nextElement();
manifest.load(url.openStream()); manifest.load(url.openStream());
String version = manifest.getProperty("KCauldron-Version"); String version = manifest.getProperty("KCauldron-Version");
if (version != null) { if (version != null) {
String path = url.getPath(); String path = url.getPath();
String jarFilePath = path.substring(path.indexOf(":") + 1, String jarFilePath = path.substring(path.indexOf(":") + 1,
path.indexOf("!")); path.indexOf("!"));
jarFilePath = URLDecoder.decode(jarFilePath, "UTF-8"); jarFilePath = URLDecoder.decode(jarFilePath, "UTF-8");
sServerLocation = new File(jarFilePath); sServerLocation = new File(jarFilePath);
sCurrentVersion = version; sCurrentVersion = version;
sGroup = manifest.getProperty("KCauldron-Group"); sGroup = manifest.getProperty("KCauldron-Group");
sBranch = manifest.getProperty("KCauldron-Branch"); sBranch = manifest.getProperty("KCauldron-Branch");
sChannel = manifest.getProperty("KCauldron-Channel"); sChannel = manifest.getProperty("KCauldron-Channel");
break; break;
} }
manifest.clear(); manifest.clear();
} }
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
} }
} }
private static String sCurrentVersion; private static String sCurrentVersion;
public static String getCurrentVersion() { public static String getCurrentVersion() {
parseManifest(); parseManifest();
return sCurrentVersion; return sCurrentVersion;
} }
private static File sServerLocation; private static File sServerLocation;
public static File getServerLocation() { public static File getServerLocation() {
parseManifest(); parseManifest();
return sServerLocation; return sServerLocation;
} }
private static File sServerHome; private static File sServerHome;
public static File getServerHome() { public static File getServerHome() {
if (sServerHome == null) { if (sServerHome == null) {
String home = System.getenv("KCAULDRON_HOME"); String home = System.getenv("KCAULDRON_HOME");
if (home != null) { if (home != null) {
sServerHome = new File(home); sServerHome = new File(home);
} else { } else {
parseManifest(); parseManifest();
sServerHome = sServerLocation.getParentFile(); sServerHome = sServerLocation.getParentFile();
} }
} }
return sServerHome; return sServerHome;
} }
private static String sGroup; private static String sGroup;
public static String getGroup() { public static String getGroup() {
parseManifest(); parseManifest();
return sGroup; return sGroup;
} }
private static String sBranch; private static String sBranch;
public static String getBranch() { public static String getBranch() {
parseManifest(); parseManifest();
return sBranch; return sBranch;
} }
private static String sChannel; private static String sChannel;
public static String getChannel() { public static String getChannel() {
parseManifest(); parseManifest();
return sChannel; return sChannel;
} }
public static File sNewServerLocation; public static File sNewServerLocation;
public static String sNewServerVersion; public static String sNewServerVersion;
public static boolean sUpdateInProgress; public static boolean sUpdateInProgress;
public static void restart() { public static void restart() {
RestartCommand.restart(true); RestartCommand.restart(true);
} }
} }

View File

@ -1,13 +1,10 @@
package kcauldron; package kcauldron;
import static org.objectweb.asm.Opcodes.*; import static org.objectweb.asm.Opcodes.ALOAD;
import static org.objectweb.asm.Opcodes.ARETURN;
import static org.objectweb.asm.Opcodes.GETFIELD;
import org.apache.logging.log4j.Level; import org.apache.logging.log4j.Level;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.FieldVisitor;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.tree.FieldInsnNode; import org.objectweb.asm.tree.FieldInsnNode;
import org.objectweb.asm.tree.InsnList; import org.objectweb.asm.tree.InsnList;
import org.objectweb.asm.tree.InsnNode; import org.objectweb.asm.tree.InsnNode;
@ -19,64 +16,28 @@ import cpw.mods.fml.common.FMLLog;
@Transformer.RegisterTransformer @Transformer.RegisterTransformer
public class KCauldronClassTransformer implements Transformer { public class KCauldronClassTransformer implements Transformer {
@Override @Override
public void transform(final ImagineASM asm) { public void transform(final ImagineASM asm) {
if (asm.is("net.minecraft.world.gen.ChunkProviderServer") if (asm.is("climateControl.utils.ChunkGeneratorExtractor")) {
|| asm.is("net.minecraftforge.common.chunkio.ChunkIOProvider") boolean undergroundBiomesInstalled = false;
|| asm.is("org.bukkit.craftbukkit.CraftWorld") try {
|| asm.is("org.bukkit.craftbukkit.v1_7_R4.CraftWorld")) { Class.forName("exterminatorJeff.undergroundBiomes.worldGen.ChunkProviderWrapper");
FMLLog.log(Level.INFO, "KCauldron: Patching " + asm.getActualName() + " for compatibility with Mystcraft"); undergroundBiomesInstalled = true;
ClassReader reader = new ClassReader(asm.build()); } catch (Exception ignored) {
ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_MAXS); }
reader.accept(new ClassVisitor(ASM5, writer) { if (!undergroundBiomesInstalled) {
@Override FMLLog.log(Level.INFO, "KCauldron: Patching " + asm.getActualName() + " for compatibility with Climate Control");
public FieldVisitor visitField(int access, String name, extractFrom(asm, asm.method("extractFrom",
String desc, String signature, Object value) { "(Lnet/minecraft/world/WorldServer;)Lnet/minecraft/world/chunk/IChunkProvider;").instructions());
if ("loadedChunkHashMap_vanilla".equals(name)) { }
name = asm.isDev() ? "loadedChunkHashMap" : "field_73244_f"; }
} }
return super.visitField(access, name, desc, signature,
value);
}
@Override public void extractFrom(ImagineASM asm, InsnList list) {
public MethodVisitor visitMethod(int access, String name, //Pair<String, String> fieldChunkProvider = asm.field("net/minecraft/world/World", "chunkProvider");
String desc, String signature, String[] exceptions) { list.clear();
return new MethodVisitor(api, super.visitMethod(access, list.add(new IntInsnNode(ALOAD, 1));
name, desc, signature, exceptions)) { list.add(new FieldInsnNode(GETFIELD, "ahb", "v", "Lapu;"));
@Override list.add(new InsnNode(ARETURN));
public void visitFieldInsn(int opcode, String owner, }
String name, String desc) {
if ("loadedChunkHashMap_vanilla".equals(name)) {
name = asm.isDev() ? "loadedChunkHashMap" : "field_73244_f";
}
super.visitFieldInsn(opcode, owner, name, desc);
}
};
}
}, 0);
asm.loadClass(writer.toByteArray());
}
if (asm.is("climateControl.utils.ChunkGeneratorExtractor")) {
boolean undergroundBiomesInstalled = false;
try {
Class.forName("exterminatorJeff.undergroundBiomes.worldGen.ChunkProviderWrapper");
undergroundBiomesInstalled = true;
} catch (Exception ignored) {
}
if (!undergroundBiomesInstalled) {
FMLLog.log(Level.INFO, "KCauldron: Patching " + asm.getActualName() + " for compatibility with Climate Control");
extractFrom(asm, asm.method("extractFrom",
"(Lnet/minecraft/world/WorldServer;)Lnet/minecraft/world/chunk/IChunkProvider;").instructions());
}
}
}
public void extractFrom(ImagineASM asm, InsnList list) {
//Pair<String, String> fieldChunkProvider = asm.field("net/minecraft/world/World", "chunkProvider");
list.clear();
list.add(new IntInsnNode(ALOAD, 1));
list.add(new FieldInsnNode(GETFIELD, "ahb", "v", "Lapu;"));
list.add(new InsnNode(ARETURN));
}
} }

View File

@ -9,72 +9,72 @@ import org.bukkit.command.Command;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
public class KCauldronCommand extends Command { public class KCauldronCommand extends Command {
public static final String NAME = "kc"; public static final String NAME = "kc";
public static final String CHECK = NAME + ".check"; public static final String CHECK = NAME + ".check";
public static final String UPDATE = NAME + ".update"; public static final String UPDATE = NAME + ".update";
public static final String RESTART = NAME + ".restart"; public static final String RESTART = NAME + ".restart";
public KCauldronCommand() { public KCauldronCommand() {
super(NAME); super(NAME);
StringBuilder builder = new StringBuilder(); StringBuilder builder = new StringBuilder();
builder.append(String.format("/%s check - Check to update\n", NAME)); builder.append(String.format("/%s check - Check to update\n", NAME));
builder.append(String builder.append(String
.format("/%s update [version] - Update to specified or latest version\n", .format("/%s update [version] - Update to specified or latest version\n",
NAME)); NAME));
builder.append(String.format("/%s restart - Restart server\n", NAME)); builder.append(String.format("/%s restart - Restart server\n", NAME));
setUsage(builder.toString()); setUsage(builder.toString());
setPermission("kcauldron"); setPermission("kcauldron");
} }
public boolean testPermission(CommandSender target, String permission) { public boolean testPermission(CommandSender target, String permission) {
if (testPermissionSilent(target, permission)) { if (testPermissionSilent(target, permission)) {
return true; return true;
} }
target.sendMessage(ChatColor.RED target.sendMessage(ChatColor.RED
+ "I'm sorry, but you do not have permission to perform this command. Please contact the server administrators if you believe that this is in error."); + "I'm sorry, but you do not have permission to perform this command. Please contact the server administrators if you believe that this is in error.");
return false; return false;
} }
public boolean testPermissionSilent(CommandSender target, String permission) { public boolean testPermissionSilent(CommandSender target, String permission) {
if (!super.testPermissionSilent(target)) { if (!super.testPermissionSilent(target)) {
return false; return false;
} }
for (String p : permission.split(";")) for (String p : permission.split(";"))
if (target.hasPermission(p)) if (target.hasPermission(p))
return true; return true;
return false; return false;
} }
@Override @Override
public boolean execute(CommandSender sender, String commandLabel, public boolean execute(CommandSender sender, String commandLabel,
String[] args) { String[] args) {
if (!testPermission(sender)) if (!testPermission(sender))
return true; return true;
if (args.length == 0) { if (args.length == 0) {
sender.sendMessage(ChatColor.YELLOW + "Please specify action"); sender.sendMessage(ChatColor.YELLOW + "Please specify action");
sender.sendMessage(ChatColor.AQUA + usageMessage); sender.sendMessage(ChatColor.AQUA + usageMessage);
return true; return true;
} }
String action = args[0]; String action = args[0];
if ("check".equals(action)) { if ("check".equals(action)) {
if (!testPermission(sender, CHECK)) if (!testPermission(sender, CHECK))
return true; return true;
sender.sendMessage(ChatColor.GREEN + "Initiated version check..."); sender.sendMessage(ChatColor.GREEN + "Initiated version check...");
KVersionRetriever.startServer(new CommandSenderUpdateCallback( KVersionRetriever.startServer(new CommandSenderUpdateCallback(
sender), false); sender), false);
} else if ("update".equals(action)) { } else if ("update".equals(action)) {
KCauldronUpdater.initUpdate(sender, args.length > 1 ? args[1] KCauldronUpdater.initUpdate(sender, args.length > 1 ? args[1]
: null); : null);
} else if ("restart".equals(action)) { } else if ("restart".equals(action)) {
if (!testPermission(sender, RESTART)) if (!testPermission(sender, RESTART))
return true; return true;
KCauldron.restart(); KCauldron.restart();
} else { } else {
sender.sendMessage(ChatColor.RED + "Unknown action"); sender.sendMessage(ChatColor.RED + "Unknown action");
} }
return true; return true;
} }
} }

View File

@ -9,71 +9,71 @@ import net.minecraftforge.cauldron.configuration.Setting;
import net.minecraftforge.cauldron.configuration.StringSetting; import net.minecraftforge.cauldron.configuration.StringSetting;
public class KCauldronConfig extends ConfigBase { public class KCauldronConfig extends ConfigBase {
public BoolSetting commandEnable = new BoolSetting(this, "command.enable", public BoolSetting commandEnable = new BoolSetting(this, "command.enable",
true, "Enable KCauldron command"); true, "Enable KCauldron command");
public BoolSetting updatecheckerEnable = new BoolSetting(this, public BoolSetting updatecheckerEnable = new BoolSetting(this,
"updatechecker.enable", true, "Enable KCauldron update checker"); "updatechecker.enable", true, "Enable KCauldron update checker");
public StringSetting updatecheckerSymlinks = new StringSetting(this, public StringSetting updatecheckerSymlinks = new StringSetting(this,
"updatechecker.symlinks", "KCauldron.jar", "(Re)create symlinks after update"); "updatechecker.symlinks", "KCauldron.jar", "(Re)create symlinks after update");
public BoolSetting updatecheckerAutoinstall = new BoolSetting(this, public BoolSetting updatecheckerAutoinstall = new BoolSetting(this,
"updatechecker.autoinstall", false, "Install updates without confirming"); "updatechecker.autoinstall", false, "Install updates without confirming");
public BoolSetting updatecheckerAutorestart = new BoolSetting(this, public BoolSetting updatecheckerAutorestart = new BoolSetting(this,
"updatechecker.autorestart", false, "Restart server after updating without confirming (set restart script in spigot.yml)"); "updatechecker.autorestart", false, "Restart server after updating without confirming (set restart script in spigot.yml)");
public BoolSetting updatecheckerQuite = new BoolSetting(this, public BoolSetting updatecheckerQuite = new BoolSetting(this,
"updatechecker.quite", false, "Print less info during update"); "updatechecker.quite", false, "Print less info during update");
public BoolSetting loggingMaterialInjection = new BoolSetting(this, public BoolSetting loggingMaterialInjection = new BoolSetting(this,
"logging.materialInjection", false, "Log material injection event"); "logging.materialInjection", false, "Log material injection event");
public KCauldronConfig() { public KCauldronConfig() {
super("kcauldron.yml", "kc"); super("kcauldron.yml", "kc");
register(commandEnable); register(commandEnable);
register(updatecheckerEnable); register(updatecheckerEnable);
register(updatecheckerSymlinks); register(updatecheckerSymlinks);
register(updatecheckerAutoinstall); register(updatecheckerAutoinstall);
register(updatecheckerAutorestart); register(updatecheckerAutorestart);
register(updatecheckerQuite); register(updatecheckerQuite);
register(loggingMaterialInjection); register(loggingMaterialInjection);
load(); load();
} }
private void register(Setting<?> setting) { private void register(Setting<?> setting) {
settings.put(setting.path, setting); settings.put(setting.path, setting);
} }
@Override @Override
public void registerCommands() { public void registerCommands() {
if (commandEnable.getValue()) { if (commandEnable.getValue()) {
super.registerCommands(); super.registerCommands();
} }
} }
@Override @Override
protected void addCommands() { protected void addCommands() {
commands.put(commandName, new KCauldronCommand()); commands.put(commandName, new KCauldronCommand());
} }
@Override @Override
protected void load() { protected void load() {
try { try {
config = YamlConfiguration.loadConfiguration(configFile); config = YamlConfiguration.loadConfiguration(configFile);
String header = ""; String header = "";
for (Setting<?> toggle : settings.values()) { for (Setting<?> toggle : settings.values()) {
if (!toggle.description.equals("")) if (!toggle.description.equals(""))
header += "Setting: " + toggle.path + " Default: " header += "Setting: " + toggle.path + " Default: "
+ toggle.def + " # " + toggle.description + "\n"; + toggle.def + " # " + toggle.description + "\n";
config.addDefault(toggle.path, toggle.def); config.addDefault(toggle.path, toggle.def);
settings.get(toggle.path).setValue( settings.get(toggle.path).setValue(
config.getString(toggle.path)); config.getString(toggle.path));
} }
config.options().header(header); config.options().header(header);
config.options().copyDefaults(true); config.options().copyDefaults(true);
save(); save();
} catch (Exception ex) { } catch (Exception ex) {
MinecraftServer.getServer().logSevere( MinecraftServer.getServer().logSevere(
"Could not load " + this.configFile); "Could not load " + this.configFile);
ex.printStackTrace(); ex.printStackTrace();
} }
} }
} }

View File

@ -4,16 +4,16 @@ import net.md_5.specialsource.JarMapping;
import net.md_5.specialsource.JarRemapper; import net.md_5.specialsource.JarRemapper;
public class KCauldronRemapper extends JarRemapper { public class KCauldronRemapper extends JarRemapper {
public KCauldronRemapper(JarMapping jarMapping) { public KCauldronRemapper(JarMapping jarMapping) {
super(jarMapping); super(jarMapping);
} }
@Override @Override
public String mapSignature(String signature, boolean typeSignature) { public String mapSignature(String signature, boolean typeSignature) {
try { try {
return super.mapSignature(signature, typeSignature); return super.mapSignature(signature, typeSignature);
} catch (Exception e) { } catch (Exception e) {
return signature; return signature;
} }
} }
} }

View File

@ -5,48 +5,48 @@ import org.apache.logging.log4j.Level;
import cpw.mods.fml.common.FMLLog; import cpw.mods.fml.common.FMLLog;
public class KLog { public class KLog {
private static final KLog DEFAULT_LOGGER = new KLog("KCauldron"); private static final KLog DEFAULT_LOGGER = new KLog("KCauldron");
public static KLog get() { public static KLog get() {
return DEFAULT_LOGGER; return DEFAULT_LOGGER;
} }
public static KLog get(String tag) { public static KLog get(String tag) {
return new KLog("KCauldron: " + tag); return new KLog("KCauldron: " + tag);
} }
private final String mTag; private final String mTag;
public KLog(String tag) { public KLog(String tag) {
mTag = tag; mTag = tag;
} }
public void log(Level level, Throwable throwable, String message, public void log(Level level, Throwable throwable, String message,
Object... args) { Object... args) {
Throwable t = null; Throwable t = null;
if (throwable != null) { if (throwable != null) {
t = new Throwable(); t = new Throwable();
t.initCause(throwable); t.initCause(throwable);
t.fillInStackTrace(); t.fillInStackTrace();
} }
FMLLog.log(mTag, level, t, String.format(message, args)); FMLLog.log(mTag, level, t, String.format(message, args));
} }
public void warning(String message, Object... args) { public void warning(String message, Object... args) {
log(Level.WARN, null, message, args); log(Level.WARN, null, message, args);
} }
public void warning(Throwable throwable, String message, public void warning(Throwable throwable, String message,
Object... args) { Object... args) {
log(Level.WARN, throwable, message, args); log(Level.WARN, throwable, message, args);
} }
public void info(String message, Object... args) { public void info(String message, Object... args) {
log(Level.INFO, null, message, args); log(Level.INFO, null, message, args);
} }
public void info(Throwable throwable, String message, public void info(Throwable throwable, String message,
Object... args) { Object... args) {
log(Level.INFO, throwable, message, args); log(Level.INFO, throwable, message, args);
} }
} }

View File

@ -10,52 +10,52 @@ import org.bukkit.ChatColor;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
public class CommandSenderUpdateCallback implements IVersionCheckCallback { public class CommandSenderUpdateCallback implements IVersionCheckCallback {
private Reference<CommandSender> mSender; private Reference<CommandSender> mSender;
public CommandSenderUpdateCallback(CommandSender sender) { public CommandSenderUpdateCallback(CommandSender sender) {
mSender = new WeakReference<CommandSender>(sender); mSender = new WeakReference<CommandSender>(sender);
} }
protected CommandSender getSender() { protected CommandSender getSender() {
return mSender.get(); return mSender.get();
} }
@Override @Override
public void upToDate() { public void upToDate() {
CommandSender sender = mSender.get(); CommandSender sender = mSender.get();
if (sender != null) { if (sender != null) {
sender.sendMessage(ChatColor.GREEN sender.sendMessage(ChatColor.GREEN
+ "Running version of KCauldron is up-to-date: " + "Running version of KCauldron is up-to-date: "
+ KCauldron.getCurrentVersion()); + KCauldron.getCurrentVersion());
} }
DefaultUpdateCallback.INSTANCE.upToDate(); DefaultUpdateCallback.INSTANCE.upToDate();
} }
@Override @Override
public void newVersion(String newVersion) { public void newVersion(String newVersion) {
CommandSender sender = mSender.get(); CommandSender sender = mSender.get();
if (sender != null) { if (sender != null) {
newVersion(sender, KCauldron.getCurrentVersion(), newVersion); newVersion(sender, KCauldron.getCurrentVersion(), newVersion);
} }
DefaultUpdateCallback.INSTANCE.newVersion(newVersion); DefaultUpdateCallback.INSTANCE.newVersion(newVersion);
} }
public static void newVersion(CommandSender sender, String currentVersion, public static void newVersion(CommandSender sender, String currentVersion,
String newVersion) { String newVersion) {
sender.sendMessage(new String[] { sender.sendMessage(new String[] {
ChatColor.YELLOW + "Found new version of KCauldron: " ChatColor.YELLOW + "Found new version of KCauldron: "
+ newVersion, + newVersion,
ChatColor.YELLOW + "Current is " + currentVersion, ChatColor.YELLOW + "Current is " + currentVersion,
ChatColor.YELLOW + "Type '" + ChatColor.BLUE + "/kc update" ChatColor.YELLOW + "Type '" + ChatColor.BLUE + "/kc update"
+ ChatColor.YELLOW + "' to update" }); + ChatColor.YELLOW + "' to update" });
} }
@Override @Override
public void error(Throwable t) { public void error(Throwable t) {
CommandSender sender = mSender.get(); CommandSender sender = mSender.get();
if (sender != null) { if (sender != null) {
sender.sendMessage(ChatColor.RED sender.sendMessage(ChatColor.RED
+ "Error ocurred durring version check, see details in server log"); + "Error ocurred durring version check, see details in server log");
} }
} }
} }

View File

@ -11,66 +11,66 @@ import org.bukkit.entity.Player;
import org.bukkit.event.player.PlayerJoinEvent; import org.bukkit.event.player.PlayerJoinEvent;
public class DefaultUpdateCallback implements IVersionCheckCallback { public class DefaultUpdateCallback implements IVersionCheckCallback {
public static DefaultUpdateCallback INSTANCE; public static DefaultUpdateCallback INSTANCE;
static { static {
INSTANCE = new DefaultUpdateCallback(); INSTANCE = new DefaultUpdateCallback();
} }
public void onPlayerJoin(PlayerJoinEvent event) { public void onPlayerJoin(PlayerJoinEvent event) {
Player player = event.getPlayer(); Player player = event.getPlayer();
if (mHasUpdate && hasPermission(player)) { if (mHasUpdate && hasPermission(player)) {
sendUpdate(player); sendUpdate(player);
} }
} }
private boolean hasPermission(CommandSender player) { private boolean hasPermission(CommandSender player) {
return player.hasPermission(KCauldronCommand.UPDATE); return player.hasPermission(KCauldronCommand.UPDATE);
} }
private void sendUpdate(CommandSender player) { private void sendUpdate(CommandSender player) {
CommandSenderUpdateCallback.newVersion(player, mCurrentVersion, CommandSenderUpdateCallback.newVersion(player, mCurrentVersion,
mNewVersion); mNewVersion);
} }
private boolean mHasUpdate; private boolean mHasUpdate;
private String mCurrentVersion; private String mCurrentVersion;
private String mNewVersion; private String mNewVersion;
private DefaultUpdateCallback() { private DefaultUpdateCallback() {
} }
@Override @Override
public void upToDate() { public void upToDate() {
mHasUpdate = false; mHasUpdate = false;
mCurrentVersion = KCauldron.getCurrentVersion(); mCurrentVersion = KCauldron.getCurrentVersion();
mNewVersion = null; mNewVersion = null;
} }
@Override @Override
public void newVersion(String newVersion) { public void newVersion(String newVersion) {
mCurrentVersion = KCauldron.getCurrentVersion(); mCurrentVersion = KCauldron.getCurrentVersion();
mNewVersion = newVersion; mNewVersion = newVersion;
if (!mHasUpdate) { if (!mHasUpdate) {
Bukkit.getConsoleSender().sendMessage( Bukkit.getConsoleSender().sendMessage(
"New version of KCauldron avaiable: " + newVersion); "New version of KCauldron avaiable: " + newVersion);
for (Player player : Bukkit.getOnlinePlayers()) { for (Player player : Bukkit.getOnlinePlayers()) {
if (hasPermission(player)) { if (hasPermission(player)) {
sendUpdate(player); sendUpdate(player);
} }
} }
} }
mHasUpdate = true; mHasUpdate = true;
if (MinecraftServer.kcauldronConfig.updatecheckerAutoinstall.getValue() if (MinecraftServer.kcauldronConfig.updatecheckerAutoinstall.getValue()
&& !mNewVersion.equals(KCauldron.sNewServerVersion) && !mNewVersion.equals(KCauldron.sNewServerVersion)
&& !KCauldron.sUpdateInProgress) { && !KCauldron.sUpdateInProgress) {
Bukkit.getConsoleSender().sendMessage("Triggering auto update"); Bukkit.getConsoleSender().sendMessage("Triggering auto update");
KCauldronUpdater.initUpdate(Bukkit.getConsoleSender(), newVersion); KCauldronUpdater.initUpdate(Bukkit.getConsoleSender(), newVersion);
} }
} }
@Override @Override
public void error(Throwable t) { public void error(Throwable t) {
} }
} }

View File

@ -26,181 +26,181 @@ import org.bukkit.command.CommandSender;
import com.google.common.base.Joiner; import com.google.common.base.Joiner;
public class KCauldronUpdater implements Runnable, IVersionCheckCallback { public class KCauldronUpdater implements Runnable, IVersionCheckCallback {
private static final class LatestVersionCallback extends private static final class LatestVersionCallback extends
CommandSenderUpdateCallback { CommandSenderUpdateCallback {
public LatestVersionCallback(CommandSender sender) { public LatestVersionCallback(CommandSender sender) {
super(sender); super(sender);
} }
@Override @Override
public void newVersion(String newVersion) { public void newVersion(String newVersion) {
startUpdate(getSender(), newVersion); startUpdate(getSender(), newVersion);
} }
@Override @Override
public void upToDate() { public void upToDate() {
KCauldron.sUpdateInProgress = false; KCauldron.sUpdateInProgress = false;
CommandSender sender = getSender(); CommandSender sender = getSender();
if (sender != null) { if (sender != null) {
sender.sendMessage(ChatColor.DARK_PURPLE + "Current version (" sender.sendMessage(ChatColor.DARK_PURPLE + "Current version ("
+ KCauldron.getCurrentVersion() + ") is up to date"); + KCauldron.getCurrentVersion() + ") is up to date");
} }
} }
@Override @Override
public void error(Throwable t) { public void error(Throwable t) {
super.error(t); super.error(t);
KCauldron.sUpdateInProgress = false; KCauldron.sUpdateInProgress = false;
} }
} }
public static void initUpdate(CommandSender sender, String version) { public static void initUpdate(CommandSender sender, String version) {
if (KCauldron.sUpdateInProgress) { if (KCauldron.sUpdateInProgress) {
sender.sendMessage(ChatColor.RED sender.sendMessage(ChatColor.RED
+ "Update stopped: another update in progress"); + "Update stopped: another update in progress");
return; return;
} }
KCauldron.sUpdateInProgress = true; KCauldron.sUpdateInProgress = true;
if (version == null) { if (version == null) {
sender.sendMessage(ChatColor.DARK_PURPLE sender.sendMessage(ChatColor.DARK_PURPLE
+ "Fetching latest version..."); + "Fetching latest version...");
KVersionRetriever.startServer(new LatestVersionCallback(sender), KVersionRetriever.startServer(new LatestVersionCallback(sender),
false); false);
} else { } else {
startUpdate(sender, version); startUpdate(sender, version);
} }
} }
private static void startUpdate(CommandSender sender, String version) { private static void startUpdate(CommandSender sender, String version) {
if (sender != null) { if (sender != null) {
sender.sendMessage(ChatColor.DARK_PURPLE + "Starting update to " sender.sendMessage(ChatColor.DARK_PURPLE + "Starting update to "
+ version + "..."); + version + "...");
} }
new KCauldronUpdater(sender, version); new KCauldronUpdater(sender, version);
} }
private final CommandSender mSender; private final CommandSender mSender;
private final String mVersion; private final String mVersion;
private final Thread mThread; private final Thread mThread;
public KCauldronUpdater(CommandSender sender, String version) { public KCauldronUpdater(CommandSender sender, String version) {
mSender = sender; mSender = sender;
mVersion = version; mVersion = version;
mThread = new Thread(this); mThread = new Thread(this);
mThread.setName("KCauldron updater"); mThread.setName("KCauldron updater");
mThread.setPriority(Thread.MIN_PRIORITY); mThread.setPriority(Thread.MIN_PRIORITY);
mThread.start(); mThread.start();
} }
@Override @Override
public void run() { public void run() {
if (!MinecraftServer.kcauldronConfig.updatecheckerQuite.getValue()) { if (!MinecraftServer.kcauldronConfig.updatecheckerQuite.getValue()) {
mSender.sendMessage(ChatColor.DARK_PURPLE mSender.sendMessage(ChatColor.DARK_PURPLE
+ "Retrieving latest KBootstrap version..."); + "Retrieving latest KBootstrap version...");
} }
new KVersionRetriever(this, false, false, "pw.prok", "KBootstrap"); new KVersionRetriever(this, false, false, "pw.prok", "KBootstrap");
} }
@Override @Override
public void upToDate() { public void upToDate() {
} }
@Override @Override
public void newVersion(String kbootstrapVersion) { public void newVersion(String kbootstrapVersion) {
boolean quite = MinecraftServer.kcauldronConfig.updatecheckerQuite boolean quite = MinecraftServer.kcauldronConfig.updatecheckerQuite
.getValue(); .getValue();
try { try {
if (!quite) { if (!quite) {
mSender.sendMessage(ChatColor.DARK_PURPLE mSender.sendMessage(ChatColor.DARK_PURPLE
+ "Downloading KBootstrap " + kbootstrapVersion + "..."); + "Downloading KBootstrap " + kbootstrapVersion + "...");
} }
File kbootstrap = File.createTempFile("kbootstrap", File kbootstrap = File.createTempFile("kbootstrap",
String.valueOf(System.currentTimeMillis())); String.valueOf(System.currentTimeMillis()));
download( download(
"https://api.prok.pw/repo/blob/pw.prok/KBootstrap/latest/app", "https://api.prok.pw/repo/blob/pw.prok/KBootstrap/latest/app",
kbootstrap); kbootstrap);
if (!quite) { if (!quite) {
mSender.sendMessage(ChatColor.DARK_PURPLE mSender.sendMessage(ChatColor.DARK_PURPLE
+ "Installing KCauldron " + mVersion + "Installing KCauldron " + mVersion
+ " via KBootstrap " + kbootstrapVersion + "..."); + " via KBootstrap " + kbootstrapVersion + "...");
} }
String javahome = System.getProperty("java.home"); String javahome = System.getProperty("java.home");
String javapath = javahome + "/bin/java"; String javapath = javahome + "/bin/java";
List<String> command = new ArrayList<String>(); List<String> command = new ArrayList<String>();
command.add(javapath); command.add(javapath);
command.add("-jar"); command.add("-jar");
command.add(kbootstrap.getCanonicalPath()); command.add(kbootstrap.getCanonicalPath());
command.add("--serverDir"); command.add("--serverDir");
command.add(KCauldron.getServerHome().getCanonicalPath()); command.add(KCauldron.getServerHome().getCanonicalPath());
command.add("--installKCauldron"); command.add("--installKCauldron");
command.add(String.format("%s:%s:%s", KCauldron.getGroup(), KCauldron.getChannel(), mVersion)); command.add(String.format("%s:%s:%s", KCauldron.getGroup(), KCauldron.getChannel(), mVersion));
final String[] symlinks = MinecraftServer.kcauldronConfig.updatecheckerSymlinks final String[] symlinks = MinecraftServer.kcauldronConfig.updatecheckerSymlinks
.getValue().trim().split(File.pathSeparator); .getValue().trim().split(File.pathSeparator);
for (String symlink : symlinks) { for (String symlink : symlinks) {
command.add("--serverSymlinks"); command.add("--serverSymlinks");
command.add(symlink); command.add(symlink);
} }
Bukkit.getConsoleSender().sendMessage( Bukkit.getConsoleSender().sendMessage(
"Starting command: " + Joiner.on(' ').join(command)); "Starting command: " + Joiner.on(' ').join(command));
ProcessBuilder builder = new ProcessBuilder(command); ProcessBuilder builder = new ProcessBuilder(command);
builder.environment().put("JAVA_HOME", javahome); builder.environment().put("JAVA_HOME", javahome);
switch (builder.start().waitFor()) { switch (builder.start().waitFor()) {
case 0: case 0:
mSender.sendMessage(ChatColor.GREEN + "KCauldron " + mVersion mSender.sendMessage(ChatColor.GREEN + "KCauldron " + mVersion
+ " installed"); + " installed");
break; break;
default: default:
mSender.sendMessage(ChatColor.RED mSender.sendMessage(ChatColor.RED
+ "Failed to install KCauldron " + mVersion); + "Failed to install KCauldron " + mVersion);
} }
} catch (Exception e) { } catch (Exception e) {
if (!quite) { if (!quite) {
e.printStackTrace(); e.printStackTrace();
} }
if (mSender != null) { if (mSender != null) {
mSender.sendMessage(ChatColor.RED + "Failed update to " mSender.sendMessage(ChatColor.RED + "Failed update to "
+ mVersion); + mVersion);
} }
} finally { } finally {
KCauldron.sUpdateInProgress = false; KCauldron.sUpdateInProgress = false;
} }
} }
@Override @Override
public void error(Throwable t) { public void error(Throwable t) {
KCauldron.sUpdateInProgress = false; KCauldron.sUpdateInProgress = false;
t.printStackTrace(); t.printStackTrace();
} }
private static void download(String url, File destination) private static void download(String url, File destination)
throws IOException { throws IOException {
HttpUriRequest request = RequestBuilder HttpUriRequest request = RequestBuilder
.get() .get()
.setUri(url) .setUri(url)
.addParameter("hostname", .addParameter("hostname",
MinecraftServer.getServer().getHostname()) MinecraftServer.getServer().getHostname())
.addParameter("port", .addParameter("port",
String.valueOf(MinecraftServer.getServer().getPort())) String.valueOf(MinecraftServer.getServer().getPort()))
.build(); .build();
CloseableHttpClient client = HttpClientBuilder.create() CloseableHttpClient client = HttpClientBuilder.create()
.setRedirectStrategy(new LaxRedirectStrategy()) .setRedirectStrategy(new LaxRedirectStrategy())
.setUserAgent("KCauldron Updater").build(); .setUserAgent("KCauldron Updater").build();
HttpResponse response = client.execute(request); HttpResponse response = client.execute(request);
if (response.getStatusLine().getStatusCode() != 200) { if (response.getStatusLine().getStatusCode() != 200) {
client.close(); client.close();
throw new IllegalStateException("Could not download " + url); throw new IllegalStateException("Could not download " + url);
} }
InputStream is = response.getEntity().getContent(); InputStream is = response.getEntity().getContent();
OutputStream os = new FileOutputStream(destination); OutputStream os = new FileOutputStream(destination);
IOUtils.copy(is, os); IOUtils.copy(is, os);
is.close(); is.close();
os.close(); os.close();
client.close(); client.close();
} }
} }

View File

@ -16,112 +16,112 @@ import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser; import org.json.simple.parser.JSONParser;
public class KVersionRetriever implements Runnable, UncaughtExceptionHandler { public class KVersionRetriever implements Runnable, UncaughtExceptionHandler {
private static final boolean DEBUG; private static final boolean DEBUG;
private static final KLog sLogger; private static final KLog sLogger;
private static final JSONParser sParser; private static final JSONParser sParser;
private static MinecraftServer sServer; private static MinecraftServer sServer;
static { static {
DEBUG = false; DEBUG = false;
sLogger = KLog.get(KVersionRetriever.class.getSimpleName()); sLogger = KLog.get(KVersionRetriever.class.getSimpleName());
sParser = new JSONParser(); sParser = new JSONParser();
} }
public static void init(MinecraftServer server) { public static void init(MinecraftServer server) {
sServer = server; sServer = server;
if (MinecraftServer.kcauldronConfig.updatecheckerEnable.getValue()) { if (MinecraftServer.kcauldronConfig.updatecheckerEnable.getValue()) {
startServer(DefaultUpdateCallback.INSTANCE, true); startServer(DefaultUpdateCallback.INSTANCE, true);
} }
} }
public static void startServer(IVersionCheckCallback callback, boolean loop) { public static void startServer(IVersionCheckCallback callback, boolean loop) {
new KVersionRetriever(callback, loop, true, KCauldron.getGroup(), new KVersionRetriever(callback, loop, true, KCauldron.getGroup(),
KCauldron.getChannel()); KCauldron.getChannel());
} }
private final IVersionCheckCallback mCallback; private final IVersionCheckCallback mCallback;
private final boolean mLoop; private final boolean mLoop;
private final Thread mThread; private final Thread mThread;
private final String mGroup; private final String mGroup;
private final String mName; private final String mName;
private final boolean mUpToDateSupport; private final boolean mUpToDateSupport;
public KVersionRetriever(IVersionCheckCallback callback, boolean loop, public KVersionRetriever(IVersionCheckCallback callback, boolean loop,
boolean upToDateSupport, String group, String name) { boolean upToDateSupport, String group, String name) {
if (DEBUG) if (DEBUG)
sLogger.info("Created new version retrivier"); sLogger.info("Created new version retrivier");
mCallback = callback; mCallback = callback;
mLoop = loop; mLoop = loop;
mUpToDateSupport = upToDateSupport; mUpToDateSupport = upToDateSupport;
mGroup = group; mGroup = group;
mName = name; mName = name;
mThread = new Thread(this); mThread = new Thread(this);
mThread.setName("KCauldron version retrievier"); mThread.setName("KCauldron version retrievier");
mThread.setPriority(Thread.MIN_PRIORITY); mThread.setPriority(Thread.MIN_PRIORITY);
mThread.setDaemon(true); mThread.setDaemon(true);
mThread.setUncaughtExceptionHandler(this); mThread.setUncaughtExceptionHandler(this);
mThread.start(); mThread.start();
} }
@Override @Override
public void run() { public void run() {
while (!mThread.isInterrupted()) { while (!mThread.isInterrupted()) {
check(); check();
if (!mLoop) if (!mLoop)
break; break;
try { try {
Thread.sleep(1000 * 60 * 10);// Sleep ten minutes Thread.sleep(1000 * 60 * 10);// Sleep ten minutes
} catch (InterruptedException e) { } catch (InterruptedException e) {
e.printStackTrace(); e.printStackTrace();
} }
} }
} }
private void check() { private void check() {
try { try {
HttpUriRequest request = RequestBuilder HttpUriRequest request = RequestBuilder
.get() .get()
.setUri("https://api.prok.pw/repo/version/" + mGroup + "/" .setUri("https://api.prok.pw/repo/version/" + mGroup + "/"
+ mName) + mName)
.addParameter("hostname", sServer.getHostname()) .addParameter("hostname", sServer.getHostname())
.addParameter("port", "" + sServer.getPort()).build(); .addParameter("port", "" + sServer.getPort()).build();
HttpResponse response = HttpClientBuilder.create() HttpResponse response = HttpClientBuilder.create()
.setUserAgent("KCauldron Version Retriever") .setUserAgent("KCauldron Version Retriever")
.setRedirectStrategy(new LaxRedirectStrategy()).build() .setRedirectStrategy(new LaxRedirectStrategy()).build()
.execute(request); .execute(request);
if (response.getStatusLine().getStatusCode() != 200) { if (response.getStatusLine().getStatusCode() != 200) {
uncaughtException(mThread, new IllegalStateException( uncaughtException(mThread, new IllegalStateException(
"Status code isn't OK")); "Status code isn't OK"));
return; return;
} }
JSONObject json = (JSONObject) sParser.parse(new InputStreamReader( JSONObject json = (JSONObject) sParser.parse(new InputStreamReader(
response.getEntity().getContent())); response.getEntity().getContent()));
String version = (String) json.get("version"); String version = (String) json.get("version");
if (!mUpToDateSupport || KCauldron.getCurrentVersion() == null if (!mUpToDateSupport || KCauldron.getCurrentVersion() == null
|| !version.equals(KCauldron.getCurrentVersion())) { || !version.equals(KCauldron.getCurrentVersion())) {
mCallback.newVersion(version); mCallback.newVersion(version);
} else { } else {
mCallback.upToDate(); mCallback.upToDate();
} }
} catch (Exception e) { } catch (Exception e) {
uncaughtException(null, e); uncaughtException(null, e);
} }
} }
@Override @Override
public void uncaughtException(Thread t, Throwable e) { public void uncaughtException(Thread t, Throwable e) {
sLogger.warning(e, "Error occured during retriving version"); sLogger.warning(e, "Error occured during retriving version");
if (mCallback != null) { if (mCallback != null) {
mCallback.error(e); mCallback.error(e);
} }
} }
public interface IVersionCheckCallback { public interface IVersionCheckCallback {
void upToDate(); void upToDate();
void newVersion(String newVersion); void newVersion(String newVersion);
void error(Throwable t); void error(Throwable t);
} }
} }

View File

@ -0,0 +1,40 @@
package kcauldron.wrapper;
import gnu.trove.map.TLongObjectMap;
import net.minecraft.util.LongHashMap;
public class LongHashMapTrove<T> extends LongHashMap {
private final TLongObjectMap<T> mMap;
public LongHashMapTrove(TLongObjectMap<T> map) {
mMap = map;
}
@SuppressWarnings("unchecked")
@Override
public void add(long key, Object value) {
mMap.put(key, (T) value);
}
@Override
public int getNumHashElements() {
return mMap.size();
}
@Override
public Object getValueByKey(long key) {
return mMap.get(key);
}
@Override
public boolean containsItem(long key) {
return mMap.containsKey(key);
}
@Override
public Object remove(long key) {
return mMap.remove(key);
}
}

View File

@ -0,0 +1,36 @@
package kcauldron.wrapper;
import gnu.trove.map.TLongObjectMap;
import net.minecraft.world.chunk.Chunk;
import org.bukkit.craftbukkit.util.LongHash;
public class VanillaChunkHashMap extends LongHashMapTrove<Chunk> {
public VanillaChunkHashMap(TLongObjectMap<Chunk> map) {
super(map);
}
private static long V2B(long key) {
return LongHash.toLong((int) (key & 0xFFFFFFFFL), (int) (key >>> 32));
}
@Override
public void add(long key, Object value) {
super.add(V2B(key), value);
}
@Override
public boolean containsItem(long key) {
return super.containsItem(V2B(key));
}
@Override
public Object getValueByKey(long key) {
return super.getValueByKey(V2B(key));
}
@Override
public Object remove(long key) {
return super.remove(V2B(key));
}
}

View File

@ -332,7 +332,7 @@ public class CauldronHooks
writer.name("name").value(world.getWorld().getName()); writer.name("name").value(world.getWorld().getName());
writer.name("dimensionId").value(world.provider.dimensionId); writer.name("dimensionId").value(world.provider.dimensionId);
writer.name("players").value(world.playerEntities.size()); writer.name("players").value(world.playerEntities.size());
writer.name("loadedChunks").value(world.theChunkProviderServer.loadedChunkHashMap.size()); writer.name("loadedChunks").value(world.theChunkProviderServer.loadedChunkHashMap_KC.size());
writer.name("activeChunks").value(world.activeChunkSet.size()); writer.name("activeChunks").value(world.activeChunkSet.size());
writer.name("entities").value(world.loadedEntityList.size()); writer.name("entities").value(world.loadedEntityList.size());
writer.name("tiles").value(world.loadedTileEntityList.size()); writer.name("tiles").value(world.loadedTileEntityList.size());

View File

@ -110,7 +110,7 @@ public class CauldronCommand extends Command
for (net.minecraft.world.WorldServer world : MinecraftServer.getServer().worlds) for (net.minecraft.world.WorldServer world : MinecraftServer.getServer().worlds)
{ {
sender.sendMessage(ChatColor.GOLD + "Dimension: " + ChatColor.GRAY + world.provider.dimensionId + sender.sendMessage(ChatColor.GOLD + "Dimension: " + ChatColor.GRAY + world.provider.dimensionId +
ChatColor.GOLD + " Loaded Chunks: " + ChatColor.GRAY + world.theChunkProviderServer.loadedChunkHashMap.size() + ChatColor.GOLD + " Loaded Chunks: " + ChatColor.GRAY + world.theChunkProviderServer.loadedChunkHashMap_KC.size() +
ChatColor.GOLD + " Active Chunks: " + ChatColor.GRAY + world.activeChunkSet.size() + ChatColor.GOLD + " Active Chunks: " + ChatColor.GRAY + world.activeChunkSet.size() +
ChatColor.GOLD + " Entities: " + ChatColor.GRAY + world.loadedEntityList.size() + ChatColor.GOLD + " Entities: " + ChatColor.GRAY + world.loadedEntityList.size() +
ChatColor.GOLD + " Tile Entities: " + ChatColor.GRAY + world.loadedTileEntityList.size() ChatColor.GOLD + " Tile Entities: " + ChatColor.GRAY + world.loadedTileEntityList.size()

View File

@ -138,7 +138,7 @@ public class CraftWorld implements World {
} }
public Chunk[] getLoadedChunks() { public Chunk[] getLoadedChunks() {
Object[] chunks = world.theChunkProviderServer.loadedChunkHashMap.values(); Object[] chunks = world.theChunkProviderServer.loadedChunkHashMap_KC.values();
org.bukkit.Chunk[] craftChunks = new CraftChunk[chunks.length]; org.bukkit.Chunk[] craftChunks = new CraftChunk[chunks.length];
for (int i = 0; i < chunks.length; i++) { for (int i = 0; i < chunks.length; i++) {
@ -262,7 +262,7 @@ public class CraftWorld implements World {
} }
world.theChunkProviderServer.chunksToUnload.remove(x, z); world.theChunkProviderServer.chunksToUnload.remove(x, z);
net.minecraft.world.chunk.Chunk chunk = world.theChunkProviderServer.loadedChunkHashMap.get(LongHash.toLong(x, z)); net.minecraft.world.chunk.Chunk chunk = world.theChunkProviderServer.loadedChunkHashMap_KC.get(LongHash.toLong(x, z));
if (chunk == null) { if (chunk == null) {
world.timings.syncChunkLoadTimer.startTiming(); // Spigot world.timings.syncChunkLoadTimer.startTiming(); // Spigot
@ -276,9 +276,8 @@ public class CraftWorld implements World {
private void chunkLoadPostProcess(net.minecraft.world.chunk.Chunk chunk, int x, int z) { private void chunkLoadPostProcess(net.minecraft.world.chunk.Chunk chunk, int x, int z) {
if (chunk != null) { if (chunk != null) {
world.theChunkProviderServer.loadedChunkHashMap.put(LongHash.toLong(x, z), chunk); world.theChunkProviderServer.loadedChunkHashMap_KC.put(LongHash.toLong(x, z), chunk);
world.theChunkProviderServer.loadedChunks.add(chunk); // Cauldron - vanilla compatibility world.theChunkProviderServer.loadedChunks.add(chunk); // Cauldron - vanilla compatibility
world.theChunkProviderServer.loadedChunkHashMap_vanilla.add(ChunkCoordIntPair.chunkXZ2Int(x, z), chunk);
chunk.onChunkLoad(); chunk.onChunkLoad();
@ -1395,7 +1394,7 @@ public class CraftWorld implements World {
} }
final net.minecraft.world.gen.ChunkProviderServer cps = world.theChunkProviderServer; final net.minecraft.world.gen.ChunkProviderServer cps = world.theChunkProviderServer;
cps.loadedChunkHashMap.forEachValue(new TObjectProcedure<net.minecraft.world.chunk.Chunk>() { cps.loadedChunkHashMap_KC.forEachValue(new TObjectProcedure<net.minecraft.world.chunk.Chunk>() {
@Override @Override
public boolean execute(net.minecraft.world.chunk.Chunk chunk) { public boolean execute(net.minecraft.world.chunk.Chunk chunk) {
// If in use, skip it // If in use, skip it

View File

@ -89,7 +89,7 @@ public class WatchdogThread extends Thread
{ {
log.log(Level.SEVERE, " Dimension:" + world.provider.dimensionId); log.log(Level.SEVERE, " Dimension:" + world.provider.dimensionId);
log.log(Level.SEVERE, log.log(Level.SEVERE,
" Loaded Chunks: " + world.theChunkProviderServer.loadedChunkHashMap.size() + " Active Chunks: " + world.activeChunkSet.size() " Loaded Chunks: " + world.theChunkProviderServer.loadedChunkHashMap_KC.size() + " Active Chunks: " + world.activeChunkSet.size()
+ " Entities: " + world.loadedEntityList.size() + " Tile Entities: " + world.loadedTileEntityList.size()); + " Entities: " + world.loadedEntityList.size() + " Tile Entities: " + world.loadedTileEntityList.size());
log.log(Level.SEVERE, " Entities Last Tick: " + world.entitiesTicked); log.log(Level.SEVERE, " Entities Last Tick: " + world.entitiesTicked);
log.log(Level.SEVERE, " Tiles Last Tick: " + world.tilesTicked); log.log(Level.SEVERE, " Tiles Last Tick: " + world.tilesTicked);
@ -153,7 +153,7 @@ public class WatchdogThread extends Thread
for (net.minecraft.world.WorldServer world : MinecraftServer.getServer().worlds) for (net.minecraft.world.WorldServer world : MinecraftServer.getServer().worlds)
{ {
log.log(Level.WARNING, " Dimension:" + world.provider.dimensionId); log.log(Level.WARNING, " Dimension:" + world.provider.dimensionId);
log.log(Level.WARNING, " Loaded Chunks: " + world.theChunkProviderServer.loadedChunkHashMap.size() + log.log(Level.WARNING, " Loaded Chunks: " + world.theChunkProviderServer.loadedChunkHashMap_KC.size() +
" Active Chunks: " + world.activeChunkSet.size() + " Active Chunks: " + world.activeChunkSet.size() +
" Entities: " + world.loadedEntityList.size() + " Entities: " + world.loadedEntityList.size() +
" Tile Entities: " + world.loadedTileEntityList.size()); " Tile Entities: " + world.loadedTileEntityList.size());