A better way to organize obfuscated names?

Discussion in 'Plugin Development' started by Bone008, Nov 20, 2012.

Thread Status:
Not open for further replies.
  1. Hey guys,
    So for some of my (still private, * hints at Father Of Time and kumpelblase2 *) plugins, I use an enormous amount of native net.minecraft.server code. It unfortunately has to be this way, since they are doing some really unusal stuff that there is no API for.
    Those projects have grown pretty huge, and as 1.4 hit, obviously, everything became a mess. There is about 60 compile errors in a single plugin - and that doesn't even include the changes that aren't noticed by the compiler (a renamed method still looks the same, but does something completely different). These are even harder to track down.

    Before I start adapting everything to 1.4.4/1.4.5, I'd like to find a more sustainable approach.
    An idea of using more descriptive "placeholders" for all obfuscated method/attribute names came to my mind.
    So for updates, I only have to change their mappings in one central place. Unfortunately, Java itself doesn't have a preprocessor that would allow "#define" quirks like in C/C++.

    Does anyone have an idea how such a thing (or a better one) could be done with Eclipse?
    I'd preferably just have something that replaces every A through B in the code, so I could for example write
    Code:
    @Override
    public void __ENTITYTICK__() { ... }
    and what would end up being compiled would be:
    Code:
    @Override
    public void h_() { ... }
    With me defining "__ENTITYTICK__" as an alias for "h_" somewhere.


    It would be awesome if someone has something suitable. I can't put everything in wrapper classes, it's just too much.
     
  2. you can use reflection to chance on runtime where a methode points to, just chance the string that gives the name of the function
     
  3. That would not make things easier on a bigger scale - and it hugely decreases performance because it's done at runtime. For things like mob AI which basically consists of many native method calls per tick per entity, that's simply not an option.

    Even if overriding methods would be possible with reflection, the "calling" of methods via reflection already adds huge writing overhead. Even with helper methods and generics, it still needs a ton of casting and blind assumptions. Especially considering that there's a lot to do with primitives.

    A little tailored example, this line of code:
    Code:
    if(this.at() >= this.b && this.af() <= this.c) ...
    (where those are fields & methods of a native superclass)
    would look something like this:
    Code:
    if((Double) ReflectionHelper.callPrivateMethod(Superclass.class, this, MethodNames.TRACKER_SOME_METHOD) >= (Double) ReflectionHelper.getPrivateField(Superclass.class, FieldNames.TRACKER_SOME_FIELD, this) && (Double) ReflectionHelper.callPrivateMethod(Superclass.class, this, MethodNames.TRACKER_OTHER_METHOD) <= (Double) ReflectionHelper.callPrivateMethod(Superclass.class, this, MethodNames.TRACKER_OTHER_FIELD)) ...
    And suddenly a tiny double comparison turned into a huge operation that is not only signicantly slower/with more overhead, but also pretty bloated when it happens to be all over the code.

    And as mentioned overriding methods can't be done with reflection at all (I'm not going to go at the needed complexity of ASM code ...).
     
  4. I don't think there is a way with 'pure' java. I can't think of a good reason in general as well. This one might not be the best, but at least a probably working, attempt. (Note: Be prepared of a shit ton of errors in eclipse until actual exporting/compiling)
    You wanted there to be placeholders, lets add placeholders! But, since eclipse won't replace them for us, we need to do that ourselves. So, you could just create a file (hardcoded list or something like that) that contains all the names with the placeholders. Then let another program go over all the files, create a new project somewhere with all the files where it replaced the placeholders with the actual method names from the list. This would make your wish that you can have placeholder come true. The only and big downside is that you get a ton of errors from eclipse ( plus actually collection all the names but you probably need to do that for every solution).
     
  5. Thanks for the suggestion. The downsides probably kill the benefit though: all of the features the IDE would provide indexing/accessing/searching these methods wouldn't work.

    I've found a guide on something really similar: http://boldinventions.com/index.php...id=34:category-electronics-articles&Itemid=53
    It explains how to set up an Ant script that basically automates the preprocessing and compiling process into one. I'm not sure if that actually fixes the "errors in project" problem or if it just works on a separate compile run.

    Never used Ant before, anyone with experience ... ? :)

    Oh, and the preprocessor they used is apparently mostly used for C-style conditionals (#ifdef), I've found another one: http://code.google.com/p/pre-processor-java/
    Gonna try out if I can manage to make something out of that ...

    Update: I think ... I'm getting somewhere. Ant (probably could have used maven as well ...) looks pretty promising to me. I realized I don't actually need a fully-fledged preprocessor for my scenario, simply a script that replaces strings. Ant happens to have a built-in task for that (simply called "replace"), so it actually turned out pretty well.

    I configured the (test) project to use Ant as the default compiler, so now it compiles everytime I save (makes sense, I guess). It automagically copies the source files to another location, "preprocesses" them (replaces some strings) and then compiles and packs them.
    Looks pretty solid to me - if only eclipse would recognize the refactored method. It appears to simply do its correctness-checks on the source file and not on the compiled class, so I still have that problem :/

    By the way, here's the build.xml-file I used. First thing I ever did in Ant, it's probably terrible and still has some tutorial code in it, but it's a start :D
    build.xml (open)
    Code:
    <project name="AntTests" default="dist" basedir=".">
        <!-- set global properties for this build -->
        <property name="src" location="src" />
        <property name="build" location="build" />
        <property name="tempsrc" location="tempsrc" />
        <property name="dist" location="dist" />
    
        <target name="init">
            <!-- Create the time stamp -->
            <!--<tstamp/>-->
            <!-- Create the build directory structure used by compile -->
        </target>
    
        <target name="preprocess">
            <delete dir="${tempsrc}" />
            <mkdir dir="${tempsrc}" />
            <copy todir="${tempsrc}">
                <fileset dir="${src}" />
            </copy>
            <replace dir="${tempsrc}" token="__METHODMAIN__" value="main" />
            <replace dir="${tempsrc}" token="__THING__" value="thing" />
        </target>
    
        <target name="compile" depends="preprocess">
            <!-- Compile the java code from ${src} into ${build} -->
            <javac srcdir="${tempsrc}" destdir="${build}" includeantruntime="false" />
        </target>
    
        <target name="dist" depends="compile" description="generate the distribution">
            <!-- Create the distribution directory -->
            <mkdir dir="${dist}" />
            <!-- Put everything in ${build} into the MyProject-${DSTAMP}.jar file -->
            <jar jarfile="${dist}/lib/MyProject-${DSTAMP}.jar" basedir="${build}" />
        </target>
    
        <target name="clean" description="clean up">
            <!-- Delete the ${build} and ${dist} directory trees -->
            <delete dir="${build}" />
            <delete dir="${dist}" />
            <delete dir="${tempsrc}" />
        </target>
    </project>


    I'll see what the effects of the error line are in a real situation, maybe I can live with them. If anyone happens to know a solution to this, please tell me :)

    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: May 30, 2016
Thread Status:
Not open for further replies.

Share This Page