package net.zhuoweizhang.mcpelauncher.patch; import java.io.*; import java.nio.*; import com.mojang.minecraftpe.MainActivity; import net.zhuoweizhang.mcpelauncher.MaraudersMap; import net.zhuoweizhang.mcpelauncher.MinecraftVersion; public final class PatchUtils { public static MinecraftVersion minecraftVersion = null; private PatchUtils(){} private static ByteBuffer positionBuf(ByteBuffer buf, int addr) { if (buf == MainActivity.minecraftLibBuffer && addr >= 0 && addr < MaraudersMap.minecraftTextBuffer.capacity()) { buf = MaraudersMap.minecraftTextBuffer; } buf.position(addr); return buf; } public static void patch(ByteBuffer buf, com.joshuahuelsman.patchtool.PTPatch patch) { MinecraftVersion.PatchTranslator translator = minecraftVersion.translator; for(patch.count = 0; patch.count < patch.getNumPatches(); patch.count++){ int addr = patch.getNextAddr(); if (translator != null) addr = translator.get(addr); ByteBuffer newBuf = positionBuf(buf, addr); newBuf.put(patch.getNextData()); } } public static void unpatch(ByteBuffer buf, byte[] original, com.joshuahuelsman.patchtool.PTPatch patch) { MinecraftVersion.PatchTranslator translator = minecraftVersion.translator; ByteBuffer originalBuf = ByteBuffer.wrap(original); for(patch.count = 0; patch.count < patch.getNumPatches(); patch.count++){ int addr = patch.getNextAddr(); if (translator != null) addr = translator.get(addr); ByteBuffer newBuf = positionBuf(buf, addr); originalBuf.position(addr); byte[] nextData = new byte[patch.getDataLength()]; originalBuf.get(nextData); newBuf.put(nextData); } } public static void copy(File from, File to) throws IOException { InputStream is = new FileInputStream(from); int length = (int) from.length(); byte[] data = new byte[length]; is.read(data); is.close(); OutputStream os = new FileOutputStream(to); os.write(data); os.close(); } public static boolean canLivePatch(File file) throws IOException { MinecraftVersion.PatchTranslator translator = minecraftVersion.translator; com.joshuahuelsman.patchtool.PTPatch patch = new com.joshuahuelsman.patchtool.PTPatch(); patch.loadPatch(file); for(patch.count = 0; patch.count < patch.getNumPatches(); patch.count++){ int address = patch.getNextAddr(); if (translator != null) address = translator.get(address); if (address >= minecraftVersion.libLoadOffsetBegin) { return false; } } return true; } public static byte[] createMovwInstr(int rd, int imm) { long instr = 0xf2400000L; instr |= (rd << 8); //RD instr |= (imm & 0xff); //Imm8 instr |= ((imm >> 8) & 0x7) << 12; //Imm3 instr |= ((imm >> 11) & 0x1) << 26; //i instr |= ((imm >> 12) & 0xf) << 16; //Imm4 byte[] finalByte = intToLEByteArray(instr); System.out.println("Port patch: " + Long.toString(instr, 16)); return finalByte; } public static final byte[] intToLEByteArray(long value) { return new byte[] { (byte)(value >>> 16), (byte)(value >>> 24), (byte)value, (byte)(value >>> 8)}; } }