Added SideTransformer to strip side only functions/fields out.

This commit is contained in:
LexManos 2012-08-08 18:53:41 -07:00
parent ac8945a4f8
commit 9b81775a2f
8 changed files with 252 additions and 15 deletions

View File

@ -1,6 +1,15 @@
--- commands.py
+++ commands.py
@@ -582,6 +582,9 @@
@@ -58,6 +58,8 @@
def reallyrmtree(path):
+ if os.path.isfile(os.path.join(path, 'asm-all-4.0.jar')): #Check if asm exists, indicating the libs folder, if so, don't delete it
+ return
if not sys.platform.startswith('win'):
if os.path.exists(path):
shutil.rmtree(path)
@@ -582,6 +584,9 @@
self.has_astyle_cfg = False
if os.path.isfile(self.astyleconf):
self.has_astyle_cfg = True
@ -10,7 +19,7 @@
def creatergcfg(self, reobf=False, keep_lvt=False, keep_generics=False, rg_update=False):
"""Create the files necessary for RetroGuard"""
@@ -779,7 +782,8 @@
@@ -779,7 +784,8 @@
testlk = {CLIENT: self.testclient, SERVER: self.testserver}
if not os.path.exists(os.path.join(srclk[side], os.path.normpath(testlk[side] + '.java'))):
@ -20,7 +29,7 @@
return True
def checkbins(self, side):
@@ -1039,6 +1043,7 @@
@@ -1039,6 +1045,7 @@
all_files = True
append_pattern = False
pkglist = filterdirs(pathsrclk[side], '*.java', append_pattern=append_pattern, all_files=all_files)
@ -28,7 +37,7 @@
dirs = ' '.join(pkglist)
classpath = os.pathsep.join(cplk[side])
forkcmd = self.cmdrecomp.format(classpath=classpath, sourcepath=pathsrclk[side], outpath=pathbinlk[side],
@@ -1195,20 +1200,20 @@
@@ -1195,20 +1202,20 @@
with open(self.csvmethods, 'rb') as fh:
methodsreader = csv.DictReader(fh)
for row in methodsreader:
@ -52,7 +61,7 @@
names['params'][row['param']] = row['name']
regexps = {
@@ -1238,6 +1243,11 @@
@@ -1238,6 +1245,11 @@
# HINT: We pathwalk the sources
for path, _, filelist in os.walk(pathsrclk[side], followlinks=True):
@ -64,7 +73,7 @@
for cur_file in fnmatch.filter(filelist, '*.java'):
updatefile(os.path.normpath(os.path.join(path, cur_file)))
return True
@@ -1320,12 +1330,14 @@
@@ -1320,12 +1332,14 @@
pathsrclk = {CLIENT: self.srcclient, SERVER: self.srcserver}
strip_comments(pathsrclk[side])
@ -79,7 +88,7 @@
def process_javadoc(self, side):
"""Add CSV descriptions to methods and fields as javadoc"""
@@ -1334,6 +1346,21 @@
@@ -1334,6 +1348,21 @@
if not self.has_doc_csv:
self.logger.warning('!! javadoc disabled due to no csvs !!')
return False
@ -101,7 +110,7 @@
#HINT: We read the relevant CSVs
methodsreader = csv.DictReader(open(self.csvmethods, 'r'))
@@ -1342,13 +1369,13 @@
@@ -1342,13 +1371,13 @@
methods = {}
for row in methodsreader:
#HINT: Only include methods that have a non-empty description
@ -117,7 +126,7 @@
fields[row['searge']] = row['desc'].replace('*/', '* /')
regexps = {
@@ -1420,6 +1447,7 @@
@@ -1420,6 +1449,7 @@
# HINT: We create the list of source directories based on the list of packages
pkglist = filterdirs(pathsrclk[side], '*.java', append_pattern=True)
@ -125,7 +134,7 @@
dirs = ' '.join(pkglist)
forkcmd = self.cmdastyle.format(classes=dirs, conffile=self.astyleconf)
self.runcmd(forkcmd)
@@ -1592,6 +1620,9 @@
@@ -1592,6 +1622,9 @@
sys.exit(1)
for entry in newfiles:

View File

@ -10,5 +10,5 @@ import cpw.mods.fml.common.Side;
@Target({ElementType.TYPE, ElementType.FIELD, ElementType.METHOD, ElementType.CONSTRUCTOR})
public @interface SideOnly
{
public Side side();
public Side value();
}

View File

@ -255,10 +255,10 @@ public class MCPMerger
private static AnnotationNode getSideAnn(boolean isClientOnly)
{
AnnotationNode ann = new AnnotationNode("L" + Type.getInternalName(SideOnly.class) + ";");
AnnotationNode ann = new AnnotationNode(Type.getDescriptor(SideOnly.class));
ann.values = new ArrayList<Object>();
ann.values.add("side");
ann.values.add(new String[]{ "L" + Type.getInternalName(Side.class) + ";", (isClientOnly ? "CLIENT" : "SERVER")});
ann.values.add("value");
ann.values.add(new String[]{ Type.getDescriptor(Side.class), (isClientOnly ? "CLIENT" : "SERVER")});
return ann;
}

View File

@ -0,0 +1,87 @@
package cpw.mods.fml.common.asm.transformers;
import java.util.Iterator;
import java.util.List;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.Type;
import org.objectweb.asm.tree.AnnotationNode;
import org.objectweb.asm.tree.ClassNode;
import org.objectweb.asm.tree.FieldNode;
import org.objectweb.asm.tree.MethodNode;
import cpw.mods.fml.common.Side;
import cpw.mods.fml.common.asm.SideOnly;
import cpw.mods.fml.relauncher.IClassTransformer;
public class SideTransformer implements IClassTransformer
{
private static String SIDE = "CLIENT"; //TODO: Pick correct side
@SuppressWarnings("unchecked")
@Override
public byte[] transform(String name, byte[] bytes)
{
ClassNode classNode = new ClassNode();
ClassReader classReader = new ClassReader(bytes);
classReader.accept(classNode, 0);
Iterator<FieldNode> fields = classNode.fields.iterator();
while(fields.hasNext())
{
FieldNode field = fields.next();
if (remove((List<AnnotationNode>)field.visibleAnnotations, SIDE))
{
System.out.println("Removing Field: " + field.name);
fields.remove();
}
}
Iterator<MethodNode> methods = classNode.methods.iterator();
while(methods.hasNext())
{
MethodNode method = methods.next();
if (remove((List<AnnotationNode>)method.visibleAnnotations, SIDE))
{
System.out.println("Removing Method: " + method.name + " " + method.desc);
methods.remove();
}
}
ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_MAXS);
classNode.accept(writer);
return writer.toByteArray();
}
private boolean remove(List<AnnotationNode> anns, String side)
{
if (anns == null)
{
return false;
}
for (AnnotationNode ann : anns)
{
if (ann.desc.equals(Type.getDescriptor(SideOnly.class)))
{
if (ann.values != null)
{
for (int x = 0; x < ann.values.size() - 1; x += 2)
{
Object key = ann.values.get(x);
Object value = ann.values.get(x+1);
if (key instanceof String && key.equals("value"))
{
if (value instanceof String[] )
{
if (!((String[])value)[1].equals(side))
{
return true;
}
}
}
}
}
}
}
return false;
}
}

View File

@ -13,7 +13,10 @@ public class FMLCorePlugin implements IFMLLoadingPlugin
@Override
public String[] getASMTransformerClass()
{
return new String[] {"cpw.mods.fml.common.asm.transformers.AccessTransformer", "cpw.mods.fml.common.asm.transformers.MarkerTransformer"};
return new String[] {"cpw.mods.fml.common.asm.transformers.AccessTransformer",
"cpw.mods.fml.common.asm.transformers.MarkerTransformer",
"cpw.mods.fml.common.asm.transformers.SideTransformer"
};
}
@Override

View File

@ -223,6 +223,12 @@ def setup_fml(fml_dir, mcp_dir):
updatemd5_side(commands, CLIENT)
updatemd5_side(commands, SERVER)
reset_logger()
#Delete /common/cpw to get rid of the Side/SideOnly classes used in decompilation
cpw_dir = os.path.join(mcp_dir, 'src', 'common', 'cpw')
if os.path.isdir(cpw_dir):
shutil.rmtree(cpw_dir)
os.chdir(fml_dir)
def merge_client_server(mcp_dir):

View File

@ -0,0 +1,21 @@
--- ../src-base/common/net/minecraft/src/EntityPlayer.java
+++ ../src-work/common/net/minecraft/src/EntityPlayer.java
@@ -2,6 +2,8 @@
import cpw.mods.fml.common.Side;
import cpw.mods.fml.common.asm.SideOnly;
+import cpw.mods.fml.common.network.FMLNetworkHandler;
+
import java.util.Iterator;
import java.util.List;
@@ -1608,4 +1610,9 @@
{
return this.field_71078_a;
}
+
+ public void openGui(Object mod, int modGuiId, World world, int x, int y, int z)
+ {
+ FMLNetworkHandler.openGui(this, mod, modGuiId, world, x, y, z);
+ }
}

View File

@ -0,0 +1,111 @@
--- ../src-base/common/net/minecraft/src/WorldType.java
+++ ../src-work/common/net/minecraft/src/WorldType.java
@@ -1,10 +1,20 @@
package net.minecraft.src;
+
+import java.util.Arrays;
+import java.util.Random;
+import java.util.Set;
+
+import com.google.common.collect.ObjectArrays;
+import com.google.common.collect.Sets;
import cpw.mods.fml.common.Side;
import cpw.mods.fml.common.asm.SideOnly;
public class WorldType
{
+ public static final BiomeGenBase[] base11Biomes = new BiomeGenBase[] {BiomeGenBase.field_76769_d, BiomeGenBase.field_76767_f, BiomeGenBase.field_76770_e, BiomeGenBase.field_76780_h, BiomeGenBase.field_76772_c, BiomeGenBase.field_76768_g};
+ public static final BiomeGenBase[] base12Biomes = ObjectArrays.concat(base11Biomes, BiomeGenBase.field_76782_w);
+
public static final WorldType[] field_77139_a = new WorldType[16];
public static final WorldType field_77137_b = (new WorldType(0, "default", 1)).func_77129_f();
public static final WorldType field_77138_c = new WorldType(1, "flat");
@@ -14,6 +24,8 @@
private final int field_77134_g;
private boolean field_77140_h;
private boolean field_77141_i;
+
+ protected BiomeGenBase[] biomesForWorldType;
private WorldType(int p_i3737_1_, String p_i3737_2_)
{
@@ -26,6 +38,14 @@
this.field_77134_g = p_i3738_3_;
this.field_77140_h = true;
field_77139_a[p_i3738_1_] = this;
+ switch (p_i3738_1_)
+ {
+ case 8:
+ biomesForWorldType = base11Biomes;
+ break;
+ default:
+ biomesForWorldType = base12Biomes;
+ }
}
public String func_77127_a()
@@ -89,4 +109,63 @@
return null;
}
+
+ public WorldChunkManager getChunkManager(World world)
+ {
+ return this == field_77138_c ? new WorldChunkManagerHell(BiomeGenBase.field_76772_c, 0.5F, 0.5F) : new WorldChunkManager(world);
+ }
+
+ public IChunkProvider getChunkGenerator(World world)
+ {
+ return (this == field_77138_c ? new ChunkProviderFlat(world, world.func_72905_C(), world.func_72912_H().func_76089_r()) : new ChunkProviderGenerate(world, world.func_72905_C(), world.func_72912_H().func_76089_r()));
+ }
+
+ public int getMinimumSpawnHeight(World world)
+ {
+ return this == field_77138_c ? 4 : 64;
+ }
+
+ public double getHorizon(World world)
+ {
+ return this == field_77138_c ? 0.0D : 63.0D;
+ }
+
+ public boolean hasVoidParticles(boolean var1)
+ {
+ return this != field_77138_c && !var1;
+ }
+
+ public double voidFadeMagnitude()
+ {
+ return this == field_77138_c ? 1.0D : 0.03125D;
+ }
+
+ public BiomeGenBase[] getBiomesForWorldType() {
+ return biomesForWorldType;
+ }
+
+ public void addNewBiome(BiomeGenBase biome)
+ {
+ Set<BiomeGenBase> newBiomesForWorld = Sets.newIdentityHashSet();
+ newBiomesForWorld.addAll(Arrays.asList(biomesForWorldType));
+ newBiomesForWorld.add(biome);
+ biomesForWorldType = newBiomesForWorld.toArray(new BiomeGenBase[0]);
+ }
+
+ public void removeBiome(BiomeGenBase biome)
+ {
+ Set<BiomeGenBase> newBiomesForWorld = Sets.newIdentityHashSet();
+ newBiomesForWorld.addAll(Arrays.asList(biomesForWorldType));
+ newBiomesForWorld.remove(biome);
+ biomesForWorldType = newBiomesForWorld.toArray(new BiomeGenBase[0]);
+ }
+
+ public boolean handleSlimeSpawnReduction(Random random, World world)
+ {
+ return this == field_77138_c ? random.nextInt(4) != 1 : false;
+ }
+ /**
+ * Called when 'Create New World' button is pressed before starting game
+ */
+ public void onGUICreateWorldPress() { }
}