天天看點

【Java】我的世界Java版外挂制作 [1] - 子產品管理器與第一個子產品1x001 建立主包和主類1x002 Category.java1x003 Module.java1x004 HackedClient.java1x005 ModuleManager.java1x006 注入1x007 第一個子產品 - AutoSprint1x008 測試

ROOT

: 挂端主檔案夾

1x001 建立主包和主類

ROOT/src/minecraft

下建立新包,名字叫

me.hack.hackedclient

。如果沒有建立包的選項,就右鍵

ROOT/src/minecraft

檔案夾,選擇

Mark Directory as

-

Sources root

就可以了。 在主包内建立一個新的類,叫

HackedClient

.java

的檔案字尾會自動加! 同時,在主包下面建立一個新的包,叫

module

,這裡面将會存放所有的子產品和子產品管理器。在

module

裡建立兩個類,

Module

ModuleManager

Module

是所有子產品的模版,

ModuleManager

則是子產品管理器。最後,在

module

裡建立一個enum類,叫

Category

1x002 Category.java

package me.hack.hackedclient.module;

public enum Category {

	COMBAT, MOVEMENT, PLAYER, RENDER, MISC

}
           

這個類就是一個子產品可能的分類,所有的子產品都會被分到這5個類裡面。

1x003 Module.java

package me.hack.hackedclient.module;

import net.minecraft.client.Minecraft;

public class Module {

	protected Minecraft mc = Minecraft.getMinecraft();
	private String name;
	private int key;
	private boolean toggled;
	private Category category;

	public Module(String nm, int k, Category c) {
		name = nm;
		key = k;
		category = c;
		toggled = false;
	}

	public void toggle() {
		toggled = !toggled;
		if(toggled) {
			onEnable();
		} else {
			onDisable();
		}
	}

	public void onEnable() {}
	public void onDisable() {}
	public void onUpdate() {}
	public void onRender() {}

	public Minecraft getMc() {
		return mc;
	}

	public void setMc(Minecraft mc) {
		this.mc = mc;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public int getKey() {
		return key;
	}

	public void setKey(int key) {
		this.key = key;
	}

	public boolean isToggled() {
		return toggled;
	}

	public void setToggled(boolean toggled) {
		this.toggled = toggled;
	}

}
           

這個類是所有子產品的模版,其中

onEnable

onDisable

onUpdate

,和

onRender

是空的,因為子產品會override。

1x004 HackedClient.java

package me.hack.hackedclient;

import org.lwjgl.opengl.Display;

import me.hack.hackedclient.module.ModuleManager;

public class HackedClient {

	public static String name = "Hacked Client", version = "1.0.0", creator = "me";

	public static ModuleManager moduleManager;

	public static void startClient() {
		moduleManager = new ModuleManager();

		Display.setTitle(name + " " + version + " by " + creator);
	}

}
           

挂端的主類,用于将外挂注入到原我的世界中。

1x005 ModuleManager.java

package me.hack.hackedclient.module;

import java.util.ArrayList;

public class ModuleManager {

	private static ArrayList<Module> mods;

	public ModuleManager() {
		mods = new ArrayList<Module>();
		// COMBAT
		// MOVEMENT
		// PLAYER
		// RENDER
		// MISC
	}

	public static void newMod(Module m) {
		mods.add(m);
	}

	public static ArrayList<Module> getModules() {
		return mods;
	}

	public static void onUpdate() {
		for(Module m : mods) {
			m.onUpdate();
		}
	}

	public static void onRender() {
		for(Module m : mods) {
			m.onRender();
		}
	}

