TileEntitySignRendererMod(Mod mod) { super(mod); RenderUtilsMod.setup(this); final FieldRef sign; final MethodRef colorizeSignText = new MethodRef(MCPatcherUtils.COLORIZE_WORLD_CLASS, "colorizeSignText", "()I"); if (ResourceLocationMod.haveClass()) { sign = new FieldRef(getDeobfClass(), "sign", "LResourceLocation;"); addClassSignature(new ResourceLocationSignature(this, sign, "textures/entity/sign.png")); } else { sign = null; addClassSignature(new ConstSignature("/item/sign.png")); } addPatch( new BytecodePatch() { { addPreMatchSignature( new BytecodeSignature() { @Override public String getMatchExpression() { return buildExpression( sign == null ? push("/item/sign.png") : reference(GETSTATIC, sign)); } }); } @Override public String getDescription() { return "override sign text color"; } @Override public String getMatchExpression() { return buildExpression( push(0), RenderUtilsMod.glDepthMask(this), push(0), capture(anyISTORE)); } @Override public byte[] getReplacementBytes() { return buildCode( push(0), RenderUtilsMod.glDepthMask(this), reference(INVOKESTATIC, colorizeSignText), getCaptureGroup(1)); } }); }
EntityRendererMod(Mod mod) { super(mod); final MethodRef updateLightmap = new MethodRef(getDeobfClass(), "updateLightmap", "(F)V"); final FieldRef mc = new FieldRef(getDeobfClass(), "mc", "LMinecraft;"); final MethodRef updateFogColor = new MethodRef(getDeobfClass(), "updateFogColor", "(F)V"); final FieldRef fogColorRed = new FieldRef(getDeobfClass(), "fogColorRed", "F"); final FieldRef fogColorGreen = new FieldRef(getDeobfClass(), "fogColorGreen", "F"); final FieldRef fogColorBlue = new FieldRef(getDeobfClass(), "fogColorBlue", "F"); final FieldRef lightmapColors = new FieldRef(getDeobfClass(), "lightmapColors", "[I"); final FieldRef lightmapTexture = new FieldRef( getDeobfClass(), "lightmapTexture", ResourceLocationMod.select("I", "LDynamicTexture;")); final FieldRef needLightmapUpdate = new FieldRef(getDeobfClass(), "needLightmapUpdate", "Z"); final FieldRef renderEngine = new FieldRef("Minecraft", "renderEngine", "LRenderEngine;"); final MethodRef createTextureFromBytes = new MethodRef("RenderEngine", "createTextureFromBytes", "([IIII)V"); final FieldRef thePlayer = new FieldRef("Minecraft", "thePlayer", "LEntityClientPlayerMP;"); final FieldRef nightVision = new FieldRef("Potion", "nightVision", "LPotion;"); final MethodRef isPotionActive = new MethodRef("EntityClientPlayerMP", "isPotionActive", "(LPotion;)Z"); final String nvEntity = getMinecraftVersion().compareTo("14w06a") >= 0 ? "LEntityLivingBase;" : "LEntityPlayer;"; final MethodRef getNightVisionStrength1 = new MethodRef(getDeobfClass(), "getNightVisionStrength1", "(" + nvEntity + "F)F"); final MethodRef getNightVisionStrength = new MethodRef(getDeobfClass(), "getNightVisionStrength", "(F)F"); final MethodRef reloadTexture = new MethodRef("DynamicTexture", "reload", "()V"); final MethodRef computeLightmap = new MethodRef( MCPatcherUtils.LIGHTMAP_CLASS, "computeLightmap", "(LEntityRenderer;LWorld;[IF)Z"); final MethodRef computeUnderwaterColor = new MethodRef(MCPatcherUtils.COLORIZE_WORLD_CLASS, "computeUnderwaterColor", "()Z"); final MethodRef computeUnderlavaColor = new MethodRef(MCPatcherUtils.COLORIZE_WORLD_CLASS, "computeUnderlavaColor", "()Z"); addClassSignature(new ConstSignature("ambient.weather.rain")); addClassSignature( new BytecodeSignature() { { setMethod(updateLightmap); addXref(1, new MethodRef("World", "getSunAngle", "(F)F")); addXref(3, new FieldRef("World", "worldProvider", "LWorldProvider;")); addXref(5, new FieldRef(getDeobfClass(), "torchFlickerX", "F")); addXref(6, com.prupe.mcpatcher.basemod.WorldMod.getLightningFlashRef()); addXref(7, com.prupe.mcpatcher.basemod.WorldProviderMod.getWorldTypeRef()); addXref(8, mc); addXref(9, new FieldRef("Minecraft", "gameSettings", "LGameSettings;")); addXref(10, new FieldRef("GameSettings", "gammaSetting", "F")); } @Override public String getMatchExpression() { return buildExpression( // sun = world.getSunAngle(1.0f) * 0.95f + 0.05f; ALOAD_2, push(1.0f), captureReference(INVOKEVIRTUAL), optional(build(anyFSTORE, anyFLOAD)), // 1.8.1-pre1 push(0.95f), FMUL, push(0.05f), FADD, FSTORE, capture(any()), // ... (1.8.1-pre1+) any(0, 20), // older: lightsun = world.worldProvider.lightBrightnessTable[i / 16] * sun; // 14w02a+: lightsun = world.worldProvider.getLightBrightnessTable()[i / 16] * // sun; ALOAD_2, captureReference(GETFIELD), anyReference(GETFIELD, INVOKEVIRTUAL), capture(anyILOAD), push(16), IDIV, FALOAD, FLOAD, backReference(2), FMUL, anyFSTORE, // older: lighttorch = world.worldProvider.lightBrightnessTable[i % 16] * // (torchFlickerX * 0.1f + 1.5f); // 14w02a+: lighttorch = world.worldProvider.getLightBrightnessTable()[i % 16] * // (torchFlickerX * 0.1f + 1.5f); any(0, 20), backReference(4), push(16), IREM, FALOAD, ALOAD_0, captureReference(GETFIELD), // ... any(0, 30), // older: if (world.lightningFlash > 0) // 14w02a+: if (world.getLightningFlash() > 0) ALOAD_2, captureReference(com.prupe.mcpatcher.basemod.WorldMod.getLightningFlashOpcode()), IFLE, any(2), // ... any(0, 300), // older: if (world.worldProvider.worldType == 1) { // 14w02a+: if (world.worldProvider.getWorldType() == 1) { ALOAD_2, backReference(3), captureReference( com.prupe.mcpatcher.basemod.WorldProviderMod.getWorldTypeOpcode()), push(1), IF_ICMPNE, any(2), // ... any(0, 200), // gamma = mc.gameSettings.gammaSetting; ALOAD_0, captureReference(GETFIELD), captureReference(GETFIELD), captureReference(GETFIELD), anyFSTORE, // ... any(0, 300), ResourceLocationMod.haveClass() ? getSubExpression16(10) : getSubExpression15(10), RETURN); } private String getSubExpression15(int xref) { addXref(xref + 1, renderEngine); addXref(xref + 2, lightmapColors); addXref(xref + 3, lightmapTexture); addXref(xref + 4, createTextureFromBytes); return buildExpression( // this.mc.renderEngine.createTextureFromBytes(this.lightmapColors, 16, 16, // this.lightmapTexture); ALOAD_0, backReference(xref - 2), captureReference(GETFIELD), ALOAD_0, captureReference(GETFIELD), push(16), push(16), ALOAD_0, captureReference(GETFIELD), captureReference(INVOKEVIRTUAL)); } private String getSubExpression16(int xref) { addXref(xref + 1, lightmapColors); addXref(xref + 2, lightmapTexture); addXref(xref + 3, reloadTexture); addXref(xref + 4, needLightmapUpdate); return buildExpression( // this.lightmapColors[i] = ...; ALOAD_0, captureReference(GETFIELD), any(0, 50), IASTORE, // ... any(0, 20), // this.lightmapTexture.load(); // this.needLightmapUpdate = false; ALOAD_0, captureReference(GETFIELD), captureReference(INVOKEVIRTUAL), ALOAD_0, push(0), captureReference(PUTFIELD), // ... any(0, 20)); } }); addClassSignature( new BytecodeSignature() { @Override public String getMatchExpression() { return buildExpression( // fogColorRed = 0.02f; ALOAD_0, push(0.02f), capture( optional( build( // 13w16a+ anyFLOAD, FADD))), captureReference(PUTFIELD), // fogColorGreen = 0.02f; ALOAD_0, push(0.02f), backReference(1), captureReference(PUTFIELD), // fogColorBlue = 0.2f; ALOAD_0, push(0.2f), backReference(1), captureReference(PUTFIELD)); } }.setMethod(updateFogColor) .addXref(2, fogColorRed) .addXref(3, fogColorGreen) .addXref(4, fogColorBlue)); addClassSignature( new BytecodeSignature() { @Override public String getMatchExpression() { return buildExpression( // if (mc.thePlayer.isPotionActive(Potion.nightVision)) { capture( build( ALOAD_0, captureReference(GETFIELD), captureReference(GETFIELD), captureReference(GETSTATIC), captureReference(INVOKEVIRTUAL))), IFEQ, any(2), // var16 = getNightVisionStrength1(mc.thePlayer, var1); capture( build( ALOAD_0, ALOAD_0, backReference(2), backReference(3), FLOAD_1, captureReference(INVOKESPECIAL))), FSTORE, any()); } }.setMethod(updateLightmap) .addXref(2, mc) .addXref(3, thePlayer) .addXref(4, nightVision) .addXref(5, isPotionActive) .addXref(7, getNightVisionStrength1)); addPatch( new AddMethodPatch(getNightVisionStrength) { @Override public byte[] generateMethod() { return buildCode( ALOAD_0, reference(GETFIELD, mc), reference(GETFIELD, thePlayer), reference(GETSTATIC, nightVision), reference(INVOKEVIRTUAL, isPotionActive), IFEQ, branch("A"), ALOAD_0, ALOAD_0, reference(GETFIELD, mc), reference(GETFIELD, thePlayer), FLOAD_1, reference(INVOKESPECIAL, getNightVisionStrength1), FRETURN, label("A"), push(0.0f), FRETURN); } }); addPatch(new MakeMemberPublicPatch(new FieldRef(getDeobfClass(), "torchFlickerX", "F"))); addPatch( new BytecodePatch() { { setInsertAfter(true); targetMethod(updateLightmap); } @Override public String getDescription() { return "override lightmap"; } @Override public String getMatchExpression() { return buildExpression(ASTORE_2); } @Override public byte[] getReplacementBytes() { return buildCode( // if (Lightmap.computeLightmap(this, world, this.lightmapColors, partialTick)) { ALOAD_0, ALOAD_2, ALOAD_0, reference(GETFIELD, lightmapColors), FLOAD_1, reference(INVOKESTATIC, computeLightmap), IFEQ, branch("A"), ResourceLocationMod.haveClass() ? loadTexture16() : loadTexture15(), // return; RETURN, // } label("A")); } private byte[] loadTexture15() { return buildCode( // this.mc.renderEngine.createTextureFromBytes(this.lightmapColors, 16, 16, // this.lightmapTexture); ALOAD_0, reference(GETFIELD, mc), reference(GETFIELD, renderEngine), ALOAD_0, reference(GETFIELD, lightmapColors), push(16), push(16), ALOAD_0, reference(GETFIELD, lightmapTexture), reference(INVOKEVIRTUAL, createTextureFromBytes)); } private byte[] loadTexture16() { return buildCode( // this.lightmapTexture.load(); // this.needLightmapUpdate = false; ALOAD_0, reference(GETFIELD, lightmapTexture), reference(INVOKEVIRTUAL, reloadTexture), ALOAD_0, push(0), reference(PUTFIELD, needLightmapUpdate)); } }); addPatch( new BytecodePatch() { { setInsertAfter(true); targetMethod(updateFogColor); } @Override public String getDescription() { return "override underwater ambient color"; } @Override public String getMatchExpression() { return buildExpression( // fogColorRed = 0.02f; ALOAD_0, push(0.02f), capture( optional( build( // 13w16a+ anyFLOAD, FADD))), reference(PUTFIELD, fogColorRed), // fogColorGreen = 0.02f; ALOAD_0, push(0.02f), backReference(1), reference(PUTFIELD, fogColorGreen), // fogColorBlue = 0.2f; ALOAD_0, push(0.2f), backReference(1), reference(PUTFIELD, fogColorBlue)); } @Override public byte[] getReplacementBytes() { return buildCode( // if (ColorizeWorld.computeUnderwaterColor()) { reference(INVOKESTATIC, computeUnderwaterColor), IFEQ, branch("A"), // fogColorRed = Colorizer.setColor[0]; ALOAD_0, reference(GETSTATIC, setColor), push(0), FALOAD, getCaptureGroup(1), reference(PUTFIELD, fogColorRed), // fogColorGreen = Colorizer.setColor[1]; ALOAD_0, reference(GETSTATIC, setColor), push(1), FALOAD, getCaptureGroup(1), reference(PUTFIELD, fogColorGreen), // fogColorBlue = Colorizer.setColor[2]; ALOAD_0, reference(GETSTATIC, setColor), push(2), FALOAD, getCaptureGroup(1), reference(PUTFIELD, fogColorBlue), // } label("A")); } }); addPatch( new BytecodePatch() { { setInsertAfter(true); targetMethod(updateFogColor); } @Override public String getDescription() { return "override underlava ambient color"; } @Override public String getMatchExpression() { return buildExpression( // this.fogColorRed = 0.6f; ALOAD_0, push(0.6f), reference(PUTFIELD, fogColorRed), // this.fogColorGreen = 0.1f; ALOAD_0, push(0.1f), reference(PUTFIELD, fogColorGreen), // this.fogColorBlue = 0.0f; ALOAD_0, push(0.0f), reference(PUTFIELD, fogColorBlue)); } @Override public byte[] getReplacementBytes() { return buildCode( // if (ColorizeWorld.computeUnderlavaColor()) { reference(INVOKESTATIC, computeUnderlavaColor), IFEQ, branch("A"), // fogColorRed = Colorizer.setColor[0]; ALOAD_0, reference(GETSTATIC, setColor), push(0), FALOAD, reference(PUTFIELD, fogColorRed), // fogColorGreen = Colorizer.setColor[1]; ALOAD_0, reference(GETSTATIC, setColor), push(1), FALOAD, reference(PUTFIELD, fogColorGreen), // fogColorBlue = Colorizer.setColor[2]; ALOAD_0, reference(GETSTATIC, setColor), push(2), FALOAD, reference(PUTFIELD, fogColorBlue), // } label("A")); } }); }
RenderGlobalMod(Mod mod) { super(mod); final FieldRef clouds; final FieldRef mc = new FieldRef(getDeobfClass(), "mc", "LMinecraft;"); final FieldRef gameSettings = new FieldRef("Minecraft", "gameSettings", "LGameSettings;"); final JavaRef fancyGraphics; final int fancyGraphicsOp; final String fancyGraphicsIf; final MethodRef drawFancyClouds; if (getMinecraftVersion().compareTo("1.8.1-pre4") < 0) { fancyGraphics = new FieldRef("GameSettings", "fancyGraphics", "Z"); fancyGraphicsOp = GETFIELD; fancyGraphicsIf = buildExpression(IFEQ, any(2)); drawFancyClouds = new MethodRef(MCPatcherUtils.COLORIZE_WORLD_CLASS, "drawFancyClouds", "(Z)Z"); } else { fancyGraphics = new MethodRef("GameSettings", "fancyGraphics", "()I"); fancyGraphicsOp = INVOKEVIRTUAL; fancyGraphicsIf = buildExpression(ICONST_2, IF_ICMPNE_or_IF_ICMPEQ, any(2)); drawFancyClouds = new MethodRef(MCPatcherUtils.COLORIZE_WORLD_CLASS, "drawFancyClouds", "(I)I"); } final boolean intParam = getMinecraftVersion().compareTo("14w25a") >= 0; final MethodRef renderClouds = new MethodRef(getDeobfClass(), "renderClouds", "(F" + (intParam ? "I" : "") + ")V"); final MethodRef renderCloudsFancy = new MethodRef(getDeobfClass(), "renderCloudsFancy", renderClouds.getType()); final FieldRef endSkyColor = new FieldRef(MCPatcherUtils.COLORIZE_WORLD_CLASS, "endSkyColor", "I"); RenderUtilsMod.setup(this); if (ResourceLocationMod.haveClass()) { clouds = new FieldRef(getDeobfClass(), "clouds", "LResourceLocation;"); addClassSignature( new ResourceLocationSignature(this, clouds, "textures/environment/clouds.png")); } else { addClassSignature(new ConstSignature("/environment/clouds.png")); clouds = null; } addClassSignature( new BytecodeSignature() { { setMethod(renderClouds); addXref(1, mc); addXref(2, gameSettings); addXref(3, fancyGraphics); addXref(4, renderCloudsFancy); if (clouds != null) { addXref(5, clouds); } } @Override public String getMatchExpression() { return buildExpression( // 1.8.1-pre4+: if (mc.gameSettings.fancyGraphics() == 2) { // earlier: if (mc.gameSettings.fancyGraphics) { ALOAD_0, captureReference(GETFIELD), captureReference(GETFIELD), captureReference(fancyGraphicsOp), fancyGraphicsIf, // this.renderCloudsFancy(...); ALOAD_0, FLOAD_1, intParam ? build(ILOAD_2) : "", captureReference(INVOKESPECIAL, INVOKEVIRTUAL), or(build(GOTO, any(2)), build(RETURN)), // ... any(0, 150), // ...(RenderGlobal.clouds); // ...("/environment/clouds.png"); clouds == null ? push("/environment/clouds.png") : captureReference(GETSTATIC)); } }); addPatch( new BytecodePatch() { @Override public String getDescription() { return "override cloud type"; } @Override public String getMatchExpression() { return buildExpression( capture( build( ALOAD_0, reference(GETFIELD, mc), reference(GETFIELD, gameSettings), reference(fancyGraphicsOp, fancyGraphics))), capture(fancyGraphicsIf)); } @Override public byte[] getReplacementBytes() { return buildCode( getCaptureGroup(1), reference(INVOKESTATIC, drawFancyClouds), getCaptureGroup(2)); } }.targetMethod(renderClouds)); if (TessellatorMod.haveVertexFormatClass()) { addPatch( new BytecodePatch() { @Override public String getDescription() { return "override end sky color"; } @Override public String getMatchExpression() { return buildExpression( // 40, 40, 40, 255 push(40), push(40), push(40), push(255)); } @Override public byte[] getReplacementBytes() { return buildCode( // (ColorizeWorld.endSkyColor >> 16) & 0xff reference(GETSTATIC, endSkyColor), push(16), ISHR, push(0xff), IAND, // (ColorizeWorld.endSkyColor >> 8) & 0xff reference(GETSTATIC, endSkyColor), push(8), ISHR, push(0xff), IAND, // ColorizeWorld.endSkyColor & 0xff reference(GETSTATIC, endSkyColor), push(0xff), IAND, // 255 push(255)); } }); } else { addPatch( new BytecodePatch() { @Override public String getDescription() { return "override end sky color"; } @Override public String getMatchExpression() { return buildExpression( or( build(push(0x181818)), // pre-12w23a build(push(0x282828)) // 12w23a+ )); } @Override public byte[] getReplacementBytes() { return buildCode(reference(GETSTATIC, endSkyColor)); } }); } }