mirror of
https://github.com/barkeser2002/CatServer.git
synced 2026-09-25 08:00:02 +03:00
282 lines
10 KiB
Diff
282 lines
10 KiB
Diff
--- ../src-base/minecraft/net/minecraft/world/gen/ChunkProviderServer.java
|
|
+++ ../src-work/minecraft/net/minecraft/world/gen/ChunkProviderServer.java
|
|
@@ -4,15 +4,11 @@
|
|
import com.google.common.collect.Sets;
|
|
import it.unimi.dsi.fastutil.longs.Long2ObjectMap;
|
|
import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;
|
|
-import java.io.IOException;
|
|
-import java.util.Collection;
|
|
-import java.util.Iterator;
|
|
-import java.util.List;
|
|
-import java.util.Set;
|
|
-import javax.annotation.Nullable;
|
|
+import net.minecraft.block.BlockSand;
|
|
import net.minecraft.crash.CrashReport;
|
|
import net.minecraft.crash.CrashReportCategory;
|
|
import net.minecraft.entity.EnumCreatureType;
|
|
+import net.minecraft.server.MinecraftServer;
|
|
import net.minecraft.util.ReportedException;
|
|
import net.minecraft.util.math.BlockPos;
|
|
import net.minecraft.util.math.ChunkPos;
|
|
@@ -21,22 +17,58 @@
|
|
import net.minecraft.world.WorldServer;
|
|
import net.minecraft.world.biome.Biome;
|
|
import net.minecraft.world.chunk.Chunk;
|
|
+import net.minecraft.world.chunk.EmptyChunk;
|
|
import net.minecraft.world.chunk.IChunkGenerator;
|
|
import net.minecraft.world.chunk.IChunkProvider;
|
|
+import net.minecraft.world.chunk.storage.AnvilChunkLoader;
|
|
import net.minecraft.world.chunk.storage.IChunkLoader;
|
|
+import net.minecraftforge.common.ForgeChunkManager;
|
|
+import net.minecraftforge.common.chunkio.ChunkIOExecutor;
|
|
+import net.minecraftforge.fml.common.FMLCommonHandler;
|
|
+import net.minecraftforge.fml.common.FMLLog;
|
|
+import net.minecraftforge.fml.common.registry.GameRegistry;
|
|
import org.apache.logging.log4j.LogManager;
|
|
import org.apache.logging.log4j.Logger;
|
|
+import org.bukkit.Server;
|
|
+import org.bukkit.craftbukkit.util.LongHash;
|
|
+import org.bukkit.craftbukkit.util.LongHashSet;
|
|
+import org.bukkit.event.world.ChunkUnloadEvent;
|
|
|
|
+import javax.annotation.Nullable;
|
|
+import java.io.IOException;
|
|
+import java.util.*;
|
|
+
|
|
+
|
|
public class ChunkProviderServer implements IChunkProvider
|
|
{
|
|
private static final Logger LOGGER = LogManager.getLogger();
|
|
- private final Set<Long> droppedChunksSet = Sets.<Long>newHashSet();
|
|
+ public final Set<Long> droppedChunksSet = Sets.<Long>newHashSet();
|
|
public final IChunkGenerator chunkGenerator;
|
|
public final IChunkLoader chunkLoader;
|
|
- public final Long2ObjectMap<Chunk> id2ChunkMap = new Long2ObjectOpenHashMap(8192);
|
|
+ protected Chunk lastChunkByPos = null;
|
|
+ public final Long2ObjectMap<Chunk> id2ChunkMap = new Long2ObjectOpenHashMap<Chunk>(8192){
|
|
+
|
|
+ @Override
|
|
+ public Chunk get(long key){
|
|
+ if(lastChunkByPos != null && key == lastChunkByPos.chunkKey){
|
|
+ return lastChunkByPos;
|
|
+ }
|
|
+ return lastChunkByPos = super.get(key);
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public Chunk remove(long key) {
|
|
+ if(lastChunkByPos != null && key == lastChunkByPos.chunkKey){
|
|
+ lastChunkByPos = null;
|
|
+ }
|
|
+ return super.remove(key);
|
|
+ }
|
|
+ };
|
|
public final WorldServer worldObj;
|
|
private Set<Long> loadingChunks = com.google.common.collect.Sets.newHashSet();
|
|
+ public boolean loadChunkOnProvideRequest = true;
|
|
|
|
+
|
|
public ChunkProviderServer(WorldServer worldObjIn, IChunkLoader chunkLoaderIn, IChunkGenerator chunkGeneratorIn)
|
|
{
|
|
this.worldObj = worldObjIn;
|
|
@@ -60,8 +92,10 @@
|
|
|
|
public void unloadAllChunks()
|
|
{
|
|
- for (Chunk chunk : this.id2ChunkMap.values())
|
|
+ Iterator<Chunk> iterator = this.id2ChunkMap.values().iterator();
|
|
+ while (iterator.hasNext())
|
|
{
|
|
+ Chunk chunk = iterator.next();
|
|
this.unload(chunk);
|
|
}
|
|
}
|
|
@@ -101,9 +135,9 @@
|
|
|
|
if (chunk != null)
|
|
{
|
|
- this.id2ChunkMap.put(ChunkPos.asLong(x, z), chunk);
|
|
- chunk.onChunkLoad();
|
|
- chunk.populateChunk(this, this.chunkGenerator);
|
|
+ this.id2ChunkMap.put(ChunkPos.asLong(x, z), chunk);
|
|
+ chunk.onChunkLoad();
|
|
+ chunk.populateChunk(this, this.chunkGenerator);
|
|
}
|
|
|
|
loadingChunks.remove(pos);
|
|
@@ -122,6 +156,24 @@
|
|
}
|
|
}
|
|
|
|
+ /*AnvilChunkLoader loader = null;
|
|
+
|
|
+ if (this.chunkGenerator instanceof AnvilChunkLoader)
|
|
+ {
|
|
+ loader = (AnvilChunkLoader) this.chunkGenerator;
|
|
+ }
|
|
+ if (chunk == null && loader != null && loader.chunkExists(this.worldObj,x,z))
|
|
+ {
|
|
+ if(runnable != null){
|
|
+ ChunkIOExecutor.queueChunkLoad(this.worldObj, loader, this, x, z, runnable);
|
|
+ return null;
|
|
+ }else{
|
|
+ chunk = ChunkIOExecutor.syncChunkLoad(this.worldObj, loader, this, x, z);
|
|
+ }
|
|
+ } else if (chunk == null) {
|
|
+ chunk = this.provideChunk(x,z);
|
|
+ }
|
|
+*/
|
|
// If we didn't load the chunk async and have a callback run it now
|
|
if (runnable != null) runnable.run();
|
|
return chunk;
|
|
@@ -133,6 +185,7 @@
|
|
|
|
if (chunk == null)
|
|
{
|
|
+ worldObj.timings.syncChunkLoadTimer.startTiming(); // Spigot
|
|
long i = ChunkPos.asLong(x, z);
|
|
|
|
try
|
|
@@ -151,12 +204,57 @@
|
|
|
|
this.id2ChunkMap.put(i, chunk);
|
|
chunk.onChunkLoad();
|
|
- chunk.populateChunk(this, this.chunkGenerator);
|
|
+ chunk.loadNearby(this, this.chunkGenerator,true);
|
|
+ worldObj.timings.syncChunkLoadTimer.stopTiming(); // Spigot
|
|
}
|
|
|
|
return chunk;
|
|
}
|
|
+ public void populate(IChunkProvider p_73153_1_, int p_73153_2_, int p_73153_3_)
|
|
+ {
|
|
+ Chunk chunk = this.provideChunk(p_73153_2_, p_73153_3_);
|
|
|
|
+ if (!chunk.isTerrainPopulated())
|
|
+ {
|
|
+ chunk.resetRelightChecks();
|
|
+
|
|
+ if (this.chunkGenerator != null)
|
|
+ {
|
|
+ this.chunkGenerator.populate(p_73153_2_, p_73153_3_);
|
|
+ // CraftBukkit start
|
|
+ BlockSand.fallInstantly = true;
|
|
+ Random random = new Random();
|
|
+ random.setSeed(worldObj.getSeed());
|
|
+ long xRand = random.nextLong() / 2L * 2L + 1L;
|
|
+ long zRand = random.nextLong() / 2L * 2L + 1L;
|
|
+ random.setSeed((long) p_73153_2_ * xRand + (long) p_73153_3_ * zRand ^ worldObj.getSeed());
|
|
+ org.bukkit.World world = this.worldObj.getWorld();
|
|
+
|
|
+ if (world != null)
|
|
+ {
|
|
+ this.worldObj.populating = true;
|
|
+
|
|
+ try
|
|
+ {
|
|
+ for (org.bukkit.generator.BlockPopulator populator : world.getPopulators())
|
|
+ {
|
|
+ populator.populate(world, random, chunk.bukkitChunk);
|
|
+ }
|
|
+ }
|
|
+ finally
|
|
+ {
|
|
+ this.worldObj.populating = false;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ BlockSand.fallInstantly = false;
|
|
+ this.worldObj.getServer().getPluginManager().callEvent(new org.bukkit.event.world.ChunkPopulateEvent(chunk.bukkitChunk));
|
|
+ // CraftBukkit end
|
|
+ GameRegistry.generateWorld(p_73153_2_, p_73153_3_, worldObj, this.chunkGenerator, p_73153_1_);
|
|
+ chunk.setChunkModified();
|
|
+ }
|
|
+ }
|
|
+ }
|
|
@Nullable
|
|
private Chunk loadChunkFromFile(int x, int z)
|
|
{
|
|
@@ -212,11 +310,10 @@
|
|
{
|
|
int i = 0;
|
|
List<Chunk> list = Lists.newArrayList(this.id2ChunkMap.values());
|
|
+ Iterator<Chunk> iterator = this.getLoadedChunks().iterator();
|
|
+ while (iterator.hasNext()){
|
|
+ Chunk chunk = iterator.next();
|
|
|
|
- for (int j = 0; j < ((List)list).size(); ++j)
|
|
- {
|
|
- Chunk chunk = (Chunk)list.get(j);
|
|
-
|
|
if (p_186027_1_)
|
|
{
|
|
this.saveChunkExtraData(chunk);
|
|
@@ -228,7 +325,7 @@
|
|
chunk.setModified(false);
|
|
++i;
|
|
|
|
- if (i == 24 && !p_186027_1_)
|
|
+ if (i == 24 && !p_186027_1_ && false) //Spigot patch..
|
|
{
|
|
return false;
|
|
}
|
|
@@ -263,14 +360,14 @@
|
|
|
|
if (chunk != null && chunk.unloaded)
|
|
{
|
|
- chunk.onChunkUnload();
|
|
- this.saveChunkData(chunk);
|
|
- this.saveChunkExtraData(chunk);
|
|
- this.id2ChunkMap.remove(olong);
|
|
+ if (!unloadChunk(chunk, true)) {
|
|
+ continue;
|
|
+ }
|
|
+
|
|
++i;
|
|
net.minecraftforge.common.ForgeChunkManager.putDormantChunk(ChunkPos.asLong(chunk.xPosition, chunk.zPosition), chunk);
|
|
if (id2ChunkMap.size() == 0 && net.minecraftforge.common.ForgeChunkManager.getPersistentChunksFor(this.worldObj).size() == 0 && !this.worldObj.provider.getDimensionType().shouldLoadSpawn()){
|
|
- net.minecraftforge.common.DimensionManager.unloadWorld(this.worldObj.provider.getDimension());
|
|
+ //net.minecraftforge.common.DimensionManager.unloadWorld(this.worldObj.provider.getDimension()); //CatServer - Disable forge unload world
|
|
break;
|
|
}
|
|
}
|
|
@@ -283,6 +380,38 @@
|
|
return false;
|
|
}
|
|
|
|
+ private boolean unloadChunk(Chunk chunk, boolean save) {
|
|
+ ChunkUnloadEvent event = new ChunkUnloadEvent(chunk.bukkitChunk, save);
|
|
+ this.worldObj.getServer().getPluginManager().callEvent(event);
|
|
+ if (event.isCancelled()) {
|
|
+ return false;
|
|
+ }
|
|
+ save = event.isSaveChunk();
|
|
+
|
|
+ // Update neighbor counts
|
|
+ for (int x = -2; x < 3; x++) {
|
|
+ for (int z = -2; z < 3; z++) {
|
|
+ if (x == 0 && z == 0) {
|
|
+ continue;
|
|
+ }
|
|
+
|
|
+ Chunk neighbor = this.getLoadedChunk(chunk.xPosition + x, chunk.zPosition + z);
|
|
+ if (neighbor != null) {
|
|
+ neighbor.setNeighborUnloaded(-x, -z);
|
|
+ chunk.setNeighborUnloaded(x, z);
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ // Moved from unloadChunks above
|
|
+ chunk.onChunkUnload();
|
|
+ if(save){
|
|
+ this.saveChunkData(chunk);
|
|
+ this.saveChunkExtraData(chunk);
|
|
+ }
|
|
+ this.id2ChunkMap.remove(chunk.chunkKey);
|
|
+ return true;
|
|
+ }
|
|
+
|
|
public boolean canSave()
|
|
{
|
|
return !this.worldObj.disableLevelSaving;
|