-
Notifications
You must be signed in to change notification settings - Fork 65
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Vanilla Crash & Furnace Speedup (#37)
* Vanilla Crash & Furnace Speedup 1) Backports a fix for URL parsing from MinecraftForge/MinecraftForge#1712 2) Makes FurnaceRecipe significantly faster by using a HashMap w/ ItemStackHashingStrategy * Thermos sledgehammer ASM for the furnace fix * Overwrite instead of ignore. * Going with the assumption GT registers things later and we want those. At first glance, most of the conflicts were dust -> ic2Ingot Update hashing strategy slightly * asm tweaks
- Loading branch information
1 parent
eafe6b9
commit 43e67ca
Showing
10 changed files
with
271 additions
and
13 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
47 changes: 47 additions & 0 deletions
47
src/main/java/com/mitchej123/hodgepodge/asm/ThermosFurnaceSledgeHammer.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
package com.mitchej123.hodgepodge.asm; | ||
|
||
import com.mitchej123.hodgepodge.core.HodgepodgeMixinPlugin; | ||
import net.minecraft.launchwrapper.IClassTransformer; | ||
import org.apache.logging.log4j.LogManager; | ||
import org.apache.logging.log4j.Logger; | ||
import org.objectweb.asm.ClassReader; | ||
import org.objectweb.asm.ClassWriter; | ||
import org.objectweb.asm.Opcodes; | ||
import org.objectweb.asm.tree.ClassNode; | ||
import org.objectweb.asm.tree.InsnList; | ||
import org.objectweb.asm.tree.InsnNode; | ||
import org.objectweb.asm.tree.MethodNode; | ||
|
||
import static org.objectweb.asm.Opcodes.ASM5; | ||
|
||
@SuppressWarnings("unused") | ||
public class ThermosFurnaceSledgeHammer implements IClassTransformer { | ||
private static final Logger LOGGER = LogManager.getLogger("ThermosFurnaceSledgeHammer"); | ||
@Override | ||
public byte[] transform(String name, String transformedName, byte[] basicClass) { | ||
if (HodgepodgeMixinPlugin.config.thermosCraftServerClass.equals(transformedName)) { | ||
LOGGER.info("Patching Thermos or derivative to not break our furnace fix"); | ||
final ClassReader cr = new ClassReader(basicClass); | ||
final ClassWriter cw = new ClassWriter(0); | ||
|
||
final ClassNode cn = new ClassNode(ASM5); | ||
cr.accept(cn, 0); | ||
for (MethodNode m : cn.methods) { | ||
if ("resetRecipes".equals(m.name)) { | ||
LOGGER.info("Taking a sledgehammer to CraftServer.resetRecipes()"); | ||
//Replace the body with a RETURN opcode | ||
InsnList insnList = new InsnList(); | ||
insnList.add(new InsnNode(Opcodes.RETURN)); | ||
m.instructions = insnList; | ||
m.maxStack = 0; | ||
} | ||
} | ||
cn.accept(cw); | ||
return cw.toByteArray(); | ||
} | ||
else { | ||
return basicClass; | ||
} | ||
} | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
24 changes: 24 additions & 0 deletions
24
src/main/java/com/mitchej123/hodgepodge/core/util/ItemStackHashingStrategy.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
package com.mitchej123.hodgepodge.core.util; | ||
|
||
import gnu.trove.strategy.HashingStrategy; | ||
import net.minecraft.item.ItemStack; | ||
|
||
/* | ||
* Strategy to make ItemStacks Hashable | ||
* - Taken from https://github.com/hilburn/AdvancedSystemsManager/blob/master/src/main/java/advancedsystemsmanager/flow/execution/buffers/maps/ItemStackHashingStrategy.java | ||
* under the the DBaJ (Don't Be a Jerk) non-commercial care-free license. | ||
* (c) hilburn | ||
*/ | ||
public class ItemStackHashingStrategy implements HashingStrategy<ItemStack> { | ||
public static final ItemStackHashingStrategy INSTANCE = new ItemStackHashingStrategy(); | ||
|
||
@Override | ||
public int computeHashCode(ItemStack stack) { | ||
return stack.getItem().hashCode() ^ (stack.getItemDamage() * 31) ^ (stack.hasTagCompound() ? stack.stackTagCompound.hashCode() : 0); | ||
} | ||
|
||
@Override | ||
public boolean equals(ItemStack stack1, ItemStack stack2) { | ||
return stack1 != null && stack1.isItemEqual(stack2) && ItemStack.areItemStackTagsEqual(stack1, stack2); | ||
} | ||
} |
68 changes: 68 additions & 0 deletions
68
src/main/java/com/mitchej123/hodgepodge/mixins/fixUrlDetection/MixinForgeHooks.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
package com.mitchej123.hodgepodge.mixins.fixUrlDetection; | ||
|
||
import net.minecraft.event.ClickEvent; | ||
import net.minecraft.util.ChatComponentText; | ||
import net.minecraft.util.IChatComponent; | ||
import net.minecraftforge.common.ForgeHooks; | ||
import org.spongepowered.asm.mixin.Mixin; | ||
import org.spongepowered.asm.mixin.Overwrite; | ||
|
||
import java.net.URI; | ||
import java.net.URISyntaxException; | ||
import java.util.regex.Matcher; | ||
import java.util.regex.Pattern; | ||
|
||
@Mixin(ForgeHooks.class) | ||
public class MixinForgeHooks { | ||
private static final Pattern URL_PATTERN = Pattern.compile( | ||
// schema ipv4 OR namespace port path ends | ||
// |-----------------| |-------------------------| |-------------------------| |---------| |--| |---------------| | ||
"((?:[a-z0-9]{2,}:\\/\\/)?(?:(?:[0-9]{1,3}\\.){3}[0-9]{1,3}|(?:[-\\w_]{1,}\\.[a-z]{2,}?))(?::[0-9]{1,5})?.*?(?=[!\"\u00A7 \n]|$))", | ||
Pattern.CASE_INSENSITIVE); | ||
|
||
/** | ||
* @author LexManos | ||
* Backported from https://github.com/MinecraftForge/MinecraftForge/commit/5b28eb53e8623448b1c2bdb46b8924662e690995 | ||
*/ | ||
@Overwrite | ||
public static IChatComponent newChatWithLinks(String string) { | ||
// Includes ipv4 and domain pattern | ||
// Matches an ip (xx.xxx.xx.xxx) or a domain (something.com) with or | ||
// without a protocol or path. | ||
IChatComponent ichat = new ChatComponentText(""); | ||
Matcher matcher = MixinForgeHooks.URL_PATTERN.matcher(string); | ||
int lastEnd = 0; | ||
|
||
// Find all urls | ||
while (matcher.find()) { | ||
int start = matcher.start(); | ||
int end = matcher.end(); | ||
|
||
// Append the previous left overs. | ||
ichat.appendText(string.substring(lastEnd, start)); | ||
lastEnd = end; | ||
String url = string.substring(start, end); | ||
IChatComponent link = new ChatComponentText(url); | ||
|
||
try { | ||
// Add schema so client doesn't crash. | ||
if ((new URI(url)).getScheme() == null) | ||
url = "http://" + url; | ||
} | ||
catch (URISyntaxException e) { | ||
// Bad syntax bail out! | ||
ichat.appendText(url); | ||
continue; | ||
} | ||
|
||
// Set the click event and append the link. | ||
ClickEvent click = new ClickEvent(ClickEvent.Action.OPEN_URL, url); | ||
link.getChatStyle().setChatClickEvent(click); | ||
ichat.appendSibling(link); | ||
} | ||
|
||
// Append the rest of the message. | ||
ichat.appendText(string.substring(lastEnd)); | ||
return ichat; | ||
} | ||
} |
97 changes: 97 additions & 0 deletions
97
...main/java/com/mitchej123/hodgepodge/mixins/speedupVanillaFurnace/MixinFurnaceRecipes.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
package com.mitchej123.hodgepodge.mixins.speedupVanillaFurnace; | ||
|
||
import com.mitchej123.hodgepodge.core.HodgepodgeMixinPlugin; | ||
import com.mitchej123.hodgepodge.core.util.ItemStackHashingStrategy; | ||
import gnu.trove.map.hash.TCustomHashMap; | ||
import net.minecraft.block.Block; | ||
import net.minecraft.item.ItemStack; | ||
import net.minecraft.item.crafting.FurnaceRecipes; | ||
import net.minecraft.launchwrapper.Launch; | ||
import org.spongepowered.asm.mixin.Mixin; | ||
import org.spongepowered.asm.mixin.Overwrite; | ||
import org.spongepowered.asm.mixin.Shadow; | ||
import org.spongepowered.asm.mixin.injection.At; | ||
import org.spongepowered.asm.mixin.injection.Redirect; | ||
|
||
import java.lang.reflect.Field; | ||
import java.util.Map; | ||
|
||
@Mixin(FurnaceRecipes.class) | ||
public abstract class MixinFurnaceRecipes { | ||
/* | ||
* Speed up FurnaceRecipes.getSmeltingResult by: | ||
* 1) Hijacking the constructor here to recreate the lists with a replacement hash map and an ItemStack hashing strategy | ||
* 2) No longer looping over every. single. recipe. in the list and using the .get() | ||
*/ | ||
@Shadow private Map smeltingList; | ||
@Shadow private Map experienceList; | ||
@Shadow abstract boolean func_151397_a(ItemStack p_151397_1_, ItemStack p_151397_2_); | ||
|
||
@Redirect( | ||
at=@At( | ||
value="INVOKE", | ||
target="Lnet/minecraft/item/crafting/FurnaceRecipes;func_151393_a(Lnet/minecraft/block/Block;Lnet/minecraft/item/ItemStack;F)V", | ||
ordinal = 0 | ||
), | ||
method="Lnet/minecraft/item/crafting/FurnaceRecipes;<init>()V" | ||
) | ||
private void doStuff(FurnaceRecipes instance, Block p_151393_1_, ItemStack p_151393_2_, float p_151393_3_) throws NoSuchFieldException, IllegalAccessException { | ||
HodgepodgeMixinPlugin.log.info("Swapping out smeltingList and experienceList in FurnaceRecipes"); | ||
|
||
// Hack into the first call in the constructor and replace the lists with a new hashmap that has an ItemStackMi hashing strategy | ||
boolean devEnv = (Boolean) Launch.blackboard.get("fml.deobfuscatedEnvironment"); | ||
try { | ||
Class<?> clazz = Class.forName("net.minecraft.item.crafting.FurnaceRecipes"); | ||
|
||
Field smeltingList = clazz.getDeclaredField(devEnv ? "smeltingList" : "field_77604_b"); | ||
smeltingList.setAccessible(true); | ||
smeltingList.set(instance, new TCustomHashMap<ItemStack, ItemStack>(ItemStackHashingStrategy.INSTANCE)); | ||
|
||
Field experienceList = clazz.getDeclaredField(devEnv ? "experienceList" : "field_77605_c"); | ||
experienceList.setAccessible(true); | ||
experienceList.set(instance, new TCustomHashMap<ItemStack, Float>(ItemStackHashingStrategy.INSTANCE)); | ||
|
||
HodgepodgeMixinPlugin.log.info("Successfully swapped the lists in FurnaceRecipes"); | ||
|
||
} catch (ClassNotFoundException | IllegalAccessException e) { | ||
e.printStackTrace(); | ||
} | ||
instance.func_151393_a(p_151393_1_, p_151393_2_, p_151393_3_); | ||
} | ||
/** | ||
* @author mitchej123 | ||
* Inspired by later versions of forge | ||
*/ | ||
@SuppressWarnings("unchecked") | ||
@Overwrite(remap = false) | ||
public void func_151394_a /* addSmeltingRecipe */ (ItemStack input, ItemStack stack, float experience) { | ||
if (getSmeltingResult(input) != null) { | ||
HodgepodgeMixinPlugin.log.info("Overwriting smelting recipe for input: {} and output {} with {}", input, getSmeltingResult(input), stack); | ||
} | ||
this.smeltingList.put(input, stack); | ||
this.experienceList.put(stack, experience); | ||
} | ||
|
||
/** | ||
* @author mitchej123 | ||
* Significantly Faster | ||
*/ | ||
@Overwrite | ||
public ItemStack getSmeltingResult(ItemStack stack) { | ||
return (ItemStack) this.smeltingList.get(stack); | ||
} | ||
|
||
/** | ||
* @author mitchej123 | ||
* Significantly Faster | ||
*/ | ||
@Overwrite(remap = false) | ||
public float func_151398_b /* getSmeltingExperience */ (ItemStack stack) { | ||
float exp = stack.getItem().getSmeltingExperience(stack); | ||
if (exp == -1) { | ||
exp = (Float) (this.experienceList.get(stack)); | ||
} | ||
return exp; | ||
} | ||
|
||
} |