3

I have a class file and I want to add some code to it. I decompiled it and got this

package net.minecraft.client.main;

import com.google.gson.Gson;
import java.util.List;
import joptsimple.OptionSet;
import java.lang.reflect.Type;
import com.mojang.authlib.properties.PropertyMap;
import com.google.gson.GsonBuilder;
import java.net.Authenticator;
import java.net.SocketAddress;
import java.net.URISyntaxException;
import java.net.InetSocketAddress;
import java.net.Proxy;
import joptsimple.OptionSpec;
import java.io.File;
import joptsimple.OptionParser;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;

public class Main
{
    public static void main(final String[] u2603) {

        System.setProperty("java.net.preferIPv4Stack", "true");
        final OptionParser optionParser = new OptionParser();
        optionParser.allowsUnrecognizedOptions();
        optionParser.accepts("demo");
        optionParser.accepts("fullscreen");
        optionParser.accepts("checkGlErrors");
        final OptionSpec<String> withRequiredArg = (OptionSpec<String>)optionParser.accepts("server").withRequiredArg();
        final OptionSpec<Integer> defaultsTo = (OptionSpec<Integer>)optionParser.accepts("port").withRequiredArg().ofType((Class)Integer.class).defaultsTo((Object)25565, (Object[])new Integer[0]);
        final OptionSpec<File> defaultsTo2 = (OptionSpec<File>)optionParser.accepts("gameDir").withRequiredArg().ofType((Class)File.class).defaultsTo((Object)new File("."), (Object[])new File[0]);
        final OptionSpec<File> ofType = (OptionSpec<File>)optionParser.accepts("assetsDir").withRequiredArg().ofType((Class)File.class);
        final OptionSpec<File> ofType2 = (OptionSpec<File>)optionParser.accepts("resourcePackDir").withRequiredArg().ofType((Class)File.class);
        final OptionSpec<String> withRequiredArg2 = (OptionSpec<String>)optionParser.accepts("proxyHost").withRequiredArg();
        final OptionSpec<Integer> ofType3 = (OptionSpec<Integer>)optionParser.accepts("proxyPort").withRequiredArg().defaultsTo((Object)"8080", (Object[])new String[0]).ofType((Class)Integer.class);
        final OptionSpec<String> withRequiredArg3 = (OptionSpec<String>)optionParser.accepts("proxyUser").withRequiredArg();
        final OptionSpec<String> withRequiredArg4 = (OptionSpec<String>)optionParser.accepts("proxyPass").withRequiredArg();
        final OptionSpec<String> defaultsTo3 = (OptionSpec<String>)optionParser.accepts("username").withRequiredArg().defaultsTo((Object)("Player" + ave.J() % 1000L), (Object[])new String[0]);
        final OptionSpec<String> withRequiredArg5 = (OptionSpec<String>)optionParser.accepts("uuid").withRequiredArg();
        final OptionSpec<String> required = (OptionSpec<String>)optionParser.accepts("accessToken").withRequiredArg().required();
        final OptionSpec<String> required2 = (OptionSpec<String>)optionParser.accepts("version").withRequiredArg().required();
        final OptionSpec<Integer> defaultsTo4 = (OptionSpec<Integer>)optionParser.accepts("width").withRequiredArg().ofType((Class)Integer.class).defaultsTo((Object)854, (Object[])new Integer[0]);
        final OptionSpec<Integer> defaultsTo5 = (OptionSpec<Integer>)optionParser.accepts("height").withRequiredArg().ofType((Class)Integer.class).defaultsTo((Object)480, (Object[])new Integer[0]);
        final OptionSpec<String> defaultsTo6 = (OptionSpec<String>)optionParser.accepts("userProperties").withRequiredArg().defaultsTo((Object)"{}", (Object[])new String[0]);
        final OptionSpec<String> defaultsTo7 = (OptionSpec<String>)optionParser.accepts("profileProperties").withRequiredArg().defaultsTo((Object)"{}", (Object[])new String[0]);
        final OptionSpec<String> withRequiredArg6 = (OptionSpec<String>)optionParser.accepts("assetIndex").withRequiredArg();
        final OptionSpec<String> defaultsTo8 = (OptionSpec<String>)optionParser.accepts("userType").withRequiredArg().defaultsTo((Object)"legacy", (Object[])new String[0]);
        final OptionSpec<String> nonOptions = (OptionSpec<String>)optionParser.nonOptions();
        final OptionSet parse = optionParser.parse(u2603);
        final List<String> values = (List<String>)parse.valuesOf((OptionSpec)nonOptions);
        if (!values.isEmpty()) {
            System.out.println("Completely ignored arguments: " + values);
        }
        final String hostname = (String)parse.valueOf((OptionSpec)withRequiredArg2);
        Proxy no_PROXY = Proxy.NO_PROXY;
        if (hostname != null) {
            try {
                no_PROXY = new Proxy(Proxy.Type.SOCKS, new InetSocketAddress(hostname, (int)parse.valueOf((OptionSpec)ofType3)));
            }
            catch (Exception ex) {}
        }
        final String u26032 = (String)parse.valueOf((OptionSpec)withRequiredArg3);
        final String u26033 = (String)parse.valueOf((OptionSpec)withRequiredArg4);
        if (!no_PROXY.equals(Proxy.NO_PROXY) && a(u26032) && a(u26033)) {
            Authenticator.setDefault((Authenticator)new Main.Main$1(u26032, u26033));
        }
        final int intValue = (int)parse.valueOf((OptionSpec)defaultsTo4);
        final int intValue2 = (int)parse.valueOf((OptionSpec)defaultsTo5);
        final boolean has = parse.has("fullscreen");
        final boolean has2 = parse.has("checkGlErrors");
        final boolean has3 = parse.has("demo");
        final String s = (String)parse.valueOf((OptionSpec)required2);
        final Gson create = new GsonBuilder().registerTypeAdapter((Type)PropertyMap.class, (Object)new PropertyMap.Serializer()).create();
        final PropertyMap propertyMap = (PropertyMap)create.fromJson((String)parse.valueOf((OptionSpec)defaultsTo6), (Class)PropertyMap.class);
        final PropertyMap propertyMap2 = (PropertyMap)create.fromJson((String)parse.valueOf((OptionSpec)defaultsTo7), (Class)PropertyMap.class);
        final File file = (File)parse.valueOf((OptionSpec)defaultsTo2);
        final File file2 = (File)(parse.has((OptionSpec)ofType) ? parse.valueOf((OptionSpec)ofType) : new File(file, "assets/"));
        final File file3 = (File)(parse.has((OptionSpec)ofType2) ? parse.valueOf((OptionSpec)ofType2) : new File(file, "resourcepacks/"));
        final String s2 = (String)(parse.has((OptionSpec)withRequiredArg5) ? withRequiredArg5.value(parse) : ((String)defaultsTo3.value(parse)));
        final String s3 = parse.has((OptionSpec)withRequiredArg6) ? ((String)withRequiredArg6.value(parse)) : null;
        final String s4 = (String)parse.valueOf((OptionSpec)withRequiredArg);
        final Integer n = (Integer)parse.valueOf((OptionSpec)defaultsTo);
        final avm avm = new avm((String)defaultsTo3.value(parse), s2, (String)required.value(parse), (String)defaultsTo8.value(parse));
        final bao bao = new bao(new bao.e(avm, propertyMap, propertyMap2, no_PROXY), new bao.a(intValue, intValue2, has, has2), new bao.b(file, file3, file2, s3), new bao.c(has3, s), new bao.d(s4, (int)n));
        Runtime.getRuntime().addShutdownHook((Thread)new Main.Main$2("Client Shutdown Thread"));
        Thread.currentThread().setName("Client thread");
        new ave(bao).a();
    }
    
