diff --git a/changelog.txt b/changelog.txt index 68176e7..03f03f5 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,3 +1,15 @@ +## Version 1.1.1: ## +Thanks to the following people who contributed to this release! +- Dawnraider +- rockoutwill + +/--Gameplay--/ +- Fixed an issue where the game would crash when attempting to spill items out from a mod inventory which was broken. + +/--Addon API--/ +- Changed how reflective constructor calls are handled to be less strict about primitives which can normally be passed as arguments. +- Fixed an issue where the game would crash on load when trying to reflectively use a block or item constructor that was not the first constructor defined for that type. + ## Version 1.1.0: ## This release will cause issues with craftguide. It will definitely no longer be able to display kiln and saw recipes, but may cause bigger issues than that. I am unfamiliar with the craftguide codebase but I am definitely willing to work with anyone who is to get it functional again. Once it is fixed though, it should have increased functionality due to how a lot of the BTW-specific recipes are now handled. diff --git a/patches/minecraft/net/minecraft/src/Block.java.patch b/patches/minecraft/net/minecraft/src/Block.java.patch index ed06879..b0fa343 100644 --- a/patches/minecraft/net/minecraft/src/Block.java.patch +++ b/patches/minecraft/net/minecraft/src/Block.java.patch @@ -764,7 +764,7 @@ if (var0 > 0 && blocksList[var0].getRenderType() == 10) { var1 = true; -@@ -1364,10 +1424,2379 @@ +@@ -1364,10 +1424,2357 @@ } useNeighborBrightness[var0] = var1; @@ -1045,38 +1045,16 @@ + parameterValues[i + 1] = parameters[i]; + } + -+ Constructor[] constructors = newClass.getDeclaredConstructors(); -+ Constructor constructorToUse = null; ++ Constructor constructorToUse = FCUtilsReflection.findMatchingConstructor(newClass, parameterTypes); + -+ for (Constructor c : constructors) { -+ boolean constructorMatches = true; ++ if (constructorToUse == null) { ++ String message = "No appropriate constructor found for " + blocksList[id] + ": "; + -+ Class[] cParamTypes = c.getParameterTypes(); -+ -+ if (cParamTypes.length == parameterTypes.length) { -+ for (int j = 0; j < cParamTypes.length; j++) { -+ if (!(cParamTypes[j].isAssignableFrom(parameterTypes[j]) || -+ parameterTypes[j].isAssignableFrom(cParamTypes[j]))) { -+ constructorMatches = false; -+ break; -+ } -+ } -+ } -+ else { -+ constructorMatches = false; -+ String message = "No appropriate constructor found for " + blocksList[id] + ": "; -+ -+ for (Class paramType : parameterTypes) { -+ message += paramType.getName() + ", "; -+ } -+ -+ throw new RuntimeException(message); ++ for (Class paramType : parameterTypes) { ++ message += paramType.getSimpleName() + ", "; + } + -+ if (constructorMatches) { -+ constructorToUse = c; -+ break; -+ } ++ throw new RuntimeException(message); + } + + try { diff --git a/patches/minecraft/net/minecraft/src/EntityList.java.patch b/patches/minecraft/net/minecraft/src/EntityList.java.patch index cda42e6..e7754c1 100644 --- a/patches/minecraft/net/minecraft/src/EntityList.java.patch +++ b/patches/minecraft/net/minecraft/src/EntityList.java.patch @@ -58,7 +58,7 @@ catch (Exception var4) { var4.printStackTrace(); -@@ -101,9 +121,16 @@ +@@ -101,9 +121,19 @@ if (var3 != null) { @@ -67,6 +67,9 @@ + + var2 = FCEntityVillager.createVillagerFromProfession(par1World, profession); + } ++ else if (EntityPlayerMP.class.equals(var3)) { ++ return null; ++ } + else { var2 = (Entity)var3.getConstructor(new Class[] {World.class}).newInstance(new Object[] {par1World}); } @@ -75,7 +78,7 @@ catch (Exception var4) { var4.printStackTrace(); -@@ -115,7 +142,10 @@ +@@ -115,7 +145,10 @@ } else { @@ -86,7 +89,7 @@ } return var2; -@@ -134,9 +164,14 @@ +@@ -134,9 +167,14 @@ if (var3 != null) { @@ -101,7 +104,7 @@ catch (Exception var4) { var4.printStackTrace(); -@@ -144,7 +179,10 @@ +@@ -144,7 +182,10 @@ if (var2 == null) { @@ -112,7 +115,7 @@ } return var2; -@@ -240,5 +278,231 @@ +@@ -240,5 +281,207 @@ addMapping(EntityIronGolem.class, "VillagerGolem", 99); addMapping(EntityVillager.class, "Villager", 120, 5651507, 12422002); addMapping(EntityEnderCrystal.class, "EnderCrystal", 200); @@ -286,31 +289,7 @@ + } + } + -+ Constructor[] constructors = entityClass.getDeclaredConstructors(); -+ Constructor constructorToUse = null; -+ -+ for (Constructor c : constructors) { -+ boolean constructorMatches = true; -+ -+ Class[] cParamTypes = c.getParameterTypes(); -+ -+ if (cParamTypes.length == parameterTypes.length) { -+ for (int j = 0; j < cParamTypes.length; j++) { -+ if (!cParamTypes[j].isAssignableFrom(parameterTypes[j])) { -+ constructorMatches = false; -+ break; -+ } -+ } -+ } -+ else { -+ constructorMatches = false; -+ } -+ -+ if (constructorMatches) { -+ constructorToUse = c; -+ break; -+ } -+ } ++ Constructor constructorToUse = FCUtilsReflection.findMatchingConstructor(entityClass, parameterTypes); + + if (constructorToUse == null) { + String message = "No appropriate constructor found for " + classToStringMapping.get(entityClass) + ": "; diff --git a/patches/minecraft/net/minecraft/src/FCBetterThanWolves.java.patch b/patches/minecraft/net/minecraft/src/FCBetterThanWolves.java.patch index cc05478..825dbba 100644 --- a/patches/minecraft/net/minecraft/src/FCBetterThanWolves.java.patch +++ b/patches/minecraft/net/minecraft/src/FCBetterThanWolves.java.patch @@ -25,7 +25,7 @@ + +public class FCBetterThanWolves extends FCAddOn +{ -+ public static final String fcVersionString = "1.1.0"; ++ public static final String fcVersionString = "1.1.1"; + + public static FCBetterThanWolves m_instance = new FCBetterThanWolves(); + diff --git a/patches/minecraft/net/minecraft/src/FCUtilsInventory.java.patch b/patches/minecraft/net/minecraft/src/FCUtilsInventory.java.patch index d97db56..3e0cfb4 100644 --- a/patches/minecraft/net/minecraft/src/FCUtilsInventory.java.patch +++ b/patches/minecraft/net/minecraft/src/FCUtilsInventory.java.patch @@ -1,6 +1,6 @@ --- /dev/null +++ b/minecraft/net/minecraft/src/FCUtilsInventory.java -@@ -0,0 +1,587 @@ +@@ -0,0 +1,589 @@ +// FCMOD + +package net.minecraft.src; @@ -52,8 +52,10 @@ + } + + itemstack.stackSize -= i1; -+ EntityItem entityitem = (EntityItem) EntityList.createEntityOfType(EntityItem.class, world, (float)i + f, (float)j + f1, (float)k + f2, new ItemStack(itemstack.itemID, i1, itemstack.getItemDamage())); -+ ++ EntityItem entityitem = (EntityItem) EntityList.createEntityOfType(EntityItem.class, world, ++ (double) ((float) i + f), (double) ((float) j + f1), (double) ((float) k + f2), ++ new ItemStack(itemstack.itemID, i1, itemstack.getItemDamage())); ++ + float f3 = 0.05F; + + entityitem.motionX = (float)world.rand.nextGaussian() * f3; diff --git a/patches/minecraft/net/minecraft/src/FCUtilsReflection.java.patch b/patches/minecraft/net/minecraft/src/FCUtilsReflection.java.patch index 3623d91..fa1ab78 100644 --- a/patches/minecraft/net/minecraft/src/FCUtilsReflection.java.patch +++ b/patches/minecraft/net/minecraft/src/FCUtilsReflection.java.patch @@ -1,8 +1,9 @@ --- /dev/null +++ b/minecraft/net/minecraft/src/FCUtilsReflection.java -@@ -0,0 +1,42 @@ +@@ -0,0 +1,111 @@ +package net.minecraft.src; + ++import java.lang.reflect.Constructor; +import java.util.HashMap; +import java.util.Map; + @@ -42,4 +43,72 @@ + + return null; + } ++ ++ public static Constructor findMatchingConstructor(Class classForSearch, Class[] parameterTypes) { ++ Constructor[] constructors = classForSearch.getDeclaredConstructors(); ++ Constructor constructorToUse = null; ++ ++ for (Constructor c : constructors) { ++ boolean constructorMatches = true; ++ ++ Class[] cParamTypes = c.getParameterTypes(); ++ ++ if (cParamTypes.length == parameterTypes.length) { ++ for (int j = 0; j < cParamTypes.length; j++) { ++ if (!doesParameterTypeSatisfyConstructorType(parameterTypes[j], cParamTypes[j])) { ++ constructorMatches = false; ++ break; ++ } ++ } ++ } ++ else { ++ constructorMatches = false; ++ } ++ ++ if (constructorMatches) { ++ constructorToUse = c; ++ break; ++ } ++ } ++ ++ return constructorToUse; ++ } ++ ++ private static boolean doesParameterTypeSatisfyConstructorType(Class parameterType, Class constructorType) { ++ if (parameterType.isPrimitive()) { ++ int pSize = getPrimitiveSize(parameterType); ++ int cSize = getPrimitiveSize(constructorType); ++ ++ if (constructorType == boolean.class) { ++ return parameterType.equals(boolean.class); ++ } ++ ++ if (!isFloatingPoint(constructorType) && isFloatingPoint(parameterType)) { ++ return false; ++ } ++ ++ return pSize <= cSize; ++ } ++ else { ++ return constructorType.isAssignableFrom(parameterType); ++ } ++ } ++ ++ private static int getPrimitiveSize(Class primitive) { ++ if (!primitive.isPrimitive()) { ++ throw new IllegalArgumentException("Class must be a primitive"); ++ } ++ ++ if (primitive == byte.class || primitive == char.class) ++ return 8; ++ if (primitive == short.class) ++ return 16; ++ if (primitive == int.class || primitive == float.class) ++ return 32; ++ return 64; ++ } ++ ++ private static boolean isFloatingPoint(Class primitive) { ++ return primitive == float.class || primitive == double.class; ++ } +} diff --git a/patches/minecraft/net/minecraft/src/Item.java.patch b/patches/minecraft/net/minecraft/src/Item.java.patch index dc6273f..ddc6b2d 100644 --- a/patches/minecraft/net/minecraft/src/Item.java.patch +++ b/patches/minecraft/net/minecraft/src/Item.java.patch @@ -425,7 +425,7 @@ /** * Called when item is crafted/smelted. Used only by maps so far. -@@ -671,4 +695,507 @@ +@@ -671,4 +695,485 @@ { StatList.initStats(); } @@ -526,38 +526,16 @@ + parameterValues[i + 1] = parameters[i]; + } + -+ Constructor[] constructors = newClass.getDeclaredConstructors(); -+ Constructor constructorToUse = null; ++ Constructor constructorToUse = FCUtilsReflection.findMatchingConstructor(newClass, parameterTypes); + -+ for (Constructor c : constructors) { -+ boolean constructorMatches = true; ++ if (constructorToUse == null) { ++ String message = "No appropriate constructor found for " + itemsList[id] + ": "; + -+ Class[] cParamTypes = c.getParameterTypes(); -+ -+ if (cParamTypes.length == parameterTypes.length) { -+ for (int j = 0; j < cParamTypes.length; j++) { -+ if (!(cParamTypes[j].isAssignableFrom(parameterTypes[j]) || -+ parameterTypes[j].isAssignableFrom(cParamTypes[j]))) { -+ constructorMatches = false; -+ break; -+ } -+ } -+ } -+ else { -+ constructorMatches = false; -+ String message = "No appropriate constructor found for " + itemsList[id] + ": "; -+ -+ for (Class paramType : parameterTypes) { -+ message += paramType.getName() + ", "; -+ } -+ -+ throw new RuntimeException(message); ++ for (Class paramType : parameterTypes) { ++ message += paramType.getSimpleName() + ", "; + } + -+ if (constructorMatches) { -+ constructorToUse = c; -+ break; -+ } ++ throw new RuntimeException(message); + } + + try { diff --git a/patches/minecraft_server/net/minecraft/src/Block.java.patch b/patches/minecraft_server/net/minecraft/src/Block.java.patch index 81a5e10..f9fd6a3 100644 --- a/patches/minecraft_server/net/minecraft/src/Block.java.patch +++ b/patches/minecraft_server/net/minecraft/src/Block.java.patch @@ -709,7 +709,7 @@ if (var0 > 0 && blocksList[var0].getRenderType() == 10) { var1 = true; -@@ -1204,10 +1261,2142 @@ +@@ -1204,10 +1261,2120 @@ } useNeighborBrightness[var0] = var1; @@ -990,38 +990,16 @@ + parameterValues[i + 1] = parameters[i]; + } + -+ Constructor[] constructors = newClass.getDeclaredConstructors(); -+ Constructor constructorToUse = null; -+ -+ for (Constructor c : constructors) { -+ boolean constructorMatches = true; -+ -+ Class[] cParamTypes = c.getParameterTypes(); -+ -+ if (cParamTypes.length == parameterTypes.length) { -+ for (int j = 0; j < cParamTypes.length; j++) { -+ if (!(cParamTypes[j].isAssignableFrom(parameterTypes[j]) || -+ parameterTypes[j].isAssignableFrom(cParamTypes[j]))) { -+ constructorMatches = false; -+ break; -+ } -+ } -+ } -+ else { -+ constructorMatches = false; -+ String message = "No appropriate constructor found for " + blocksList[id] + ": "; -+ -+ for (Class paramType : parameterTypes) { -+ message += paramType.getName() + ", "; -+ } -+ -+ throw new RuntimeException(message); -+ } -+ -+ if (constructorMatches) { -+ constructorToUse = c; -+ break; ++ Constructor constructorToUse = FCUtilsReflection.findMatchingConstructor(newClass, parameterTypes); ++ ++ if (constructorToUse == null) { ++ String message = "No appropriate constructor found for " + blocksList[id] + ": "; ++ ++ for (Class paramType : parameterTypes) { ++ message += paramType.getSimpleName() + ", "; + } ++ ++ throw new RuntimeException(message); + } + + try { diff --git a/patches/minecraft_server/net/minecraft/src/EntityList.java.patch b/patches/minecraft_server/net/minecraft/src/EntityList.java.patch index b319075..3d1c3ff 100644 --- a/patches/minecraft_server/net/minecraft/src/EntityList.java.patch +++ b/patches/minecraft_server/net/minecraft/src/EntityList.java.patch @@ -49,7 +49,7 @@ catch (Exception var4) { var4.printStackTrace(); -@@ -101,9 +115,16 @@ +@@ -101,9 +115,19 @@ if (var3 != null) { @@ -58,6 +58,9 @@ + + var2 = FCEntityVillager.createVillagerFromProfession(par1World, profession); + } ++ else if (EntityPlayerMP.class.equals(var3)) { ++ return null; ++ } + else { var2 = (Entity)var3.getConstructor(new Class[] {World.class}).newInstance(new Object[] {par1World}); } @@ -66,7 +69,7 @@ catch (Exception var4) { var4.printStackTrace(); -@@ -115,6 +136,9 @@ +@@ -115,6 +139,9 @@ } else { @@ -76,7 +79,7 @@ par1World.getWorldLogAgent().func_98236_b("Skipping Entity with id " + par0NBTTagCompound.getString("id")); } -@@ -134,9 +158,14 @@ +@@ -134,9 +161,14 @@ if (var3 != null) { @@ -91,7 +94,7 @@ catch (Exception var4) { var4.printStackTrace(); -@@ -144,6 +173,9 @@ +@@ -144,6 +176,9 @@ if (var2 == null) { @@ -101,7 +104,7 @@ par1World.getWorldLogAgent().func_98236_b("Skipping Entity with id " + par0); } -@@ -240,5 +272,196 @@ +@@ -240,5 +275,172 @@ addMapping(EntityIronGolem.class, "VillagerGolem", 99); addMapping(EntityVillager.class, "Villager", 120, 5651507, 12422002); addMapping(EntityEnderCrystal.class, "EnderCrystal", 200); @@ -240,31 +243,7 @@ + } + } + -+ Constructor[] constructors = entityClass.getDeclaredConstructors(); -+ Constructor constructorToUse = null; -+ -+ for (Constructor c : constructors) { -+ boolean constructorMatches = true; -+ -+ Class[] cParamTypes = c.getParameterTypes(); -+ -+ if (cParamTypes.length == parameterTypes.length) { -+ for (int j = 0; j < cParamTypes.length; j++) { -+ if (!cParamTypes[j].isAssignableFrom(parameterTypes[j])) { -+ constructorMatches = false; -+ break; -+ } -+ } -+ } -+ else { -+ constructorMatches = false; -+ } -+ -+ if (constructorMatches) { -+ constructorToUse = c; -+ break; -+ } -+ } ++ Constructor constructorToUse = FCUtilsReflection.findMatchingConstructor(entityClass, parameterTypes); + + if (constructorToUse == null) { + String message = "No appropriate constructor found for " + classToStringMapping.get(entityClass) + ": "; diff --git a/patches/minecraft_server/net/minecraft/src/FCBetterThanWolves.java.patch b/patches/minecraft_server/net/minecraft/src/FCBetterThanWolves.java.patch index 827561c..af0d19f 100644 --- a/patches/minecraft_server/net/minecraft/src/FCBetterThanWolves.java.patch +++ b/patches/minecraft_server/net/minecraft/src/FCBetterThanWolves.java.patch @@ -22,7 +22,7 @@ + +public class FCBetterThanWolves extends FCAddOn +{ -+ public static final String fcVersionString = "1.1.0"; ++ public static final String fcVersionString = "1.1.1"; + + + public static FCBetterThanWolves m_instance = new FCBetterThanWolves(); diff --git a/patches/minecraft_server/net/minecraft/src/FCUtilsInventory.java.patch b/patches/minecraft_server/net/minecraft/src/FCUtilsInventory.java.patch index ec84802..ddb8dd0 100644 --- a/patches/minecraft_server/net/minecraft/src/FCUtilsInventory.java.patch +++ b/patches/minecraft_server/net/minecraft/src/FCUtilsInventory.java.patch @@ -1,6 +1,6 @@ --- /dev/null +++ b/minecraft_server/net/minecraft/src/FCUtilsInventory.java -@@ -0,0 +1,587 @@ +@@ -0,0 +1,589 @@ +// FCMOD + +package net.minecraft.src; @@ -52,7 +52,9 @@ + } + + itemstack.stackSize -= i1; -+ EntityItem entityitem = (EntityItem) EntityList.createEntityOfType(EntityItem.class, world, (float)i + f, (float)j + f1, (float)k + f2, new ItemStack(itemstack.itemID, i1, itemstack.getItemDamage())); ++ EntityItem entityitem = (EntityItem) EntityList.createEntityOfType(EntityItem.class, world, ++ (double) ((float) i + f), (double) ((float) j + f1), (double) ((float) k + f2), ++ new ItemStack(itemstack.itemID, i1, itemstack.getItemDamage())); + + float f3 = 0.05F; + diff --git a/patches/minecraft_server/net/minecraft/src/FCUtilsReflection.java.patch b/patches/minecraft_server/net/minecraft/src/FCUtilsReflection.java.patch index 1f85f89..c750e3a 100644 --- a/patches/minecraft_server/net/minecraft/src/FCUtilsReflection.java.patch +++ b/patches/minecraft_server/net/minecraft/src/FCUtilsReflection.java.patch @@ -1,8 +1,9 @@ --- /dev/null +++ b/minecraft_server/net/minecraft/src/FCUtilsReflection.java -@@ -0,0 +1,42 @@ +@@ -0,0 +1,111 @@ +package net.minecraft.src; + ++import java.lang.reflect.Constructor; +import java.util.HashMap; +import java.util.Map; + @@ -42,5 +43,73 @@ + + return null; + } ++ ++ public static Constructor findMatchingConstructor(Class classForSearch, Class[] parameterTypes) { ++ Constructor[] constructors = classForSearch.getDeclaredConstructors(); ++ Constructor constructorToUse = null; ++ ++ for (Constructor c : constructors) { ++ boolean constructorMatches = true; ++ ++ Class[] cParamTypes = c.getParameterTypes(); ++ ++ if (cParamTypes.length == parameterTypes.length) { ++ for (int j = 0; j < cParamTypes.length; j++) { ++ if (!doesParameterTypeSatisfyConstructorType(parameterTypes[j], cParamTypes[j])) { ++ constructorMatches = false; ++ break; ++ } ++ } ++ } ++ else { ++ constructorMatches = false; ++ } ++ ++ if (constructorMatches) { ++ constructorToUse = c; ++ break; ++ } ++ } ++ ++ return constructorToUse; ++ } ++ ++ private static boolean doesParameterTypeSatisfyConstructorType(Class parameterType, Class constructorType) { ++ if (parameterType.isPrimitive()) { ++ int pSize = getPrimitiveSize(parameterType); ++ int cSize = getPrimitiveSize(constructorType); ++ ++ if (constructorType == boolean.class) { ++ return parameterType.equals(boolean.class); ++ } ++ ++ if (!isFloatingPoint(constructorType) && isFloatingPoint(parameterType)) { ++ return false; ++ } ++ ++ return pSize <= cSize; ++ } ++ else { ++ return constructorType.isAssignableFrom(parameterType); ++ } ++ } ++ ++ private static int getPrimitiveSize(Class primitive) { ++ if (!primitive.isPrimitive()) { ++ throw new IllegalArgumentException("Class must be a primitive"); ++ } ++ ++ if (primitive == byte.class || primitive == char.class) ++ return 8; ++ if (primitive == short.class) ++ return 16; ++ if (primitive == int.class || primitive == float.class) ++ return 32; ++ return 64; ++ } ++ ++ private static boolean isFloatingPoint(Class primitive) { ++ return primitive == float.class || primitive == double.class; ++ } +} \ No newline at end of file diff --git a/patches/minecraft_server/net/minecraft/src/Item.java.patch b/patches/minecraft_server/net/minecraft/src/Item.java.patch index 2e13820..46d2ab9 100644 --- a/patches/minecraft_server/net/minecraft/src/Item.java.patch +++ b/patches/minecraft_server/net/minecraft/src/Item.java.patch @@ -423,7 +423,7 @@ /** * Called when item is crafted/smelted. Used only by maps so far. -@@ -573,4 +591,502 @@ +@@ -573,4 +591,480 @@ { StatList.initStats(); } @@ -524,38 +524,16 @@ + parameterValues[i + 1] = parameters[i]; + } + -+ Constructor[] constructors = newClass.getDeclaredConstructors(); -+ Constructor constructorToUse = null; -+ -+ for (Constructor c : constructors) { -+ boolean constructorMatches = true; -+ -+ Class[] cParamTypes = c.getParameterTypes(); -+ -+ if (cParamTypes.length == parameterTypes.length) { -+ for (int j = 0; j < cParamTypes.length; j++) { -+ if (!(cParamTypes[j].isAssignableFrom(parameterTypes[j]) || -+ parameterTypes[j].isAssignableFrom(cParamTypes[j]))) { -+ constructorMatches = false; -+ break; -+ } -+ } -+ } -+ else { -+ constructorMatches = false; -+ String message = "No appropriate constructor found for " + itemsList[id] + ": "; -+ -+ for (Class paramType : parameterTypes) { -+ message += paramType.getName() + ", "; -+ } -+ -+ throw new RuntimeException(message); -+ } -+ -+ if (constructorMatches) { -+ constructorToUse = c; -+ break; ++ Constructor constructorToUse = FCUtilsReflection.findMatchingConstructor(newClass, parameterTypes); ++ ++ if (constructorToUse == null) { ++ String message = "No appropriate constructor found for " + itemsList[id] + ": "; ++ ++ for (Class paramType : parameterTypes) { ++ message += paramType.getSimpleName() + ", "; + } ++ ++ throw new RuntimeException(message); + } + + try {