提示
若您并没有拥有 Minecraft 账号,请自行退出,否则在完成之后你可能将会违反 Minecraft EULA,该教程仅适用于拥有 Minecraft 账号的人。
反编译
首先下载用于反编译 Minecraft 1.12.2 的工具,MCP,若打不开链接可使用 DevSidecar。
下载完成之后将下载好的文件解压到单独一个目录。
然后使用任意 Minecraft 启动器切换到官方启动器目录并使用 正版登录/微软登录 启动一次原版 Minecraft 1.12.2 并退出。
退出之后,在打开的目录中打开 powershell 并输入:
./decompile.bat
输入后等待反编译完成即可,反编译大概需要 10-20 分钟左右,反编译时间受电脑配置影响。
最后反编译完成将会显示大概如下内容:
导入项目
这里以 IntelliJ IDEA 为例,进入主界面后点击 打开项目 然后选择打开的目录中的 eclipse\Client 目录。
然后打开项目结构导入模块,首先点到模块界面点击导入模块并选择打开的目录的 eclipse\Client\.project 文件点击确定,然后一直点下一步和创建,最后点击否,然后点击添加内容根,内容根选择打开的目录的 src\minecraft 目录,语言级别选择 JDK 8。
提示:若导入模块后已有其他内容根,请全部删除。
最后点击应用并关闭即可。
运行
首先点击 IDEA 右上角的当前文件并选择编辑配置,随后点击添加应用程序,选择 JDK 17,主类选择 Start,然后添加 VM 选项,VM选项填写以下内容:
-Djava.library.path=打开的目录\jars\versions\1.12.2\1.12.2-natives
提示:natives 目录名称与启动器有关,此教程示例为 PCL2 启动器。
工作目录选择打开的目录的 jars 目录,程序实参填写 --username Dev (可选)。
最后保存并运行测试即可。
打包
首先打开项目结构并点到工件界面添加 JAR,选择空,然后将 'Client' 编译输出 添加进去,最后应用关闭。
最后构建工件即可看到打包好的文件,若需运行,可将构建好的文件覆盖原版文件运行,但请注意,若启动器有文件校验,需要提前关闭启动器的文件校验功能。
修改游戏窗口标题及简易功能实现
修改游戏窗口标题
首先打开类文件 net.minecraft.client.Minecraft,随后找到函数 createDisplay ,然后将 Minecraft 1.12.2 改为你想要的名称即可。
截图超出上传的文件大小范围就不上传了
简易功能实现-Spider
功能名称解释
使你能够像蜘蛛一样随意在墙上攀爬。
实现
首先新建一个软件包,并新建一个类,然后创建两个函数,以及一个布尔值函数。
package cn.ksmcbrigade; //packet
public class Client {
public static boolean enabled = false;
public static void tick(){ //event
}
public static void keyInput(int key){ //event
}
}
然后在 net.minecraft.client.Minecraft 类中的 runTick 函数中的任意位置插入引用 tick 函数的代码以注册客户端 Tick 事件:
public void runTick() throws IOException
{
Client.tick(); // add
if (this.rightClickDelayTimer > 0)
{
--this.rightClickDelayTimer;
}
this.mcProfiler.startSection("gui");
if (!this.isGamePaused)
{
this.ingameGUI.updateTick();
}
this.mcProfiler.endSection();
this.entityRenderer.getMouseOver(1.0F);
this.field_193035_aW.func_193297_a(this.world, this.objectMouseOver);
this.mcProfiler.startSection("gameMode");
if (!this.isGamePaused && this.world != null)
{
this.playerController.updateController();
}
this.mcProfiler.endStartSection("textures");
[...]
}
然后再在 runTickKeyboard 函数的任意位置插入 keyInput 函数以注册按键检测事件。
private void runTickKeyboard() throws IOException
{
while (Keyboard.next())
{
int i = Keyboard.getEventKey() == 0 ? Keyboard.getEventCharacter() + 256 : Keyboard.getEventKey();
if (this.debugCrashKeyPressTime > 0L)
{
if (getSystemTime() - this.debugCrashKeyPressTime >= 6000L)
{
throw new ReportedException(new CrashReport("Manually triggered debug crash", new Throwable()));
}
if (!Keyboard.isKeyDown(46) || !Keyboard.isKeyDown(61))
{
this.debugCrashKeyPressTime = -1L;
}
}
else if (Keyboard.isKeyDown(46) && Keyboard.isKeyDown(61))
{
this.actionKeyF3 = true;
this.debugCrashKeyPressTime = getSystemTime();
}
this.dispatchKeypresses();
if (this.currentScreen != null)
{
this.currentScreen.handleKeyboardInput();
}
boolean flag = Keyboard.getEventKeyState();
if (flag)
{
Client.keyInput(i); //add
if (i == 62 && this.entityRenderer != null)
{
this.entityRenderer.switchUseShader();
}
boolean flag1 = false;
if (this.currentScreen == null)
{
if (i == 1)
{
this.displayInGameMenu();
}
flag1 = Keyboard.isKeyDown(61) && this.processKeyF3(i);
this.actionKeyF3 |= flag1;
if (i == 59)
{
this.gameSettings.hideGUI = !this.gameSettings.hideGUI;
}
}
[...]
然后在 keyInput 函数中判断你想要设置的键位是否启用,比如 V 键,若启用则将布尔值函数设置为 true:
public static void keyInput(int key){ //event
if(Keyboard.KEY_V==key){ //if key
enabled=!enabled; //set enabled
}
}
然后再在 tick 函数中判断是否启用,启用则判断玩家是否是水平碰撞状态,若是,则判断玩家 Y 运动值是否小于 0.2,若小于,则设置为 0.2:
public static void tick(){ //event
if(enabled){ //if enabled
EntityPlayerSP player = Minecraft.getMinecraft().player; //get player
if(player!=null && player.isCollidedHorizontally){ //if != null and collided horizontally
if(player.motionY<0.2){ //if < 0.2
player.motionY = 0.2; //set 0.2
}
}
}
}
最后运行测试即可。
Client.java 完整代码
package cn.ksmcbrigade; //packet
import net.minecraft.client.Minecraft;
import net.minecraft.client.entity.EntityPlayerSP;
import org.lwjgl.input.Keyboard;
public class Client {
public static boolean enabled = false;
public static void tick(){ //event
if(enabled){ //if enabled
EntityPlayerSP player = Minecraft.getMinecraft().player; //get player
if(player!=null && player.isCollidedHorizontally){ //if != null and collided horizontally
if(player.motionY<0.2){ //if < 0.2
player.motionY = 0.2; //set 0.2
}
}
}
}
public static void keyInput(int key){ //event
if(Keyboard.KEY_V==key){ //if key
enabled=!enabled; //set enabled
}
}
}