Merge branch 'master' into TESRculling

This commit is contained in:
Christian 2013-01-29 10:01:00 -05:00
commit 0f3bd780e1
16 changed files with 225 additions and 43 deletions

View file

@ -126,3 +126,9 @@ public yc.o #FD:World/field_73018_p #prevThunderingStrength
public ayp.b(Llq;)V #MD:WorldClient/func_72847_b #releaseEntitySkin
#WorldServer
public in.b(Llq;)V #MD:WorldServer/func_72847_b #releaseEntitySkin
public in.N #FD:WorldServer/field_73068_P #allPlayersSleeping
# ChunkCache
public ys.e # FD:ChunkCache/field_72815_e # worldObj
# InventoryLargeChest
public kz.c #FD:InventoryLargeChest/field_70478_c #lowerChest
public kz.b #FD:InventoryLargeChest/field_70477_b #upperChest

View file

@ -440,6 +440,7 @@ public class Configuration
}
BufferedReader buffer = null;
UnicodeInputStreamReader input = null;
try
{
if (file.getParentFile() != null)
@ -454,7 +455,7 @@ public class Configuration
if (file.canRead())
{
UnicodeInputStreamReader input = new UnicodeInputStreamReader(new FileInputStream(file), defaultEncoding);
input = new UnicodeInputStreamReader(new FileInputStream(file), defaultEncoding);
defaultEncoding = input.getEncoding();
buffer = new BufferedReader(input);
@ -638,6 +639,13 @@ public class Configuration
buffer.close();
} catch (IOException e){}
}
if (input != null)
{
try
{
input.close();
} catch (IOException e){}
}
}
}

View file

