Skip to content

Commit

Permalink
Woo, dynamic patching! This is pretty much a rewrite which includes:
Browse files Browse the repository at this point in the history
- Loading patch info from a JSON file
- Added an ugly UI for generating this file
- Blacklist file also uses JSON and supports multiple blacklists
- Removed the need for me to patch things :)
- Can't remember the others

There are still a few things I need to finish up and a few cases I should account for.
  • Loading branch information
Joe12o committed Jan 26, 2014
1 parent 9bd424d commit 5106c38
Show file tree
Hide file tree
Showing 18 changed files with 699 additions and 379 deletions.
4 changes: 3 additions & 1 deletion build.xml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
<property name="classes.dir" value="${build.dir}/classes"/>
<property name="reobf.dir" value="${mcp.dir}/reobf"/>
<property name="download.dir" value="download"/>
<property name="af.version" value="1.2.0"/>
<property name="af.version" value="2.0.0"/>
<property name="forge.version" value="9.11.1.933"/>
<property name="mc.version" value="1.6.4"/>
<property name="forge.name" value="minecraftforge-src-${mc.version}-${forge.version}.zip"/>
Expand Down Expand Up @@ -93,7 +93,9 @@

<target name="package" depends="compile">
<jar destfile="${build.dir}/AliceFixes-${af.version}.jar" basedir="${classes.dir}">
<zipfileset includes="**/*.class" src="${mcp.dir}/jars/libraries/com/google/code/gson/gson/2.2.2/gson-2.2.2.jar"/>
<manifest>
<attribute name="Main-Class" value="com.skcraft.alicefixes.jsongenerator.Generator"/>
<attribute name="FMLCorePlugin" value="com.skcraft.alicefixes.LoadingPlugin"/>
<attribute name="FMLCorePluginContainsFMLMod" value="true"/>
</manifest>
Expand Down
4 changes: 2 additions & 2 deletions src/main/java/com/skcraft/alicefixes/AFListener.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,15 @@ public class AFListener {

@ForgeSubscribe
public void onLaserHitBlock(LaserHitsBlockEvent evt) {
if(!ASMHelper.canMine(evt.owner, null, evt.x, evt.y, evt.z)) {
if(!ASMHelper.canMine(evt.owner, evt.x, evt.y, evt.z, false, this)) {
evt.lasershot.setDead();
evt.setCanceled(true);
}
}

@ForgeSubscribe
public void onLaserExplode(LaserExplodesEvent evt) {
if(!ASMHelper.canMine(evt.owner, null, (int)evt.lasershot.posX, (int)evt.lasershot.posY, (int)evt.lasershot.posZ)) {
if(!ASMHelper.canMine(evt.owner, (int)evt.lasershot.posX, (int)evt.lasershot.posY, (int)evt.lasershot.posZ, false, this)) {
evt.lasershot.setDead();
evt.setCanceled(true);
}
Expand Down
6 changes: 5 additions & 1 deletion src/main/java/com/skcraft/alicefixes/AliceFixes.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import cpw.mods.fml.common.Mod;
import cpw.mods.fml.common.Mod.EventHandler;
import cpw.mods.fml.common.event.FMLPostInitializationEvent;
import cpw.mods.fml.common.event.FMLServerStoppingEvent;
import net.minecraftforge.common.MinecraftForge;

@Mod(modid = "com.skcraft.alicefixes", name = "AliceFixes", version = "1.2.0")
Expand All @@ -11,7 +12,10 @@ public class AliceFixes {
@EventHandler
public void postInit(FMLPostInitializationEvent evt) {
MinecraftForge.EVENT_BUS.register(new AFListener());
BreakerBlacklist.load();
}

@EventHandler
public void serverStopped(FMLServerStoppingEvent evt) {
Blacklist.save();
}
}
139 changes: 122 additions & 17 deletions src/main/java/com/skcraft/alicefixes/AliceTransformer.java
Original file line number Diff line number Diff line change
@@ -1,27 +1,120 @@
package com.skcraft.alicefixes;

import com.skcraft.alicefixes.transformers.TransformBreaker;
import com.skcraft.alicefixes.transformers.TransformTools;
import com.skcraft.alicefixes.transformers.TransformExcavationWand;
import com.skcraft.alicefixes.transformers.TransformTradeWand;
import com.skcraft.alicefixes.util.ASMHelper;
import com.google.gson.Gson;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.skcraft.alicefixes.jsongenerator.GeneratorFrame.PatchList;
import com.skcraft.alicefixes.jsongenerator.JsonHelperObject;
import com.skcraft.alicefixes.transformers.ClassTransformer;
import com.skcraft.alicefixes.util.Obfs;
import cpw.mods.fml.common.FMLLog;
import net.minecraft.launchwrapper.IClassTransformer;
import org.apache.commons.io.FileUtils;

import java.io.File;
import java.util.*;
import java.util.logging.Level;

public class AliceTransformer implements IClassTransformer {

private final IClassTransformer[] transformers = {
new TransformExcavationWand(),
new TransformTradeWand(),
new TransformTools("thaumcraft.common.items.equipment.ItemElementalAxe", "func_77648_a", "(Lnet/minecraft/item/ItemStack;Lnet/minecraft/entity/player/EntityPlayer;Lnet/minecraft/world/World;IIIIFFF)Z"),
new TransformTools("thaumcraft.common.items.equipment.ItemElementalShovel", "func_77660_a", "(Lnet/minecraft/item/ItemStack;Lnet/minecraft/world/World;IIIILnet/minecraft/entity/EntityLivingBase;)Z"),
new TransformTools("gravisuite.ItemVajra", "a", "(L" + ASMHelper.getObf("ItemStack") + ";L" + ASMHelper.getObf("EntityPlayer") + ";L" + ASMHelper.getObf("World") + ";IIIIFFF)Z"),
new TransformTools("thermalexpansion.item.tool.ItemWrench", "onItemUseFirst", "(Lnet/minecraft/item/ItemStack;Lnet/minecraft/entity/player/EntityPlayer;Lnet/minecraft/world/World;IIIIFFF)Z"),
new TransformTools("thermalexpansion.item.tool.ItemWrenchBattle", "onItemUseFirst", "(Lnet/minecraft/item/ItemStack;Lnet/minecraft/entity/player/EntityPlayer;Lnet/minecraft/world/World;IIIIFFF)Z"),
new TransformTools("gregtechmod.api.items.GT_Wrench_Item", "onItemUseFirst", "(Lnet/minecraft/item/ItemStack;Lnet/minecraft/entity/player/EntityPlayer;Lnet/minecraft/world/World;IIIIFFF)Z"),
new TransformBreaker()
};
private final JsonParser parser = new JsonParser();
public static Map<String, String> primitives = new HashMap();

private final List<IClassTransformer> transformers = new ArrayList<IClassTransformer>();

public AliceTransformer() {
try {
File configDir = new File(LoadingPlugin.getMCDirectory(), "config");
Blacklist.load(configDir);
File configFile = new File(configDir, "AFPatches.json");

if(configFile.isFile()) {
Gson gson = new Gson();
JsonObject obj = parser.parse(FileUtils.readFileToString(configFile)).getAsJsonObject();
PatchList patchList = gson.fromJson(obj, PatchList.class);
Iterator<JsonHelperObject> i = patchList.getPatches().values().iterator();
while(i.hasNext()) {
JsonHelperObject patch = i.next();
transformers.add(
new ClassTransformer(patch, buildDescriptor(patch.params, patch.returnType), sortVars(patch.params))
);
if(patch.blacklist) {
Blacklist.addBlacklist(patch.className, new int[] {-1});
}
}
}
} catch(Throwable t) {
t.printStackTrace();
}
}

private String buildDescriptor(String[] params, String returnType) {
StringBuilder sb = new StringBuilder();
sb.append("(");
for(int i = 0; i < params.length; i++) {
if(primitives.containsKey(params[i])) {
sb.append(primitives.get(params[i]));
} else if(!params[i].equals("")) {
sb.append("L" + params[i] + ";");
}
}
sb.append(")");
if(primitives.containsKey(returnType)) {
sb.append(primitives.get(returnType));
} else {
sb.append("L" + returnType + ";");
}
return sb.toString();
}

private List sortVars(String[] params) {
List<Integer> desiredVars = new ArrayList<Integer>();
boolean foundCoords = false;

//Find the player
for(int i = 0; i < params.length; i++) {
if((params[i].equals("net/minecraft/entity/player/EntityPlayer") || params[i].equals(Obfs.get("EntityPlayer")) ||
params[i].equals("net/minecraft/entity/EntityLivingBase") || params[i].equals(Obfs.get("EntityLivingBase")))) {
desiredVars.add(i + 1);
break;
}
}

//Check if the coords were indicated by user
for(int i = 0; i < params.length; i++) {
if(params[i].equals("intCOORD")) {
desiredVars.add(i + 1);
foundCoords = true;
}
}

//Search for the xyz coords if they weren't indicated, THIS IS NOT VERY RELIABLE!
//It will search for the first 3 parameters which are integers
if(!foundCoords) {
for(int i = 0; i < params.length; i++) {
if(params[i].equals("int")) {
int foundInts = 1;
for(int j = 1; j < 3; j++) {
if(params.length <= i + j) {
break;
}
if(params[i + j].equals("int")) {
foundInts++;
} else {
break;
}
}
if(foundInts == 3) {
for(int j = 0; j < 3; j++) {
desiredVars.add(i + j + 1);
}
break;
}
}
}
}
return desiredVars;
}

@Override
public byte[] transform(String name, String transformedName, byte[] bytes) {
Expand All @@ -34,7 +127,19 @@ public byte[] transform(String name, String transformedName, byte[] bytes) {
if(bytes == null)
FMLLog.log(Level.SEVERE, "Transformer " + transformer.getClass().getCanonicalName() + " has corrupted class " + name);
}

return bytes;
}

static {
primitives.put("byte", "B");
primitives.put("int", "I");
primitives.put("short", "S");
primitives.put("long", "L");
primitives.put("float", "F");
primitives.put("double", "D");
primitives.put("boolean", "Z");
primitives.put("char", "C");
primitives.put("void", "V");
primitives.put("intCOORD", "I");
}
}
63 changes: 63 additions & 0 deletions src/main/java/com/skcraft/alicefixes/Blacklist.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
package com.skcraft.alicefixes;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import org.apache.commons.io.FileUtils;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.util.HashMap;
import java.util.Map;

public class Blacklist {

private static File config;
private static Map<String, int[]> blacklists = new HashMap<String, int[]>();
private static BlackLists lists = new BlackLists();

public static void load(File configDir) {
try {
Gson gson = new Gson();
config = new File(configDir, "Blacklists.json");
BufferedReader br = new BufferedReader(new FileReader(config));
BlackLists storedLists = gson.fromJson(br, BlackLists.class);
if(storedLists != null) {
blacklists.putAll(storedLists.blacklists);
}
br.close();
}
catch(Throwable t) {
t.printStackTrace();
}
}

public static void save() {
Gson gson = new GsonBuilder().setPrettyPrinting().create();
try {
lists.setBlacklists(blacklists);
FileUtils.writeStringToFile(config, gson.toJson(lists));
} catch(Throwable t) {
t.printStackTrace();
}
}

public static void addBlacklist(String key, int[] def) {
if(!blacklists.containsKey(key)) {
blacklists.put(key, def);
}
}

public static int[] getBlacklist(String key) {
return blacklists.get(key);
}

public static class BlackLists {
private Map<String, int[]> blacklists = new HashMap();

public void setBlacklists(Map lists) {
blacklists = lists;
}
}
}
35 changes: 0 additions & 35 deletions src/main/java/com/skcraft/alicefixes/BreakerBlacklist.java

This file was deleted.

12 changes: 11 additions & 1 deletion src/main/java/com/skcraft/alicefixes/LoadingPlugin.java
Original file line number Diff line number Diff line change
@@ -1,10 +1,18 @@
package com.skcraft.alicefixes;

import cpw.mods.fml.relauncher.IFMLLoadingPlugin;

import java.io.File;
import java.util.Map;

public class LoadingPlugin implements IFMLLoadingPlugin {

private static File mcDir;

public static File getMCDirectory() {
return mcDir;
}

@Override
public String[] getLibraryRequestClass() {
return null;
Expand All @@ -26,5 +34,7 @@ public String getSetupClass() {
}

@Override
public void injectData(Map<String, Object> data) {}
public void injectData(Map<String, Object> data) {
mcDir = (File)data.get("mcLocation");
}
}
20 changes: 20 additions & 0 deletions src/main/java/com/skcraft/alicefixes/jsongenerator/Generator.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package com.skcraft.alicefixes.jsongenerator;

import javax.swing.*;

public class Generator {

public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
try{
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
new GeneratorFrame().setVisible(true);
} catch(Throwable t) {

}
}
});
}
}
Loading

0 comments on commit 5106c38

Please sign in to comment.