package micdoodle8.mods.galacticraft.core.world;
import micdoodle8.mods.galacticraft.core.util.GCCoreUtil;
import micdoodle8.mods.galacticraft.core.util.GCLog;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.server.MinecraftServer;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.BlockPos;
import net.minecraft.world.ChunkCoordIntPair;
import net.minecraft.world.World;
import net.minecraft.world.WorldServer;
import net.minecraftforge.common.DimensionManager;
import net.minecraftforge.common.ForgeChunkManager;
import net.minecraftforge.common.ForgeChunkManager.LoadingCallback;
import net.minecraftforge.common.ForgeChunkManager.Ticket;
import net.minecraftforge.common.config.Configuration;
import java.io.*;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map.Entry;
public class ChunkLoadingCallback implements LoadingCallback
{
private static boolean loaded;
private static HashMap<String, HashMap<Integer, HashSet<BlockPos>>> chunkLoaderList = new HashMap<String, HashMap<Integer, HashSet<BlockPos>>>();
// private static HashMap<Integer, HashSet<IChunkLoader>> loadedChunks = new
// HashMap<Integer, HashSet<IChunkLoader>>();
private static boolean configLoaded;
private static Configuration config;
// private static boolean keepLoadedOffline;
private static boolean loadOnLogin;
private static boolean dirtyData;
@Override
public void ticketsLoaded(List<Ticket> tickets, World world)
{
for (Ticket ticket : tickets)
{
NBTTagCompound nbt = ticket.getModData();
if (nbt != null)
{
int tileX = nbt.getInteger("ChunkLoaderTileX");
int tileY = nbt.getInteger("ChunkLoaderTileY");
int tileZ = nbt.getInteger("ChunkLoaderTileZ");
TileEntity tile = world.getTileEntity(new BlockPos(tileX, tileY, tileZ));
if (tile instanceof IChunkLoader)
{
((IChunkLoader) tile).onTicketLoaded(ticket, false);
}
}
}
}
public static void loadConfig(File file)
{
if (!ChunkLoadingCallback.configLoaded)
{
ChunkLoadingCallback.config = new Configuration(file);
}
try
{
// keepLoadedOffline = config.get("CHUNKLOADING",
// "OfflineKeepLoaded", true,
// "Set to false if you want each player's chunk loaders to unload when they log out.").getBoolean(true);
ChunkLoadingCallback.loadOnLogin = ChunkLoadingCallback.config.get("CHUNKLOADING", "LoadOnLogin", true, "If you don't want each player's chunks to load when they log in, set to false.").getBoolean(true);
}
catch (final Exception e)
{
GCLog.severe("Problem loading chunkloading config (\"core.conf\")");
}
finally
{
if (ChunkLoadingCallback.config.hasChanged())
{
ChunkLoadingCallback.config.save();
}
ChunkLoadingCallback.configLoaded = true;
}
}
public static void addToList(World world, int x, int y, int z, String playerName)
{
HashMap<Integer, HashSet<BlockPos>> dimensionMap = ChunkLoadingCallback.chunkLoaderList.get(playerName);
if (dimensionMap == null)
{
dimensionMap = new HashMap<Integer, HashSet<BlockPos>>();
ChunkLoadingCallback.chunkLoaderList.put(playerName, dimensionMap);
}
HashSet<BlockPos> chunkLoaders = dimensionMap.get(GCCoreUtil.getDimensionID(world));
if (chunkLoaders == null)
{
chunkLoaders = new HashSet<BlockPos>();
}
chunkLoaders.add(new BlockPos(x, y, z));
dimensionMap.put(GCCoreUtil.getDimensionID(world), chunkLoaders);
ChunkLoadingCallback.chunkLoaderList.put(playerName, dimensionMap);
ChunkLoadingCallback.dirtyData = true;
}
public static void forceChunk(Ticket ticket, World world, int x, int y, int z, String playerName)
{
ChunkLoadingCallback.addToList(world, x, y, z, playerName);
ChunkCoordIntPair chunkPos = new ChunkCoordIntPair(x >> 4, z >> 4);
ForgeChunkManager.forceChunk(ticket, chunkPos);
//
// TileEntity tile = world.getTileEntity(x, y, z);
//
// if (tile instanceof IChunkLoader)
// {
// IChunkLoader chunkLoader = (IChunkLoader) tile;
// int dimID = world);
//
// HashSet<IChunkLoader> chunkList = loadedChunks.get(dimID);
//
// if (chunkList == null)
// {
// chunkList = new HashSet<IChunkLoader>();
// }
//
// ForgeChunkManager.forceChunk(ticket, chunkPos);
// chunkList.add(chunkLoader);
// loadedChunks.put(dimID, chunkList);
// }
}
public static void save(WorldServer world)
{
if (!ChunkLoadingCallback.dirtyData)
{
return;
}
File saveDir = ChunkLoadingCallback.getSaveDir();
if (saveDir != null)
{
File saveFile = new File(saveDir, "chunkloaders.dat");
if (!saveFile.exists())
{
try
{
if (!saveFile.createNewFile())
{
GCLog.severe("Could not create chunk loader data file: " + saveFile.getAbsolutePath());
}
}
catch (IOException e)
{
GCLog.severe("Could not create chunk loader data file: " + saveFile.getAbsolutePath());
e.printStackTrace();
}
}
FileOutputStream fos = null;
try
{
fos = new FileOutputStream(saveFile);
}
catch (FileNotFoundException e)
{
e.printStackTrace();
}
if (fos != null)
{
DataOutputStream dataStream = new DataOutputStream(fos);
try
{
dataStream.writeInt(ChunkLoadingCallback.chunkLoaderList.size());
for (Entry<String, HashMap<Integer, HashSet<BlockPos>>> playerEntry : ChunkLoadingCallback.chunkLoaderList.entrySet())
{
dataStream.writeUTF(playerEntry.getKey());
dataStream.writeInt(playerEntry.getValue().size());
for (Entry<Integer, HashSet<BlockPos>> dimensionEntry : playerEntry.getValue().entrySet())
{
dataStream.writeInt(dimensionEntry.getKey());
dataStream.writeInt(dimensionEntry.getValue().size());
for (BlockPos coords : dimensionEntry.getValue())
{
dataStream.writeInt(coords.getX());
dataStream.writeInt(coords.getY());
dataStream.writeInt(coords.getZ());
}
}
}
}
catch (IOException e)
{
e.printStackTrace();
}
try
{
dataStream.close();
fos.close();
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
ChunkLoadingCallback.dirtyData = false;
}
private static File getSaveDir()
{
if (DimensionManager.getWorld(0) != null)
{
File saveDir = new File(DimensionManager.getCurrentSaveRootDirectory(), "galacticraft");
if (!saveDir.exists())
{
if (!saveDir.mkdirs())
{
GCLog.severe("Could not create chunk loader save data folder: " + saveDir.getAbsolutePath());
}
}
return saveDir;
}
return null;
}
public static void load(WorldServer world)
{
if (ChunkLoadingCallback.loaded)
{
return;
}
DataInputStream dataStream = null;
try
{
File saveDir = ChunkLoadingCallback.getSaveDir();
if (saveDir != null)
{
if (!saveDir.exists())
{
if (!saveDir.mkdirs())
{
GCLog.severe("Could not create chunk loader save data folder: " + saveDir.getAbsolutePath());
}
}
File saveFile = new File(saveDir, "chunkloaders.dat");
if (saveFile.exists())
{
dataStream = new DataInputStream(new FileInputStream(saveFile));
int playerCount = dataStream.readInt();
for (int l = 0; l < playerCount; l++)
{
String ownerName = dataStream.readUTF();
int mapSize = dataStream.readInt();
HashMap<Integer, HashSet<BlockPos>> dimensionMap = new HashMap<Integer, HashSet<BlockPos>>();
for (int i = 0; i < mapSize; i++)
{
int dimensionID = dataStream.readInt();
HashSet<BlockPos> coords = new HashSet<BlockPos>();
dimensionMap.put(dimensionID, coords);
int coordSetSize = dataStream.readInt();
for (int j = 0; j < coordSetSize; j++)
{
coords.add(new BlockPos(dataStream.readInt(), dataStream.readInt(), dataStream.readInt()));
}
}
ChunkLoadingCallback.chunkLoaderList.put(ownerName, dimensionMap);
}
dataStream.close();
}
}
}
catch (Exception e)
{
e.printStackTrace();
if (dataStream != null)
{
try
{
dataStream.close();
}
catch (IOException e1)
{
e1.printStackTrace();
}
}
}
ChunkLoadingCallback.loaded = true;
ChunkLoadingCallback.dirtyData = false;
}
public static void onPlayerLogin(EntityPlayer player)
{
for (Entry<String, HashMap<Integer, HashSet<BlockPos>>> playerEntry : ChunkLoadingCallback.chunkLoaderList.entrySet())
{
if (player.getGameProfile().getName().equals(playerEntry.getKey()))
{
for (Entry<Integer, HashSet<BlockPos>> dimensionEntry : playerEntry.getValue().entrySet())
{
int dimID = dimensionEntry.getKey();
if (ChunkLoadingCallback.loadOnLogin)
{
MinecraftServer.getServer().worldServerForDimension(dimID);
}
}
}
}
}
public static void onPlayerLogout(EntityPlayer player)
{
// if (!keepLoadedOffline)
// {
// for (Entry<Integer, HashSet<IChunkLoader>> dimEntry :
// loadedChunks.entrySet())
// {
// int dimID = dimEntry.getKey();
//
// for (IChunkLoader loader : new
// ArrayList<IChunkLoader>(dimEntry.getValue()))
// {
// World world = loader.getWorldObj();
//
// BlockPos coords = loader.getCoords();
// TileEntity tile = world.getTileEntity(coords.posX, coords.posY,
// coords.posZ);
//
// if (tile != null && tile.equals(loader))
// {
// Chunk chunkAt = world.getChunkFromChunkCoords(coords.posX >> 4,
// coords.posZ >> 4);
// boolean foundOtherLoader = false;
//
// for (Object o : chunkAt.chunkTileEntityMap.values())
// {
// TileEntity otherTile = (TileEntity) o;
//
// if (otherTile != null && !otherTile.equals(tile))
// {
// if (otherTile instanceof IChunkLoader)
// {
// IChunkLoader otherLoader = (IChunkLoader) otherTile;
//
// if (!otherLoader.getOwnerName().equals(loader.getOwnerName()))
// {
// HashMap<Integer, HashSet<BlockPos>> otherDimMap =
// chunkLoaderList.get(loader.getOwnerName());
//
// if (otherDimMap != null)
// {
// HashSet<BlockPos> otherLoaders = otherDimMap.get(dimID);
//
// if (otherLoaders != null && otherLoaders.contains(otherLoader))
// {
// foundOtherLoader = true;
// break;
// }
// }
// }
// }
// }
// }
//
// if (!foundOtherLoader)
// {
// ForgeChunkManager.unforceChunk(loader.getTicket(), new
// ChunkCoordIntPair(coords.posX >> 4, coords.posZ >> 4));
// dimEntry.getValue().remove(loader);
// }
// }
// else
// {
// dimEntry.getValue().remove(loader);
//
// HashMap<Integer, HashSet<BlockPos>> dimMap =
// chunkLoaderList.get(player.getGameProfile().getName());
//
// if (dimMap != null)
// {
// HashSet<BlockPos> coordSet = dimMap.get(dimID);
//
// if (coordSet != null)
// {
// coordSet.remove(loader.getCoords());
// }
//
// dimm
// chunkLoaderList.put(player.getGameProfile().getName(), dimMap);
// }
// }
// }
// }
// }
}
}