diff --git a/forge/forge_common/net/minecraft/src/forge/ForgeHooks.java b/forge/forge_common/net/minecraft/src/forge/ForgeHooks.java index fd520bb08..777ae2f20 100644 --- a/forge/forge_common/net/minecraft/src/forge/ForgeHooks.java +++ b/forge/forge_common/net/minecraft/src/forge/ForgeHooks.java @@ -18,6 +18,7 @@ import net.minecraft.src.ItemStack; import net.minecraft.src.Item; import net.minecraft.src.EnumStatus; import net.minecraft.src.ModLoader; +import net.minecraft.src.NBTTagCompound; import net.minecraft.src.NetworkManager; import net.minecraft.src.Packet; import net.minecraft.src.Packet1Login; @@ -272,6 +273,55 @@ public class ForgeHooks return message; } static LinkedList chatHandlers = new LinkedList(); + + public static void onWorldLoad(World world) + { + for (ISaveEventHandler handler : saveHandlers) + { + handler.onWorldLoad(world); + } + } + + public static void onWorldSave(World world) + { + for (ISaveEventHandler handler : saveHandlers) + { + handler.onWorldSave(world); + } + } + + public static void onChunkLoad(World world, Chunk chunk) + { + for (ISaveEventHandler handler : saveHandlers) + { + handler.onChunkLoad(world, chunk); + } + } + + public static void onChunkUnload(World world, Chunk chunk) + { + for (ISaveEventHandler handler : saveHandlers) + { + handler.onChunkUnload(world, chunk); + } + } + + public static void onChunkLoadData(World world, Chunk chunk, NBTTagCompound data) + { + for (ISaveEventHandler handler : saveHandlers) + { + handler.onChunkLoadData(world, chunk, data); + } + } + + public static void onChunkSaveData(World world, Chunk chunk, NBTTagCompound data) + { + for (ISaveEventHandler handler : saveHandlers) + { + handler.onChunkSaveData(world, chunk, data); + } + } + static LinkedList saveHandlers = new LinkedList(); // Plant Management // ------------------------------------------------------------ diff --git a/forge/forge_common/net/minecraft/src/forge/ISaveEventHandler.java b/forge/forge_common/net/minecraft/src/forge/ISaveEventHandler.java new file mode 100644 index 000000000..7a6023995 --- /dev/null +++ b/forge/forge_common/net/minecraft/src/forge/ISaveEventHandler.java @@ -0,0 +1,50 @@ +package net.minecraft.src.forge; + +import net.minecraft.src.Chunk; +import net.minecraft.src.NBTTagCompound; +import net.minecraft.src.World; + +public interface ISaveEventHandler +{ + /** + * Called when the world is created, either newly created or loaded from a save file + * @param world The world being loaded. + */ + public void onWorldLoad(World world); + + /** + * Called whenever the world is saving. Use this to save extra data alongside the world, eg. maps. + * @param world The world being saved. + */ + public void onWorldSave(World world); + + /** + * Called when a chunk is created, either newly generated or loaded from a save file + * @param world The world containing this chunk. + * @param chunk The chunk being loaded. + */ + public void onChunkLoad(World world, Chunk chunk); + + /** + * Called when a chunk is unloaded and removed from the world + * @param world The world containing this chunk. + * @param chunk The chunk being loaded. + */ + public void onChunkUnload(World world, Chunk chunk); + + /** + * Use this to save extra data in with the chunk file. + * @param world The world containing this chunk. + * @param chunk The chunk being saved. + * @param data The compound to save data into and be written to disk + */ + public void onChunkSaveData(World world, Chunk chunk, NBTTagCompound data); + + /** + * Use this to load extra save data from a chunk file. + * @param world The world containing this chunk. + * @param chunk The chunk being loaded. + * @param data The compound to load data from + */ + public void onChunkLoadData(World world, Chunk chunk, NBTTagCompound data); +} \ No newline at end of file diff --git a/forge/forge_common/net/minecraft/src/forge/MinecraftForge.java b/forge/forge_common/net/minecraft/src/forge/MinecraftForge.java index 8975b5be9..346b78bad 100755 --- a/forge/forge_common/net/minecraft/src/forge/MinecraftForge.java +++ b/forge/forge_common/net/minecraft/src/forge/MinecraftForge.java @@ -128,6 +128,15 @@ public class MinecraftForge { ForgeHooks.chatHandlers.add(handler); } + + /** + * Register a new Save handler + * @param handler The handler to be registered + */ + public static void registerSaveHandler(ISaveEventHandler handler) + { + ForgeHooks.saveHandlers.add(handler); + } /** * This is not supposed to be called outside of Minecraft internals. diff --git a/forge/patches/minecraft/net/minecraft/src/AnvilChunkLoader.java.patch b/forge/patches/minecraft/net/minecraft/src/AnvilChunkLoader.java.patch new file mode 100644 index 000000000..2a5b90985 --- /dev/null +++ b/forge/patches/minecraft/net/minecraft/src/AnvilChunkLoader.java.patch @@ -0,0 +1,27 @@ +--- ../src_base/minecraft/net/minecraft/src/AnvilChunkLoader.java 0000-00-00 00:00:00.000000000 -0000 ++++ ../src_work/minecraft/net/minecraft/src/AnvilChunkLoader.java 0000-00-00 00:00:00.000000000 -0000 +@@ -10,6 +10,8 @@ + import java.util.List; + import java.util.Set; + ++import net.minecraft.src.forge.ForgeHooks; ++ + public class AnvilChunkLoader implements IThreadedFileIO, IChunkLoader + { + private List field_48451_a = new ArrayList(); +@@ -88,6 +90,7 @@ + } + + var5.removeUnknownBlocks(); ++ ForgeHooks.onChunkLoadData(par1World, var5, par4NBTTagCompound); + return var5; + } + } +@@ -103,6 +106,7 @@ + var3.setTag("Level", var4); + this.writeChunkToNBT(par2Chunk, par1World, var4); + this.func_48446_a(par2Chunk.getChunkCoordIntPair(), var3); ++ ForgeHooks.onChunkSaveData(par1World, par2Chunk, var3); + } + catch (Exception var5) + { diff --git a/forge/patches/minecraft/net/minecraft/src/Chunk.java.patch b/forge/patches/minecraft/net/minecraft/src/Chunk.java.patch index 83d67628a..470931596 100644 --- a/forge/patches/minecraft/net/minecraft/src/Chunk.java.patch +++ b/forge/patches/minecraft/net/minecraft/src/Chunk.java.patch @@ -1,6 +1,15 @@ --- ../src_base/minecraft/net/minecraft/src/Chunk.java 0000-00-00 00:00:00.000000000 -0000 +++ ../src_work/minecraft/net/minecraft/src/Chunk.java 0000-00-00 00:00:00.000000000 -0000 -@@ -585,7 +585,7 @@ +@@ -8,6 +8,8 @@ + import java.util.Map; + import java.util.Random; + ++import net.minecraft.src.forge.ForgeHooks; ++ + public class Chunk + { + /** +@@ -585,7 +587,7 @@ { Block.blocksList[var8].onBlockRemoval(this.worldObj, var11, par2, var12); } @@ -9,7 +18,7 @@ { this.worldObj.removeBlockTileEntity(var11, par2, var12); } -@@ -629,32 +629,23 @@ +@@ -629,32 +631,23 @@ Block.blocksList[par4].onBlockAdded(this.worldObj, var11, par2, var12); } @@ -45,7 +54,7 @@ this.isModified = true; return true; } -@@ -686,7 +677,7 @@ +@@ -686,7 +679,7 @@ var5.setExtBlockMetadata(par1, par2 & 15, par3, par4); int var7 = var5.getExtBlockID(par1, par2 & 15, par3); @@ -54,7 +63,7 @@ { TileEntity var8 = this.getChunkBlockTileEntity(par1, par2, par3); -@@ -852,34 +843,33 @@ +@@ -852,34 +845,33 @@ { ChunkPosition var4 = new ChunkPosition(par1, par2, par3); TileEntity var5 = (TileEntity)this.chunkTileEntityMap.get(var4); @@ -100,7 +109,7 @@ } /** -@@ -894,7 +884,7 @@ +@@ -894,7 +886,7 @@ if (this.isChunkLoaded) { @@ -109,7 +118,7 @@ } } -@@ -909,8 +899,14 @@ +@@ -909,8 +901,14 @@ par4TileEntity.yCoord = par2; par4TileEntity.zCoord = this.zPosition * 16 + par3; @@ -125,7 +134,23 @@ par4TileEntity.validate(); this.chunkTileEntityMap.put(var5, par4TileEntity); } -@@ -1228,6 +1224,16 @@ +@@ -946,6 +944,7 @@ + { + this.worldObj.addLoadedEntities(this.entityLists[var1]); + } ++ ForgeHooks.onChunkLoad(worldObj, this); + } + + /** +@@ -966,6 +965,7 @@ + { + this.worldObj.unloadEntities(this.entityLists[var3]); + } ++ ForgeHooks.onChunkUnload(worldObj, this); + } + + /** +@@ -1228,6 +1228,16 @@ public void func_48494_a(byte[] par1ArrayOfByte, int par2, int par3, boolean par4) { @@ -142,7 +167,7 @@ int var5 = 0; int var6; -@@ -1331,6 +1337,29 @@ +@@ -1331,6 +1341,29 @@ TileEntity var9 = (TileEntity)var10.next(); var9.updateContainingBlockInfo(); } @@ -172,7 +197,7 @@ } public BiomeGenBase func_48490_a(int par1, int par2, WorldChunkManager par3WorldChunkManager) -@@ -1435,4 +1464,18 @@ +@@ -1435,4 +1468,18 @@ } } } diff --git a/forge/patches/minecraft/net/minecraft/src/World.java.patch b/forge/patches/minecraft/net/minecraft/src/World.java.patch index 4a4c9dc13..8cb017863 100644 --- a/forge/patches/minecraft/net/minecraft/src/World.java.patch +++ b/forge/patches/minecraft/net/minecraft/src/World.java.patch @@ -18,7 +18,39 @@ /** Option > Difficulty setting (0 - 3) */ public int difficultySetting; -@@ -559,7 +561,8 @@ +@@ -214,6 +216,7 @@ + this.chunkProvider = this.createChunkProvider(); + this.calculateInitialSkylight(); + this.calculateInitialWeather(); ++ ForgeHooks.onWorldLoad(this); + } + + public World(World par1World, WorldProvider par2WorldProvider) +@@ -259,6 +262,7 @@ + this.chunkProvider = this.createChunkProvider(); + this.calculateInitialSkylight(); + this.calculateInitialWeather(); ++ ForgeHooks.onWorldLoad(this); + } + + public World(ISaveHandler par1ISaveHandler, String par2Str, WorldSettings par3WorldSettings) +@@ -340,6 +344,7 @@ + + this.calculateInitialSkylight(); + this.calculateInitialWeather(); ++ ForgeHooks.onWorldLoad(this); + } + + /** +@@ -507,6 +512,7 @@ + } + + this.chunkProvider.saveChunks(par1, par2IProgressUpdate); ++ ForgeHooks.onWorldSave(this); + } + } + +@@ -559,7 +565,8 @@ */ public boolean isAirBlock(int par1, int par2, int par3) { @@ -28,7 +60,7 @@ } /** -@@ -2067,7 +2070,7 @@ +@@ -2067,7 +2074,7 @@ if (var7 != null) { @@ -37,7 +69,7 @@ } } } -@@ -2097,18 +2100,18 @@ +@@ -2097,18 +2104,18 @@ { this.loadedTileEntityList.add(var8); } @@ -60,7 +92,7 @@ } } -@@ -2121,13 +2124,13 @@ +@@ -2121,13 +2128,13 @@ public void addTileEntity(Collection par1Collection) { @@ -80,7 +112,7 @@ } } -@@ -2149,7 +2152,7 @@ +@@ -2149,7 +2156,7 @@ int var4 = MathHelper.floor_double(par1Entity.posZ); byte var5 = 32; @@ -89,7 +121,7 @@ { par1Entity.lastTickPosX = par1Entity.posX; par1Entity.lastTickPosY = par1Entity.posY; -@@ -2326,7 +2329,14 @@ +@@ -2326,7 +2333,14 @@ if (var11 == Block.fire.blockID || var11 == Block.lavaMoving.blockID || var11 == Block.lavaStill.blockID) { return true; @@ -105,7 +137,7 @@ } } } -@@ -2630,25 +2640,19 @@ +@@ -2630,25 +2644,19 @@ */ public void setBlockTileEntity(int par1, int par2, int par3, TileEntity par4TileEntity) { @@ -143,7 +175,7 @@ } } -@@ -2657,27 +2661,10 @@ +@@ -2657,27 +2665,10 @@ */ public void removeBlockTileEntity(int par1, int par2, int par3) { @@ -174,7 +206,7 @@ } } -@@ -2703,7 +2690,8 @@ +@@ -2703,7 +2694,8 @@ */ public boolean isBlockNormalCube(int par1, int par2, int par3) { @@ -184,7 +216,7 @@ } /** -@@ -2984,6 +2972,7 @@ +@@ -2984,6 +2976,7 @@ } } } @@ -192,7 +224,7 @@ Profiler.endSection(); -@@ -3307,7 +3296,7 @@ +@@ -3307,7 +3300,7 @@ private int computeBlockLightValue(int par1, int par2, int par3, int par4, int par5, int par6) { @@ -201,7 +233,7 @@ int var8 = this.getSavedLightValue(EnumSkyBlock.Block, par2 - 1, par3, par4) - par6; int var9 = this.getSavedLightValue(EnumSkyBlock.Block, par2 + 1, par3, par4) - par6; int var10 = this.getSavedLightValue(EnumSkyBlock.Block, par2, par3 - 1, par4) - par6; -@@ -3839,7 +3828,10 @@ +@@ -3839,7 +3832,10 @@ { var8 = null; } @@ -213,7 +245,7 @@ return par1 > 0 && var8 == null && var9.canPlaceBlockOnSide(this, par2, par3, par4, par6); } } -@@ -4443,4 +4435,39 @@ +@@ -4443,4 +4439,39 @@ { return this.worldInfo.getTerrainType() == WorldType.FLAT ? 0.0D : 63.0D; } diff --git a/forge/patches/minecraft_server/net/minecraft/src/AnvilChunkLoader.java.patch b/forge/patches/minecraft_server/net/minecraft/src/AnvilChunkLoader.java.patch new file mode 100644 index 000000000..fa005be0d --- /dev/null +++ b/forge/patches/minecraft_server/net/minecraft/src/AnvilChunkLoader.java.patch @@ -0,0 +1,27 @@ +--- ../src_base/minecraft_server/net/minecraft/src/AnvilChunkLoader.java 0000-00-00 00:00:00.000000000 -0000 ++++ ../src_work/minecraft_server/net/minecraft/src/AnvilChunkLoader.java 0000-00-00 00:00:00.000000000 -0000 +@@ -10,6 +10,8 @@ + import java.util.List; + import java.util.Set; + ++import net.minecraft.src.forge.ForgeHooks; ++ + public class AnvilChunkLoader implements IChunkLoader, IThreadedFileIO + { + private List field_48469_a = new ArrayList(); +@@ -88,6 +90,7 @@ + } + + var5.removeUnknownBlocks(); ++ ForgeHooks.onChunkLoadData(par1World, var5, par4NBTTagCompound); + return var5; + } + } +@@ -103,6 +106,7 @@ + var3.setTag("Level", var4); + this.writeChunkToNBT(par2Chunk, par1World, var4); + this.func_48463_a(par2Chunk.getChunkCoordIntPair(), var3); ++ ForgeHooks.onChunkSaveData(par1World, par2Chunk, var3); + } + catch (Exception var5) + { diff --git a/forge/patches/minecraft_server/net/minecraft/src/Chunk.java.patch b/forge/patches/minecraft_server/net/minecraft/src/Chunk.java.patch index dd44ef11d..22875b33e 100644 --- a/forge/patches/minecraft_server/net/minecraft/src/Chunk.java.patch +++ b/forge/patches/minecraft_server/net/minecraft/src/Chunk.java.patch @@ -1,6 +1,15 @@ --- ../src_base/minecraft_server/net/minecraft/src/Chunk.java 0000-00-00 00:00:00.000000000 -0000 +++ ../src_work/minecraft_server/net/minecraft/src/Chunk.java 0000-00-00 00:00:00.000000000 -0000 -@@ -545,7 +545,7 @@ +@@ -8,6 +8,8 @@ + import java.util.Map; + import java.util.Random; + ++import net.minecraft.src.forge.ForgeHooks; ++ + public class Chunk + { + /** +@@ -545,7 +547,7 @@ { Block.blocksList[var8].onBlockRemoval(this.worldObj, var11, par2, var12); } @@ -9,7 +18,7 @@ { this.worldObj.removeBlockTileEntity(var11, par2, var12); } -@@ -589,32 +589,23 @@ +@@ -589,32 +591,23 @@ Block.blocksList[par4].onBlockAdded(this.worldObj, var11, par2, var12); } @@ -45,7 +54,7 @@ this.isModified = true; return true; } -@@ -646,7 +637,7 @@ +@@ -646,7 +639,7 @@ var5.setExtBlockMetadata(par1, par2 & 15, par3, par4); int var7 = var5.getExtBlockID(par1, par2 & 15, par3); @@ -54,7 +63,7 @@ { TileEntity var8 = this.getChunkBlockTileEntity(par1, par2, par3); -@@ -812,34 +803,31 @@ +@@ -812,34 +805,31 @@ { ChunkPosition var4 = new ChunkPosition(par1, par2, par3); TileEntity var5 = (TileEntity)this.chunkTileEntityMap.get(var4); @@ -99,7 +108,7 @@ } /** -@@ -854,7 +842,7 @@ +@@ -854,7 +844,7 @@ if (this.isChunkLoaded) { @@ -108,7 +117,7 @@ } } -@@ -869,8 +857,14 @@ +@@ -869,8 +859,14 @@ par4TileEntity.yCoord = par2; par4TileEntity.zCoord = this.zPosition * 16 + par3; @@ -124,7 +133,23 @@ par4TileEntity.validate(); this.chunkTileEntityMap.put(var5, par4TileEntity); } -@@ -1287,4 +1281,18 @@ +@@ -906,6 +902,7 @@ + { + this.worldObj.addLoadedEntities(this.entityLists[var1]); + } ++ ForgeHooks.onChunkLoad(worldObj, this); + } + + /** +@@ -926,6 +923,7 @@ + { + this.worldObj.unloadEntities(this.entityLists[var3]); + } ++ ForgeHooks.onChunkUnload(worldObj, this); + } + + /** +@@ -1287,4 +1285,18 @@ } } } diff --git a/forge/patches/minecraft_server/net/minecraft/src/World.java.patch b/forge/patches/minecraft_server/net/minecraft/src/World.java.patch index a6e6ff739..e9ad142ac 100644 --- a/forge/patches/minecraft_server/net/minecraft/src/World.java.patch +++ b/forge/patches/minecraft_server/net/minecraft/src/World.java.patch @@ -18,7 +18,23 @@ /** Whether monsters are enabled or not. (1 = on, 0 = off) */ public int difficultySetting; -@@ -354,7 +356,8 @@ +@@ -219,6 +221,7 @@ + + this.calculateInitialSkylight(); + this.calculateInitialWeather(); ++ ForgeHooks.onWorldLoad(this); + } + + /** +@@ -323,6 +326,7 @@ + } + + this.chunkProvider.saveChunks(par1, par2IProgressUpdate); ++ ForgeHooks.onWorldSave(this); + } + } + +@@ -354,7 +358,8 @@ */ public boolean isAirBlock(int par1, int par2, int par3) { @@ -28,7 +44,7 @@ } public boolean func_48084_h(int par1, int par2, int par3) -@@ -1600,7 +1603,7 @@ +@@ -1600,7 +1605,7 @@ if (var7 != null) { @@ -37,7 +53,7 @@ } } } -@@ -1630,14 +1633,16 @@ +@@ -1630,14 +1635,16 @@ { this.loadedTileEntityList.add(var8); } @@ -56,7 +72,7 @@ } } -@@ -1654,13 +1659,13 @@ +@@ -1654,13 +1661,13 @@ public void addTileEntity(Collection par1Collection) { @@ -76,7 +92,7 @@ } } -@@ -1682,7 +1687,7 @@ +@@ -1682,7 +1689,7 @@ int var4 = MathHelper.floor_double(par1Entity.posZ); byte var5 = 32; @@ -85,7 +101,7 @@ { par1Entity.lastTickPosX = par1Entity.posX; par1Entity.lastTickPosY = par1Entity.posY; -@@ -1905,6 +1910,13 @@ +@@ -1905,6 +1912,13 @@ if (var11 == Block.fire.blockID || var11 == Block.lavaMoving.blockID || var11 == Block.lavaStill.blockID) { return true; @@ -99,7 +115,7 @@ } } } -@@ -2188,25 +2200,21 @@ +@@ -2188,25 +2202,21 @@ */ public void setBlockTileEntity(int par1, int par2, int par3, TileEntity par4TileEntity) { @@ -138,7 +154,7 @@ } } -@@ -2215,27 +2223,10 @@ +@@ -2215,27 +2225,10 @@ */ public void removeBlockTileEntity(int par1, int par2, int par3) { @@ -169,7 +185,7 @@ } } -@@ -2261,7 +2252,8 @@ +@@ -2261,7 +2254,8 @@ */ public boolean isBlockNormalCube(int par1, int par2, int par3) { @@ -179,7 +195,7 @@ } /** -@@ -2536,6 +2528,7 @@ +@@ -2536,6 +2530,7 @@ } } } @@ -187,7 +203,7 @@ Profiler.endSection(); -@@ -2859,7 +2852,7 @@ +@@ -2859,7 +2854,7 @@ private int computeBlockLightValue(int par1, int par2, int par3, int par4, int par5, int par6) { @@ -196,7 +212,7 @@ int var8 = this.getSavedLightValue(EnumSkyBlock.Block, par2 - 1, par3, par4) - par6; int var9 = this.getSavedLightValue(EnumSkyBlock.Block, par2 + 1, par3, par4) - par6; int var10 = this.getSavedLightValue(EnumSkyBlock.Block, par2, par3 - 1, par4) - par6; -@@ -3345,6 +3338,11 @@ +@@ -3345,6 +3340,11 @@ { var8 = null; } @@ -208,7 +224,7 @@ return par1 > 0 && var8 == null && var9.canPlaceBlockOnSide(this, par2, par3, par4, par6); } -@@ -3855,4 +3853,38 @@ +@@ -3855,4 +3855,38 @@ { return this.getChunkProvider().findClosestStructure(this, par1Str, par2, par3, par4); }