Close #18 (allow client use on servers)
This commit is contained in:
@@ -15,6 +15,7 @@ import net.minecraft.block.Blocks;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.renderer.color.BlockColors;
|
||||
import net.minecraft.world.DimensionType;
|
||||
import net.minecraft.world.IWorld;
|
||||
import net.minecraft.world.chunk.ChunkSection;
|
||||
import net.minecraft.world.chunk.IChunk;
|
||||
import net.minecraft.world.gen.Heightmap;
|
||||
@@ -55,13 +56,13 @@ public class LodBuilder
|
||||
|
||||
|
||||
|
||||
public void generateLodChunkAsync(IChunk chunk, LodWorld lodWorld, DimensionType dim)
|
||||
public void generateLodChunkAsync(IChunk chunk, LodWorld lodWorld, IWorld world)
|
||||
{
|
||||
if (lodWorld == null || !lodWorld.getIsWorldLoaded())
|
||||
return;
|
||||
|
||||
// is this chunk from the same world as the lodWorld?
|
||||
if (!lodWorld.getWorldName().equals(LodUtils.getCurrentWorldID()))
|
||||
if (!lodWorld.getWorldName().equals(LodUtils.getWorldID(world)))
|
||||
// we are not in the same world anymore
|
||||
// don't add this LOD
|
||||
return;
|
||||
@@ -77,13 +78,15 @@ public class LodBuilder
|
||||
{
|
||||
try
|
||||
{
|
||||
DimensionType dim = world.getDimensionType();
|
||||
|
||||
LodChunk lod = generateLodFromChunk(chunk);
|
||||
|
||||
LodDimension lodDim;
|
||||
|
||||
if (lodWorld.getLodDimension(dim) == null)
|
||||
{
|
||||
lodDim = new LodDimension(dim, regionWidth);
|
||||
lodDim = new LodDimension(dim, lodWorld, regionWidth);
|
||||
lodWorld.addLodDimension(lodDim);
|
||||
}
|
||||
else
|
||||
|
||||
@@ -62,7 +62,7 @@ public class LodChunkGenWorker implements IWorker
|
||||
//System.out.println(endTime - startTime + "\t" + lodBuilder.hasBlockData(chunk));
|
||||
|
||||
|
||||
lodBuilder.generateLodChunkAsync(chunk, ClientProxy.getLodWorld(), serverWorld.getDimensionType());
|
||||
lodBuilder.generateLodChunkAsync(chunk, ClientProxy.getLodWorld(), serverWorld);
|
||||
// this is called so that the new LOD chunk is drawn
|
||||
// after it is generated
|
||||
lodRenderer.regenerateLODsNextFrame();
|
||||
|
||||
@@ -12,8 +12,6 @@ import com.backsun.lod.objects.LodChunk;
|
||||
import com.backsun.lod.objects.LodDimension;
|
||||
import com.backsun.lod.objects.LodRegion;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
|
||||
/**
|
||||
* This object handles creating LodRegions
|
||||
* from files and saving LodRegion objects
|
||||
@@ -63,11 +61,6 @@ public class LodDimensionFileHandler
|
||||
*/
|
||||
public LodRegion loadRegionFromFile(int regionX, int regionZ)
|
||||
{
|
||||
// we don't currently support reading or writing
|
||||
// files when connected to a server
|
||||
if (!Minecraft.getInstance().isIntegratedServerRunning())
|
||||
return null;
|
||||
|
||||
if (!readyToReadAndWrite())
|
||||
return null;
|
||||
|
||||
@@ -138,11 +131,6 @@ public class LodDimensionFileHandler
|
||||
*/
|
||||
public synchronized void saveDirtyRegionsToFileAsync()
|
||||
{
|
||||
// we don't currently support reading or writing
|
||||
// files when connected to a server
|
||||
if (!Minecraft.getInstance().isIntegratedServerRunning())
|
||||
return;
|
||||
|
||||
if (!readyToReadAndWrite())
|
||||
// we aren't ready to read and write yet
|
||||
return;
|
||||
@@ -231,7 +219,7 @@ public class LodDimensionFileHandler
|
||||
// ".\Super Flat\DIM-1\data"
|
||||
// or
|
||||
// ".\Super Flat\data"
|
||||
return dimensionDataSaveFolder.getCanonicalPath() + "\\lod\\" +
|
||||
return dimensionDataSaveFolder.getCanonicalPath() + "\\" +
|
||||
FILE_NAME_PREFIX + "." + regionX + "." + regionZ + FILE_EXTENSION;
|
||||
}
|
||||
catch(IOException e)
|
||||
|
||||
@@ -1,11 +1,16 @@
|
||||
package com.backsun.lod.objects;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
import com.backsun.lod.handlers.LodDimensionFileHandler;
|
||||
import com.backsun.lod.util.LodUtils;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.util.math.ChunkPos;
|
||||
import net.minecraft.world.DimensionType;
|
||||
import net.minecraft.world.server.ServerChunkProvider;
|
||||
import net.minecraft.world.server.ServerWorld;
|
||||
|
||||
/**
|
||||
* This object holds all loaded LOD regions
|
||||
@@ -30,13 +35,42 @@ public class LodDimension
|
||||
private LodDimensionFileHandler fileHandler;
|
||||
|
||||
|
||||
public LodDimension(DimensionType newDimension, int newMaxWidth)
|
||||
public LodDimension(DimensionType newDimension, LodWorld lodWorld, int newMaxWidth)
|
||||
{
|
||||
dimension = newDimension;
|
||||
width = newMaxWidth;
|
||||
|
||||
ServerChunkProvider provider = LodUtils.getServerWorldFromDimension(newDimension).getChunkProvider();
|
||||
fileHandler = new LodDimensionFileHandler(provider.getSavedData().folder, this);
|
||||
try
|
||||
{
|
||||
Minecraft mc = Minecraft.getInstance();
|
||||
|
||||
File saveDir;
|
||||
if(mc.isIntegratedServerRunning())
|
||||
{
|
||||
// local world
|
||||
|
||||
ServerWorld serverWorld = LodUtils.getServerWorldFromDimension(newDimension);
|
||||
// provider needs a separate variable to prevent
|
||||
// the compiler from complaining
|
||||
ServerChunkProvider provider = serverWorld.getChunkProvider();
|
||||
saveDir = new File(provider.getSavedData().folder.getCanonicalFile() + "\\lod");
|
||||
}
|
||||
else
|
||||
{
|
||||
// connected to server
|
||||
|
||||
saveDir = new File(mc.gameDir.getCanonicalFile() +
|
||||
"\\lod server data\\" + LodUtils.getDimensionIDFromWorld(mc.world));
|
||||
}
|
||||
|
||||
fileHandler = new LodDimensionFileHandler(saveDir, this);
|
||||
}
|
||||
catch(IOException e)
|
||||
{
|
||||
// the file handler wasn't able to be created
|
||||
// we won't be able to read or write any files
|
||||
}
|
||||
|
||||
|
||||
regions = new LodRegion[width][width];
|
||||
isRegionDirty = new boolean[width][width];
|
||||
@@ -229,7 +263,7 @@ public class LodDimension
|
||||
region.addLod(lod);
|
||||
|
||||
// don't save empty place holders to disk
|
||||
if (!lod.isPlaceholder())
|
||||
if (!lod.isPlaceholder() && fileHandler != null)
|
||||
{
|
||||
// mark the region as dirty so it will be saved to disk
|
||||
int xIndex = (pos.x - centerX) + halfWidth;
|
||||
@@ -265,7 +299,10 @@ public class LodDimension
|
||||
*/
|
||||
public LodRegion getRegionFromFile(int regionX, int regionZ)
|
||||
{
|
||||
return fileHandler.loadRegionFromFile(regionX, regionZ);
|
||||
if (fileHandler != null)
|
||||
return fileHandler.loadRegionFromFile(regionX, regionZ);
|
||||
else
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -19,9 +19,11 @@ public class LodWorld
|
||||
/** If true then the LOD world is setup and ready to use */
|
||||
private boolean isWorldLoaded = false;
|
||||
|
||||
public static final String NO_WORLD_LOADED = "No world loaded";
|
||||
|
||||
public LodWorld()
|
||||
{
|
||||
worldName = "No world loaded";
|
||||
worldName = NO_WORLD_LOADED;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -31,6 +33,17 @@ public class LodWorld
|
||||
*/
|
||||
public void selectWorld(String newWorldName)
|
||||
{
|
||||
if(newWorldName.isEmpty())
|
||||
{
|
||||
deselectWorld();
|
||||
return;
|
||||
}
|
||||
|
||||
if (worldName.equals(newWorldName))
|
||||
// don't recreate everything if we
|
||||
// didn't actually change worlds
|
||||
return;
|
||||
|
||||
worldName = newWorldName;
|
||||
lodDimensions = new Hashtable<DimensionType, LodDimension>();
|
||||
isWorldLoaded = true;
|
||||
@@ -43,7 +56,7 @@ public class LodWorld
|
||||
*/
|
||||
public void deselectWorld()
|
||||
{
|
||||
worldName = "No world loaded";
|
||||
worldName = NO_WORLD_LOADED;
|
||||
lodDimensions = null;
|
||||
isWorldLoaded = false;
|
||||
}
|
||||
|
||||
@@ -14,9 +14,6 @@ import net.minecraftforge.event.world.ChunkEvent;
|
||||
import net.minecraftforge.event.world.WorldEvent;
|
||||
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
||||
|
||||
//TODO Find a way to replace getIntegratedServer so this mod could be used on non-local worlds.
|
||||
// Minecraft.getMinecraft().getIntegratedServer()
|
||||
|
||||
/**
|
||||
* This handles all events sent to the client,
|
||||
* and is the starting point for most of this program.
|
||||
@@ -51,9 +48,12 @@ public class ClientProxy
|
||||
*/
|
||||
public void renderLods(float partialTicks)
|
||||
{
|
||||
if (mc == null || mc.player == null || !lodWorld.getIsWorldLoaded())
|
||||
return;
|
||||
|
||||
// update each regions' width to match the new render distance
|
||||
int newWidth = Math.max(4, (mc.gameSettings.renderDistanceChunks * LodChunk.WIDTH * 2) / LodRegion.SIZE);
|
||||
if (lodWorld != null && lodBuilder.regionWidth != newWidth)
|
||||
if (lodBuilder.regionWidth != newWidth)
|
||||
{
|
||||
lodWorld.resizeDimensionRegionWidth(newWidth);
|
||||
lodBuilder.regionWidth = newWidth;
|
||||
@@ -63,10 +63,6 @@ public class ClientProxy
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (mc == null || mc.player == null || !lodWorld.getIsWorldLoaded())
|
||||
return;
|
||||
|
||||
LodDimension lodDim = lodWorld.getLodDimension(mc.player.world.getDimensionType());
|
||||
if (lodDim == null)
|
||||
return;
|
||||
@@ -99,27 +95,33 @@ public class ClientProxy
|
||||
@SubscribeEvent
|
||||
public void chunkLoadEvent(ChunkEvent.Load event)
|
||||
{
|
||||
lodBuilder.generateLodChunkAsync(event.getChunk(), lodWorld, event.getWorld().getDimensionType());
|
||||
lodBuilder.generateLodChunkAsync(event.getChunk(), lodWorld, event.getWorld());
|
||||
}
|
||||
|
||||
|
||||
@SubscribeEvent
|
||||
public void worldLoadEvent(WorldEvent.Load event)
|
||||
{
|
||||
// update the LodWorld to use the new world the player
|
||||
// is loaded
|
||||
lodWorld.selectWorld(LodUtils.getCurrentWorldID());
|
||||
// the player just loaded a new world/dimension
|
||||
lodWorld.selectWorld(LodUtils.getWorldID(event.getWorld()));
|
||||
// make sure the correct LODs are being rendered
|
||||
// (if this isn't done the previous world's LODs may be drawn)
|
||||
renderer.regenerateLODsNextFrame();
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public void worldUnloadEvent(WorldEvent.Unload event)
|
||||
{
|
||||
lodWorld.deselectWorld();
|
||||
// the player just loaded a new world/dimension
|
||||
|
||||
if(mc.getConnection().getWorld() == null)
|
||||
// the player has disconnected from a server
|
||||
lodWorld.deselectWorld();
|
||||
}
|
||||
|
||||
|
||||
@SubscribeEvent
|
||||
public void worldChangeEvent(BlockEvent event)
|
||||
public void blockChangeEvent(BlockEvent event)
|
||||
{
|
||||
if (event.getClass() == BlockEvent.BreakEvent.class ||
|
||||
event.getClass() == BlockEvent.EntityPlaceEvent.class ||
|
||||
@@ -128,7 +130,7 @@ public class ClientProxy
|
||||
event.getClass() == BlockEvent.PortalSpawnEvent.class)
|
||||
{
|
||||
// recreate the LOD where the blocks were changed
|
||||
lodBuilder.generateLodChunkAsync(event.getWorld().getChunk(event.getPos()), lodWorld, event.getWorld().getDimensionType());
|
||||
lodBuilder.generateLodChunkAsync(event.getWorld().getChunk(event.getPos()), lodWorld, event.getWorld());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@ import net.minecraft.client.multiplayer.ServerData;
|
||||
import net.minecraft.server.integrated.IntegratedServer;
|
||||
import net.minecraft.util.math.ChunkPos;
|
||||
import net.minecraft.world.DimensionType;
|
||||
import net.minecraft.world.IWorld;
|
||||
import net.minecraft.world.chunk.ChunkSection;
|
||||
import net.minecraft.world.chunk.IChunk;
|
||||
import net.minecraft.world.server.ServerChunkProvider;
|
||||
@@ -109,32 +110,104 @@ public class LodUtils
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static String getCurrentDimensionID()
|
||||
{
|
||||
|
||||
Minecraft mc = Minecraft.getInstance();
|
||||
|
||||
if(mc.isIntegratedServerRunning())
|
||||
{
|
||||
// this will return the world save location
|
||||
// and the dimension folder
|
||||
|
||||
if(mc.world == null)
|
||||
return "";
|
||||
|
||||
ServerWorld serverWorld = LodUtils.getServerWorldFromDimension(mc.world.getDimensionType());
|
||||
if(serverWorld == null)
|
||||
return "";
|
||||
|
||||
ServerChunkProvider provider = serverWorld.getChunkProvider();
|
||||
if(provider == null)
|
||||
return "";
|
||||
|
||||
return provider.getSavedData().folder.toString();
|
||||
}
|
||||
else
|
||||
{
|
||||
ServerData server = mc.getCurrentServerData();
|
||||
return server.serverName + ", IP " +
|
||||
server.serverIP + ", GameVersion " +
|
||||
server.gameVersion.getString() + "\\"
|
||||
+ "dim_" + mc.world.getDimensionType().getEffects().getPath() + "\\";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* If on single player this will return the name of the user's
|
||||
* world, if in multiplayer it will return the server name
|
||||
* and game version.
|
||||
* world and the dimensional save folder, if in multiplayer
|
||||
* it will return the server name, game version, and dimension.<br>
|
||||
* <br>
|
||||
* This can be used to determine where to save files for a given
|
||||
* dimension.
|
||||
*/
|
||||
public static String getCurrentWorldID()
|
||||
public static String getDimensionIDFromWorld(IWorld world)
|
||||
{
|
||||
Minecraft mc = Minecraft.getInstance();
|
||||
|
||||
if(mc.isIntegratedServerRunning())
|
||||
{
|
||||
ServerWorld serverWorld = LodUtils.getFirstValidServerWorld();
|
||||
if (serverWorld == null)
|
||||
throw new NullPointerException("getCurrentWorldID tried to get the ServerWorld but it was null");
|
||||
// this will return the world save location
|
||||
// and the dimension folder
|
||||
|
||||
ServerWorld serverWorld = LodUtils.getServerWorldFromDimension(world.getDimensionType());
|
||||
if(serverWorld == null)
|
||||
throw new NullPointerException("getDimensionIDFromWorld wasn't able to get the ServerWorld for the dimension " + world.getDimensionType().getEffects().getPath());
|
||||
|
||||
ServerChunkProvider provider = serverWorld.getChunkProvider();
|
||||
if(provider != null)
|
||||
return provider.getSavedData().folder.toString();
|
||||
if(provider == null)
|
||||
throw new NullPointerException("getDimensionIDFromWorld wasn't able to get the ServerChunkProvider for the dimension " + world.getDimensionType().getEffects().getPath());
|
||||
|
||||
return "";
|
||||
return provider.getSavedData().folder.toString();
|
||||
}
|
||||
else
|
||||
{
|
||||
ServerData server = mc.getCurrentServerData();
|
||||
return server.serverName + ", IP " + server.serverIP + ", GameVersion " + server.gameVersion.getString();
|
||||
return server.serverName + ", IP " +
|
||||
server.serverIP + ", GameVersion " +
|
||||
server.gameVersion.getString() + "\\"
|
||||
+ "dim_" + world.getDimensionType().getEffects().getPath() + "\\";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* If on single player this will return the name of the user's
|
||||
* world, if in multiplayer it will return the server name
|
||||
* and game version.
|
||||
*/
|
||||
public static String getWorldID(IWorld world)
|
||||
{
|
||||
if(mc.isIntegratedServerRunning())
|
||||
{
|
||||
// chop off the dimension ID as it is not needed/wanted
|
||||
String dimId = getDimensionIDFromWorld(world);
|
||||
|
||||
// get the world name
|
||||
int saveIndex = dimId.indexOf("saves") + 1 + "saves".length();
|
||||
int slashIndex = dimId.indexOf('\\', saveIndex);
|
||||
dimId = dimId.substring(saveIndex, slashIndex);
|
||||
return dimId;
|
||||
}
|
||||
else
|
||||
{
|
||||
ServerData server = mc.getCurrentServerData();
|
||||
return server.serverName + ", IP " +
|
||||
server.serverIP + ", GameVersion " +
|
||||
server.gameVersion.getString();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user