	public static void onKey(int k) {
		for(Module m : mods) {
			if(m.getKey() == k) {
				m.toggle();
			}
		}
	}

}
           

這個類是子產品控制器,所有的子產品都會在這裡被注冊。

1x006 注入

現在,我們會把我們挂端需要執行的代碼混到我的世界的源代碼裡面。

首先,輕按兩下RShift,打開

Minecraft.java

。然後,Ctrl+F搜尋

ingameGUI

,直到這行代碼:

...
this.ingameGUI = new GuiIngame(this);
...
           

在這行代碼下面添加:

// Hacked Client
HackedClient.startClient();
           

然後導入這個類。我建議你們在動我的世界源代碼的時候寫上注釋,這樣才能知道那些事我的世界的源代碼,那些是你後來加進去的。

往下翻,直到這裡:

...
private void createDisplay() throws LWJGLException
{
	Display.setResizable(true);
	Display.setTitle("Minecraft 1.8.8");
	...
           

修改為:

...
private void createDisplay() throws LWJGLException
{
	Display.setResizable(true);
	Display.setTitle("Loading Hacked Client");
	...
           

随後,還是在

Minecraft.java

裡,搜尋

k == 1

,直到這裡:

...
if (this.currentScreen != null)
{
	this.currentScreen.handleKeyboardInput();
}
else
{
	if(k == 1)
	{
		this.displayInGameMenu();
	}
	...
           

修改為:

...
if (this.currentScreen != null)
{
	this.currentScreen.handleKeyboardInput();
}
else
{
	// Hacked Client
	HackedClient.moduleManager.onKey(k);
	if(k == 1)
	{
		this.displayInGameMenu();
	}
	...
           

輕按兩下RShift,搜尋

EntityPlayerSP

,打開檔案後Ctrl+F搜尋

onLivingUpdate

,直到這裡:

...
public void onLivingUpdate()
{
	if (this.sprintingTicksLeft > 0)
	{
		--this.sprintingTicksLeft;
		...
           

修改為:

...
public void onLivingUpdate()
{
	// Hacked Client
	HackedClient.moduleManager.onUpdate();
	if (this.sprintingTicksLeft > 0)
	{
		--this.sprintingTicksLeft;
		...
           

輕按兩下RShift,搜尋

EntityRenderer

,打開後搜尋

"hand"

,直到這附近:

...
this.mc.mcProfiler.endStartSection("hand");
boolean flag3 = Reflector.callBoolean(Reflector.ForgeHooksClient_renderFirstPersonHand, new Object[] {this.mc.renderGlobal, Float.valueOf(partialTicks), Integer.valueOf(pass)});
...
           

修改為:

...
this.mc.mcProfiler.endStartSection("hand");
// Hacked Client
HackedClient.moduleManager.onRender();
boolean flag3 = Reflector.callBoolean(Reflector.ForgeHooksClient_renderFirstPersonHand, new Object[] {this.mc.renderGlobal, Float.valueOf(partialTicks), Integer.valueOf(pass)});
...
           

然後,你就可以開始寫子產品了!

1x007 第一個子產品 - AutoSprint

me.hack.hackedclient.module

中建立一個包,叫

movement

,所有移動類的子產品都會被存放在這裡。在這個包下建立一個類,叫

AutoSprint

,在裡面寫:

package me.hack.hackedclient.module.movement;

import me.hack.hackedclient.module.Category;
import me.hack.hackedclient.module.Module;
import org.lwjgl.input.Keyboard;

public class AutoSprint extends Module {

    public AutoSprint() {
        super("AutoSprint", Keyboard.KEY_F, Category.MOVEMENT);
    }

    @Override
    public void onUpdate() {
    	if(this.isToggled()) {
            if(!mc.thePlayer.isCollidedHorizontally && mc.thePlayer.moveForward > 0 && !mc.thePlayer.isSneaking()) {
                mc.thePlayer.setSprinting(true);
            }
        }
        super.onUpdate();
    }

}
           

随後,把

ModuleManager

的構造器更改為:

public ModuleManager() {
	mods = new ArrayList<Module>();
	// COMBAT
	// MOVEMENT
	newMod(new AutoSprint());
	
	// PLAYER
	// RENDER
	// MISC
}
           

并在

import

部分添加:

1x008 測試

現在,打開指令行,

cd

ROOT

,然後運作

recompile.bat

來重新編譯我的世界。編譯完成後,運作

startclient.bat

來啟動新的我的世界。如果沒錯的話,現在進入一個世界後按F,那麼你前進的時候将會自動跑步。至此,我們已經完成了第一個子產品!

— 完 —

如果大家遇到任何問題可以發在評論區,我會盡快回複!