    private static boolean a(final String u2603) {
        return u2603 != null && !u2603.isEmpty();
    }
}

I want to add some code at the start of the main function

String jarPath;
try {
    File BetterSettings = new File(System.getProperty("user.dir"), "BetterSettings.txt");
    
    jarPath = Main.class
             .getProtectionDomain()
             .getCodeSource()
             .getLocation()
             .toURI()
             .getPath();
     System.out.println("JAR Path : " + jarPath);
     try {
        PrintWriter printwriter = new PrintWriter(new FileWriter(BetterSettings));
        String[] texts= jarPath.split("/");
        String version = texts[texts.length-1];
        printwriter.println(jarPath);
        printwriter.println(version);
        printwriter.close();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

} catch (URISyntaxException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
}

I add the code in, but when I go to recompile it in cmd it doesn't work.

Is there any way for me to decompile 1 class file add code and recompile? The class file was part of a whole jar file. Do I need to decompile the whole jar file?

Mark Rotteveel
  • 100,966
  • 191
  • 140
  • 197
  • 2
    In theory it should work with just having the other classes on the classpath. However, I've not yet seen a decompiler that generates 100% recompilable code - it might work or it might not and you might have to fix some other portions of the code. Without knowing in what way "it doesn't work" we can't tell you what you'd need to do. ... However, I'd strongly advise against this approach anyway. There might be better options such as AOP - can you elaborate on what you want to achieve in the end? – Thomas Jun 14 '22 at 06:02

0 Answers0