1

背景: アプレットを取得するために Minecraft ランチャーを挿入していますが (これは実行済みです)、クラス ローダーを介して Minecraft のファイルをロードしたいと考えています。私は、GameUpdater.java (Minecraft の gameupdater、クライアントのアプレットのディスパッチャーでもある) のメソッドを見つけました。その下には、「createApplet」というメソッドがあります。

GameUpdater.java:

public Applet createApplet() throws ClassNotFoundException, InstantiationException, IllegalAccessException {
Class localClass = classLoader.loadClass("net.minecraft.client.MinecraftApplet");
return (Applet)localClass.newInstance();
}   

わかりました、簡単ですが、classLoader.loadClass を独自の静的ロード メソッドに置き換えます。だから、私は自分のクラスローダで試しました。ここに私の変換コードがあります:

for(Method method : generator.getMethods()) {
                    if(method.getName().equals("createApplet")) {
                        ConstantPoolGen cpg = generator.getConstantPool();
                        MethodGen methodGen = new MethodGen(method, generator.getClassName(), cpg);
                        Instruction instruction = null;
                        InstructionList instructionList = methodGen.getInstructionList();
                        InstructionHandle[] instructionHandles = instructionList.getInstructionHandles();
                        for(int i = 0; i < instructionHandles.length; i++) {
                            //System.out.println(instructionHandles[i].getInstruction());  //debug
                            if(instructionHandles[i].getInstruction() instanceof LDC) {
                                instruction = instructionHandles[i].getInstruction();
                                InstructionFactory instructionFactory = new InstructionFactory(generator, cpg);
                                InvokeInstruction classLoaderCall =
                                        instructionFactory.createInvoke(
                                        "MinecraftLauncher", "loadClass", Type.CLASS, new Type[]{Type.STRING},Constants.INVOKESTATIC);
                                instructionList.insert(instruction, classLoaderCall);
                                methodGen.setInstructionList(instructionList);
                                instructionList.setPositions();
                                methodGen.setMaxStack();
                                methodGen.setMaxLocals();
                                methodGen.removeLineNumbers();
                                generator.replaceMethod(method, methodGen.getMethod());
                                generator.getJavaClass().dump("gameupdater.class");
                            }
                        }
                    }

それでも、私は顔に落ちました。これが更新された gameupdater.class です (上記のように、ダンプします)

public Applet createApplet() throws ClassNotFoundException, InstantiationException, IllegalAccessException {
Class localClass = MinecraftLauncher.loadClass(classLoader).loadClass("net.minecraft.client.MinecraftApplet");
return (Applet)localClass.newInstance();
}

これは、GameUpdater のメソッド createApplet のバイトコードの図です。 バイトコード情報

今、私は他にこれを行う方法がわかりません。誰かが私を正しい方向に向けることができれば、それは素晴らしいことです! それまでの間、私は努力を続け、bcel doc を読んでいきます。

その他のコードなどについて質問がある場合は、教えてください。

4

1 に答える 1

1

解決しました。秘訣は、新しいもの(ロード関数を置き換える静的メソッド)を追加した後、InvokerVirtualを削除する(命令リストからOPCODEを削除する)ことです。

instructionList.insert(instruction, classLoaderCall);
instructionList.delete(instruction);
于 2013-01-06T05:59:20.977 に答える