@ -2,16 +2,25 @@ package net.minecraftforge.common;
import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.BitSet;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.concurrent.ConcurrentMap;
import java.util.logging.Level;
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.ImmutableListMultimap;
import com.google.common.collect.ListMultimap;
import com.google.common.collect.Lists;
import com.google.common.collect.MapMaker;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import cpw.mods.fml.common.FMLCommonHandler;
import cpw.mods.fml.common.FMLLog;
@ -40,9 +49,10 @@ public class DimensionManager
private static Hashtable<Integer, WorldServer> worlds = new Hashtable<Integer, WorldServer>();
private static boolean hasInit = false;
private static Hashtable<Integer, Integer> dimensions = new Hashtable<Integer, Integer>();
private static Map<World, ListMultimap<ChunkCoordIntPair, String>> persistentChunkStore = Maps.newHashMap(); //FIXME: Unused?
private static ArrayList<Integer> unloadQueue = new ArrayList<Integer>();
private static BitSet dimensionMap = new BitSet(Long.SIZE << 4);
private static ConcurrentMap<World, World> weakWorldMap = new MapMaker().weakKeys().weakValues().<World,World>makeMap();
private static Set<Integer> leakedWorlds = Sets.newHashSet();
public static boolean registerProviderType(int id, Class<? extends WorldProvider> provider, boolean keepLoaded)
{
@ -55,6 +65,38 @@ public class DimensionManager
return true;
}
/**
* Unregisters a Provider type, and returns a array of all dimensions that are
* registered to this provider type.
* If the return size is greater then 0, it is required that the caller either
* change those dimensions's registered type, or replace this type before the
* world is attempted to load, else the loader will throw an exception.
*
* @param id The provider type ID to unreigster
* @return An array containing all dimension IDs still registered to this provider type.
*/
public static int[] unregisterProviderType(int id)
{
if (!providers.containsKey(id))
{
return new int[0];
}
providers.remove(id);
spawnSettings.remove(id);
int[] ret = new int[dimensions.size()];
int x = 0;
for (Map.Entry<Integer, Integer> ent : dimensions.entrySet())
{
if (ent.getValue() == id)
{
ret[x++] = ent.getKey();
}
}
return Arrays.copyOf(ret, x);
}
public static void init()
{
if (hasInit)
@ -115,6 +157,34 @@ public class DimensionManager
return getWorld(dim).provider;
}
public static Integer[] getIDs(boolean check)
{
if (check)
{
List<World> allWorlds = Lists.newArrayList(weakWorldMap.keySet());
allWorlds.removeAll(worlds.values());
Set<Integer> newLeaks = Sets.newHashSet();
for (ListIterator<World> li = allWorlds.listIterator(); li.hasNext(); )
{
World w = li.next();
if (leakedWorlds.contains(System.identityHashCode(w)))
{
li.remove();
}
newLeaks.add(System.identityHashCode(w));
}
leakedWorlds = newLeaks;
if (allWorlds.size() > 0)
{
FMLLog.severe("Detected leaking worlds in memory. There are %d worlds that appear to be persisting. A mod is likely caching the world incorrectly\n", allWorlds.size() + leakedWorlds.size());
for (World w : allWorlds)
{
FMLLog.severe("The world %x (%s) has leaked.\n", System.identityHashCode(w), w.getWorldInfo().getWorldName());
}
}
}
return getIDs();
}
public static Integer[] getIDs()
{
return worlds.keySet().toArray(new Integer[worlds.size()]); //Only loaded dims, since usually used to cycle through loaded worlds
@ -124,6 +194,7 @@ public class DimensionManager
{
if (world != null) {
worlds.put(id, world);
weakWorldMap.put(world, world);
MinecraftServer.getServer().worldTickTimes.put(id, new long[100]);
FMLLog.info("Loading dimension %d (%s) (%s)", id, world.getWorldInfo().getWorldName(), world.getMinecraftServer());
} else {

View file

@ -3,6 +3,9 @@ package net.minecraftforge.common;
import java.util.ArrayList;
import java.util.Random;
import cpw.mods.fml.common.FMLLog;
import net.minecraft.inventory.IInventory;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.util.WeightedRandom;
@ -148,12 +151,18 @@ public class DungeonHooks
{
int min = theMinimumChanceToGenerateItem;
int max = theMaximumChanceToGenerateItem;
ItemStack ret = this.theItemId.copy();
ret.stackSize = min + (rand.nextInt(max - min + 1));
return ret;
}
@Override
protected final ItemStack[] generateChestContent(Random random, IInventory newInventory)
{
FMLLog.warning("Some mod is still using DungeonHooks.DungonLoot, tell them to stop! %s", this);
return new ItemStack[] { generateStack(random) };
}
public boolean equals(ItemStack item, int min, int max)
{
int minCount = theMinimumChanceToGenerateItem;

View file

@ -653,10 +653,13 @@ public class ForgeChunkManager
int allowedCount = ticketConstraints.containsKey(modId) ? ticketConstraints.get(modId) : defaultMaxCount;
if (tickets.get(world).get(modId).size() >= allowedCount && !warnedMods.contains(modId))
if (tickets.get(world).get(modId).size() >= allowedCount)
{
FMLLog.info("The mod %s has attempted to allocate a chunkloading ticket beyond it's currently allocated maximum : %d", modId, allowedCount);
warnedMods.add(modId);
if (!warnedMods.contains(modId))
{
FMLLog.info("The mod %s has attempted to allocate a chunkloading ticket beyond it's currently allocated maximum : %d", modId, allowedCount);
warnedMods.add(modId);
}
return null;
}
Ticket ticket = new Ticket(modId, type, world);

View file

@ -25,7 +25,7 @@ import static net.minecraftforge.common.ForgeVersion.*;
public class ForgeDummyContainer extends DummyModContainer implements WorldAccessContainer
{
public static int clumpingThreshold;
public static int clumpingThreshold = 64;
public ForgeDummyContainer()
{

View file

@ -35,7 +35,6 @@ public class MinecraftForge
public static final EventBus ORE_GEN_BUS = new EventBus();
@Deprecated //Vanilla feature now
public static boolean SPAWNER_ALLOW_ON_INVERTED = false;
public static final int clumpingThreshold = ForgeDummyContainer.clumpingThreshold;
private static final ForgeInternalHandler INTERNAL_HANDLER = new ForgeInternalHandler();

View file

@ -251,4 +251,14 @@ public class ShapedOreRecipe implements IRecipe
mirrored = mirror;
return this;
}
/**
* Returns the input for this recipe, any mod accessing this value should never
* manipulate the values in this array as it will effect the recipe itself.
* @return The recipes input vales.
*/
public Object[] getInput()
{
return this.input;
}
}

View file

@ -139,4 +139,14 @@ public class ShapelessOreRecipe implements IRecipe
{
return (target.itemID == input.itemID && (target.getItemDamage() == -1 || target.getItemDamage() == input.getItemDamage()));
}
/**
* Returns the input for this recipe, any mod accessing this value should never
* manipulate the values in this array as it will effect the recipe itself.
* @return The recipes input vales.
*/
public ArrayList getInput()
{
return this.input;
}
}

View file

@ -141,7 +141,22 @@
{
ItemStack var8 = this.createStackedBlock(par6);
@@ -1364,4 +1380,840 @@
@@ -1097,12 +1113,13 @@
}
}
+ private int silk_check_meta = -1; //Dirty hack to stop us from needing to special case the silk check hook.
/**
* Return true if a player with Silk Touch can harvest this block directly, and not its normal drops.
*/
protected boolean canSilkHarvest()
{
- return this.renderAsNormalBlock() && !this.isBlockContainer;
+ return this.renderAsNormalBlock() && !this.hasTileEntity(silk_check_meta);
}
/**
@@ -1364,4 +1381,839 @@
canBlockGrass[0] = true;
StatList.initBreakableStats();
}
@ -493,11 +508,10 @@
+ */
+ public boolean canSilkHarvest(World world, EntityPlayer player, int x, int y, int z, int metadata)
+ {
+ if (this instanceof BlockGlass || this instanceof BlockEnderChest)
+ {
+ return true;
+ }
+ return renderAsNormalBlock() && !hasTileEntity(metadata);
+ silk_check_meta = metadata;
+ boolean ret = this.canSilkHarvest();
+ silk_check_meta = 0;
+ return ret;
+ }
+
+ /**

View file

@ -0,0 +1,26 @@
--- ../src_base/minecraft/net/minecraft/client/renderer/tileentity/TileEntityChestRenderer.java
+++ ../src_work/minecraft/net/minecraft/client/renderer/tileentity/TileEntityChestRenderer.java
@@ -1,5 +1,6 @@
package net.minecraft.client.renderer.tileentity;
+import cpw.mods.fml.common.FMLLog;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import java.util.Calendar;
@@ -50,7 +51,15 @@
if (var10 != null && var9 == 0)
{
- ((BlockChest)var10).unifyAdjacentChests(par1TileEntityChest.getWorldObj(), par1TileEntityChest.xCoord, par1TileEntityChest.yCoord, par1TileEntityChest.zCoord);
+ try
+ {
+ ((BlockChest)var10).unifyAdjacentChests(par1TileEntityChest.getWorldObj(), par1TileEntityChest.xCoord, par1TileEntityChest.yCoord, par1TileEntityChest.zCoord);
+ }
+ catch (ClassCastException e)
+ {
+ FMLLog.severe("Attempted to render a chest at %d, %d, %d that was not a chest",
+ par1TileEntityChest.xCoord, par1TileEntityChest.yCoord, par1TileEntityChest.zCoord);
+ }
var9 = par1TileEntityChest.getBlockMetadata();
}

View file

@ -314,7 +314,15 @@
switch (var2)
{
@@ -1846,7 +1953,7 @@
@@ -1571,7 +1678,6 @@
return this.sleeping && this.sleepTimer >= 100;
}
- @SideOnly(Side.CLIENT)
public int getSleepTimer()
{
return this.sleepTimer;
@@ -1846,7 +1952,7 @@
{
if (par1ItemStack.getItem().requiresMultipleRenderPasses())
{
@ -323,7 +331,7 @@
}
if (this.itemInUse != null && par1ItemStack.itemID == Item.bow.itemID)
@@ -1868,6 +1975,7 @@
@@ -1868,6 +1974,7 @@
return 101;
}
}
@ -331,7 +339,7 @@
}
return var3;
@@ -2088,6 +2196,14 @@
@@ -2088,6 +2195,14 @@
}
this.theInventoryEnderChest = par1EntityPlayer.theInventoryEnderChest;

View file

@ -1,19 +1,23 @@
--- ../src_base/minecraft/net/minecraft/network/packet/Packet52MultiBlockChange.java
+++ ../src_work/minecraft/net/minecraft/network/packet/Packet52MultiBlockChange.java
@@ -6,6 +6,7 @@
@@ -6,6 +6,8 @@
import java.io.IOException;
import net.minecraft.world.World;
import net.minecraft.world.chunk.Chunk;
+import net.minecraftforge.common.ForgeDummyContainer;
+import net.minecraftforge.common.MinecraftForge;
public class Packet52MultiBlockChange extends Packet
{
@@ -38,7 +39,7 @@
@@ -38,10 +40,8 @@
try
{
- if (par4 >= 64)
+ if (par4 >= MinecraftForge.clumpingThreshold)
+ if (par4 >= ForgeDummyContainer.clumpingThreshold)
{
System.out.println("ChunkTilesUpdatePacket compress " + par4);
- System.out.println("ChunkTilesUpdatePacket compress " + par4);
-
if (field_73449_e.length < var6)
{
field_73449_e = new byte[var6];

View file

@ -117,7 +117,7 @@
- for (var1 = 0; var1 < this.worldServers.length; ++var1)
- {
+ Integer[] ids = DimensionManager.getIDs();
+ Integer[] ids = DimensionManager.getIDs(this.tickCounter % 200 == 0);
+ for (int x = 0; x < ids.length; x++)
+ {
+ int id = ids[x];

View file

@ -12,10 +12,11 @@
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.network.packet.Packet;
import net.minecraft.network.packet.Packet51MapChunk;
@@ -10,9 +14,15 @@
@@ -10,9 +14,16 @@
import net.minecraft.tileentity.TileEntity;
import net.minecraft.world.ChunkCoordIntPair;
+import net.minecraftforge.common.ForgeDummyContainer;
+import net.minecraftforge.common.ForgeHooks;
+import net.minecraftforge.common.MinecraftForge;
+import net.minecraftforge.event.world.ChunkWatchEvent;
@ -29,7 +30,7 @@
/** note: this is final */
private final ChunkCoordIntPair chunkLocation;
@@ -56,6 +66,8 @@
@@ -56,6 +67,8 @@
this.playersInChunk.remove(par1EntityPlayerMP);
par1EntityPlayerMP.loadedChunks.remove(this.chunkLocation);
@ -38,7 +39,7 @@
if (this.playersInChunk.isEmpty())
{
long var2 = (long)this.chunkLocation.chunkXPos + 2147483647L | (long)this.chunkLocation.chunkZPos + 2147483647L << 32;
@@ -80,20 +92,21 @@
@@ -80,20 +93,21 @@
this.field_73260_f |= 1 << (par2 >> 4);
@ -74,12 +75,12 @@
}
public void sendToAllPlayersWatchingChunk(Packet par1Packet)
@@ -133,40 +146,26 @@
@@ -133,40 +147,26 @@
{
int var4;
- if (this.numberOfTilesToUpdate == 64)
+ if (this.numberOfTilesToUpdate >= MinecraftForge.clumpingThreshold)
+ if (this.numberOfTilesToUpdate >= ForgeDummyContainer.clumpingThreshold)
{
var1 = this.chunkLocation.chunkXPos * 16;
var2 = this.chunkLocation.chunkZPos * 16;

View file

@ -1,11 +1,12 @@
--- ../src_base/minecraft/net/minecraft/util/WeightedRandomChestContent.java
+++ ../src_work/minecraft/net/minecraft/util/WeightedRandomChestContent.java
@@ -1,9 +1,13 @@
@@ -1,9 +1,14 @@
package net.minecraft.util;
import java.util.Random;
+
+import cpw.mods.fml.common.FMLLog;
+import net.minecraft.inventory.IInventory;
import net.minecraft.item.ItemStack;
import net.minecraft.tileentity.TileEntityChest;
import net.minecraft.tileentity.TileEntityDispenser;
@ -14,7 +15,7 @@
public class WeightedRandomChestContent extends WeightedRandomItem
{
@@ -35,27 +39,26 @@
@@ -35,27 +40,17 @@
/**
* Generates the Chest contents.
*/
@ -25,24 +26,17 @@
{
WeightedRandomChestContent var5 = (WeightedRandomChestContent)WeightedRandom.getRandomItem(par0Random, par1ArrayOfWeightedRandomChestContent);
- int var6 = var5.theMinimumChanceToGenerateItem + par0Random.nextInt(var5.theMaximumChanceToGenerateItem - var5.theMinimumChanceToGenerateItem + 1);
+ ItemStack[] stacks = var5.generateChestContent(par0Random, par2TileEntityChest);
- if (var5.theItemId.getMaxStackSize() >= var6)
+ if (var5 instanceof DungeonHooks.DungeonLoot)
+ for (ItemStack item : stacks)
{
- ItemStack var7 = var5.theItemId.copy();
- var7.stackSize = var6;
- par2TileEntityChest.setInventorySlotContents(par0Random.nextInt(par2TileEntityChest.getSizeInventory()), var7);
+ DungeonHooks.DungeonLoot loot = (DungeonHooks.DungeonLoot)var5;
+ par2TileEntityChest.setInventorySlotContents(par0Random.nextInt(par2TileEntityChest.getSizeInventory()), loot.generateStack(par0Random));
+ FMLLog.warning("Some mod is still using DungeonHooks.DungonLoot, tell them to stop! %s", loot);
+ continue;
}
- }
- else
+
+ ItemStack[] stacks = ChestGenHooks.generateStacks(par0Random, var5.theItemId, var5.theMinimumChanceToGenerateItem, var5.theMaximumChanceToGenerateItem);
+
+ for (ItemStack item : stacks)
{
- {
- for (int var9 = 0; var9 < var6; ++var9)
- {
- ItemStack var8 = var5.theItemId.copy();
@ -53,12 +47,12 @@
}
}
}
@@ -68,22 +71,11 @@
@@ -68,22 +63,11 @@
for (int var4 = 0; var4 < par3; ++var4)
{
WeightedRandomChestContent var5 = (WeightedRandomChestContent)WeightedRandom.getRandomItem(par0Random, par1ArrayOfWeightedRandomChestContent);
- int var6 = var5.theMinimumChanceToGenerateItem + par0Random.nextInt(var5.theMaximumChanceToGenerateItem - var5.theMinimumChanceToGenerateItem + 1);
+ ItemStack[] stacks = ChestGenHooks.generateStacks(par0Random, var5.theItemId, var5.theMinimumChanceToGenerateItem, var5.theMaximumChanceToGenerateItem);
+ ItemStack[] stacks = var5.generateChestContent(par0Random, par2TileEntityDispenser);
- if (var5.theItemId.getMaxStackSize() >= var6)
+ for (ItemStack item : stacks)
@ -79,3 +73,22 @@
}
}
}
@@ -109,4 +93,18 @@
return var2;
}
+
+ // -- Forge hooks
+ /**
+ * Allow a mod to submit a custom implementation that can delegate item stack generation beyond simple stack lookup
+ *
+ * @param random The current random for generation
+ * @param newInventory The inventory being generated (do not populate it, but you can refer to it)
+ * @return An array of {@link ItemStack} to put into the chest
+ */
+ protected ItemStack[] generateChestContent(Random random, IInventory newInventory)
+ {
+ return ChestGenHooks.generateStacks(random, theItemId, theMinimumChanceToGenerateItem, theMaximumChanceToGenerateItem);
+ }
+
}