package net.fybertech.dynamicmappings.mappers;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import net.fybertech.dynamicmappings.DynamicMappings;
import net.fybertech.dynamicmappings.Mapping;
import net.fybertech.dynamicmappings.MappingsClass;
import net.fybertech.meddle.Meddle;
import net.fybertech.meddle.MeddleUtil;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.Type;
import org.objectweb.asm.tree.AbstractInsnNode;
import org.objectweb.asm.tree.ClassNode;
import org.objectweb.asm.tree.FieldInsnNode;
import org.objectweb.asm.tree.FieldNode;
import org.objectweb.asm.tree.LdcInsnNode;
import org.objectweb.asm.tree.MethodInsnNode;
import org.objectweb.asm.tree.MethodNode;
import org.objectweb.asm.tree.TypeInsnNode;
import org.objectweb.asm.tree.VarInsnNode;
@MappingsClass(clientSide=true)
public class ClientMappings extends MappingsBase
{
@Mapping(provides="net/minecraft/client/main/Main")
public boolean getMainClass()
{
ClassNode main = getClassNode("net/minecraft/client/main/Main");
if (main == null) return false;
addClassMapping("net/minecraft/client/main/Main", main);
return true;
}
@Mapping(provides={
"net/minecraft/client/Minecraft",
"net/minecraft/client/main/GameConfiguration"},
depends="net/minecraft/client/main/Main")
public boolean getMinecraftClass()
{
ClassNode main = getClassNodeFromMapping("net/minecraft/client/main/Main");
if (main == null) return false;
List<MethodNode> methods = DynamicMappings.getMatchingMethods(main, "main", "([Ljava/lang/String;)V");
if (methods.size() != 1) return false;
MethodNode mainMethod = methods.get(0);
String minecraftClassName = null;
String gameConfigClassName = null;
boolean confirmed = false;
// We're looking for these instructions:
// NEW net/minecraft/client/Minecraft
// INVOKESPECIAL net/minecraft/client/Minecraft.<init> (Lnet/minecraft/client/main/GameConfiguration;)V
// INVOKEVIRTUAL net/minecraft/client/Minecraft.run ()V
for (AbstractInsnNode insn = mainMethod.instructions.getLast(); insn != null; insn = insn.getPrevious())
{
if (insn.getOpcode() == Opcodes.INVOKEVIRTUAL) {
MethodInsnNode mn = (MethodInsnNode)insn;
minecraftClassName = mn.owner;
}
else if (insn.getOpcode() == Opcodes.INVOKESPECIAL) {
MethodInsnNode mn = (MethodInsnNode)insn;
// Check for something wrong
if (minecraftClassName == null || !mn.owner.equals(minecraftClassName)) return false;
Type t = Type.getMethodType(mn.desc);
Type[] args = t.getArgumentTypes();
if (args.length != 1) return false;
// Get this while we're here
gameConfigClassName = args[0].getClassName();
}
else if (insn.getOpcode() == Opcodes.NEW) {
TypeInsnNode vn = (TypeInsnNode)insn;
if (minecraftClassName != null && vn.desc.equals(minecraftClassName)) {
confirmed = true;
break;
}
}
}
if (confirmed) {
addClassMapping("net/minecraft/client/Minecraft", getClassNode(minecraftClassName));
addClassMapping("net/minecraft/client/main/GameConfiguration", getClassNode(gameConfigClassName));
return true;
}
return false;
}
@Mapping(provides={
"net/minecraft/world/WorldSettings",
"net/minecraft/server/integrated/IntegratedServer",
"net/minecraft/client/multiplayer/WorldClient"
},
providesFields={
"net/minecraft/client/Minecraft theWorld Lnet/minecraft/client/multiplayer/WorldClient;"
},
providesMethods={
"net/minecraft/client/Minecraft getMinecraft ()Lnet/minecraft/client/Minecraft;",
"net/minecraft/client/Minecraft getRenderItem ()Lnet/minecraft/client/renderer/entity/RenderItem;",
"net/minecraft/client/Minecraft refreshResources ()V",
"net/minecraft/client/Minecraft launchIntegratedServer (Ljava/lang/String;Ljava/lang/String;Lnet/minecraft/world/WorldSettings;)V",
"net/minecraft/client/Minecraft getIntegratedServer ()Lnet/minecraft/server/integrated/IntegratedServer;",
"net/minecraft/client/Minecraft getTextureMapBlocks ()Lnet/minecraft/client/renderer/texture/TextureMap;"
},
depends={
"net/minecraft/client/Minecraft",
"net/minecraft/client/renderer/entity/RenderItem",
"net/minecraft/world/World",
"net/minecraft/client/renderer/texture/TextureMap"
})
public boolean processMinecraftClass()
{
ClassNode minecraft = getClassNodeFromMapping("net/minecraft/client/Minecraft");
ClassNode renderItem = getClassNodeFromMapping("net/minecraft/client/renderer/entity/RenderItem");
ClassNode world = getClassNodeFromMapping("net/minecraft/world/World");
ClassNode textureMap = getClassNodeFromMapping("net/minecraft/client/renderer/texture/TextureMap");
if (!MeddleUtil.notNull(minecraft, renderItem, world, textureMap)) return false;
List<FieldNode> fields;
Set<String> fieldClasses = new HashSet<String>();
for (FieldNode field : minecraft.fields) {
if (!field.desc.startsWith("L")) continue;
Type t = Type.getType(field.desc);
fieldClasses.add(t.getClassName());
}
// public static Minecraft getMinecraft()
List<MethodNode> methods = DynamicMappings.getMatchingMethods(minecraft, null, "()L" + minecraft.name + ";");
if (methods.size() == 1) {
addMethodMapping("net/minecraft/client/Minecraft getMinecraft ()Lnet/minecraft/client/Minecraft;",
minecraft.name + " " + methods.get(0).name + " " + methods.get(0).desc);
}
// public RenderItem getRenderItem()
methods = DynamicMappings.getMatchingMethods(minecraft, null, "()L" + renderItem.name + ";");
if (methods.size() == 1) {
addMethodMapping("net/minecraft/client/Minecraft getRenderItem ()Lnet/minecraft/client/renderer/entity/RenderItem;",
minecraft.name + " " + methods.get(0).name + " " + methods.get(0).desc);
}
boolean found = false;
// public void refreshResources()
methods = DynamicMappings.getMatchingMethods(minecraft, null, "()V");
for (MethodNode method : methods) {
for (AbstractInsnNode insn = method.instructions.getFirst(); insn != null; insn = insn.getNext()) {
if (!DynamicMappings.isLdcWithString(insn, "Caught error stitching, removing all assigned resourcepacks")) continue;
addMethodMapping("net/minecraft/client/Minecraft refreshResources ()V", minecraft.name + " " + method.name + " ()V");
found = true;
}
if (found) break;
}
String integratedServer_name = null;
// public void launchIntegratedServer(String folderName, String worldName, WorldSettings worldSettingsIn)
// net/minecraft/world/WorldSettings
// net/minecraft/server/integrated/IntegratedServer
methods.clear();
for (MethodNode method : minecraft.methods) {
if (!DynamicMappings.checkMethodParameters(method, Type.OBJECT, Type.OBJECT, Type.OBJECT)) continue;
if (Type.getMethodType(method.desc).getReturnType().getSort() != Type.VOID) continue;
if (!method.desc.startsWith("(Ljava/lang/String;Ljava/lang/String;L")) continue;
methods.add(method);
}
if (methods.size() == 1) {
MethodNode method = methods.get(0);
Type t = Type.getMethodType(method.desc);
String worldSettings = t.getArgumentTypes()[2].getClassName();
addClassMapping("net/minecraft/world/WorldSettings", worldSettings);
addMethodMapping("net/minecraft/client/Minecraft launchIntegratedServer (Ljava/lang/String;Ljava/lang/String;Lnet/minecraft/world/WorldSettings;)V",
minecraft.name + " " + method.name + " " + method.desc);
for (AbstractInsnNode insn = method.instructions.getFirst(); insn != null; insn = insn.getNext()) {
if (insn.getOpcode() != Opcodes.NEW) continue;
TypeInsnNode tn = (TypeInsnNode)insn;
if (DynamicMappings.searchConstantPoolForStrings(tn.desc, "saves", "Generating keypair", "Saving and pausing game...")) {
integratedServer_name = tn.desc;
addClassMapping("net/minecraft/server/integrated/IntegratedServer", tn.desc);
break;
}
}
}
// public IntegratedServer getIntegratedServer()
if (integratedServer_name != null) {
methods = DynamicMappings.getMatchingMethods(minecraft, null, "()L" + integratedServer_name + ";");
if (methods.size() == 1) {
addMethodMapping("net/minecraft/client/Minecraft getIntegratedServer ()Lnet/minecraft/server/integrated/IntegratedServer;",
minecraft.name + " " + methods.get(0).name + " " + methods.get(0).desc);
}
}
ClassNode worldClient = null;
methods = DynamicMappings.getMatchingMethods(minecraft, null, "(I)V");
for (MethodNode method : methods) {
List<FieldInsnNode> fieldNodes = DynamicMappings.getAllInsnNodesOfType(method.instructions.getFirst(), FieldInsnNode.class);
String theWorld_name = null;
int count = 0;
for (FieldInsnNode f : fieldNodes) {
if (!f.desc.startsWith("L")) continue;
if (!f.owner.equals(minecraft.name)) continue;
String className = Type.getType(f.desc).getClassName();
if (worldClient == null) {
ClassNode cn = getClassNode(className);
if (cn == null) continue;
if (cn.superName.equals(world.name) && DynamicMappings.searchConstantPoolForStrings(className, "MpServer", "doDaylightCycle", "Quitting")) {
addClassMapping("net/minecraft/client/multiplayer/WorldClient", className);
worldClient = cn;
}
}
if (worldClient != null && worldClient.name.equals(className)) {
if (theWorld_name == null) { theWorld_name = f.name; count++; }
else if (!theWorld_name.equals(f.name)) count++;
}
}
if (count == 1) {
addFieldMapping("net/minecraft/client/Minecraft theWorld Lnet/minecraft/client/multiplayer/WorldClient;",
minecraft.name + " " + theWorld_name + " L" + worldClient.name + ";");
}
}
// public TextureMap getTextureMapBlocks()
methods = DynamicMappings.getMatchingMethods(minecraft, null, "()L" + textureMap.name + ";");
if (methods.size() == 1) {
addMethodMapping("net/minecraft/client/Minecraft getTextureMapBlocks ()Lnet/minecraft/client/renderer/texture/TextureMap;",
minecraft.name + " " + methods.get(0).name + " " + methods.get(0).desc);
}
return true;
}
@Mapping(providesMethods={
"net/minecraft/client/renderer/entity/RenderItem getItemModelMesher ()Lnet/minecraft/client/renderer/ItemModelMesher;"
},
depends={
"net/minecraft/client/renderer/entity/RenderItem",
"net/minecraft/client/renderer/ItemModelMesher"
})
public boolean parseRenderItemClass()
{
ClassNode renderItem = getClassNodeFromMapping("net/minecraft/client/renderer/entity/RenderItem");
ClassNode modelMesher = getClassNodeFromMapping("net/minecraft/client/renderer/ItemModelMesher");
if (renderItem == null || modelMesher == null) return false;
List<MethodNode> methods = DynamicMappings.getMatchingMethods(renderItem, null, "()L" + modelMesher.name + ";");
if (methods.size() == 1) {
addMethodMapping("net/minecraft/client/renderer/entity/RenderItem getItemModelMesher ()Lnet/minecraft/client/renderer/ItemModelMesher;",
renderItem.name + " " + methods.get(0).name + " " + methods.get(0).desc);
}
return true;
}
@Mapping(provides="net/minecraft/client/renderer/entity/RenderItem", depends="net/minecraft/client/Minecraft")
public boolean getRenderItemClass()
{
ClassNode minecraft = getClassNodeFromMapping("net/minecraft/client/Minecraft");
if (minecraft == null) return false;
for (MethodNode method : (List<MethodNode>)minecraft.methods) {
Type t = Type.getMethodType(method.desc);
if (t.getArgumentTypes().length != 0) continue;
if (t.getReturnType().getSort() != Type.OBJECT) continue;
String className = t.getReturnType().getClassName();
if (className.contains(".")) continue;
if (DynamicMappings.searchConstantPoolForStrings(className, "textures/misc/enchanted_item_glint.png", "Rendering item")) {
addClassMapping("net/minecraft/client/renderer/entity/RenderItem", getClassNode(className));
return true;
}
// TODO - Use this to process other getters from Minecraft class
}
return false;
}
@Mapping(provides="net/minecraft/client/renderer/ItemModelMesher", depends="net/minecraft/client/renderer/entity/RenderItem")
public boolean getItemModelMesherClass()
{
ClassNode renderItem = getClassNodeFromMapping("net/minecraft/client/renderer/entity/RenderItem");
if (renderItem == null) return false;
// Find constructor RenderItem(TextureManager, ModelManager)
MethodNode initMethod = null;
int count = 0;
for (MethodNode method : (List<MethodNode>)renderItem.methods) {
if (!method.name.equals("<init>")) continue;
if (!DynamicMappings.checkMethodParameters(method, Type.OBJECT, Type.OBJECT, Type.OBJECT)) continue;
count++;
initMethod = method;
}
if (count != 1) return false;
Type t = Type.getMethodType(initMethod.desc);
Type[] args = t.getArgumentTypes();
// TODO: Get TextureManager and ModelManager from args
String className = null;
count = 0;
for (AbstractInsnNode insn = initMethod.instructions.getFirst(); insn != null; insn = insn.getNext()) {
if (insn.getOpcode() == Opcodes.NEW) {
TypeInsnNode tn = (TypeInsnNode)insn;
className = tn.desc;
count++;
}
}
if (count != 1 || className == null) return false;
// We'll assume this is it, might do more detailed confirmations later if necessary
addClassMapping("net/minecraft/client/renderer/ItemModelMesher", getClassNode(className));
return true;
}
@Mapping(providesMethods={
"net/minecraft/client/Minecraft startGame ()V",
"net/minecraft/client/Minecraft getBlockRendererDispatcher ()Lnet/minecraft/client/renderer/BlockRendererDispatcher;"
},
provides={
"net/minecraft/client/gui/GuiMainMenu",
"net/minecraft/client/gui/GuiIngame",
"net/minecraft/client/multiplayer/GuiConnecting",
"net/minecraft/client/renderer/RenderGlobal",
"net/minecraft/client/renderer/BlockRendererDispatcher",
"net/minecraft/client/renderer/texture/TextureMap"
},
depends="net/minecraft/client/Minecraft")
public boolean processMinecraftClass2()
{
ClassNode minecraft = getClassNodeFromMapping("net/minecraft/client/Minecraft");
if (minecraft == null) return false;
List<String> postStartupClasses = new ArrayList<String>();
List<String> startupClasses = new ArrayList<String>();
List<MethodNode> methods = DynamicMappings.getMatchingMethods(minecraft, null, "()V");
boolean foundMethod = false;
for (MethodNode method : methods) {
boolean foundLWJGLVersion = false;
boolean foundPostStartup = false;
boolean foundStartup = false;
for (AbstractInsnNode insn = method.instructions.getFirst(); insn != null; insn = insn.getNext())
{
if (!foundLWJGLVersion && !DynamicMappings.isLdcWithString(insn, "LWJGL Version: {}")) continue;
foundLWJGLVersion = true;
if (!foundStartup && !DynamicMappings.isLdcWithString(insn, "Startup")) continue;
foundStartup = true;
foundMethod = true;
addMethodMapping("net/minecraft/client/Minecraft startGame ()V", minecraft.name + " " + method.name + " ()V");
if (foundStartup && !foundPostStartup) {
if (insn.getOpcode() == Opcodes.NEW) {
TypeInsnNode tn = (TypeInsnNode)insn;
startupClasses.add(tn.desc);
}
}
if (!foundPostStartup && !DynamicMappings.isLdcWithString(insn, "Post startup")) continue;
foundPostStartup = true;
if (insn.getOpcode() == Opcodes.NEW) {
TypeInsnNode tn = (TypeInsnNode)insn;
postStartupClasses.add(tn.desc);
}
}
if (foundMethod) break;
}
String guiIngame = null;
String guiConnecting = null;
String guiMainMenu = null;
String loadingScreenRenderer = null;
for (String className : postStartupClasses) {
if (guiIngame == null && DynamicMappings.searchConstantPoolForStrings(className, "textures/misc/vignette.png", "bossHealth")) {
guiIngame = className;
continue;
}
if (guiConnecting == null && DynamicMappings.searchConstantPoolForStrings(className, "Connecting to {}, {}", "connect.connecting")) {
guiConnecting = className;
continue;
}
if (guiMainMenu == null && DynamicMappings.searchConstantPoolForStrings(className, "texts/splashes.txt", "Merry X-mas!")) {
guiMainMenu = className;
continue;
}
// TODO - Figure out a way to scan for the class
//if (loadingScreenRenderer == null
}
String renderGlobal = null;
String blockRendererDispatcher = null;
String textureMap = null;
for (String className : startupClasses) {
if (textureMap == null && DynamicMappings.searchConstantPoolForStrings(className, "missingno", "textures/atlas/blocks.png")) {
textureMap = className;
continue;
}
if (renderGlobal == null && DynamicMappings.searchConstantPoolForStrings(className, "textures/environment/moon_phases.png", "Exception while adding particle")) {
renderGlobal = className;
continue;
}
if (blockRendererDispatcher == null && DynamicMappings.searchConstantPoolForStrings(className, "Tesselating block in world", "Block being tesselated")) {
blockRendererDispatcher = className;
continue;
}
}
if (textureMap != null) {
addClassMapping("net/minecraft/client/renderer/texture/TextureMap", textureMap);
}
if (blockRendererDispatcher != null) {
addClassMapping("net/minecraft/client/renderer/BlockRendererDispatcher", blockRendererDispatcher);
// public BlockRendererDispatcher getBlockRendererDispatcher()
methods = getMatchingMethods(minecraft, null, "()L" + blockRendererDispatcher + ";");
if (methods.size() == 1) {
addMethodMapping("net/minecraft/client/Minecraft getBlockRendererDispatcher ()Lnet/minecraft/client/renderer/BlockRendererDispatcher;",
minecraft.name + " " + methods.get(0).name + " " + methods.get(0).desc);
}
}
if (guiMainMenu != null)
addClassMapping("net/minecraft/client/gui/GuiMainMenu", guiMainMenu);
if (guiIngame != null)
addClassMapping("net/minecraft/client/gui/GuiIngame", guiIngame);
if (guiConnecting != null)
addClassMapping("net/minecraft/client/multiplayer/GuiConnecting", guiConnecting);
if (renderGlobal != null)
addClassMapping("net/minecraft/client/renderer/RenderGlobal",renderGlobal);
return true;
}
@Mapping(providesFields={
"net/minecraft/client/Minecraft itemColors Lnet/minecraft/client/renderer/color/ItemColors;"
},
provides={
},
depends={
"net/minecraft/client/Minecraft",
"net/minecraft/client/renderer/color/ItemColors"
})
public boolean processMinecraftClass3()
{
ClassNode minecraft = getClassNodeFromMapping("net/minecraft/client/Minecraft");
ClassNode itemColors = getClassNodeFromMapping("net/minecraft/client/renderer/color/ItemColors");
if (!MeddleUtil.notNull(minecraft, itemColors)) return false;
List<FieldNode> fields = getMatchingFields(minecraft, null, "L" + itemColors.name + ";");
if (fields.size() == 1) {
addFieldMapping("net/minecraft/client/Minecraft itemColors Lnet/minecraft/client/renderer/color/ItemColors;",
minecraft.name + " " + fields.get(0).name + " " + fields.get(0).desc);
}
return true;
}
@Mapping(provides="net/minecraft/client/resources/model/ModelResourceLocation",
depends={
"net/minecraft/item/Item",
"net/minecraft/client/renderer/ItemModelMesher"})
public boolean getModelResourceLocationClass()
{
ClassNode item = getClassNodeFromMapping("net/minecraft/item/Item");
ClassNode itemModelMesher = getClassNodeFromMapping("net/minecraft/client/renderer/ItemModelMesher");
if (!MeddleUtil.notNull(item, itemModelMesher)) return false;
for (MethodNode method : (List<MethodNode>)itemModelMesher.methods) {
if (!DynamicMappings.checkMethodParameters(method, Type.OBJECT, Type.INT, Type.OBJECT)) continue;
Type t = Type.getMethodType(method.desc);
if (!t.getArgumentTypes()[0].getClassName().equals(item.name)) continue;
addClassMapping("net/minecraft/client/resources/model/ModelResourceLocation",
getClassNode(t.getArgumentTypes()[2].getClassName()));
return true;
}
return false;
}
/*
* Moved elsewhere in 16w02a
* TODO - Find item color override registry
*
* @Mapping(providesMethods={
"net/minecraft/item/Item getColorFromItemStack (Lnet/minecraft/item/ItemStack;I)I",
},
depends={
"net/minecraft/item/Item",
"net/minecraft/item/ItemStack"
})
public boolean getItemClassMethods()
{
ClassNode item = getClassNodeFromMapping("net/minecraft/item/Item");
ClassNode itemStack = getClassNodeFromMapping("net/minecraft/item/ItemStack");
// public int getColorFromItemStack(ItemStack, int)
List<MethodNode> methods = DynamicMappings.getMethodsWithDescriptor(item.methods, "(L" + itemStack.name + ";I)I");
methods = DynamicMappings.removeMethodsWithFlags(methods, Opcodes.ACC_STATIC);
if (methods.size() == 1) {
MethodNode mn = methods.get(0);
DynamicMappings.addMethodMapping(
"net/minecraft/item/Item getColorFromItemStack (Lnet/minecraft/item/ItemStack;I)I",
item.name + " " + mn.name + " " + mn.desc);
}
return true;
}*/
@Mapping(providesMethods={
"net/minecraft/client/renderer/ItemModelMesher register (Lnet/minecraft/item/Item;ILnet/minecraft/client/resources/model/ModelResourceLocation;)V"
},
depends={
"net/minecraft/item/Item",
"net/minecraft/client/renderer/ItemModelMesher",
"net/minecraft/client/resources/model/ModelResourceLocation"
})
public boolean parseItemModelMesherClass()
{
ClassNode item = getClassNodeFromMapping("net/minecraft/item/Item");
ClassNode modelMesher = getClassNodeFromMapping("net/minecraft/client/renderer/ItemModelMesher");
ClassNode modelResLoc = getClassNodeFromMapping("net/minecraft/client/resources/model/ModelResourceLocation");
if (item == null || modelMesher == null || modelResLoc == null) return false;
List<MethodNode> methods = DynamicMappings.getMatchingMethods(modelMesher, null, "(L" + item.name + ";IL" + modelResLoc.name + ";)V");
if (methods.size() == 1) {
addMethodMapping("net/minecraft/client/renderer/ItemModelMesher register (Lnet/minecraft/item/Item;ILnet/minecraft/client/resources/model/ModelResourceLocation;)V",
modelMesher.name + " " + methods.get(0).name + " " + methods.get(0).desc);
}
return true;
}
@Mapping(provides={
"net/minecraft/client/gui/Gui",
"net/minecraft/client/gui/GuiScreen",
"net/minecraft/client/gui/GuiYesNoCallback"
},
depends={
"net/minecraft/client/gui/GuiMainMenu"
})
public boolean findGuiStuff()
{
ClassNode guiMainMenu = getClassNodeFromMapping("net/minecraft/client/gui/GuiMainMenu");
if (guiMainMenu == null || guiMainMenu.superName == null) return false;
ClassNode guiScreen = null;
String guiScreenName = null;
if (DynamicMappings.searchConstantPoolForStrings(guiMainMenu.superName, "Invalid Item!", "java.awt.Desktop")) {
guiScreenName = guiMainMenu.superName;
guiScreen = getClassNode(guiScreenName);
addClassMapping("net/minecraft/client/gui/GuiScreen", guiScreenName);
}
if (guiScreen == null || guiScreen.superName == null) return false;
if (guiScreen.interfaces.size() == 1) {
addClassMapping("net/minecraft/client/gui/GuiYesNoCallback", guiScreen.interfaces.get(0));
}
if (DynamicMappings.searchConstantPoolForStrings(guiScreen.superName, "textures/gui/options_background.png", "textures/gui/icons.png")) {
addClassMapping("net/minecraft/client/gui/Gui", guiScreen.superName);
}
return true;
}
private boolean verifyGuiButtonClass(String className)
{
String soundClick = getSoundFieldFull("ui.button.click");
if (searchConstantPoolForStrings(className, "textures/gui/widgets.png") && searchConstantPoolForFields(className, soundClick))
return true;
else return false;
}
@Mapping(provides={
"net/minecraft/client/gui/FontRenderer",
"net/minecraft/client/gui/GuiButton"
},
providesFields={
"net/minecraft/client/gui/GuiScreen mc Lnet/minecraft/client/Minecraft;",
"net/minecraft/client/gui/GuiScreen itemRender Lnet/minecraft/client/renderer/entity/RenderItem;",
"net/minecraft/client/gui/GuiScreen width I",
"net/minecraft/client/gui/GuiScreen height I",
"net/minecraft/client/gui/GuiScreen fontRendererObj Lnet/minecraft/client/gui/FontRenderer;",
"net/minecraft/client/gui/GuiScreen buttonList Ljava/util/List;"
},
providesMethods={
"net/minecraft/client/Minecraft displayGuiScreen (Lnet/minecraft/client/gui/GuiScreen;)V",
"net/minecraft/client/gui/GuiScreen setWorldAndResolution (Lnet/minecraft/client/Minecraft;II)V",
"net/minecraft/client/gui/GuiScreen initGui ()V",
"net/minecraft/client/gui/GuiScreen drawScreen (IIF)V",
"net/minecraft/client/gui/GuiScreen keyTyped (CI)V",
"net/minecraft/client/gui/GuiScreen mouseClicked (III)V",
"net/minecraft/client/gui/GuiScreen mouseReleased (III)V",
"net/minecraft/client/gui/GuiScreen onResize (Lnet/minecraft/client/Minecraft;II)V",
"net/minecraft/client/gui/GuiScreen actionPerformed (Lnet/minecraft/client/gui/GuiButton;)V",
"net/minecraft/client/gui/GuiScreen drawDefaultBackground ()V",
"net/minecraft/client/gui/GuiScreen drawWorldBackground (I)V"
},
dependsFields={
"net/minecraft/init/Sounds ui_button_click Lnet/minecraft/util/Sound;"
},
depends={
"net/minecraft/client/gui/GuiScreen",
"net/minecraft/client/Minecraft",
"net/minecraft/client/renderer/entity/RenderItem"
})
public boolean processGuiScreenClass()
{
ClassNode guiScreen = getClassNodeFromMapping("net/minecraft/client/gui/GuiScreen");
ClassNode minecraft = getClassNodeFromMapping("net/minecraft/client/Minecraft");
ClassNode renderItem = getClassNodeFromMapping("net/minecraft/client/renderer/entity/RenderItem");
if (guiScreen == null || minecraft == null || renderItem == null) return false;
List<MethodNode> methods = DynamicMappings.getMatchingMethods(minecraft, null, "(L" + guiScreen.name + ";)V");
if (methods.size() != 1) return false;
MethodNode displayGuiScreen = methods.get(0);
addMethodMapping("net/minecraft/client/Minecraft displayGuiScreen (Lnet/minecraft/client/gui/GuiScreen;)V",
minecraft.name + " " + displayGuiScreen.name + " " + displayGuiScreen.desc);
String setWorldAndResolutionName = null;
String setWorldAndResolutionDesc = "(L" + minecraft.name + ";II)V";
for (AbstractInsnNode insn = displayGuiScreen.instructions.getFirst(); insn != null; insn = insn.getNext()) {
if (!(insn instanceof MethodInsnNode)) continue;
MethodInsnNode mn = (MethodInsnNode)insn;
if (mn.owner.equals(guiScreen.name) && mn.desc.equals(setWorldAndResolutionDesc)) {
setWorldAndResolutionName = mn.name;
break;
}
}
if (setWorldAndResolutionName == null) return false;
addMethodMapping("net/minecraft/client/gui/GuiScreen setWorldAndResolution (Lnet/minecraft/client/Minecraft;II)V",
guiScreen.name + " " + setWorldAndResolutionName + " " + setWorldAndResolutionDesc);
methods = DynamicMappings.getMatchingMethods(guiScreen, setWorldAndResolutionName, setWorldAndResolutionDesc);
MethodNode setWorldAndResolution = methods.get(0);
if (setWorldAndResolution == null) return false;
AbstractInsnNode prevInsn = null;
List<FieldInsnNode> unknownFields = new ArrayList<FieldInsnNode>();
List<FieldInsnNode> unknownListFields = new ArrayList<FieldInsnNode>();
List<MethodInsnNode> unknownVoidMethods = new ArrayList<MethodInsnNode>();
for (AbstractInsnNode insn = setWorldAndResolution.instructions.getFirst(); insn != null; insn = insn.getNext())
{
if (insn.getOpcode() == Opcodes.PUTFIELD) {
FieldInsnNode fn = (FieldInsnNode)insn;
if (fn.desc.equals("L" + minecraft.name + ";")) {
addFieldMapping("net/minecraft/client/gui/GuiScreen mc Lnet/minecraft/client/Minecraft;",
guiScreen.name + " " + fn.name + " " + fn.desc);
}
else if (fn.desc.equals("L" + renderItem.name + ";")) {
addFieldMapping("net/minecraft/client/gui/GuiScreen itemRender Lnet/minecraft/client/renderer/entity/RenderItem;",
renderItem.name + " " + fn.name + " " + fn.desc);
}
else if (fn.desc.equals("I")) {
if (prevInsn.getOpcode() == Opcodes.ILOAD) {
VarInsnNode vn = (VarInsnNode)prevInsn;
if (vn.var == 2) {
addFieldMapping("net/minecraft/client/gui/GuiScreen width I",
guiScreen.name + " " + fn.name + " I");
}
else if (vn.var == 3) {
addFieldMapping("net/minecraft/client/gui/GuiScreen height I",
guiScreen.name + " " + fn.name + " I");
}
}
}
else if (fn.desc.startsWith("L")) {
unknownFields.add(fn);
}
}
else if (insn.getOpcode() == Opcodes.GETFIELD) {
FieldInsnNode fn = (FieldInsnNode)insn;
if (fn.desc.equals("Ljava/util/List;")) unknownListFields.add(fn);
}
else if (insn.getOpcode() == Opcodes.INVOKEVIRTUAL) {
MethodInsnNode mn = (MethodInsnNode)insn;
if (mn.desc.equals("()V")) unknownVoidMethods.add(mn);
}
prevInsn = insn;
}
// Should have only been one unknown field set in setWorldAndResolution,
// and that should be for the FontRenderer.
if (unknownFields.size() == 1) {
FieldInsnNode fn = unknownFields.get(0);
Type t = Type.getType(fn.desc);
String fontRendererName = t.getClassName();
if (DynamicMappings.searchConstantPoolForStrings(fontRendererName, "0123456789abcdef"))
{
addFieldMapping("net/minecraft/client/gui/GuiScreen fontRendererObj Lnet/minecraft/client/gui/FontRenderer;",
guiScreen.name + " " + fn.name + " " + fn.desc);
addClassMapping("net/minecraft/client/gui/FontRenderer", fontRendererName);
}
}
if (unknownListFields.size() == 1) {
FieldInsnNode fn = unknownListFields.get(0);
addFieldMapping("net/minecraft/client/gui/GuiScreen buttonList Ljava/util/List;",
guiScreen.name + " " + fn.name + " " + fn.desc);
}
if (unknownVoidMethods.size() == 1) {
MethodInsnNode mn = unknownVoidMethods.get(0);
addMethodMapping("net/minecraft/client/gui/GuiScreen initGui ()V", guiScreen.name + " " + mn.name + " ()V");
}
String drawScreenMethodName = null;
methods = DynamicMappings.getMatchingMethods(guiScreen, null, "(IIF)V");
if (methods.size() == 1) {
drawScreenMethodName = methods.get(0).name;
addMethodMapping("net/minecraft/client/gui/GuiScreen drawScreen (IIF)V",
guiScreen.name + " " + drawScreenMethodName + " (IIF)V");
}
if (drawScreenMethodName == null) return false;
// protected void keyTyped(char typedChar, int keyCode) throws IOException
methods = DynamicMappings.getMatchingMethods(guiScreen, null, "(CI)V");
if (methods.size() == 1) {
addMethodMapping("net/minecraft/client/gui/GuiScreen keyTyped (CI)V",
guiScreen.name + " " + methods.get(0).name + " " + methods.get(0).desc);
}
String guiButton = null;
// protected void mouseClicked(int mouseX, int mouseY, int mouseButton) throws IOException
// protected void mouseReleased(int mouseX, int mouseY, int state)
methods = DynamicMappings.getMatchingMethods(guiScreen, null, "(III)V");
if (methods.size() == 2) {
MethodNode mouseClicked = null;
MethodNode mouseReleased = null;
for (MethodNode method : methods) {
for (AbstractInsnNode insn = method.instructions.getFirst(); insn != null; insn = insn.getNext()) {
if (insn.getOpcode() == Opcodes.CHECKCAST) {
TypeInsnNode tn = (TypeInsnNode)insn;
if (verifyGuiButtonClass(tn.desc)) {
addClassMapping("net/minecraft/client/gui/GuiButton", tn.desc);
guiButton = tn.desc;
}
continue;
}
if (insn.getOpcode() != Opcodes.GETFIELD) continue;
FieldInsnNode fn = (FieldInsnNode)insn;
if (!fn.owner.equals(guiScreen.name)) continue;
if (fn.desc.equals("Ljava/util/List;")) mouseClicked = method;
else mouseReleased = method;
}
}
if (mouseClicked != null && mouseReleased != null && mouseClicked != mouseReleased) {
addMethodMapping("net/minecraft/client/gui/GuiScreen mouseClicked (III)V",
guiScreen.name + " " + mouseClicked.name + " " + mouseClicked.desc);
addMethodMapping("net/minecraft/client/gui/GuiScreen mouseReleased (III)V",
guiScreen.name + " " + mouseReleased.name + " " + mouseReleased.desc);
}
}
// public void onResize(Minecraft mcIn, int p_175273_2_, int p_175273_3_)
methods = getMatchingMethods(guiScreen, null, "(L" + minecraft.name + ";II)V");
if (methods.size() == 2) {
for (Iterator<MethodNode> it = methods.iterator(); it.hasNext();) {
if (it.next().name.equals(setWorldAndResolutionName)) it.remove();
}
if (methods.size() == 1) {
addMethodMapping("net/minecraft/client/gui/GuiScreen onResize (Lnet/minecraft/client/Minecraft;II)V",
guiScreen.name + " " + methods.get(0).name + " " + methods.get(0).desc);
}
}
// protected void actionPerformed(GuiButton button) throws IOException
methods = getMatchingMethods(guiScreen, null, "(L" + guiButton + ";)V");
if (methods.size() == 1) {
addMethodMapping("net/minecraft/client/gui/GuiScreen actionPerformed (Lnet/minecraft/client/gui/GuiButton;)V",
guiScreen.name + " " + methods.get(0).name + " " + methods.get(0).desc);
}
// public void drawDefaultBackground()
methods = getMatchingMethods(guiScreen, null, "()V");
for (Iterator<MethodNode> it = methods.iterator(); it.hasNext();) {
MethodNode method = it.next();
if (!matchOpcodeSequence(method.instructions.getFirst(), Opcodes.ALOAD, Opcodes.ICONST_0, Opcodes.INVOKEVIRTUAL, Opcodes.RETURN))
it.remove();
}
MethodNode drawWorldBackground = null;
if (methods.size() == 1) {
List<MethodInsnNode> nodes = getAllInsnNodesOfType(methods.get(0).instructions.getFirst(), MethodInsnNode.class);
MethodInsnNode mn = nodes.get(0);
// public void drawWorldBackground(int tint)
if (mn.owner.equals(guiScreen.name) && mn.desc.equals("(I)V")) {
MethodNode tempMethodNode = getMethodNode(guiScreen, mn.owner + " " + mn.name + " " + mn.desc);
if (tempMethodNode != null) {
boolean firstMatch = false;
boolean secondMatch = false;
for (AbstractInsnNode insn = tempMethodNode.instructions.getFirst(); insn != null; insn = insn.getNext()) {
if (!firstMatch && isLdcWithInteger(insn, 0xC0101010)) firstMatch = true;
if (!secondMatch && isLdcWithInteger(insn, 0xD0101010)) secondMatch = true;
}
if (firstMatch && secondMatch) {
addMethodMapping("net/minecraft/client/gui/GuiScreen drawDefaultBackground ()V",
guiScreen.name + " " + methods.get(0).name + " " + methods.get(0).desc);
addMethodMapping("net/minecraft/client/gui/GuiScreen drawWorldBackground (I)V",
guiScreen.name + " " + tempMethodNode.name + " " + tempMethodNode.desc);
drawWorldBackground = tempMethodNode;
}
}
}
}
return true;
}
@Mapping(provides={
"net/minecraft/client/gui/GuiOptions",
"net/minecraft/client/gui/GuiLanguage",
"net/minecraft/client/gui/GuiSelectWorld",
"net/minecraft/client/gui/GuiMultiplayer",
"net/minecraft/client/gui/GuiYesNo"
},
dependsMethods="net/minecraft/client/gui/GuiScreen actionPerformed (Lnet/minecraft/client/gui/GuiButton;)V",
depends={
"net/minecraft/client/gui/GuiScreen",
"net/minecraft/client/gui/GuiMainMenu"
})
public boolean discoverGuiClasses()
{
ClassNode guiScreen = getClassNodeFromMapping("net/minecraft/client/gui/GuiScreen");
ClassNode guiMainMenu = getClassNodeFromMapping("net/minecraft/client/gui/GuiMainMenu");
if (guiScreen == null || guiMainMenu == null) return false;
MethodNode actionPerformed = getMethodNodeFromMapping(guiMainMenu, "net/minecraft/client/gui/GuiScreen actionPerformed (Lnet/minecraft/client/gui/GuiButton;)V");
if (actionPerformed == null) return false;
ClassNode guiOptions = null;
ClassNode guiLanguage = null;
ClassNode guiSelectWorld = null;
ClassNode guiMultiplayer = null;
ClassNode guiYesNo = null;
List<TypeInsnNode> nodes = getAllInsnNodesOfType(actionPerformed.instructions.getFirst(), TypeInsnNode.class);
for (TypeInsnNode node : nodes) {
if (node.desc.startsWith("java")) continue;
ClassNode cn = getClassNode(node.desc);
if (cn == null) continue;
if (!cn.superName.equals(guiScreen.name)) continue;
if (guiOptions == null && searchConstantPoolForStrings(node.desc, "Options", "options.title", "options.video")) {
addClassMapping("net/minecraft/client/gui/GuiOptions", node.desc);
guiOptions = cn;
}
if (guiLanguage == null && searchConstantPoolForStrings(node.desc, "options.language", "options.languageWarning")) {
addClassMapping("net/minecraft/client/gui/GuiLanguage", node.desc);
guiLanguage = cn;
}
if (guiSelectWorld == null && searchConstantPoolForStrings(node.desc, "Select world", "selectWorld.title")) {
addClassMapping("net/minecraft/client/gui/GuiSelectWorld", node.desc);
guiSelectWorld = cn;
}
if (guiMultiplayer == null && searchConstantPoolForStrings(node.desc, "Unable to start LAN server detection: {}", "selectServer.edit")) {
addClassMapping("net/minecraft/client/gui/GuiMultiplayer", node.desc);
guiMultiplayer = cn;
}
if (guiYesNo == null && searchConstantPoolForStrings(node.desc, "gui.yes", "gui.no")) {
addClassMapping("net/minecraft/client/gui/GuiYesNo", node.desc);
guiYesNo = cn;
}
}
return true;
}
@Mapping(providesFields={
"net/minecraft/client/gui/GuiButton id I",
"net/minecraft/client/gui/GuiButton xPosition I",
"net/minecraft/client/gui/GuiButton yPosition I",
"net/minecraft/client/gui/GuiButton width I",
"net/minecraft/client/gui/GuiButton height I",
"net/minecraft/client/gui/GuiButton displayString Ljava/lang/String;"
},
depends={
"net/minecraft/client/gui/GuiButton"
})
public boolean processGuiButtonClass()
{
ClassNode guiButton = getClassNodeFromMapping("net/minecraft/client/gui/GuiButton");
if (guiButton == null) return false;
// public GuiButton(int buttonId, int x, int y, int widthIn, int heightIn, String buttonText)
List<MethodNode> methods = getMatchingMethods(guiButton, "<init>", "(IIIIILjava/lang/String;)V");
if (methods.size() == 1) {
Map<Integer, String> fieldMap = new HashMap<>();
for (AbstractInsnNode insn = getNextRealOpcode(methods.get(0).instructions.getFirst()); insn != null; insn = getNextRealOpcode(insn.getNext())) {
@SuppressWarnings("unchecked")
AbstractInsnNode[] nodes = getInsnNodeSequenceArray(insn, VarInsnNode.class, VarInsnNode.class, FieldInsnNode.class);
if (nodes == null) continue;
insn = nodes[2];
FieldInsnNode fn = (FieldInsnNode)nodes[2];
if (fn.owner.equals(guiButton.name)) fieldMap.put(((VarInsnNode)nodes[1]).var, fn.name);
}
if (fieldMap.size() == 6) {
for (int n = 1; n <= 6; n++) {
switch (n) {
case 1 : addFieldMapping("net/minecraft/client/gui/GuiButton id I", guiButton.name + " " + fieldMap.get(n) + " I");
break;
case 2 : addFieldMapping("net/minecraft/client/gui/GuiButton xPosition I", guiButton.name + " " + fieldMap.get(n) + " I");
break;
case 3 : addFieldMapping("net/minecraft/client/gui/GuiButton yPosition I", guiButton.name + " " + fieldMap.get(n) + " I");
break;
case 4 : addFieldMapping("net/minecraft/client/gui/GuiButton width I", guiButton.name + " " + fieldMap.get(n) + " I");
break;
case 5 : addFieldMapping("net/minecraft/client/gui/GuiButton height I", guiButton.name + " " + fieldMap.get(n) + " I");
break;
case 6 : addFieldMapping("net/minecraft/client/gui/GuiButton displayString Ljava/lang/String;", guiButton.name + " " + fieldMap.get(n) + " Ljava/lang/String;");
break;
}
}
}
}
return true;
}
@Mapping(provides={
},
providesFields={
},
providesMethods={
"net/minecraft/client/gui/FontRenderer getStringWidth (Ljava/lang/String;)I",
"net/minecraft/client/gui/Gui drawCenteredString (Lnet/minecraft/client/gui/FontRenderer;Ljava/lang/String;III)V",
"net/minecraft/client/gui/Gui drawString (Lnet/minecraft/client/gui/FontRenderer;Ljava/lang/String;III)V"
},
depends={
"net/minecraft/client/gui/GuiMainMenu",
"net/minecraft/client/gui/GuiScreen",
"net/minecraft/client/gui/Gui",
"net/minecraft/client/Minecraft",
"net/minecraft/client/gui/FontRenderer"
})
public boolean processGuiMainMenuClass()
{
ClassNode guiMainMenu = getClassNodeFromMapping("net/minecraft/client/gui/GuiMainMenu");
ClassNode guiScreen = getClassNodeFromMapping("net/minecraft/client/gui/GuiScreen");
ClassNode gui = getClassNodeFromMapping("net/minecraft/client/gui/Gui");
ClassNode minecraft = getClassNodeFromMapping("net/minecraft/client/Minecraft");
ClassNode fontRenderer = getClassNodeFromMapping("net/minecraft/client/gui/FontRenderer");
if (!MeddleUtil.notNull(guiMainMenu, guiScreen, gui, minecraft, fontRenderer)) return false;
String drawScreenDesc = "net/minecraft/client/gui/GuiScreen drawScreen (IIF)V";
MethodNode drawScreenMethod = DynamicMappings.getMethodNodeFromMapping(guiMainMenu, drawScreenDesc);
if (drawScreenMethod == null) return false;
String drawStringMethodsDesc = "(L" + fontRenderer.name + ";Ljava/lang/String;III)V";
String getStringWidthName = null;
String drawCenteredStringName = null;
String drawStringName = null;
for (AbstractInsnNode insn = drawScreenMethod.instructions.getFirst(); insn != null; insn = insn.getNext()) {
if (insn.getOpcode() != Opcodes.INVOKEVIRTUAL) continue;
MethodInsnNode mn = (MethodInsnNode)insn;
if (getStringWidthName == null && mn.owner.equals(fontRenderer.name) && mn.desc.equals("(Ljava/lang/String;)I")) {
getStringWidthName = mn.name;
addMethodMapping("net/minecraft/client/gui/FontRenderer getStringWidth (Ljava/lang/String;)I",
fontRenderer.name + " " + mn.name + " " + mn.desc);
}
if (mn.owner.equals(guiMainMenu.name) && mn.desc.equals(drawStringMethodsDesc)) {
if (drawCenteredStringName == null) {
drawCenteredStringName = mn.name;
addMethodMapping("net/minecraft/client/gui/Gui drawCenteredString (Lnet/minecraft/client/gui/FontRenderer;Ljava/lang/String;III)V",
gui.name + " " + mn.name + " " + mn.desc);
}
else if (drawStringName == null) {
drawStringName = mn.name;
addMethodMapping("net/minecraft/client/gui/Gui drawString (Lnet/minecraft/client/gui/FontRenderer;Ljava/lang/String;III)V",
gui.name + " " + mn.name + " " + mn.desc);
}
}
}
return true;
}
@Mapping(
providesMethods={
"net/minecraft/block/state/BlockState getProperty (Ljava/lang/String;)Lnet/minecraft/block/properties/IProperty;"
},
depends={
"net/minecraft/block/state/BlockState",
"net/minecraft/block/properties/IProperty"
})
public boolean processBlockStateClass()
{
ClassNode blockState = getClassNodeFromMapping("net/minecraft/block/state/BlockState");
ClassNode iProperty = getClassNodeFromMapping("net/minecraft/block/properties/IProperty");
ClassNode block = getClassNodeFromMapping("net/minecraft/block/Block");
if (!MeddleUtil.notNull(blockState, iProperty, block)) return false;
List<MethodNode> methods = new ArrayList<MethodNode>();
// public IProperty getProperty(String param0)
// Note: Not an MCP name
methods = DynamicMappings.getMatchingMethods(blockState, null, "(Ljava/lang/String;)L" + iProperty.name + ";");
if (methods.size() == 1) {
addMethodMapping("net/minecraft/block/state/BlockState getProperty (Ljava/lang/String;)Lnet/minecraft/block/properties/IProperty;",
blockState.name + " " + methods.get(0).name + " " + methods.get(0).desc);
}
return true;
}
@Mapping(provides={
"net/minecraft/client/entity/EntityPlayerSP",
"net/minecraft/client/entity/AbstractClientPlayer"
},
dependsFields={
"net/minecraft/init/Sounds block_portal_trigger Lnet/minecraft/util/Sound;"
},
depends={
"net/minecraft/client/Minecraft",
"net/minecraft/entity/player/EntityPlayer"
})
public boolean getEntityPlayerSPClass()
{
ClassNode minecraft = getClassNodeFromMapping("net/minecraft/client/Minecraft");
ClassNode entityPlayer = getClassNodeFromMapping("net/minecraft/entity/player/EntityPlayer");
if (minecraft == null || entityPlayer == null) return false;
String entityPlayerSP_name = null;
String portalSound = getSoundFieldFull("block.portal.trigger");
List<MethodNode> methods = DynamicMappings.getMatchingMethods(minecraft, null, "(I)V");
startloop:
for (MethodNode method : methods) {
for (AbstractInsnNode insn = method.instructions.getFirst(); insn != null; insn = insn.getNext()) {
if (insn.getOpcode() != Opcodes.PUTFIELD) continue;
FieldInsnNode fn = (FieldInsnNode)insn;
if (!fn.owner.equals(minecraft.name) || fn.desc.contains("/")) continue;
String className = fn.desc.substring(1, fn.desc.length() - 1);
if (DynamicMappings.searchConstantPoolForStrings(className, "minecraft:chest", "minecraft:anvil") &&
searchConstantPoolForFields(className, portalSound)) {
entityPlayerSP_name = className;
break startloop;
}
}
}
if (entityPlayerSP_name == null) return false;
ClassNode entityPlayerSP = getClassNode(entityPlayerSP_name);
if (entityPlayerSP == null) return false;
// Confirm parents
if (DynamicMappings.searchConstantPoolForStrings(entityPlayerSP.superName, "http://skins.minecraft.net/MinecraftSkins/%s.png")) {
ClassNode abstractClientPlayer = getClassNode(entityPlayerSP.superName);
if (abstractClientPlayer == null) return false;
if (!abstractClientPlayer.superName.equals(entityPlayer.name)) return false;
}
addClassMapping("net/minecraft/client/entity/EntityPlayerSP", entityPlayerSP);
addClassMapping("net/minecraft/client/entity/AbstractClientPlayer", entityPlayerSP.superName);
return true;
}
@Mapping(provides={
},
depends={
"net/minecraft/entity/player/EntityPlayer",
"net/minecraft/client/entity/EntityPlayerSP",
"net/minecraft/world/IInteractionObject"
})
public boolean processEntityPlayerSPClass()
{
ClassNode entityPlayer = getClassNodeFromMapping("net/minecraft/entity/player/EntityPlayer");
ClassNode entityPlayerSP = getClassNodeFromMapping("net/minecraft/client/entity/EntityPlayerSP");
ClassNode iInteractionObject = getClassNodeFromMapping("net/minecraft/world/IInteractionObject");
if (!MeddleUtil.notNull(entityPlayer, entityPlayerSP, iInteractionObject)) return false;
// TODO
return true;
}
@Mapping(provides={
"net/minecraft/client/gui/inventory/GuiChest",
"net/minecraft/client/gui/inventory/GuiContainer"
},
dependsMethods={
"net/minecraft/entity/player/EntityPlayer displayGUIChest (Lnet/minecraft/inventory/IInventory;)V"
},
depends={
"net/minecraft/client/gui/GuiScreen",
"net/minecraft/client/entity/EntityPlayerSP"
})
public boolean getGuiChestClass()
{
ClassNode guiScreen = getClassNodeFromMapping("net/minecraft/client/gui/GuiScreen");
ClassNode entityPlayerSP = getClassNodeFromMapping("net/minecraft/client/entity/EntityPlayerSP");
if (!MeddleUtil.notNull(guiScreen, entityPlayerSP)) return false;
MethodNode displayGuiChest = DynamicMappings.getMethodNodeFromMapping(entityPlayerSP, "net/minecraft/entity/player/EntityPlayer displayGUIChest (Lnet/minecraft/inventory/IInventory;)V");
if (displayGuiChest == null) return false;
Map<String, String> guiMap = new HashMap<>();
String lastString = null;
for (AbstractInsnNode insn = displayGuiChest.instructions.getFirst(); insn != null; insn = insn.getNext()) {
String s = DynamicMappings.getLdcString(insn);
if (s != null) { lastString = s; continue; }
if (insn.getOpcode() != Opcodes.NEW) continue;
TypeInsnNode tn = (TypeInsnNode)insn;
if (lastString != null) guiMap.put(lastString, tn.desc);
}
String className = guiMap.get("minecraft:chest");
if (className != null) {
if (!DynamicMappings.searchConstantPoolForStrings(className, "textures/gui/container/generic_54.png")) return false;
ClassNode guiChest = getClassNode(className);
if (guiChest == null) return false;
ClassNode guiContainer = getClassNode(guiChest.superName);
if (!DynamicMappings.searchConstantPoolForStrings(guiContainer.name, "textures/gui/container/inventory.png")) return false;
if (!guiContainer.superName.equals(guiScreen.name)) return false;
addClassMapping("net/minecraft/client/gui/inventory/GuiChest", guiChest);
addClassMapping("net/minecraft/client/gui/inventory/GuiContainer", guiContainer);
}
return true;
}
@Mapping(provides={
"net/minecraft/client/settings/GameSettings"
},
providesFields={
"net/minecraft/client/Minecraft thePlayer Lnet/minecraft/client/entity/EntityPlayerSP;",
"net/minecraft/client/gui/inventory/GuiContainer guiLeft I",
"net/minecraft/client/gui/inventory/GuiContainer guiTop I"
},
providesMethods={
"net/minecraft/client/gui/inventory/GuiContainer handleMouseClick (Lnet/minecraft/inventory/Slot;III)V",
"net/minecraft/client/gui/inventory/GuiContainer checkHotbarKeys (I)Z",
"net/minecraft/client/gui/inventory/GuiContainer drawItemStack (Lnet/minecraft/item/ItemStack;IILjava/lang/String;)V",
"net/minecraft/client/gui/inventory/GuiContainer drawGuiContainerForegroundLayer (II)V",
"net/minecraft/client/gui/inventory/GuiContainer drawGuiContainerBackgroundLayer (FII)V",
"net/minecraft/client/gui/inventory/GuiContainer drawSlot (Lnet/minecraft/inventory/Slot;)V",
"net/minecraft/client/gui/inventory/GuiContainer getSlotAtPosition (II)Lnet/minecraft/inventory/Slot;",
"net/minecraft/client/gui/GuiScreen mouseClickMove (IIIJ)V",
"net/minecraft/client/gui/inventory/GuiContainer isMouseOverSlot (Lnet/minecraft/inventory/Slot;II)Z",
"net/minecraft/client/gui/inventory/GuiContainer isPointInRegion (IIIIII)Z",
"net/minecraft/client/gui/GuiScreen doesGuiPauseGame ()Z",
"net/minecraft/client/gui/GuiScreen onGuiClosed ()V",
"net/minecraft/client/gui/GuiScreen updateScreen ()V",
"net/minecraft/client/gui/inventory/GuiContainer updateDragSplitting ()V"
},
dependsMethods={
"net/minecraft/inventory/Container onContainerClosed (Lnet/minecraft/entity/player/EntityPlayer;)V",
"net/minecraft/client/gui/GuiScreen initGui ()V"
},
depends={
"net/minecraft/client/gui/inventory/GuiContainer",
"net/minecraft/inventory/Slot",
"net/minecraft/client/Minecraft",
"net/minecraft/client/entity/EntityPlayerSP",
"net/minecraft/item/ItemStack",
"net/minecraft/client/gui/GuiScreen",
"net/minecraft/inventory/EnumContainerAction"
})
public boolean processGuiContainerClass()
{
ClassNode guiContainer = getClassNodeFromMapping("net/minecraft/client/gui/inventory/GuiContainer");
ClassNode slot = getClassNodeFromMapping("net/minecraft/inventory/Slot");
ClassNode minecraft = getClassNodeFromMapping("net/minecraft/client/Minecraft");
ClassNode playerSP = getClassNodeFromMapping("net/minecraft/client/entity/EntityPlayerSP");
ClassNode itemStack = getClassNodeFromMapping("net/minecraft/item/ItemStack");
ClassNode guiScreen = getClassNodeFromMapping("net/minecraft/client/gui/GuiScreen");
ClassNode containerAction = getClassNodeFromMapping("net/minecraft/inventory/EnumContainerAction");
if (!MeddleUtil.notNull(guiContainer, slot, minecraft, playerSP, itemStack, guiScreen, containerAction)) return false;
// protected void handleMouseClick(Slot slotIn, int slotId, int clickedButton, int clickType)
// As of 15w44a: protected void handleMouseClick(Slot slotIn, int slotId, int clickedButton, EnumContainerAction clickType)
List<MethodNode> methods = DynamicMappings.getMatchingMethods(guiContainer, null, "(L" + slot.name + ";IIL" + containerAction.name + ";)V");
if (methods.size() == 1) {
addMethodMapping("net/minecraft/client/gui/inventory/GuiContainer handleMouseClick (Lnet/minecraft/inventory/Slot;III)V",
guiContainer.name + " " + methods.get(0).name + " " + methods.get(0).desc);
}
// protected boolean checkHotbarKeys(int keyCode)
methods = DynamicMappings.getMatchingMethods(guiContainer, null, "(I)Z");
if (methods.size() == 1) {
addMethodMapping("net/minecraft/client/gui/inventory/GuiContainer checkHotbarKeys (I)Z",
guiContainer.name + " " + methods.get(0).name + " " + methods.get(0).desc);
// Find Minecraft.thePlayer and Minecraft.gameSettings
for (AbstractInsnNode insn = methods.get(0).instructions.getFirst(); insn != null; insn = insn.getNext()) {
if (insn.getOpcode() != Opcodes.GETFIELD) continue;
FieldInsnNode fn = (FieldInsnNode)insn;
if (!fn.owner.equals(minecraft.name)) continue;
Type t = Type.getType(fn.desc);
if (t.getSort() != Type.OBJECT) continue;
if (t.getClassName().equals(playerSP.name)) {
addFieldMapping("net/minecraft/client/Minecraft thePlayer Lnet/minecraft/client/entity/EntityPlayerSP;",
minecraft.name + " " + fn.name + " " + fn.desc);
}
else if (DynamicMappings.searchConstantPoolForStrings(t.getClassName(), "options.particles.all", "key.forward", "enableVsync:")) {
addClassMapping("net/minecraft/client/settings/GameSettings", t.getClassName());
addFieldMapping("net/minecraft/client/Minecraft gameSettings Lnet/minecraft/client/entity/EntityPlayerSP;",
minecraft.name + " " + fn.name + " " + fn.desc);
}
}
}
// private void drawItemStack(ItemStack stack, int x, int y, String altText)
methods = DynamicMappings.getMatchingMethods(guiContainer, null, "(L" + itemStack.name + ";IILjava/lang/String;)V");
if (methods.size() == 1) {
addMethodMapping("net/minecraft/client/gui/inventory/GuiContainer drawItemStack (Lnet/minecraft/item/ItemStack;IILjava/lang/String;)V",
guiContainer.name + " " + methods.get(0).name + " " + methods.get(0).desc);
}
// protected void drawGuiContainerForegroundLayer(int mouseX, int mouseY) {}
methods = DynamicMappings.getMatchingMethods(guiContainer, null, "(II)V");
if (methods.size() == 1) {
addMethodMapping("net/minecraft/client/gui/inventory/GuiContainer drawGuiContainerForegroundLayer (II)V",
guiContainer.name + " " + methods.get(0).name + " " + methods.get(0).desc);
}
// protected abstract void drawGuiContainerBackgroundLayer(float partialTicks, int mouseX, int mouseY);
methods = DynamicMappings.getMatchingMethods(guiContainer, null, "(FII)V");
if (methods.size() == 1) {
addMethodMapping("net/minecraft/client/gui/inventory/GuiContainer drawGuiContainerBackgroundLayer (FII)V",
guiContainer.name + " " + methods.get(0).name + " " + methods.get(0).desc);
}
// private void drawSlot(Slot slotIn)
methods = DynamicMappings.getMatchingMethods(guiContainer, null, "(L" + slot.name + ";)V");
if (methods.size() == 1) {
addMethodMapping("net/minecraft/client/gui/inventory/GuiContainer drawSlot (Lnet/minecraft/inventory/Slot;)V",
guiContainer.name + " " + methods.get(0).name + " " + methods.get(0).desc);
}
// private Slot getSlotAtPosition(int x, int y)
methods = DynamicMappings.getMatchingMethods(guiContainer, null, "(II)L" + slot.name + ";");
if (methods.size() == 1) {
addMethodMapping("net/minecraft/client/gui/inventory/GuiContainer getSlotAtPosition (II)Lnet/minecraft/inventory/Slot;",
guiContainer.name + " " + methods.get(0).name + " " + methods.get(0).desc);
}
// protected void mouseClickMove(int mouseX, int mouseY, int clickedMouseButton, long timeSinceLastClick)
methods = DynamicMappings.getMatchingMethods(guiContainer, null, "(IIIJ)V");
if (methods.size() == 1) {
addMethodMapping("net/minecraft/client/gui/GuiScreen mouseClickMove (IIIJ)V",
guiScreen.name + " " + methods.get(0).name + " " + methods.get(0).desc);
}
// private boolean isMouseOverSlot(Slot slotIn, int mouseX, int mouseY)
methods = DynamicMappings.getMatchingMethods(guiContainer, null, "(L" + slot.name + ";II)Z");
if (methods.size() == 1) {
addMethodMapping("net/minecraft/client/gui/inventory/GuiContainer isMouseOverSlot (Lnet/minecraft/inventory/Slot;II)Z",
guiContainer.name + " " + methods.get(0).name + " " + methods.get(0).desc);
}
// protected boolean isPointInRegion(int left, int top, int right, int bottom, int pointX, int pointY)
methods = DynamicMappings.getMatchingMethods(guiContainer, null, "(IIIIII)Z");
if (methods.size() == 1) {
addMethodMapping("net/minecraft/client/gui/inventory/GuiContainer isPointInRegion (IIIIII)Z",
guiContainer.name + " " + methods.get(0).name + " " + methods.get(0).desc);
List<String> fields = new ArrayList<>();
for (AbstractInsnNode insn = methods.get(0).instructions.getFirst(); insn != null; insn = insn.getNext()) {
if (insn.getOpcode() != Opcodes.GETFIELD) continue;
FieldInsnNode fn = (FieldInsnNode)insn;
if (fn.owner.equals(guiContainer.name) && fn.desc.equals("I")) fields.add(fn.name);
}
if (fields.size() == 2) {
addFieldMapping("net/minecraft/client/gui/inventory/GuiContainer guiLeft I", guiContainer.name + " " + fields.get(0) + " I");
addFieldMapping("net/minecraft/client/gui/inventory/GuiContainer guiTop I", guiContainer.name + " " + fields.get(1) + " I");
}
}
// public boolean doesGuiPauseGame()
methods = DynamicMappings.getMatchingMethods(guiContainer, null, "()Z");
if (methods.size() == 1) {
addMethodMapping("net/minecraft/client/gui/GuiScreen doesGuiPauseGame ()Z",
guiScreen.name + " " + methods.get(0).name + " " + methods.get(0).desc);
}
String onContainerClosed = DynamicMappings.getMethodMapping("net/minecraft/inventory/Container onContainerClosed (Lnet/minecraft/entity/player/EntityPlayer;)V");
String initGui = DynamicMappings.getMethodMapping("net/minecraft/client/gui/GuiScreen initGui ()V");
// public void onGuiClosed()
// public void updateScreen()
methods = DynamicMappings.getMatchingMethods(guiContainer, null, "()V");
if (methods.size() == 5 && onContainerClosed != null && initGui != null)
{
MethodNode onGuiClosed = null;
MethodNode updateScreen = null;
MethodNode updateDragSplitting = null;
for (Iterator<MethodNode> it = methods.iterator(); it.hasNext();) {
MethodNode method = it.next();
if (method.name.contains("<")) { it.remove(); continue; }
if (initGui.endsWith(" " + method.name + " " + method.desc)) { it.remove(); continue; }
for (AbstractInsnNode insn = method.instructions.getFirst(); insn != null; insn = insn.getNext())
{
if (insn.getOpcode() != Opcodes.INVOKEVIRTUAL) continue;
MethodInsnNode mn = (MethodInsnNode)insn;
if (onContainerClosed.equals(mn.owner + " " + mn.name + " " + mn.desc)) {
onGuiClosed = method;
it.remove();
break;
}
}
}
if (methods.size() == 2) {
for (MethodNode method : methods) {
if ((method.access & Opcodes.ACC_PRIVATE) > 0) updateDragSplitting = method;
else updateScreen = method;
}
}
if (MeddleUtil.notNull(onGuiClosed, updateScreen, updateDragSplitting)) {
addMethodMapping("net/minecraft/client/gui/GuiScreen onGuiClosed ()V",
guiScreen.name + " " + onGuiClosed.name + " " + onGuiClosed.desc);
addMethodMapping("net/minecraft/client/gui/GuiScreen updateScreen ()V",
guiScreen.name + " " + updateScreen.name + " " + updateScreen.desc);
addMethodMapping("net/minecraft/client/gui/inventory/GuiContainer updateDragSplitting ()V",
guiContainer.name + " " + updateDragSplitting.name + " " + updateDragSplitting.desc);
}
}
return true;
}
@Mapping(provides="net/minecraft/client/network/NetHandlerPlayClient",
depends="net/minecraft/client/entity/EntityPlayerSP")
public boolean getNetHandlerPlayClientClass()
{
ClassNode playerSP = getClassNodeFromMapping("net/minecraft/client/entity/EntityPlayerSP");
if (playerSP == null) return false;
for (FieldNode field : playerSP.fields) {
Type t = Type.getType(field.desc);
if (t.getSort() != Type.OBJECT) continue;
if (DynamicMappings.searchConstantPoolForStrings(t.getClassName(), "MC|Brand", "disconnect.lost", "minecraft:container"))
{
addClassMapping("net/minecraft/client/network/NetHandlerPlayClient", t.getClassName());
return true;
}
}
return false;
}
@Mapping(provides={
},
providesMethods={
"net/minecraft/client/network/NetHandlerPlayClient handleOpenWindow (Lnet/minecraft/network/play/server/S2DPacketOpenWindow;)V"
},
depends={
"net/minecraft/client/network/NetHandlerPlayClient",
"net/minecraft/network/play/server/S2DPacketOpenWindow"
})
public boolean processNetHandlerPlayClientClass()
{
ClassNode clientHandler = getClassNodeFromMapping("net/minecraft/client/network/NetHandlerPlayClient");
ClassNode openWindow = getClassNodeFromMapping("net/minecraft/network/play/server/S2DPacketOpenWindow");
if (!MeddleUtil.notNull(clientHandler, openWindow)) return false;
// public void handleOpenWindow(S2DPacketOpenWindow packetIn)
List<MethodNode> methods = DynamicMappings.getMatchingMethods(clientHandler, null, "(L" + openWindow.name + ";)V");
if (methods.size() == 1) {
addMethodMapping("net/minecraft/client/network/NetHandlerPlayClient handleOpenWindow (Lnet/minecraft/network/play/server/S2DPacketOpenWindow;)V",
clientHandler.name + " " + methods.get(0).name + " " + methods.get(0).desc);
}
return true;
}
@Mapping(providesFields={
"net/minecraft/network/play/server/S2DPacketOpenWindow windowId I",
"net/minecraft/network/play/server/S2DPacketOpenWindow inventoryType Ljava/lang/String",
"net/minecraft/network/play/server/S2DPacketOpenWindow windowTitle Lnet/minecraft/util/IChatComponent;",
"net/minecraft/network/play/server/S2DPacketOpenWindow slotCount I"
},
providesMethods={
"net/minecraft/network/play/server/S2DPacketOpenWindow getGuiId ()Ljava/lang/String;",
"net/minecraft/network/play/server/S2DPacketOpenWindow getWindowTitle ()Lnet/minecraft/util/IChatComponent;",
"net/minecraft/network/play/server/S2DPacketOpenWindow getWindowId ()I",
"net/minecraft/network/play/server/S2DPacketOpenWindow getSlotCount ()I",
"net/minecraft/network/play/server/S2DPacketOpenWindow hasSlots ()Z"
},
depends={
"net/minecraft/network/play/server/S2DPacketOpenWindow",
"net/minecraft/util/IChatComponent"
})
public boolean processS2DPacketOpenWindowClass()
{
ClassNode packet = getClassNodeFromMapping("net/minecraft/network/play/server/S2DPacketOpenWindow");
ClassNode iChatComponent = getClassNodeFromMapping("net/minecraft/util/IChatComponent");
if (packet == null || iChatComponent == null) return false;
String windowId = null;
String inventoryType = null;
String windowTitle = null;
String slotCount = null;
List<MethodNode> methods = DynamicMappings.getMatchingMethods(packet, "<init>", "(ILjava/lang/String;L" + iChatComponent.name + ";I)V");
if (methods.size() == 1) {
for (AbstractInsnNode insn = methods.get(0).instructions.getFirst(); insn != null; insn = insn.getNext()) {
if (insn.getOpcode() != Opcodes.PUTFIELD) continue;
FieldInsnNode fn = (FieldInsnNode)insn;
if (!fn.owner.equals(packet.name)) continue;
if (windowId == null && fn.desc.equals("I")) { windowId = fn.name; continue; }
if (windowId != null && inventoryType == null && fn.desc.equals("Ljava/lang/String;")) { inventoryType = fn.name; continue; }
if (windowId != null && inventoryType != null && windowTitle == null && fn.desc.equals("L" + iChatComponent.name + ";")) { windowTitle = fn.name; continue; }
if (windowId != null && inventoryType != null && windowTitle != null && slotCount == null && fn.desc.equals("I")) { slotCount = fn.name; continue; }
}
}
if (MeddleUtil.notNull(windowId, inventoryType, windowTitle, slotCount)) {
addFieldMapping("net/minecraft/network/play/server/S2DPacketOpenWindow windowId I", packet.name + " " + windowId + " I");
addFieldMapping("net/minecraft/network/play/server/S2DPacketOpenWindow inventoryType Ljava/lang/String", packet.name + " " + inventoryType + " Ljava/lang/String;");
addFieldMapping("net/minecraft/network/play/server/S2DPacketOpenWindow windowTitle Lnet/minecraft/util/IChatComponent;", packet.name + " " + windowTitle + " L" + iChatComponent.name + ";");
addFieldMapping("net/minecraft/network/play/server/S2DPacketOpenWindow slotCount I", packet.name + " " + slotCount + " I");
}
// public String getGuiId()
methods = DynamicMappings.getMatchingMethods(packet, null, "()Ljava/lang/String;");
if (methods.size() == 1) {
addMethodMapping("net/minecraft/network/play/server/S2DPacketOpenWindow getGuiId ()Ljava/lang/String;",
packet.name + " " + methods.get(0).name + " " + methods.get(0).desc);
}
// public IChatComponent getWindowTitle()
methods = DynamicMappings.getMatchingMethods(packet, null, "()L" + iChatComponent.name + ";");
if (methods.size() == 1) {
addMethodMapping("net/minecraft/network/play/server/S2DPacketOpenWindow getWindowTitle ()Lnet/minecraft/util/IChatComponent;",
packet.name + " " + methods.get(0).name + " " + methods.get(0).desc);
}
// public int getWindowId() - windowId
// public int getSlotCount() - slotCount
// public int getEntityId() - TODO
methods = DynamicMappings.getMatchingMethods(packet, null, "()I");
for (MethodNode method : methods) {
for (AbstractInsnNode insn = method.instructions.getFirst(); insn != null; insn = insn.getNext()) {
if (insn.getOpcode() != Opcodes.GETFIELD) continue;
FieldInsnNode fn = (FieldInsnNode)insn;
if (!fn.owner.equals(packet.name)) continue;
if (fn.name.equals(windowId)) {
addMethodMapping("net/minecraft/network/play/server/S2DPacketOpenWindow getWindowId ()I",
packet.name + " " + method.name + " " + method.desc);
break;
}
if (fn.name.equals(slotCount)) {
addMethodMapping("net/minecraft/network/play/server/S2DPacketOpenWindow getSlotCount ()I",
packet.name + " " + method.name + " " + method.desc);
break;
}
}
}
// public boolean hasSlots()
methods = DynamicMappings.getMatchingMethods(packet, null, "()Z");
if (methods.size() == 1) {
addMethodMapping("net/minecraft/network/play/server/S2DPacketOpenWindow hasSlots ()Z",
packet.name + " " + methods.get(0).name + " " + methods.get(0).desc);
}
return true;
}
public static class TallyKeeper<T>
{
private Map<T, Integer> counts = new HashMap<>();
public void put(T t)
{
Integer count = counts.get(t);
if (count == null) count = new Integer(0);
count++;
counts.put(t, count);
}
public T getHighestObj()
{
int maxCount = -1;
T maxKey = null;
for (T key : counts.keySet()) {
int count = counts.get(key);
if (count > maxCount) { maxCount = count; maxKey = key; }
}
return maxKey;
}
public int getHighestCount()
{
int maxCount = -1;
for (T key : counts.keySet()) {
int count = counts.get(key);
if (count > maxCount) maxCount = count;
}
return maxCount;
}
}
@Mapping(provides={
"net/minecraft/client/settings/KeyBinding"
},
depends={
"net/minecraft/client/settings/GameSettings",
"net/minecraft/client/Minecraft"
})
public boolean getKeybindingClass()
{
ClassNode gameSettings = getClassNodeFromMapping("net/minecraft/client/settings/GameSettings");
ClassNode minecraft = getClassNodeFromMapping("net/minecraft/client/Minecraft");
if (gameSettings == null || minecraft == null) return false;
// Bit of a roundabout way to locate and confirm KeyBinding
List<MethodNode> methods = DynamicMappings.getMatchingMethods(gameSettings, "<init>", "(L" + minecraft.name + ";Ljava/io/File;)V");
if (methods.size() == 1)
{
TallyKeeper<String> tallies = new TallyKeeper<>();
for (AbstractInsnNode insn = methods.get(0).instructions.getFirst(); insn != null; insn = insn.getNext()) {
if (insn.getOpcode() != Opcodes.NEW) continue;
TypeInsnNode tn = (TypeInsnNode)insn;
tallies.put(tn.desc);
}
String keyBinding_name = tallies.getHighestObj();
ClassNode keyBinding = getClassNode(keyBinding_name);
boolean comparable = false;
for (String iface : keyBinding.interfaces) {
if (iface.equals("java/lang/Comparable")) comparable = true;
}
if (comparable) {
addClassMapping("net/minecraft/client/settings/KeyBinding", keyBinding_name);
return true;
}
}
return false;
}
@Mapping(providesFields={
"net/minecraft/client/settings/KeyBinding keyDescription Ljava/lang/String;",
"net/minecraft/client/settings/KeyBinding keyCode I",
"net/minecraft/client/settings/KeyBinding keyCodeDefault I",
"net/minecraft/client/settings/KeyBinding keyCategory Ljava/lang/String;",
"net/minecraft/client/settings/KeyBinding pressed Z",
"net/minecraft/client/settings/KeyBinding pressTime I"
},
providesMethods={
"net/minecraft/client/settings/KeyBinding onTick (I)V",
"net/minecraft/client/settings/KeyBinding setKeyBindState (IZ)V",
"net/minecraft/client/settings/KeyBinding getKeybinds ()Ljava/util/Set;",
"net/minecraft/client/settings/KeyBinding unpressKey ()V",
"net/minecraft/client/settings/KeyBinding unPressAllKeys ()V",
"net/minecraft/client/settings/KeyBinding resetKeyBindingArrayAndHash ()V",
"net/minecraft/client/settings/KeyBinding setKeyCode (I)V",
"net/minecraft/client/settings/KeyBinding isKeyDown ()Z",
"net/minecraft/client/settings/KeyBinding isPressed ()Z",
"net/minecraft/client/settings/KeyBinding updateAllKeys ()V"
},
depends={
"net/minecraft/client/settings/KeyBinding"
})
public boolean processKeybindingClass()
{
ClassNode keyBinding = getClassNodeFromMapping("net/minecraft/client/settings/KeyBinding");
if (keyBinding == null) return false;
String keyDescription = null;
String keyCode = null;
String keyCodeDefault = null;
String keyCategory = null;
// public KeyBinding(String description, int keyCode, String category)
List<MethodNode> methods = DynamicMappings.getMatchingMethods(keyBinding, "<init>", "(Ljava/lang/String;ILjava/lang/String;)V");
if (methods.size() == 1) {
List<FieldInsnNode> fields = new ArrayList<>();
for (AbstractInsnNode insn = methods.get(0).instructions.getFirst(); insn != null; insn = insn.getNext()) {
if (insn.getOpcode() != Opcodes.PUTFIELD) continue;
fields.add((FieldInsnNode)insn);
}
if (fields.size() == 4) {
if (fields.get(0).desc.equals("Ljava/lang/String;")) {
keyDescription = fields.get(0).name;
addFieldMapping("net/minecraft/client/settings/KeyBinding keyDescription Ljava/lang/String;",
keyBinding.name + " " + fields.get(0).name + " Ljava/lang/String;");
}
if (fields.get(1).desc.equals("I") && fields.get(2).desc.equals("I")) {
keyCode = fields.get(1).name;
keyCodeDefault = fields.get(2).name;
addFieldMapping("net/minecraft/client/settings/KeyBinding keyCode I",
keyBinding.name + " " + fields.get(1).name + " I");
addFieldMapping("net/minecraft/client/settings/KeyBinding keyCodeDefault I",
keyBinding.name + " " + fields.get(2).name + " I");
}
if (fields.get(3).desc.equals("Ljava/lang/String;")) {
keyCategory = fields.get(3).name;
addFieldMapping("net/minecraft/client/settings/KeyBinding keyCategory Ljava/lang/String;",
keyBinding.name + " " + fields.get(3).name + " Ljava/lang/String;");
}
}
}
// public static void onTick(int keyCode)
methods = DynamicMappings.getMatchingMethods(keyBinding, null, "(I)V");
methods = DynamicMappings.removeMethodsWithoutFlags(methods, Opcodes.ACC_STATIC);
if (methods.size() == 1) {
addMethodMapping("net/minecraft/client/settings/KeyBinding onTick (I)V",
keyBinding.name + " " + methods.get(0).name + " " + methods.get(0).desc);
}
// public static void setKeyBindState(int keyCode, boolean pressed)
methods = DynamicMappings.getMatchingMethods(keyBinding, null, "(IZ)V");
methods = DynamicMappings.removeMethodsWithoutFlags(methods, Opcodes.ACC_STATIC);
if (methods.size() == 1) {
addMethodMapping("net/minecraft/client/settings/KeyBinding setKeyBindState (IZ)V",
keyBinding.name + " " + methods.get(0).name + " " + methods.get(0).desc);
}
// public static Set getKeybinds()
methods = DynamicMappings.getMatchingMethods(keyBinding, null, "()Ljava/util/Set;");
methods = DynamicMappings.removeMethodsWithoutFlags(methods, Opcodes.ACC_STATIC);
if (methods.size() == 1) {
addMethodMapping("net/minecraft/client/settings/KeyBinding getKeybinds ()Ljava/util/Set;",
keyBinding.name + " " + methods.get(0).name + " " + methods.get(0).desc);
}
// private void unpressKey()
String unpressKey = null;
methods = DynamicMappings.getMatchingMethods(keyBinding, null, "()V");
methods = DynamicMappings.removeMethodsWithFlags(methods, Opcodes.ACC_STATIC);
for (Iterator<MethodNode> it = methods.iterator(); it.hasNext();) {
if (it.next().name.contains("<")) it.remove();
}
if (methods.size() == 1) {
unpressKey = methods.get(0).name;
addMethodMapping("net/minecraft/client/settings/KeyBinding unpressKey ()V",
keyBinding.name + " " + methods.get(0).name + " " + methods.get(0).desc);
String pressTime = null;
int count = 0;
for (AbstractInsnNode insn = methods.get(0).instructions.getFirst(); insn != null; insn = insn.getNext()) {
if (insn.getOpcode() != Opcodes.PUTFIELD) continue;
FieldInsnNode fn = (FieldInsnNode)insn;
if (fn.owner.equals(keyBinding.name) && fn.desc.equals("I")) {
count++;
pressTime = fn.name;
}
}
if (count == 1 && pressTime != null) {
addFieldMapping("net/minecraft/client/settings/KeyBinding pressTime I",
keyBinding.name + " " + pressTime + " I");
}
}
// public static void updateAllKeys() - NEW in 15w37a
// public static void unPressAllKeys()
// public static void resetKeyBindingArrayAndHash()
methods = DynamicMappings.getMatchingMethods(keyBinding, null, "()V");
methods = DynamicMappings.removeMethodsWithoutFlags(methods, Opcodes.ACC_STATIC);
for (Iterator<MethodNode> it = methods.iterator(); it.hasNext();) {
if (it.next().name.contains("<")) it.remove();
}
if (methods.size() == 3 && unpressKey != null)
{
MethodNode updateAllKeys = null;
MethodNode unPressAllKeys = null;
MethodNode resetKeyBindingArrayAndHash = null;
outerloop:
for (Iterator<MethodNode> it = methods.iterator(); it.hasNext();) {
MethodNode method = it.next();
List<MethodInsnNode> list = DynamicMappings.getAllInsnNodesOfType(method.instructions.getFirst(), MethodInsnNode.class);
for (MethodInsnNode mn : list) {
if (mn.owner.equals("org/lwjgl/input/Keyboard") && mn.name.equals("isKeyDown")) {
addMethodMapping("net/minecraft/client/settings/KeyBinding updateAllKeys ()V",
keyBinding.name + " " + method.name + " " + method.desc);
it.remove();
break outerloop;
}
}
}
if (methods.size() == 2) {
for (MethodNode method : methods) {
boolean is_unpressAllKeys = false;
for (AbstractInsnNode insn = method.instructions.getFirst(); insn != null; insn = insn.getNext()) {
if (insn.getOpcode() != Opcodes.INVOKESPECIAL) continue;
MethodInsnNode mn = (MethodInsnNode)insn;
if (mn.owner.equals(keyBinding.name) && mn.name.equals(unpressKey) && mn.desc.equals("()V")) {
unPressAllKeys = method;
is_unpressAllKeys = true;
break;
}
}
if (!is_unpressAllKeys) resetKeyBindingArrayAndHash = method;
}
}
if (unPressAllKeys != null && resetKeyBindingArrayAndHash != null) {
addMethodMapping("net/minecraft/client/settings/KeyBinding unPressAllKeys ()V",
keyBinding.name + " " + unPressAllKeys.name + " " + unPressAllKeys.desc);
addMethodMapping("net/minecraft/client/settings/KeyBinding resetKeyBindingArrayAndHash ()V",
keyBinding.name + " " + resetKeyBindingArrayAndHash.name + " " + resetKeyBindingArrayAndHash.desc);
}
}
// public void setKeyCode(int keyCode)
methods = DynamicMappings.getMatchingMethods(keyBinding, null, "(I)V");
methods = DynamicMappings.removeMethodsWithFlags(methods, Opcodes.ACC_STATIC);
if (methods.size() == 1) {
addMethodMapping("net/minecraft/client/settings/KeyBinding setKeyCode (I)V",
keyBinding.name + " " + methods.get(0).name + " " + methods.get(0).desc);
}
// public boolean isKeyDown()
// public boolean isPressed()
methods = DynamicMappings.getMatchingMethods(keyBinding, null, "()Z");
if (methods.size() == 2) {
boolean isGetter0 = DynamicMappings.matchOpcodeSequence(methods.get(0).instructions.getFirst(), Opcodes.ALOAD, Opcodes.GETFIELD, Opcodes.IRETURN);
boolean isGetter1 = DynamicMappings.matchOpcodeSequence(methods.get(1).instructions.getFirst(), Opcodes.ALOAD, Opcodes.GETFIELD, Opcodes.IRETURN);
MethodNode isKeyDown = null;
MethodNode isPressed = null;
if (isGetter0 && !isGetter1) { isKeyDown = methods.get(0); isPressed = methods.get(1); }
if (!isGetter0 && isGetter1) { isKeyDown = methods.get(1); isPressed = methods.get(0); }
if (isKeyDown != null && isPressed != null) {
addMethodMapping("net/minecraft/client/settings/KeyBinding isKeyDown ()Z",
keyBinding.name + " " + isKeyDown.name + " " + isKeyDown.desc);
addMethodMapping("net/minecraft/client/settings/KeyBinding isPressed ()Z",
keyBinding.name + " " + isPressed.name + " " + isPressed.desc);
for (AbstractInsnNode insn = isKeyDown.instructions.getFirst(); insn != null; insn = insn.getNext()) {
if (insn.getOpcode() != Opcodes.GETFIELD) continue;
FieldInsnNode fn = (FieldInsnNode)insn;
if (fn.owner.equals(keyBinding.name) && fn.desc.equals("Z")) {
addFieldMapping("net/minecraft/client/settings/KeyBinding pressed Z",
keyBinding.name + " " + fn.name + " " + fn.desc);
}
}
}
}
// TODO
// public String getKeyCategory()
// public String getKeyDescription()
// public int getKeyCodeDefault()
// public int getKeyCode()
// public int compareTo(KeyBinding p_compareTo_1_)
return true;
}
@Mapping(provides={
"net/minecraft/client/renderer/RenderHelper"
},
dependsMethods={
"net/minecraft/client/gui/GuiScreen drawScreen (IIF)V"
},
depends={
"net/minecraft/client/gui/inventory/GuiContainer",
"net/minecraft/util/Vec3"
})
public boolean getRenderHelperClass()
{
ClassNode guiContainer = getClassNodeFromMapping("net/minecraft/client/gui/inventory/GuiContainer");
ClassNode vec3 = getClassNodeFromMapping("net/minecraft/util/Vec3");
if (guiContainer == null || vec3 == null) return false;
MethodNode drawScreen = DynamicMappings.getMethodNodeFromMapping(guiContainer, "net/minecraft/client/gui/GuiScreen drawScreen (IIF)V");
if (drawScreen == null) return false;
String renderHelper = null;
int count = 0;
for (AbstractInsnNode insn = drawScreen.instructions.getFirst(); insn != null; insn = insn.getNext()) {
if (insn.getOpcode() != Opcodes.INVOKESTATIC) continue;
MethodInsnNode mn = (MethodInsnNode)insn;
if (DynamicMappings.searchConstantPoolForClasses(mn.owner, vec3.name, "java/nio/FloatBuffer"))
{
if (!mn.owner.equals(renderHelper)) {
renderHelper = mn.owner;
count++;
}
}
}
if (count == 1) {
addClassMapping("net/minecraft/client/renderer/RenderHelper", renderHelper);
}
return true;
}
@Mapping(providesMethods={
"net/minecraft/client/renderer/RenderHelper enableStandardItemLighting ()V",
"net/minecraft/client/renderer/RenderHelper enableGUIStandardItemLighting ()V",
"net/minecraft/client/renderer/RenderHelper disableStandardItemLighting ()V"
},
depends={
"net/minecraft/client/renderer/RenderHelper"
})
public boolean processRenderHelperClass()
{
ClassNode renderHelper = getClassNodeFromMapping("net/minecraft/client/renderer/RenderHelper");
if (renderHelper == null) return false;
List<MethodNode> methods = DynamicMappings.getMatchingMethods(renderHelper, null, "()V");
for (Iterator<MethodNode> it = methods.iterator(); it.hasNext();) {
MethodNode method = it.next();
if ((method.access & Opcodes.ACC_STATIC) == 0) it.remove();
if ((method.access & Opcodes.ACC_PRIVATE) > 0) it.remove();
if (method.name.contains("<")) it.remove();
}
if (methods.size() != 3) return false;
MethodNode enableStandardItemLighting = null;
for (MethodNode method : methods) {
for (AbstractInsnNode insn = method.instructions.getFirst(); insn != null; insn = insn.getNext()) {
if (insn.getOpcode() != Opcodes.INVOKESTATIC) continue;
MethodInsnNode mn = (MethodInsnNode)insn;
// Changed in snapshot prior to 16w02a
//if (!mn.owner.equals("org/lwjgl/opengl/GL11") || !mn.name.equals("glLight")) continue;
if (!mn.desc.equals("(IILjava/nio/FloatBuffer;)V")) continue;
if (enableStandardItemLighting != null) return false;
enableStandardItemLighting = method;
break;
}
}
if (enableStandardItemLighting == null) return false;
addMethodMapping("net/minecraft/client/renderer/RenderHelper enableStandardItemLighting ()V",
renderHelper.name + " " + enableStandardItemLighting.name + " ()V");
methods.remove(enableStandardItemLighting);
MethodNode enableGUIStandardItemLighting = null;
for (MethodNode method : methods) {
for (AbstractInsnNode insn = method.instructions.getFirst(); insn != null; insn = insn.getNext()) {
if (insn.getOpcode() != Opcodes.INVOKESTATIC) continue;
MethodInsnNode mn = (MethodInsnNode)insn;
if (!mn.owner.equals(renderHelper.name) || !mn.name.equals(enableStandardItemLighting.name)) continue;
if (enableGUIStandardItemLighting != null) return false;
enableGUIStandardItemLighting = method;
break;
}
}
if (enableGUIStandardItemLighting == null) return false;
addMethodMapping("net/minecraft/client/renderer/RenderHelper enableGUIStandardItemLighting ()V",
renderHelper.name + " " + enableGUIStandardItemLighting.name + " ()V");
methods.remove(enableGUIStandardItemLighting);
addMethodMapping("net/minecraft/client/renderer/RenderHelper disableStandardItemLighting ()V",
renderHelper.name + " " + methods.get(0).name + " ()V");
return true;
}
@Mapping(providesMethods={
/*"net/minecraft/block/Block getRenderType ()I"*/
},
depends={
"net/minecraft/block/BlockLiquid",
"net/minecraft/block/Block"
})
public boolean processBlockDynamicLiquidClass()
{
ClassNode liquid = getClassNodeFromMapping("net/minecraft/block/BlockLiquid");
ClassNode block = getClassNodeFromMapping("net/minecraft/block/Block");
if (!MeddleUtil.notNull(liquid, block)) return false;
// TODO - This changed in 15w37a, stopped being needed for MeddleAPI
// public int getRenderType()
/*
List<MethodNode> methods = DynamicMappings.getMatchingMethods(liquid, null, "()I");
if (methods.size() == 1) {
addMethodMapping("net/minecraft/block/Block getRenderType ()I", block.name + " " + methods.get(0).name + " ()I");
}*/
return true;
}
@Mapping(provides={
"net/minecraft/client/renderer/WorldRenderer",
"net/minecraft/client/renderer/BlockModelShapes"
},
providesFields={
"net/minecraft/client/renderer/BlockRendererDispatcher blockModelShapes Lnet/minecraft/client/renderer/BlockModelShapes;"
},
providesMethods={
"net/minecraft/client/renderer/BlockRendererDispatcher renderBlock (Lnet/minecraft/block/state/IBlockState;Lnet/minecraft/util/BlockPos;Lnet/minecraft/world/IBlockAccess;Lnet/minecraft/client/renderer/WorldRenderer;)Z",
"net/minecraft/client/renderer/BlockRendererDispatcher getBlockModelShapes ()Lnet/minecraft/client/renderer/BlockModelShapes;"
},
depends={
"net/minecraft/client/renderer/BlockRendererDispatcher",
"net/minecraft/block/state/IBlockState",
"net/minecraft/util/BlockPos",
"net/minecraft/world/IBlockAccess"
})
public boolean processBlockRendererDispatcherClass()
{
ClassNode blockRenderer = getClassNodeFromMapping("net/minecraft/client/renderer/BlockRendererDispatcher");
ClassNode iBlockState = getClassNodeFromMapping("net/minecraft/block/state/IBlockState");
ClassNode blockPos = getClassNodeFromMapping("net/minecraft/util/BlockPos");
ClassNode iBlockAccess = getClassNodeFromMapping("net/minecraft/world/IBlockAccess");
if (!MeddleUtil.notNull(blockRenderer, iBlockState, blockPos, iBlockAccess)) return false;
String blockModelShapes_name = null;
for (FieldNode field : blockRenderer.fields) {
Type t = Type.getType(field.desc);
if (t.getSort() != Type.OBJECT) continue;
String className = t.getClassName();
if (blockModelShapes_name == null && searchConstantPoolForStrings(className, "minecraft:blocks/planks_oak", "minecraft:items/barrier")) {
addClassMapping("net/minecraft/client/renderer/BlockModelShapes", className);
blockModelShapes_name = className;
if (countFieldsWithDesc(blockRenderer, "L" + blockModelShapes_name + ";") == 1) {
addFieldMapping("net/minecraft/client/renderer/BlockRendererDispatcher blockModelShapes Lnet/minecraft/client/renderer/BlockModelShapes;",
blockRenderer.name + " " + field.name + " " + field.desc);
}
}
}
// public BlockModelShapes getBlockModelShapes()
List<MethodNode> methods = getMatchingMethods(blockRenderer, null, "()L" + blockModelShapes_name + ";");
if (methods.size() == 1) {
addMethodMapping("net/minecraft/client/renderer/BlockRendererDispatcher getBlockModelShapes ()Lnet/minecraft/client/renderer/BlockModelShapes;",
blockRenderer.name + " " + methods.get(0).name + " " + methods.get(0).desc);
}
String worldRenderer_name = null;
// public boolean renderBlock(IBlockState state, BlockPos pos, IBlockAccess blockAccess, WorldRenderer worldRendererIn)
String desc_front = DynamicMappings.assembleDescriptor("(", iBlockState, blockPos, iBlockAccess);
methods.clear();
for (MethodNode method : blockRenderer.methods) {
if (method.desc.startsWith(desc_front) && method.desc.endsWith(";)Z")) {
methods.add(method);
}
}
if (methods.size() == 1) {
Type t = Type.getMethodType(methods.get(0).desc);
Type[] args = t.getArgumentTypes();
worldRenderer_name = args[3].getClassName();
if (DynamicMappings.searchConstantPoolForStrings(worldRenderer_name, "Already building!", "Not building!")) {
addClassMapping("net/minecraft/client/renderer/WorldRenderer", worldRenderer_name);
addMethodMapping("net/minecraft/client/renderer/BlockRendererDispatcher renderBlock (Lnet/minecraft/block/state/IBlockState;Lnet/minecraft/util/BlockPos;Lnet/minecraft/world/IBlockAccess;Lnet/minecraft/client/renderer/WorldRenderer;)Z",
blockRenderer.name + " " + methods.get(0).name + " " + methods.get(0).desc);
}
else worldRenderer_name = null;
}
return true;
}
@Mapping(provides={
"net/minecraft/client/renderer/vertex/VertexFormat"
},
providesMethods={
"net/minecraft/client/renderer/WorldRenderer startDrawing (ILnet/minecraft/client/renderer/vertex/VertexFormat;)V",
"net/minecraft/client/renderer/WorldRenderer finishDrawing ()V"
},
depends={
"net/minecraft/client/renderer/WorldRenderer"
})
public boolean processWorldRendererClass()
{
ClassNode worldRenderer = getClassNodeFromMapping("net/minecraft/client/renderer/WorldRenderer");
if (!MeddleUtil.notNull(worldRenderer)) return false;
List<MethodNode> methods = new ArrayList<>();
String vertexFormat_name = null;
// public void startDrawing(int mode, VertexFormat format)
for (MethodNode method : worldRenderer.methods) {
Type t = Type.getMethodType(method.desc);
if (t.getReturnType().getSort() != Type.VOID) continue;
Type[] args = t.getArgumentTypes();
if (args.length != 2) continue;
if (args[0].getSort() != Type.INT || args[1].getSort() != Type.OBJECT) continue;
methods.add(method);
vertexFormat_name = args[1].getClassName();
}
if (methods.size() == 1 && DynamicMappings.searchConstantPoolForStrings(vertexFormat_name, "VertexFormat error: Trying to add a position VertexFormatElement when one already exists, ignoring.")) {
addClassMapping("net/minecraft/client/renderer/vertex/VertexFormat", vertexFormat_name);
addMethodMapping("net/minecraft/client/renderer/WorldRenderer startDrawing (ILnet/minecraft/client/renderer/vertex/VertexFormat;)V",
worldRenderer.name + " " + methods.get(0).name + " " + methods.get(0).desc);
}
else vertexFormat_name = null;
// public void finishDrawing()
methods = DynamicMappings.getMatchingMethods(worldRenderer, null, "()V");
int count = 0;
String finishDrawing = null;
for (MethodNode method : methods) {
for (AbstractInsnNode insn = method.instructions.getFirst(); insn != null; insn = insn.getNext()) {
if (DynamicMappings.isLdcWithString(insn, "Not building!")) {
finishDrawing = method.name;
count++;
}
}
}
if (count == 1 && finishDrawing != null) {
addMethodMapping("net/minecraft/client/renderer/WorldRenderer finishDrawing ()V", worldRenderer.name + " " + finishDrawing + " ()V");
}
return true;
}
@Mapping(providesMethods={
"net/minecraft/client/renderer/WorldRenderer sortQuads (FFF)V",
"net/minecraft/client/renderer/WorldRenderer putColor4 (I)V",
"net/minecraft/client/renderer/WorldRenderer getByteBuffer ()Ljava/nio/ByteBuffer;",
"net/minecraft/client/renderer/WorldRenderer postNormal (FFF)V",
"net/minecraft/client/renderer/WorldRenderer getDrawMode ()I",
"net/minecraft/client/renderer/WorldRenderer setTranslation (DDD)V",
"net/minecraft/client/renderer/WorldRenderer endVertex ()V",
"net/minecraft/client/renderer/WorldRenderer setNormal (FFF)Lnet/minecraft/client/renderer/WorldRenderer;",
"net/minecraft/client/renderer/WorldRenderer setColorRGBA (IIII)Lnet/minecraft/client/renderer/WorldRenderer;",
"net/minecraft/client/renderer/WorldRenderer setColorRGBA_F (FFFF)Lnet/minecraft/client/renderer/WorldRenderer;",
"net/minecraft/client/renderer/WorldRenderer setBrightness (II)Lnet/minecraft/client/renderer/WorldRenderer;",
"net/minecraft/client/renderer/WorldRenderer setTextureUV (DD)Lnet/minecraft/client/renderer/WorldRenderer;",
"net/minecraft/client/renderer/WorldRenderer addVertex (DDD)Lnet/minecraft/client/renderer/WorldRenderer;",
"net/minecraft/client/renderer/WorldRenderer putBrightness4 (IIII)V",
"net/minecraft/client/renderer/WorldRenderer putPosition (DDD)V",
"net/minecraft/client/renderer/WorldRenderer putColorRGB_F (FFFI)V",
"net/minecraft/client/renderer/WorldRenderer putColorMultiplier (FFFI)V",
"net/minecraft/client/renderer/WorldRenderer putBulkData ([I)V",
"net/minecraft/client/renderer/WorldRenderer getVertexCount ()I",
"net/minecraft/client/renderer/WorldRenderer reset ()V",
"net/minecraft/client/renderer/WorldRenderer putColorRGB_F4 (FFF)V",
"net/minecraft/client/renderer/WorldRenderer markDirty ()V"
},
depends={
"net/minecraft/client/renderer/WorldRenderer",
"net/minecraft/client/renderer/vertex/VertexFormat"
})
public boolean processRealmsBufferBuilderClass()
{
ClassNode bufferBuilder = getClassNode("net/minecraft/realms/RealmsBufferBuilder");
ClassNode worldRenderer = getClassNodeFromMapping("net/minecraft/client/renderer/WorldRenderer");
ClassNode vertexFormat = getClassNodeFromMapping("net/minecraft/client/renderer/vertex/VertexFormat");
if (!MeddleUtil.notNull(bufferBuilder, worldRenderer, vertexFormat)) return false;
MethodNode method = null;
// public void sortQuads(float param0, float param1, float param2)
method = getMethodNode(bufferBuilder, "- sortQuads (FFF)V");
if (method != null) {
List<MethodInsnNode> list = DynamicMappings.getAllInsnNodesOfType(method.instructions.getFirst(), MethodInsnNode.class);
for (MethodInsnNode mn : list) {
if (mn.owner.equals(worldRenderer.name) && mn.desc.equals("(FFF)V")) {
addMethodMapping("net/minecraft/client/renderer/WorldRenderer sortQuads (FFF)V", worldRenderer.name + " " + mn.name + " " + mn.desc);
break;
}
}
}
// public void putColor4(int param0)
method = getMethodNode(bufferBuilder, "- fixupQuadColor (I)V");
if (method != null) {
List<MethodInsnNode> list = DynamicMappings.getAllInsnNodesOfType(method.instructions.getFirst(), MethodInsnNode.class);
for (MethodInsnNode mn : list) {
if (mn.owner.equals(worldRenderer.name) && mn.desc.equals("(I)V")) {
addMethodMapping("net/minecraft/client/renderer/WorldRenderer putColor4 (I)V", worldRenderer.name + " " + mn.name + " " + mn.desc);
break;
}
}
}
// public ByteBuffer getByteBuffer()
method = getMethodNode(bufferBuilder, "- getBuffer ()Ljava/nio/ByteBuffer;");
if (method != null) {
List<MethodInsnNode> list = DynamicMappings.getAllInsnNodesOfType(method.instructions.getFirst(), MethodInsnNode.class);
for (MethodInsnNode mn : list) {
if (mn.owner.equals(worldRenderer.name) && mn.desc.equals("()Ljava/nio/ByteBuffer;")) {
addMethodMapping("net/minecraft/client/renderer/WorldRenderer getByteBuffer ()Ljava/nio/ByteBuffer;", worldRenderer.name + " " + mn.name + " " + mn.desc);
break;
}
}
}
// public void postNormal(float param0, float param1, float param2)
method = getMethodNode(bufferBuilder, "- postNormal (FFF)V");
if (method != null) {
List<MethodInsnNode> list = DynamicMappings.getAllInsnNodesOfType(method.instructions.getFirst(), MethodInsnNode.class);
for (MethodInsnNode mn : list) {
if (mn.owner.equals(worldRenderer.name) && mn.desc.equals("(FFF)V")) {
addMethodMapping("net/minecraft/client/renderer/WorldRenderer postNormal (FFF)V", worldRenderer.name + " " + mn.name + " " + mn.desc);
break;
}
}
}
// public int getDrawMode()
method = getMethodNode(bufferBuilder, "- getDrawMode ()I");
if (method != null) {
List<MethodInsnNode> list = DynamicMappings.getAllInsnNodesOfType(method.instructions.getFirst(), MethodInsnNode.class);
for (MethodInsnNode mn : list) {
if (mn.owner.equals(worldRenderer.name) && mn.desc.equals("()I")) {
addMethodMapping("net/minecraft/client/renderer/WorldRenderer getDrawMode ()I", worldRenderer.name + " " + mn.name + " " + mn.desc);
break;
}
}
}
// public void setTranslation(double param0, double param1, double param2)
method = getMethodNode(bufferBuilder, "- offset (DDD)V");
if (method != null) {
List<MethodInsnNode> list = DynamicMappings.getAllInsnNodesOfType(method.instructions.getFirst(), MethodInsnNode.class);
for (MethodInsnNode mn : list) {
if (mn.owner.equals(worldRenderer.name) && mn.desc.equals("(DDD)V")) {
addMethodMapping("net/minecraft/client/renderer/WorldRenderer setTranslation (DDD)V", worldRenderer.name + " " + mn.name + " " + mn.desc);
break;
}
}
}
// public void endVertex()
method = getMethodNode(bufferBuilder, "- endVertex ()V");
if (method != null) {
List<MethodInsnNode> list = DynamicMappings.getAllInsnNodesOfType(method.instructions.getFirst(), MethodInsnNode.class);
for (MethodInsnNode mn : list) {
if (mn.owner.equals(worldRenderer.name) && mn.desc.equals("()V")) {
addMethodMapping("net/minecraft/client/renderer/WorldRenderer endVertex ()V", worldRenderer.name + " " + mn.name + " " + mn.desc);
break;
}
}
}
// public WorldRenderer setNormal(float param0, float param1, float param2)
method = getMethodNode(bufferBuilder, "- normal (FFF)Lnet/minecraft/realms/RealmsBufferBuilder;");
if (method != null) {
List<MethodInsnNode> list = DynamicMappings.getAllInsnNodesOfType(method.instructions.getFirst(), MethodInsnNode.class);
for (MethodInsnNode mn : list) {
if (mn.owner.equals(worldRenderer.name) && mn.desc.equals("(FFF)L" + worldRenderer.name + ";")) {
addMethodMapping("net/minecraft/client/renderer/WorldRenderer setNormal (FFF)Lnet/minecraft/client/renderer/WorldRenderer;", worldRenderer.name + " " + mn.name + " " + mn.desc);
break;
}
}
}
// public WorldRenderer setColorRGBA(int param0, int param1, int param2, int param3)
method = getMethodNode(bufferBuilder, "- color (IIII)Lnet/minecraft/realms/RealmsBufferBuilder;");
if (method != null) {
List<MethodInsnNode> list = DynamicMappings.getAllInsnNodesOfType(method.instructions.getFirst(), MethodInsnNode.class);
for (MethodInsnNode mn : list) {
if (mn.owner.equals(worldRenderer.name) && mn.desc.equals("(IIII)L" + worldRenderer.name + ";")) {
addMethodMapping("net/minecraft/client/renderer/WorldRenderer setColorRGBA (IIII)Lnet/minecraft/client/renderer/WorldRenderer;", worldRenderer.name + " " + mn.name + " " + mn.desc);
break;
}
}
}
// public WorldRenderer setColorRGBA_F(float param0, float param1, float param2, float param3)
method = getMethodNode(bufferBuilder, "- color (FFFF)Lnet/minecraft/realms/RealmsBufferBuilder;");
if (method != null) {
List<MethodInsnNode> list = DynamicMappings.getAllInsnNodesOfType(method.instructions.getFirst(), MethodInsnNode.class);
for (MethodInsnNode mn : list) {
if (mn.owner.equals(worldRenderer.name) && mn.desc.equals("(FFFF)L" + worldRenderer.name + ";")) {
addMethodMapping("net/minecraft/client/renderer/WorldRenderer setColorRGBA_F (FFFF)Lnet/minecraft/client/renderer/WorldRenderer;", worldRenderer.name + " " + mn.name + " " + mn.desc);
break;
}
}
}
// public WorldRenderer setBrightness(int param0, int param1)
method = getMethodNode(bufferBuilder, "- tex2 (II)Lnet/minecraft/realms/RealmsBufferBuilder;");
if (method != null) {
List<MethodInsnNode> list = DynamicMappings.getAllInsnNodesOfType(method.instructions.getFirst(), MethodInsnNode.class);
for (MethodInsnNode mn : list) {
if (mn.owner.equals(worldRenderer.name) && mn.desc.equals("(II)L" + worldRenderer.name + ";")) {
addMethodMapping("net/minecraft/client/renderer/WorldRenderer setBrightness (II)Lnet/minecraft/client/renderer/WorldRenderer;", worldRenderer.name + " " + mn.name + " " + mn.desc);
break;
}
}
}
// public WorldRenderer setTextureUV(double param0, double param1)
method = getMethodNode(bufferBuilder, "- tex (DD)Lnet/minecraft/realms/RealmsBufferBuilder;");
if (method != null) {
List<MethodInsnNode> list = DynamicMappings.getAllInsnNodesOfType(method.instructions.getFirst(), MethodInsnNode.class);
for (MethodInsnNode mn : list) {
if (mn.owner.equals(worldRenderer.name) && mn.desc.equals("(DD)L" + worldRenderer.name + ";")) {
addMethodMapping("net/minecraft/client/renderer/WorldRenderer setTextureUV (DD)Lnet/minecraft/client/renderer/WorldRenderer;", worldRenderer.name + " " + mn.name + " " + mn.desc);
break;
}
}
}
// public WorldRenderer addVertex(double param0, double param1, double param2)
method = getMethodNode(bufferBuilder, "- vertex (DDD)Lnet/minecraft/realms/RealmsBufferBuilder;");
if (method != null) {
List<MethodInsnNode> list = DynamicMappings.getAllInsnNodesOfType(method.instructions.getFirst(), MethodInsnNode.class);
for (MethodInsnNode mn : list) {
if (mn.owner.equals(worldRenderer.name) && mn.desc.equals("(DDD)L" + worldRenderer.name + ";")) {
addMethodMapping("net/minecraft/client/renderer/WorldRenderer addVertex (DDD)Lnet/minecraft/client/renderer/WorldRenderer;", worldRenderer.name + " " + mn.name + " " + mn.desc);
break;
}
}
}
// public void putBrightness4(int param0, int param1, int param2, int param3)
method = getMethodNode(bufferBuilder, "- faceTex2 (IIII)V");
if (method != null) {
List<MethodInsnNode> list = DynamicMappings.getAllInsnNodesOfType(method.instructions.getFirst(), MethodInsnNode.class);
for (MethodInsnNode mn : list) {
if (mn.owner.equals(worldRenderer.name) && mn.desc.equals("(IIII)V")) {
addMethodMapping("net/minecraft/client/renderer/WorldRenderer putBrightness4 (IIII)V", worldRenderer.name + " " + mn.name + " " + mn.desc);
break;
}
}
}
// public void putPosition(double param0, double param1, double param2)
method = getMethodNode(bufferBuilder, "- postProcessFacePosition (DDD)V");
if (method != null) {
List<MethodInsnNode> list = DynamicMappings.getAllInsnNodesOfType(method.instructions.getFirst(), MethodInsnNode.class);
for (MethodInsnNode mn : list) {
if (mn.owner.equals(worldRenderer.name) && mn.desc.equals("(DDD)V")) {
addMethodMapping("net/minecraft/client/renderer/WorldRenderer putPosition (DDD)V", worldRenderer.name + " " + mn.name + " " + mn.desc);
break;
}
}
}
// public void putColorRGB_F(float param0, float param1, float param2, int param3)
method = getMethodNode(bufferBuilder, "- fixupVertexColor (FFFI)V");
if (method != null) {
List<MethodInsnNode> list = DynamicMappings.getAllInsnNodesOfType(method.instructions.getFirst(), MethodInsnNode.class);
for (MethodInsnNode mn : list) {
if (mn.owner.equals(worldRenderer.name) && mn.desc.equals("(FFFI)V")) {
addMethodMapping("net/minecraft/client/renderer/WorldRenderer putColorRGB_F (FFFI)V", worldRenderer.name + " " + mn.name + " " + mn.desc);
break;
}
}
}
// public void putColorMultiplier(float param0, float param1, float param2, int param3)
method = getMethodNode(bufferBuilder, "- faceTint (FFFI)V");
if (method != null) {
List<MethodInsnNode> list = DynamicMappings.getAllInsnNodesOfType(method.instructions.getFirst(), MethodInsnNode.class);
for (MethodInsnNode mn : list) {
if (mn.owner.equals(worldRenderer.name) && mn.desc.equals("(FFFI)V")) {
addMethodMapping("net/minecraft/client/renderer/WorldRenderer putColorMultiplier (FFFI)V", worldRenderer.name + " " + mn.name + " " + mn.desc);
break;
}
}
}
// public void putBulkData(int[] param0)
method = getMethodNode(bufferBuilder, "- putBulkData ([I)V");
if (method != null) {
List<MethodInsnNode> list = DynamicMappings.getAllInsnNodesOfType(method.instructions.getFirst(), MethodInsnNode.class);
for (MethodInsnNode mn : list) {
if (mn.owner.equals(worldRenderer.name) && mn.desc.equals("([I)V")) {
addMethodMapping("net/minecraft/client/renderer/WorldRenderer putBulkData ([I)V", worldRenderer.name + " " + mn.name + " " + mn.desc);
break;
}
}
}
// public int getVertexCount()
method = getMethodNode(bufferBuilder, "- getVertexCount ()I");
if (method != null) {
List<MethodInsnNode> list = DynamicMappings.getAllInsnNodesOfType(method.instructions.getFirst(), MethodInsnNode.class);
for (MethodInsnNode mn : list) {
if (mn.owner.equals(worldRenderer.name) && mn.desc.equals("()I")) {
addMethodMapping("net/minecraft/client/renderer/WorldRenderer getVertexCount ()I", worldRenderer.name + " " + mn.name + " " + mn.desc);
break;
}
}
}
// public void reset()
method = getMethodNode(bufferBuilder, "- clear ()V");
if (method != null) {
List<MethodInsnNode> list = DynamicMappings.getAllInsnNodesOfType(method.instructions.getFirst(), MethodInsnNode.class);
for (MethodInsnNode mn : list) {
if (mn.owner.equals(worldRenderer.name) && mn.desc.equals("()V")) {
addMethodMapping("net/minecraft/client/renderer/WorldRenderer reset ()V", worldRenderer.name + " " + mn.name + " " + mn.desc);
break;
}
}
}
// public void putColorRGB_F4(float param0, float param1, float param2)
method = getMethodNode(bufferBuilder, "- fixupQuadColor (FFF)V");
if (method != null) {
List<MethodInsnNode> list = DynamicMappings.getAllInsnNodesOfType(method.instructions.getFirst(), MethodInsnNode.class);
for (MethodInsnNode mn : list) {
if (mn.owner.equals(worldRenderer.name) && mn.desc.equals("(FFF)V")) {
addMethodMapping("net/minecraft/client/renderer/WorldRenderer putColorRGB_F4 (FFF)V", worldRenderer.name + " " + mn.name + " " + mn.desc);
break;
}
}
}
// public void markDirty()
method = getMethodNode(bufferBuilder, "- noColor ()V");
if (method != null) {
List<MethodInsnNode> list = DynamicMappings.getAllInsnNodesOfType(method.instructions.getFirst(), MethodInsnNode.class);
for (MethodInsnNode mn : list) {
if (mn.owner.equals(worldRenderer.name) && mn.desc.equals("()V")) {
addMethodMapping("net/minecraft/client/renderer/WorldRenderer markDirty ()V", worldRenderer.name + " " + mn.name + " " + mn.desc);
break;
}
}
}
// TODO
// restoreState (WorldRenderer.State param0)V
// public RealmsVertexFormat getVertexFormat()
return true;
}
@Mapping(provides={
"net/minecraft/util/EnumWorldBlockLayer"
},
providesMethods={
"net/minecraft/client/renderer/RenderGlobal renderBlockLayer (Lnet/minecraft/util/EnumWorldBlockLayer;)V"
},
depends={
"net/minecraft/client/renderer/RenderGlobal",
"net/minecraft/client/renderer/vertex/VertexFormat"
})
public boolean processRenderGlobalClass()
{
ClassNode renderGlobal = getClassNodeFromMapping("net/minecraft/client/renderer/RenderGlobal");
ClassNode vertexFormat = getClassNodeFromMapping("net/minecraft/client/renderer/vertex/VertexFormat");
if (!MeddleUtil.notNull(renderGlobal, vertexFormat)) return false;
String renderBlockLayer_name = null;
String enumWorldBlockLayer_name = null;
MethodNode renderBlockLayer = null;
// private void renderBlockLayer(EnumWorldBlockLayer param0)
// net/minecraft/util/EnumWorldBlockLayer
Set<String> matches = new HashSet<>();
for (MethodNode method : renderGlobal.methods) {
Type t = Type.getMethodType(method.desc);
if (t.getReturnType().getSort() != Type.VOID) continue;
Type[] args = t.getArgumentTypes();
if (args.length != 1 || args[0].getSort() != Type.OBJECT) continue;
matches.add(args[0].getClassName());
}
for (String className : matches) {
if (DynamicMappings.searchConstantPoolForStrings(className, "Solid", "Mipped Cutout", "Cutout", "Translucent")) {
addClassMapping("net/minecraft/util/EnumWorldBlockLayer", className);
enumWorldBlockLayer_name = className;
break;
}
}
List<MethodNode> methods = DynamicMappings.getMatchingMethods(renderGlobal, null, "(L" + enumWorldBlockLayer_name + ";)V");
if (methods.size() == 1) {
renderBlockLayer = methods.get(0);
addMethodMapping("net/minecraft/client/renderer/RenderGlobal renderBlockLayer (Lnet/minecraft/util/EnumWorldBlockLayer;)V",
renderGlobal.name + " " + methods.get(0).name + " "+ methods.get(0).desc);
}
return true;
}
@Mapping(provides={
"net/minecraft/client/renderer/texture/TextureAtlasSprite"
},
providesMethods={
"net/minecraft/client/renderer/texture/TextureMap getAtlasSprite (Ljava/lang/String;)Lnet/minecraft/client/renderer/texture/TextureAtlasSprite;"
},
depends={
"net/minecraft/client/renderer/texture/TextureMap"
})
public boolean processTextureMapClass()
{
ClassNode textureMap = getClassNodeFromMapping("net/minecraft/client/renderer/texture/TextureMap");
if (!MeddleUtil.notNull(textureMap)) return false;
List<MethodNode> methods = new ArrayList<>();
String textureAtlasSprite_name = null;
// public TextureAtlasSprite getAtlasSprite(String iconName)
// net/minecraft/client/renderer/texture/TextureAtlasSprite
for (MethodNode method : textureMap.methods) {
if (!method.desc.startsWith("(Ljava/lang/String;)L")) continue;
Type t = Type.getMethodType(method.desc);
String className = t.getReturnType().getClassName();
if (textureAtlasSprite_name == null && DynamicMappings.searchConstantPoolForStrings(className, "TextureAtlasSprite{name=\'", "Generating mipmaps for frame", "broken aspect ratio and not an animation")) {
addClassMapping("net/minecraft/client/renderer/texture/TextureAtlasSprite", className);
methods.add(method);
continue;
}
else if (textureAtlasSprite_name != null && className.equals(textureAtlasSprite_name)) {
methods.add(method);
continue;
}
}
if (methods.size() == 1) {
addMethodMapping("net/minecraft/client/renderer/texture/TextureMap getAtlasSprite (Ljava/lang/String;)Lnet/minecraft/client/renderer/texture/TextureAtlasSprite;",
textureMap.name + " " + methods.get(0).name + " " + methods.get(0).desc);
}
return true;
}
@Mapping(provides={
},
providesFields={
"net/minecraft/client/renderer/texture/TextureAtlasSprite iconName Ljava/lang/String;",
"net/minecraft/client/renderer/texture/TextureAtlasSprite framesTextureData Ljava/util/List;",
"net/minecraft/client/renderer/texture/TextureAtlasSprite rotated Z",
"net/minecraft/client/renderer/texture/TextureAtlasSprite originX I",
"net/minecraft/client/renderer/texture/TextureAtlasSprite originY I",
"net/minecraft/client/renderer/texture/TextureAtlasSprite height I",
"net/minecraft/client/renderer/texture/TextureAtlasSprite width I",
"net/minecraft/client/renderer/texture/TextureAtlasSprite minU F",
"net/minecraft/client/renderer/texture/TextureAtlasSprite maxU F",
"net/minecraft/client/renderer/texture/TextureAtlasSprite minV F",
"net/minecraft/client/renderer/texture/TextureAtlasSprite maxV F"
},
providesMethods={
"net/minecraft/client/renderer/texture/TextureAtlasSprite getIconName ()Ljava/lang/String;",
"net/minecraft/client/renderer/texture/TextureAtlasSprite getMinU ()F",
"net/minecraft/client/renderer/texture/TextureAtlasSprite getMinV ()F",
"net/minecraft/client/renderer/texture/TextureAtlasSprite getMaxU ()F",
"net/minecraft/client/renderer/texture/TextureAtlasSprite getMaxV ()F",
"net/minecraft/client/renderer/texture/TextureAtlasSprite getInterpolatedU (D)F",
"net/minecraft/client/renderer/texture/TextureAtlasSprite getInterpolatedV (D)F"
},
depends={
"net/minecraft/client/renderer/texture/TextureAtlasSprite"
})
public boolean processTextureAtlasSpriteClass()
{
ClassNode sprite = getClassNodeFromMapping("net/minecraft/client/renderer/texture/TextureAtlasSprite");
if (!MeddleUtil.notNull(sprite)) return false;
MethodNode toString = DynamicMappings.getMethodNode(sprite, "- toString ()Ljava/lang/String;");
if (toString == null) return false;
String iconName = null;
String framesTextureData = null;
String rotated = null;
String originX = null;
String originY = null;
String height = null;
String width = null;
String minU = null;
String maxU = null;
String minV = null;
String maxV = null;
for (AbstractInsnNode insn = toString.instructions.getFirst(); insn != null; insn = insn.getNext())
{
if (iconName == null && DynamicMappings.isLdcWithString(insn, "TextureAtlasSprite{name=\'")) {
FieldInsnNode fn = DynamicMappings.getNextInsnNodeOfType(insn, FieldInsnNode.class);
if (fn == null || !fn.owner.equals(sprite.name) || !fn.desc.equals("Ljava/lang/String;")) continue;
iconName = fn.name;
insn = fn;
continue;
}
if (framesTextureData == null && DynamicMappings.isLdcWithString(insn, ", frameCount=")) {
FieldInsnNode fn = DynamicMappings.getNextInsnNodeOfType(insn, FieldInsnNode.class);
if (fn == null || !fn.owner.equals(sprite.name) || !fn.desc.equals("Ljava/util/List;")) continue;
framesTextureData = fn.name;
insn = fn;
continue;
}
if (rotated == null && DynamicMappings.isLdcWithString(insn, ", rotated=")) {
FieldInsnNode fn = DynamicMappings.getNextInsnNodeOfType(insn, FieldInsnNode.class);
if (fn == null || !fn.owner.equals(sprite.name) || !fn.desc.equals("Z")) continue;
rotated = fn.name;
insn = fn;
continue;
}
if (originX == null && DynamicMappings.isLdcWithString(insn, ", x=")) {
FieldInsnNode fn = DynamicMappings.getNextInsnNodeOfType(insn, FieldInsnNode.class);
if (fn == null || !fn.owner.equals(sprite.name) || !fn.desc.equals("I")) continue;
originX = fn.name;
insn = fn;
continue;
}
if (originY == null && DynamicMappings.isLdcWithString(insn, ", y=")) {
FieldInsnNode fn = DynamicMappings.getNextInsnNodeOfType(insn, FieldInsnNode.class);
if (fn == null || !fn.owner.equals(sprite.name) || !fn.desc.equals("I")) continue;
originY = fn.name;
insn = fn;
continue;
}
if (height == null && DynamicMappings.isLdcWithString(insn, ", height=")) {
FieldInsnNode fn = DynamicMappings.getNextInsnNodeOfType(insn, FieldInsnNode.class);
if (fn == null || !fn.owner.equals(sprite.name) || !fn.desc.equals("I")) continue;
height = fn.name;
insn = fn;
continue;
}
if (width == null && DynamicMappings.isLdcWithString(insn, ", width=")) {
FieldInsnNode fn = DynamicMappings.getNextInsnNodeOfType(insn, FieldInsnNode.class);
if (fn == null || !fn.owner.equals(sprite.name) || !fn.desc.equals("I")) continue;
width = fn.name;
insn = fn;
continue;
}
if (minU == null && DynamicMappings.isLdcWithString(insn, ", u0=")) {
FieldInsnNode fn = DynamicMappings.getNextInsnNodeOfType(insn, FieldInsnNode.class);
if (fn == null || !fn.owner.equals(sprite.name) || !fn.desc.equals("F")) continue;
minU = fn.name;
insn = fn;
continue;
}
if (maxU == null && DynamicMappings.isLdcWithString(insn, ", u1=")) {
FieldInsnNode fn = DynamicMappings.getNextInsnNodeOfType(insn, FieldInsnNode.class);
if (fn == null || !fn.owner.equals(sprite.name) || !fn.desc.equals("F")) continue;
maxU = fn.name;
insn = fn;
continue;
}
if (minV == null && DynamicMappings.isLdcWithString(insn, ", v0=")) {
FieldInsnNode fn = DynamicMappings.getNextInsnNodeOfType(insn, FieldInsnNode.class);
if (fn == null || !fn.owner.equals(sprite.name) || !fn.desc.equals("F")) continue;
minV = fn.name;
insn = fn;
continue;
}
if (maxV == null && DynamicMappings.isLdcWithString(insn, ", v1=")) {
FieldInsnNode fn = DynamicMappings.getNextInsnNodeOfType(insn, FieldInsnNode.class);
if (fn == null || !fn.owner.equals(sprite.name) || !fn.desc.equals("F")) continue;
maxV = fn.name;
insn = fn;
continue;
}
}
if (iconName != null) {
addFieldMapping("net/minecraft/client/renderer/texture/TextureAtlasSprite iconName Ljava/lang/String;",
sprite.name + " " + iconName + " Ljava/lang/String;");
}
if (framesTextureData != null) {
addFieldMapping("net/minecraft/client/renderer/texture/TextureAtlasSprite framesTextureData Ljava/util/List;",
sprite.name + " " + framesTextureData + " Ljava/util/List;");
}
if (rotated != null) {
addFieldMapping("net/minecraft/client/renderer/texture/TextureAtlasSprite rotated Z",
sprite.name + " " + rotated + " Z");
}
if (originX != null) {
addFieldMapping("net/minecraft/client/renderer/texture/TextureAtlasSprite originX I",
sprite.name + " " + originX + " I");
}
if (originY != null) {
addFieldMapping("net/minecraft/client/renderer/texture/TextureAtlasSprite originY I",
sprite.name + " " + originY + " I");
}
if (height != null) {
addFieldMapping("net/minecraft/client/renderer/texture/TextureAtlasSprite height I",
sprite.name + " " + height + " I");
}
if (width != null) {
addFieldMapping("net/minecraft/client/renderer/texture/TextureAtlasSprite width I",
sprite.name + " " + width + " I");
}
if (minU != null) {
addFieldMapping("net/minecraft/client/renderer/texture/TextureAtlasSprite minU F",
sprite.name + " " + minU + " F");
}
if (maxU != null) {
addFieldMapping("net/minecraft/client/renderer/texture/TextureAtlasSprite maxU F",
sprite.name + " " + maxU + " F");
}
if (minV != null) {
addFieldMapping("net/minecraft/client/renderer/texture/TextureAtlasSprite minV F",
sprite.name + " " + minV + " F");
}
if (maxV != null) {
addFieldMapping("net/minecraft/client/renderer/texture/TextureAtlasSprite maxV F",
sprite.name + " " + maxV + " F");
}
MethodNode method;
// public String getIconName()
if ((method = findGetterMethod(sprite, iconName, "Ljava/lang/String;")) != null) {
addMethodMapping("net/minecraft/client/renderer/texture/TextureAtlasSprite getIconName ()Ljava/lang/String;",
sprite.name + " " + method.name + " " + method.desc);
}
// public float getMinU()
if ((method = findGetterMethod(sprite, minU, "F")) != null) {
addMethodMapping("net/minecraft/client/renderer/texture/TextureAtlasSprite getMinU ()F",
sprite.name + " " + method.name + " " + method.desc);
}
// public float getMinV()
if ((method = findGetterMethod(sprite, minV, "F")) != null) {
addMethodMapping("net/minecraft/client/renderer/texture/TextureAtlasSprite getMinV ()F",
sprite.name + " " + method.name + " " + method.desc);
}
// public float getMaxU()
if ((method = findGetterMethod(sprite, maxU, "F")) != null) {
addMethodMapping("net/minecraft/client/renderer/texture/TextureAtlasSprite getMaxU ()F",
sprite.name + " " + method.name + " " + method.desc);
}
// public float getMaxV()
if ((method = findGetterMethod(sprite, maxV, "F")) != null) {
addMethodMapping("net/minecraft/client/renderer/texture/TextureAtlasSprite getMaxV ()F",
sprite.name + " " + method.name + " " + method.desc);
}
// TODO - Other getters
// public float getInterpolatedU(double u)
// public float getInterpolatedV(double v)
List<MethodNode> methods = DynamicMappings.getMatchingMethods(sprite, null, "(D)F");
if (methods.size() == 2) {
FieldInsnNode fn1 = DynamicMappings.getNextInsnNodeOfType(methods.get(0).instructions.getFirst(), FieldInsnNode.class);
FieldInsnNode fn2 = DynamicMappings.getNextInsnNodeOfType(methods.get(1).instructions.getFirst(), FieldInsnNode.class);
if (fn1.owner.equals(sprite.name) && fn2.owner.equals(sprite.name)) {
MethodNode getInterpolatedU = null;
MethodNode getInterpolatedV = null;
if (fn1.name.equals(maxU) && fn2.name.equals(maxV)) { getInterpolatedU = methods.get(0); getInterpolatedV = methods.get(1); }
else if (fn1.name.equals(maxV) && fn2.name.equals(maxU)) { getInterpolatedU = methods.get(1); getInterpolatedV = methods.get(0); }
if (getInterpolatedU != null && getInterpolatedV != null) {
addMethodMapping("net/minecraft/client/renderer/texture/TextureAtlasSprite getInterpolatedU (D)F", sprite.name + " " + getInterpolatedU.name + " (D)F");
addMethodMapping("net/minecraft/client/renderer/texture/TextureAtlasSprite getInterpolatedV (D)F", sprite.name + " " + getInterpolatedV.name + " (D)F");
}
}
}
return true;
}
@Mapping(providesMethods={
"net/minecraft/block/Block getMixedBrightnessForBlock (Lnet/minecraft/block/state/IBlockState;Lnet/minecraft/world/IBlockAccess;Lnet/minecraft/util/BlockPos;)I",
"net/minecraft/block/Block getSelectedBoundingBox (Lnet/minecraft/block/state/IBlockState;Lnet/minecraft/world/World;Lnet/minecraft/util/BlockPos;)Lnet/minecraft/util/AxisAlignedBB;",
"net/minecraft/block/Block shouldSideBeRendered (Lnet/minecraft/block/state/IBlockState;Lnet/minecraft/world/IBlockAccess;Lnet/minecraft/util/BlockPos;Lnet/minecraft/util/EnumFacing;)Z",
"net/minecraft/block/Block randomDisplayTick (Lnet/minecraft/block/state/IBlockState;Lnet/minecraft/world/World;Lnet/minecraft/util/BlockPos;Ljava/util/Random;)V",
"net/minecraft/block/Block getSubBlocks (Lnet/minecraft/item/Item;Lnet/minecraft/creativetab/CreativeTabs;Lnet/minecraft/util/MCList;)V",
"net/minecraft/block/Block getCreativeTabToDisplayOn ()Lnet/minecraft/creativetab/CreativeTabs;",
"net/minecraft/block/Block getBlockLayer ()Lnet/minecraft/util/EnumWorldBlockLayer;",
//"net/minecraft/block/Block colorMultiplier (Lnet/minecraft/world/IBlockAccess;Lnet/minecraft/util/BlockPos;I)I"
"net/minecraft/block/Block isTranslucent (Lnet/minecraft/block/state/IBlockState;)Z",
"net/minecraft/block/Block getAmbientOcclusionLightValue (Lnet/minecraft/block/state/IBlockState;)F"
},
dependsMethods={
"net/minecraft/block/Block getCollisionBoundingBox (Lnet/minecraft/block/state/IBlockState;Lnet/minecraft/world/IBlockAccess;Lnet/minecraft/util/BlockPos;)Lnet/minecraft/util/AxisAlignedBB;"
},
dependsFields={
"net/minecraft/block/Block translucent Z"
},
depends={
"net/minecraft/block/Block",
"net/minecraft/world/IBlockAccess",
"net/minecraft/util/BlockPos",
"net/minecraft/block/state/IBlockState",
"net/minecraft/world/World",
"net/minecraft/util/AxisAlignedBB",
"net/minecraft/util/EnumFacing",
"net/minecraft/item/Item",
"net/minecraft/creativetab/CreativeTabs",
"net/minecraft/util/EnumWorldBlockLayer",
"net/minecraft/util/MCList"
})
public boolean processBlockClass()
{
ClassNode block = getClassNodeFromMapping("net/minecraft/block/Block");
ClassNode iBlockAccess = getClassNodeFromMapping("net/minecraft/world/IBlockAccess");
ClassNode blockPos = getClassNodeFromMapping("net/minecraft/util/BlockPos");
ClassNode iBlockState = getClassNodeFromMapping("net/minecraft/block/state/IBlockState");
ClassNode world = getClassNodeFromMapping("net/minecraft/world/World");
ClassNode aabb = getClassNodeFromMapping("net/minecraft/util/AxisAlignedBB");
ClassNode enumFacing = getClassNodeFromMapping("net/minecraft/util/EnumFacing");
ClassNode item = getClassNodeFromMapping("net/minecraft/item/Item");
ClassNode creativeTabs = getClassNodeFromMapping("net/minecraft/creativetab/CreativeTabs");
ClassNode enumWorldBlockLayer = getClassNodeFromMapping("net/minecraft/util/EnumWorldBlockLayer");
ClassNode mcList = getClassNodeFromMapping("net/minecraft/util/MCList");
if (!MeddleUtil.notNull(block, iBlockAccess, blockPos, world, aabb, enumFacing, item, creativeTabs,
enumWorldBlockLayer, mcList)) return false;
// public int getMixedBrightnessForBlock(IBlockState state, IBlockAccess worldIn, BlockPos pos)
List<MethodNode> methods = DynamicMappings.getMatchingMethods(block, null, DynamicMappings.assembleDescriptor("(", iBlockState, iBlockAccess, blockPos, ")I"));
if (methods.size() == 1) {
addMethodMapping("net/minecraft/block/Block getMixedBrightnessForBlock (Lnet/minecraft/block/state/IBlockState;Lnet/minecraft/world/IBlockAccess;Lnet/minecraft/util/BlockPos;)I",
block.name + " " + methods.get(0).name + " " + methods.get(0).desc);
}
//MethodNode getCollisionBoundingBox = getMethodNodeFromMapping(block, "net/minecraft/block/Block getCollisionBoundingBox (Lnet/minecraft/block/state/IBlockState;Lnet/minecraft/world/IBlockAccess;Lnet/minecraft/util/BlockPos;)Lnet/minecraft/util/AxisAlignedBB;");
// public AxisAlignedBB getSelectedBoundingBox(IBlockState state, World worldIn, BlockPos pos)
methods = getMatchingMethods(block, null, assembleDescriptor("(", iBlockState, world, blockPos, ")", aabb));
if (methods.size() == 1) { // && getCollisionBoundingBox != null) {
/*for (Iterator<MethodNode> it = methods.iterator(); it.hasNext();) {
MethodNode method = it.next();
if (method.name.equals(getCollisionBoundingBox.name)) it.remove();
}*/
if (methods.size() == 1) {
addMethodMapping("net/minecraft/block/Block getSelectedBoundingBox (Lnet/minecraft/block/state/IBlockState;Lnet/minecraft/world/World;Lnet/minecraft/util/BlockPos;)Lnet/minecraft/util/AxisAlignedBB;",
block.name + " " + methods.get(0).name + " " + methods.get(0).desc);
}
}
// public boolean shouldSideBeRendered(IBlockState param0, IBlockAccess param1, BlockPos param2, EnumFacing param3)
methods = getMatchingMethods(block, null, assembleDescriptor("(", iBlockState, iBlockAccess, blockPos, enumFacing, ")Z"));
if (methods.size() == 1) {
addMethodMapping("net/minecraft/block/Block shouldSideBeRendered (Lnet/minecraft/block/state/IBlockState;Lnet/minecraft/world/IBlockAccess;Lnet/minecraft/util/BlockPos;Lnet/minecraft/util/EnumFacing;)Z",
block.name + " " + methods.get(0).name + " " + methods.get(0).desc);
}
// public void randomDisplayTick(IBlockState param0, World param1, BlockPos param2, Random param3)
methods = getMatchingMethods(block, null, assembleDescriptor("(", iBlockState, world, blockPos, "Ljava/util/Random;)V"));
if (methods.size() == 1) {
addMethodMapping("net/minecraft/block/Block randomDisplayTick (Lnet/minecraft/block/state/IBlockState;Lnet/minecraft/world/World;Lnet/minecraft/util/BlockPos;Ljava/util/Random;)V",
block.name + " " + methods.get(0).name + " " + methods.get(0).desc);
}
// public void getSubBlocks(Item itemIn, CreativeTabs tab, List list)
methods = getMatchingMethods(block, null, assembleDescriptor("(", item, creativeTabs, mcList, ")V"));
if (methods.size() == 1) {
addMethodMapping("net/minecraft/block/Block getSubBlocks (Lnet/minecraft/item/Item;Lnet/minecraft/creativetab/CreativeTabs;Lnet/minecraft/util/MCList;)V",
block.name + " " + methods.get(0).name + " " + methods.get(0).desc);
}
// public CreativeTabs getCreativeTabToDisplayOn()
methods = getMatchingMethods(block, null, assembleDescriptor("()", creativeTabs));
if (methods.size() == 1) {
addMethodMapping("net/minecraft/block/Block getCreativeTabToDisplayOn ()Lnet/minecraft/creativetab/CreativeTabs;",
block.name + " " + methods.get(0).name + " " + methods.get(0).desc);
}
// public EnumWorldBlockLayer getBlockLayer()
methods = getMatchingMethods(block, null, "()L" + enumWorldBlockLayer.name + ";");
if (methods.size() == 1) {
addMethodMapping("net/minecraft/block/Block getBlockLayer ()Lnet/minecraft/util/EnumWorldBlockLayer;",
block.name + " " + methods.get(0).name + " " + methods.get(0).desc);
}
// Removed at 16w02a, moved to separate color override registry
// public int colorMultiplier(IBlockAccess worldIn, BlockPos pos, int renderPass)
/*methods = getMatchingMethods(block, null, assembleDescriptor("(", iBlockAccess, blockPos, "I)I"));
if (methods.size() == 1) {
addMethodMapping("net/minecraft/block/Block colorMultiplier (Lnet/minecraft/world/IBlockAccess;Lnet/minecraft/util/BlockPos;I)I",
block.name + " " + methods.get(0).name + " " + methods.get(0).desc);
}*/
// public boolean isTranslucent(IBlockState state)
FieldNode translucent_field = getFieldNodeFromMapping(block, "net/minecraft/block/Block translucent Z");
if (translucent_field != null) {
methods = getMatchingMethods(block, null, assembleDescriptor("(", iBlockState, ")Z"));
methods = filterMethodsUsingField(methods, block.name, translucent_field.name, translucent_field.desc);
if (methods.size() == 1) {
addMethodMapping("net/minecraft/block/Block isTranslucent (Lnet/minecraft/block/state/IBlockState;)Z",
block.name + " " + methods.get(0).name + " " + methods.get(0).desc);
}
}
// public float getAmbientOcclusionLightValue(IBlockState state)
methods = getMatchingMethods(block, null, assembleDescriptor("(", iBlockState, ")F"));
if (methods.size() == 1) {
List<Float> floats = getFloatsFromMethod(methods.get(0));
if (floats.size() == 1 && floats.get(0) == 0.2F) {
addMethodMapping("net/minecraft/block/Block getAmbientOcclusionLightValue (Lnet/minecraft/block/state/IBlockState;)F",
block.name + " " + methods.get(0).name + " " + methods.get(0).desc);
}
}
return true;
}
/*
* Methods removed for 16w02a, all are moved out of the Block class
* TODO - Locate ColorizerGrass again elsewhere, and identify new color override registry
*
@Mapping(provides="net/minecraft/world/ColorizerGrass",
providesMethods={
"net/minecraft/block/Block getBlockColor ()I",
"net/minecraft/block/Block getRenderColor (Lnet/minecraft/block/state/IBlockState;)I",
"net/minecraft/world/ColorizerGrass getGrassColor (DD)I"
},
depends={
"net/minecraft/block/Block",
"net/minecraft/block/BlockGrass",
"net/minecraft/block/state/IBlockState"
})
public boolean processBlockGrassClass()
{
ClassNode block = getClassNodeFromMapping("net/minecraft/block/Block");
ClassNode grass = getClassNodeFromMapping("net/minecraft/block/BlockGrass");
ClassNode iBlockState = getClassNodeFromMapping("net/minecraft/block/state/IBlockState");
if (!MeddleUtil.notNull(block, grass, iBlockState)) return false;
// public int getBlockColor()
List<MethodNode> methods = getMatchingMethods(grass, null, "()I");
if (methods.size() == 1) {
addMethodMapping("net/minecraft/block/Block getBlockColor ()I",
block.name + " " + methods.get(0).name + " " + methods.get(0).desc);
// ColorizerGrass.getGrassColor(D, D);
List<MethodInsnNode> nodes = getAllInsnNodesOfType(methods.get(0), MethodInsnNode.class);
if (nodes.size() == 1 && nodes.get(0).getOpcode() == Opcodes.INVOKESTATIC && nodes.get(0).desc.equals("(DD)I")) {
addClassMapping("net/minecraft/world/ColorizerGrass", nodes.get(0).owner);
addMethodMapping("net/minecraft/world/ColorizerGrass getGrassColor (DD)I",
nodes.get(0).owner + " " + nodes.get(0).name + " (DD)I");
}
}
// public int getRenderColor(IBlockState state)
methods = getMatchingMethods(grass, null, "(L" + iBlockState.name + ";)I");
for (Iterator<MethodNode> it = methods.iterator(); it.hasNext();) {
MethodNode method = it.next();
// Strip out getMetaFromState
if (matchOpcodeSequence(method.instructions.getFirst(), Opcodes.ICONST_0, Opcodes.IRETURN)) it.remove();
}
if (methods.size() == 1) {
addMethodMapping("net/minecraft/block/Block getRenderColor (Lnet/minecraft/block/state/IBlockState;)I",
block.name + " " + methods.get(0).name + " " + methods.get(0).desc);
}
return true;
}
*/
@Mapping(provides={
"net/minecraft/client/gui/GuiSlot",
"net/minecraft/client/gui/GuiListExtended",
"net/minecraft/client/gui/ServerSelectionList",
"net/minecraft/client/multiplayer/ServerList"
},
dependsMethods={
"net/minecraft/client/gui/GuiScreen initGui ()V"
},
depends={
"net/minecraft/client/gui/GuiMultiplayer",
"net/minecraft/client/Minecraft"
})
public boolean processGuiMultiplayerClass()
{
ClassNode guiMultiplayer = getClassNodeFromMapping("net/minecraft/client/gui/GuiMultiplayer");
ClassNode minecraft = getClassNodeFromMapping("net/minecraft/client/Minecraft");
if (!MeddleUtil.notNull(guiMultiplayer, minecraft)) return false;
MethodNode initGui = getMethodNodeFromMapping(guiMultiplayer, "net/minecraft/client/gui/GuiScreen initGui ()V");
if (initGui == null) return false;
String serverList = null;
List<TypeInsnNode> nodes = getAllInsnNodesOfType(initGui.instructions.getFirst(), TypeInsnNode.class);
for (TypeInsnNode node : nodes) {
if (node.desc.startsWith("java/")) continue;
if (serverList == null && searchConstantPoolForStrings(node.desc, "servers.dat", "servers", "Couldn\'t load server list")) {
addClassMapping("net/minecraft/client/multiplayer/ServerList", node.desc);
serverList = node.desc;
continue;
}
}
List<MethodInsnNode> miNodes = getAllInsnNodesOfType(initGui.instructions.getFirst(), MethodInsnNode.class);
for (Iterator<MethodInsnNode> it = miNodes.iterator(); it.hasNext(); ) {
MethodInsnNode mn = it.next();
if (!mn.name.equals("<init>") || !mn.desc.equals("(L" + guiMultiplayer.name + ";L" + minecraft.name + ";IIIII)V"))
it.remove();
}
ClassNode serverSelectionList = null;
if (miNodes.size() == 1) {
serverSelectionList = getClassNode(miNodes.get(0).owner);
if (serverSelectionList.superName.equals("java/lang/Object")) return false;
ClassNode guiListExtended = getClassNode(serverSelectionList.superName);
if (guiListExtended.superName.equals("java/lang/Object")) return false;
if ((guiListExtended.access & Opcodes.ACC_ABSTRACT) == 0) return false;
ClassNode guiSlot = getClassNode(guiListExtended.superName);
if ((guiSlot.access & Opcodes.ACC_ABSTRACT) == 0) return false;
if (guiSlot.superName.equals("java/lang/Object")) {
addClassMapping("net/minecraft/client/gui/ServerSelectionList", serverSelectionList.name);
addClassMapping("net/minecraft/client/gui/GuiListExtended", guiListExtended.name);
addClassMapping("net/minecraft/client/gui/GuiSlot", guiSlot.name);
}
else {
serverSelectionList = null;
guiListExtended = null;
guiSlot = null;
}
}
return true;
}
@Mapping(provides={
"net/minecraft/client/gui/GuiListExtended$IGuiListEntry"
},
providesMethods={
"net/minecraft/client/gui/GuiSlot elementClicked (IZII)V",
"net/minecraft/client/gui/GuiSlot isSelected (I)Z",
"net/minecraft/client/gui/GuiSlot drawBackground ()V",
"net/minecraft/client/gui/GuiSlot drawSlot (IIIIII)V",
"net/minecraft/client/gui/GuiSlot func_178040_a (III)V",
"net/minecraft/client/gui/GuiListExtended getListEntry (I)Lnet/minecraft/client/gui/GuiListExtended$IGuiListEntry;",
"net/minecraft/client/gui/GuiListExtended mouseClicked (III)Z",
"net/minecraft/client/gui/GuiListExtended mouseReleased (III)Z"
},
depends={
"net/minecraft/client/gui/GuiListExtended",
"net/minecraft/client/gui/GuiSlot"
})
public boolean processGuiListExtendedClass()
{
ClassNode guiListExtended = getClassNodeFromMapping("net/minecraft/client/gui/GuiListExtended");
ClassNode guiSlot = getClassNodeFromMapping("net/minecraft/client/gui/GuiSlot");
if (!MeddleUtil.notNull(guiListExtended, guiSlot)) return false;
// protected void elementClicked(int slotIndex, boolean isDoubleClick, int mouseX, int mouseY)
List<MethodNode> methods = getMatchingMethods(guiListExtended, null, "(IZII)V");
if (methods.size() == 1) {
addMethodMapping("net/minecraft/client/gui/GuiSlot elementClicked (IZII)V",
guiSlot.name + " " + methods.get(0).name + " " + methods.get(0).desc);
}
// protected boolean isSelected(int slotIndex)
methods = getMatchingMethods(guiListExtended, null, "(I)Z");
if (methods.size() == 1) {
addMethodMapping("net/minecraft/client/gui/GuiSlot isSelected (I)Z",
guiSlot.name + " " + methods.get(0).name + " " + methods.get(0).desc);
}
// protected void drawBackground()
methods = getMatchingMethods(guiListExtended, null, "()V");
if (methods.size() == 1) {
addMethodMapping("net/minecraft/client/gui/GuiSlot drawBackground ()V",
guiSlot.name + " " + methods.get(0).name + " " + methods.get(0).desc);
}
// protected void drawSlot(int entryID, int p_180791_2_, int p_180791_3_, int p_180791_4_, int mouseXIn, int mouseYIn)
methods = getMatchingMethods(guiListExtended, null, "(IIIIII)V");
if (methods.size() == 1) {
addMethodMapping("net/minecraft/client/gui/GuiSlot drawSlot (IIIIII)V",
guiSlot.name + " " + methods.get(0).name + " " + methods.get(0).desc);
}
// protected void func_178040_a(int p_178040_1_, int p_178040_2_, int p_178040_3_)
methods = getMatchingMethods(guiListExtended, null, "(III)V");
if (methods.size() == 1) {
addMethodMapping("net/minecraft/client/gui/GuiSlot func_178040_a (III)V",
guiSlot.name + " " + methods.get(0).name + " " + methods.get(0).desc);
}
// public abstract GuiListExtended.IGuiListEntry getListEntry(int p_148180_1_);
methods.clear();
for (MethodNode mn : guiListExtended.methods) {
if (mn.desc.startsWith("(I)L")) methods.add(mn);
}
ClassNode iGuiListEntry = null;
if (methods.size() == 1) {
Type t = Type.getMethodType(methods.get(0).desc);
Type returnType = t.getReturnType();
iGuiListEntry = getClassNode(returnType.getClassName());
if (iGuiListEntry != null && (iGuiListEntry.access & Opcodes.ACC_INTERFACE) != 0) {
addClassMapping("net/minecraft/client/gui/GuiListExtended$IGuiListEntry", iGuiListEntry.name);
addMethodMapping("net/minecraft/client/gui/GuiListExtended getListEntry (I)Lnet/minecraft/client/gui/GuiListExtended$IGuiListEntry;",
guiListExtended.name + " " + methods.get(0).name + " " + methods.get(0).desc);
}
else iGuiListEntry = null;
}
// public boolean mouseClicked(int mouseX, int mouseY, int mouseEvent)
// public boolean mouseReleased(int p_148181_1_, int p_148181_2_, int p_148181_3_)
methods = getMatchingMethods(guiListExtended, null, "(III)Z");
if (methods.size() == 2) {
List<String> mousePressed = new ArrayList<>();
List<String> mouseReleased = new ArrayList<>();
List<MethodInsnNode> mnList1 = getAllInsnNodesOfType(methods.get(0).instructions.getFirst(), MethodInsnNode.class);
List<MethodInsnNode> mnList2 = getAllInsnNodesOfType(methods.get(1).instructions.getFirst(), MethodInsnNode.class);
for (MethodInsnNode mn : mnList1) {
if (mn.desc.equals("(IIIIII)Z")) { mousePressed.add(methods.get(0).name); continue; }
else if (mn.desc.equals("(IIIIII)V")) { mouseReleased.add(methods.get(0).name); continue; }
}
for (MethodInsnNode mn : mnList2) {
if (mn.desc.equals("(IIIIII)Z")) { mousePressed.add(methods.get(1).name); continue; }
else if (mn.desc.equals("(IIIIII)V")) { mouseReleased.add(methods.get(1).name); continue; }
}
if (mousePressed.size() == 1 && mouseReleased.size() == 1) {
addMethodMapping("net/minecraft/client/gui/GuiListExtended mouseClicked (III)Z", guiListExtended.name + " " + mousePressed.get(0) + " (III)Z");
addMethodMapping("net/minecraft/client/gui/GuiListExtended mouseReleased (III)Z", guiListExtended.name + " " + mouseReleased.get(0) + " (III)Z");
}
}
return true;
}
public static MethodNode findGetterMethod(ClassNode cn, String fieldName, String fieldDesc)
{
int returnOpcode = Opcodes.ARETURN;
if (fieldDesc.equals("I")) returnOpcode = Opcodes.IRETURN;
else if (fieldDesc.equals("F")) returnOpcode = Opcodes.FRETURN;
else if (fieldDesc.equals("D")) returnOpcode = Opcodes.DRETURN;
else if (fieldDesc.equals("J")) returnOpcode = Opcodes.LRETURN;
List<MethodNode> methods = new ArrayList<>();
for (MethodNode method : cn.methods) {
AbstractInsnNode[] list = DynamicMappings.getOpcodeSequenceArray(method.instructions.getFirst(), Opcodes.ALOAD, Opcodes.GETFIELD, returnOpcode);
if (list == null) continue;
FieldInsnNode fn = (FieldInsnNode)list[1];
if (fn.owner.equals(cn.name) && fn.name.equals(fieldName)) methods.add(method);
}
if (methods.size() == 1) return methods.get(0);
else return null;
}
public static void main(String[] args)
{
DynamicMappings.main(args);
/*DynamicMappings.generateClassMappings();
generateClassMappings();
String[] sortedKeys = DynamicMappings.classMappings.keySet().toArray(new String[0]);
Arrays.sort(sortedKeys);
for (String key : sortedKeys) {
String className = DynamicMappings.getClassMapping(key);
System.out.println(key + " -> " + (className != null ? className : "[MISSING]"));
}*/
}
@Mapping(providesFields={
"net/minecraft/util/EnumWorldBlockLayer SOLID Lnet/minecraft/util/EnumWorldBlockLayer;",
"net/minecraft/util/EnumWorldBlockLayer CUTOUT_MIPPED Lnet/minecraft/util/EnumWorldBlockLayer;",
"net/minecraft/util/EnumWorldBlockLayer CUTOUT Lnet/minecraft/util/EnumWorldBlockLayer;",
"net/minecraft/util/EnumWorldBlockLayer TRANSLUCENT Lnet/minecraft/util/EnumWorldBlockLayer;"
},
depends={
"net/minecraft/util/EnumWorldBlockLayer"
})
public boolean processEnumWorldBlockLayerClass()
{
ClassNode blockLayer = getClassNodeFromMapping("net/minecraft/util/EnumWorldBlockLayer");
if (blockLayer == null) return false;
MethodNode clinit = getMethodNode(blockLayer, "--- <clinit> ()V");
if (clinit != null) {
String name = null;
for (AbstractInsnNode insn = clinit.instructions.getFirst(); insn != null; insn = insn.getNext()) {
String temp = getLdcString(insn);
if (name == null && temp != null) { name = temp; continue; }
if (name != null && insn.getOpcode() == Opcodes.PUTSTATIC) {
FieldInsnNode fn = (FieldInsnNode)insn;
if (!fn.desc.equals("L" + blockLayer.name + ";")) continue;
addFieldMapping("net/minecraft/util/EnumWorldBlockLayer " + name + " Lnet/minecraft/util/EnumWorldBlockLayer;",
blockLayer.name + " " + fn.name + " " + fn.desc);
name = null;
}
}
}
return true;
}
@Mapping(depends={
"net/minecraft/client/renderer/entity/RenderItem",
"net/minecraft/init/Items",
"net/minecraft/item/ItemStack"
},
providesMethods={
"net/minecraft/client/renderer/color/IItemColor getItemColor (Lnet/minecraft/item/ItemStack;I)I"
},
provides={
"net/minecraft/client/renderer/texture/TextureManager",
//TODO - "net/minecraft/client/renderer/block/model/ModelManager",
"net/minecraft/client/renderer/color/ItemColors",
"net/minecraft/client/renderer/color/IItemColor"
}
)
public boolean processRenderItemClass()
{
ClassNode renderItem = getClassNodeFromMapping("net/minecraft/client/renderer/entity/RenderItem");
ClassNode items = getClassNodeFromMapping("net/minecraft/init/Items");
ClassNode itemStack = getClassNodeFromMapping("net/minecraft/item/ItemStack");
if (renderItem == null || items == null || itemStack == null) return false;
List<MethodNode> methods = getMatchingMethods(renderItem, "<init>", null);
if (methods.size() == 1) {
Type t = Type.getMethodType(methods.get(0).desc);
Type[] args = t.getArgumentTypes();
if (args.length == 3) {
String textureManagerName = args[0].getClassName();
String modelManagerName = args[1].getClassName();
String itemColorsName = args[2].getClassName();
if (searchConstantPoolForStrings(textureManagerName, "Failed to load texture: {}", "Registering texture")) {
addClassMapping("net/minecraft/client/renderer/texture/TextureManager", textureManagerName);
}
if (searchConstantPoolForClasses(itemColorsName, items.name)) {
ClassNode itemColors = getClassNode(itemColorsName);
String descriptor = assembleDescriptor("(", itemStack, "I)I");
methods = getMatchingMethods(itemColors, null, descriptor);
if (methods.size() == 1) {
// Look for methods invoked with the same signature as the method we're in
List<MethodInsnNode> mns = getAllInsnNodesOfType(methods.get(0), MethodInsnNode.class);
for (Iterator<MethodInsnNode> it = mns.iterator(); it.hasNext();) {
MethodInsnNode mn = it.next();
if (!mn.desc.equals(descriptor)) it.remove();
}
if (mns.size() == 1) {
ClassNode iitemColor = getClassNode(mns.get(0).owner);
if ((iitemColor.access & Opcodes.ACC_INTERFACE) != 0 && iitemColor.methods.size() == 1) {
addClassMapping("net/minecraft/client/renderer/color/IItemColor", iitemColor.name);
addClassMapping("net/minecraft/client/renderer/color/ItemColors", itemColorsName);
addMethodMapping("net/minecraft/client/renderer/color/IItemColor getItemColor (Lnet/minecraft/item/ItemStack;I)I",
iitemColor.name + " " + iitemColor.methods.get(0).name + " " + descriptor);
}
}
}
}
}
}
return true;
}
@Mapping(depends={
"net/minecraft/client/renderer/color/ItemColors",
"net/minecraft/client/renderer/color/IItemColor",
"net/minecraft/item/ItemStack",
"net/minecraft/item/Item",
"net/minecraft/block/Block"
},
providesMethods={
"net/minecraft/client/renderer/color/ItemColors getItemColor (Lnet/minecraft/item/ItemStack;I)I",
"net/minecraft/client/renderer/color/ItemColors registerBlockColor (Lnet/minecraft/client/renderer/color/IItemColor;[Lnet/minecraft/block/Block;)V",
"net/minecraft/client/renderer/color/ItemColors registerItemColor (Lnet/minecraft/client/renderer/color/IItemColor;[Lnet/minecraft/item/Item;)V"
}
)
public boolean processItemColorClass()
{
ClassNode itemColors = getClassNodeFromMapping("net/minecraft/client/renderer/color/ItemColors");
ClassNode iitemColor = getClassNodeFromMapping("net/minecraft/client/renderer/color/IItemColor");
ClassNode itemStack = getClassNodeFromMapping("net/minecraft/item/ItemStack");
ClassNode item = getClassNodeFromMapping("net/minecraft/item/Item");
ClassNode block = getClassNodeFromMapping("net/minecraft/block/Block");
if (!MeddleUtil.notNull(itemColors, iitemColor, itemStack, item, block)) return false;
List<MethodNode> methods = getMatchingMethods(itemColors, null, assembleDescriptor("(", itemStack, "I)I"));
if (methods.size() == 1) {
addMethodMapping("net/minecraft/client/renderer/color/ItemColors getItemColor (Lnet/minecraft/item/ItemStack;I)I",
itemColors.name + " " + methods.get(0).name + " " + methods.get(0).desc);
}
methods = getMatchingMethods(itemColors, null, assembleDescriptor("(", iitemColor, "[", block, ")V"));
if (methods.size() == 1) {
addMethodMapping("net/minecraft/client/renderer/color/ItemColors registerBlockColor (Lnet/minecraft/client/renderer/color/IItemColor;[Lnet/minecraft/block/Block;)V",
itemColors.name + " " + methods.get(0).name + " " + methods.get(0).desc);
}
methods = getMatchingMethods(itemColors, null, assembleDescriptor("(", iitemColor, "[", item, ")V"));
if (methods.size() == 1) {
addMethodMapping("net/minecraft/client/renderer/color/ItemColors registerItemColor (Lnet/minecraft/client/renderer/color/IItemColor;[Lnet/minecraft/item/Item;)V",
itemColors.name + " " + methods.get(0).name + " " + methods.get(0).desc);
}
return true;
}
@Mapping(depends = "net/minecraft/client/gui/GuiIngame",
provides = "net/minecraft/client/gui/ScaledResolution",
providesMethods = "net/minecraft/client/gui/GuiIngame renderPotionEffects (Lnet/minecraft/client/gui/ScaledResolution;)V")
public boolean processGuiIngameClass()
{
ClassNode node = getClassNodeFromMapping("net/minecraft/client/gui/GuiIngame");
if(!MeddleUtil.notNull(node)) return false;
//ScaledResolution
List<MethodNode> methods = DynamicMappings.getMatchingMethods(node, Opcodes.ACC_PROTECTED, Type.VOID, Type.OBJECT);
if(methods.size() == 1){
String scaledResolution = Type.getArgumentTypes(methods.get(0).desc)[0].getClassName();
addClassMapping("net/minecraft/client/gui/ScaledResolution", scaledResolution);
addMethodMapping("net/minecraft/client/gui/GuiIngame renderPotionEffects (Lnet/minecraft/client/gui/ScaledResolution;)V", node.name + " " + methods.get(0).name + " " + methods.get(0).desc);
}
return true;
}
}