[Forge] Fix //regen + improve performance.

This commit is contained in:
Kenzie Togami 2016-06-25 11:37:07 -07:00
parent d0cf497939
commit b3d6644972
2 changed files with 39 additions and 20 deletions

View File

@ -42,7 +42,6 @@ import java.lang.ref.WeakReference;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Random; import java.util.Random;
import java.util.Set;
import java.util.logging.Level; import java.util.logging.Level;
import java.util.logging.Logger; import java.util.logging.Logger;
import javax.annotation.Nullable; import javax.annotation.Nullable;
@ -54,15 +53,21 @@ import net.minecraft.block.BlockPlanks;
import net.minecraft.block.state.IBlockState; import net.minecraft.block.state.IBlockState;
import net.minecraft.entity.EntityList; import net.minecraft.entity.EntityList;
import net.minecraft.entity.item.EntityItem; import net.minecraft.entity.item.EntityItem;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.init.Blocks; import net.minecraft.init.Blocks;
import net.minecraft.inventory.IInventory; import net.minecraft.inventory.IInventory;
import net.minecraft.nbt.NBTTagCompound; import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.network.play.server.SPacketChunkData;
import net.minecraft.server.management.PlayerChunkMap;
import net.minecraft.server.management.PlayerChunkMapEntry;
import net.minecraft.tileentity.TileEntity; import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.ChunkPos; import net.minecraft.util.math.ChunkPos;
import net.minecraft.world.World; import net.minecraft.world.World;
import net.minecraft.world.WorldServer;
import net.minecraft.world.biome.Biome; import net.minecraft.world.biome.Biome;
import net.minecraft.world.chunk.Chunk; import net.minecraft.world.chunk.Chunk;
import net.minecraft.world.chunk.IChunkGenerator;
import net.minecraft.world.chunk.IChunkProvider; import net.minecraft.world.chunk.IChunkProvider;
import net.minecraft.world.gen.ChunkProviderServer; import net.minecraft.world.gen.ChunkProviderServer;
import net.minecraft.world.gen.feature.WorldGenBigMushroom; import net.minecraft.world.gen.feature.WorldGenBigMushroom;
@ -238,6 +243,11 @@ public class ForgeWorld extends AbstractWorld {
@Override @Override
public boolean regenerate(Region region, EditSession editSession) { public boolean regenerate(Region region, EditSession editSession) {
// Don't even try to regen if it's going to fail.
IChunkProvider provider = getWorld().getChunkProvider();
if (!(provider instanceof ChunkProviderServer)) {
return false;
}
BaseBlock[] history = new BaseBlock[256 * (getMaxY() + 1)]; BaseBlock[] history = new BaseBlock[256 * (getMaxY() + 1)];
for (Vector2D chunk : region.getChunks()) { for (Vector2D chunk : region.getChunks()) {
@ -252,28 +262,29 @@ public class ForgeWorld extends AbstractWorld {
} }
} }
} }
PlayerChunkMap playerManager = ((WorldServer) getWorld()).getPlayerChunkMap();
List<EntityPlayerMP> oldWatchers = null;
Chunk mcChunk = null;
try { try {
Set<Vector2D> chunks = region.getChunks();
IChunkProvider provider = getWorld().getChunkProvider();
if (!(provider instanceof ChunkProviderServer)) {
return false;
}
ChunkProviderServer chunkServer = (ChunkProviderServer) provider; ChunkProviderServer chunkServer = (ChunkProviderServer) provider;
for (Vector2D coord : chunks) { IChunkGenerator gen = chunkServer.chunkGenerator;
long pos = ChunkPos.chunkXZ2Int(coord.getBlockX(), coord.getBlockZ()); long pos = ChunkPos.chunkXZ2Int(chunk.getBlockX(), chunk.getBlockZ());
Chunk mcChunk; if (chunkServer.chunkExists(chunk.getBlockX(), chunk.getBlockZ())) {
if (chunkServer.chunkExists(coord.getBlockX(), coord.getBlockZ())) { mcChunk = chunkServer.loadChunk(chunk.getBlockX(), chunk.getBlockZ());
mcChunk = chunkServer.loadChunk(coord.getBlockX(), coord.getBlockZ()); PlayerChunkMapEntry entry = playerManager.getEntry(chunk.getBlockX(), chunk.getBlockZ());
mcChunk.onChunkUnload(); if (entry != null) {
} oldWatchers = entry.players;
chunkServer.droppedChunksSet.remove(pos); playerManager.removeEntry(entry);
chunkServer.id2ChunkMap.remove(pos);
mcChunk = chunkServer.provideChunk(coord.getBlockX(), coord.getBlockZ());
chunkServer.id2ChunkMap.put(pos, mcChunk);
if (mcChunk != null) {
mcChunk.onChunkLoad();
mcChunk.populateChunk(chunkServer, chunkServer.chunkGenerator);
} }
mcChunk.onChunkUnload();
}
chunkServer.droppedChunksSet.remove(pos);
chunkServer.id2ChunkMap.remove(pos);
mcChunk = gen.provideChunk(chunk.getBlockX(), chunk.getBlockZ());
chunkServer.id2ChunkMap.put(pos, mcChunk);
if (mcChunk != null) {
mcChunk.onChunkLoad();
mcChunk.populateChunk(chunkServer, chunkServer.chunkGenerator);
} }
} catch (Throwable t) { } catch (Throwable t) {
logger.log(Level.WARNING, "Failed to generate chunk", t); logger.log(Level.WARNING, "Failed to generate chunk", t);
@ -294,6 +305,13 @@ public class ForgeWorld extends AbstractWorld {
} }
} }
} }
// We don't need to recreate the ChunkMapEntry unless there are players
// but addPlayer handles that for us
if (oldWatchers != null) {
for (EntityPlayerMP player : oldWatchers) {
playerManager.addPlayer(player);
}
}
} }
return false; return false;

View File

@ -1 +1,2 @@
public net.minecraft.world.gen.ChunkProviderServer field_73248_b # droppedChunksSet public net.minecraft.world.gen.ChunkProviderServer field_73248_b # droppedChunksSet
public net.minecraft.server.management.PlayerChunkMapEntry field_187283_c # players