- 致编者:请牢记我们的域名wiki.mcbe-dev.net!
- 致编者:欢迎加入本Wiki的官方交流QQ群或Discord服务器!
- 基岩版1.19.31现已发布!(了解更多)
- Inner Core现已支持Xbox模组联机!(了解更多)
- 如果您是第一次来到本Wiki,欢迎注册一个账户
- 点击顶部的“编辑”或“编辑源代码”按钮即可编辑当前页面
- 请知悉:在不登录时也可以编辑和新建页面,但是您当前的IP地址会记录在编辑历史中
原生遊戲模組/N模組API
NModAPI文件涵蓋了NModAPI的全部內容,且含有少許原生外掛編寫指南。它由ModelPart、int100和TimScriptov共同編寫,支援中文、英文與俄文,使用Apache 2.0許可在GitHub上發布。
本頁面是NModAPI的搬運,有少量修改[注 1]。經三位作者同意後,使用CC BY-NC-SA 4.0(即本Wiki的預設許可)授權。
文件中有些內容已經過時,僅供參考用。
NModAPI文件[編輯]
其它語言[編輯]
NMod是什麼?[編輯]
NMod的全稱是Native-Mod。Native-Mod透過原生程式碼(C/C++)來修改Minecraft,所以被稱為NMod。
眾所周知,MCPE主要由C++編寫。NMod比ModPE腳本有著更好的修改效果,為什麼不學著去做NMod呢?
但是,製作NMod不是一件易事,因為C++語言比JavaScript更難,以及原生修改方法的操作不是那麼容易理解的。以下的內容將告訴你如何開發NMod。
開發準備[編輯]
- C++基礎
- 一個支援NDK的Android IDE(如Android Studio, Eclipse, AIDE等)
- 知道如何構建Android原生庫(
*.so
) - Json語法
連結庫[編輯]
NMod透過連結libsubstrate.so
[注 2]和libminecraftpe.so
以執行對MCPE的修改。請確保你的NMod已連結至substrate模組與minecraftpe模組(你可以透過閱讀我們的實例知悉如何連結這些庫)。
事件監聽器[編輯]
NModAPI為NMod載入完畢、遊戲啟動與遊戲退出三個事件提供了監聽器,你只需定義這些方法。當事件發生時,NModAPI將會呼叫這些方法。
NMod載入完畢(OnLoad)[編輯]
NMod_OnLoad(JavaVM* javaVM, JNIEnv* jniEnv, const char* minecraftVersion, const char* nmodApiVersion, const char* pathOflibminecraftpeso)
javaVM
是一個指向JavaVM
的指針。jniEnv
是一個指向JNIEnv
的指針。minecraftVersion
是一個C風格的字串,內容為目前Minecraft的版本名稱。nmodApiVersion
是一個C風格的字串,內容為NModAPI的版本名稱。pathOflibminecraftpeso
是一個C風格字串,內容為libminecraftpe.so
的路徑。你可以使用dlopen
裝載它:dlopen(pathOflibminecraftpeso, RTLD_LAZY)
。
遊戲啟動(OnActivityCreate)[編輯]
NMod_OnActivityCreate(JNIEnv* env, jobject thiz, jobject savedInstanceState)
env
是一個指向JNIEnv
的指針。thiz
是一個jobject
,Java型別簽名為[Lcom/mojang/minecraftpe/MainActivity;]
。savedInstanceState
是一個jobject
,Java型別簽名為[Landroid/os/Bundle;]
。
遊戲退出(OnActivityFinish)[編輯]
NMod_OnActivityFinish(JNIEnv* env, jobject thiz)
env
是一個指向JNIEnv
的指針。thiz
是一個jobject
,Java型別簽名為[Lcom/mojang/minecraftpe/MainActivity;]
。
修改內建方法[編輯]
經過以上的步驟後,我們該如何修改Minecraft中的內建方法?
Substrate框架提供了一個修改的方法——MSHookFunction
,該方法可以用我們自己定義的方法替換libminecraftpe.so
中定義的預設方法,也提供了一個呼叫預設方法的途徑。
呼叫MSHookFunction
方法需要三個參數:
MSHookFunction(
(void*)& DefaultMethod,
(void*)& ReplacementMethod,
(void**)& MethodPointerOfDefaultMethod
);
例如,如果我們想要替換libminecraftpe.so
中的Explosion::explode()
方法,我們可以這樣寫:
// 定义默认方法(原方法)
class Explosion
{
public:
void explode();
}
// 定义一个函数指针
void (*explode_default)(Explosion*);
void explode_replacement(Explosion* self)
{
// Do Something
// 如果不想忽略这次爆炸,请调用函数指针:
explode_default(self);
}
// 在 NMod_OnLoad 中注册 MSHookFunction 方法
extern "C" void NMod_OnLoad(JavaVM*,JNIEnv*,const char*,const char*,const char*)
{
MSHookFunction((void*)& Explosion::explode,
(void*)& explode_replacement,
(void**)& explode_default);
}
NMod組態[編輯]
NModAPI透過讀取nmod_manifest.json
來取得NMod組態。你也可以在組態中編輯assets
下的Json與文字。[注 3]
{
// 提示:你不用定义该配置文件中的所有内容。
// NMod 名称
"name" : "My NMod",
// NMod 的包名,必须与 AndroidManifest.xml 中的包名一致。
"package_name" : "my.nmod.package.name",
// NMod 的作者,在此写下你的名字或组织名。
"author" : "Me or My Company",
// NMod 原生库
"native_libs_info" :
[
{
// 原生库名,必须与你的库名一致。
"name" : "libmynmodlib.so",
// 该 NMod 是否使用 NModAPI
// 如果你使用了事件监听器(NMod_OnLoad, NMod_OnActivityCreate,
// NMod_OnActivityFinish),use_api 必须为 true 。
"use_api" : "true"
}
// 你还可以在此加载更多库
//,
//{
// "name" : "libmynmodlib2.so",
// "use_api" : false
//}
],
// NMod 版本号
// 默认值为 -1 。
"version_code" : 1,
// NMod 版本名
"version_name" : "1.0",
// Minecraft 版本名
"minecraft_version_name" : "1.11.0.1",
// NMod 描述
"description" : "My NMod Description",
// 更新内容
"change_log" : "My NMod Change Log",
// NMod Banner
// NMod Banner 是在主界面展示的一张图像。
// 图像下方的文本视图,默认值为 NMod 名称(name)。
"banner_title" : "My NMod is the Best!",
// 在 assets 文件夹内的图像路径
// 图像大小必须为 1024(长) * 500(宽)。
// 在当前设置下,NMod 将会寻找 assets/my_banner.png 。
"banner_image_path" : "my_banner.png"
// 材质文本编辑 API
// text_edit 允许你编辑 Minecraft PE 中材质的文本文件。
/*
,
"text_edit" :
[
{
// assets 中要修改的的文本文件路径
// 要替换的文件与默认文件(源文件)必须同时在 NMod 与 Minecraft PE 的 assets 中定义。
// 在当前设置下,NModAPI 将会读取 assets/resource_packs/vanilla/texts/en_US.lang 。
"path" : "resource_packs/vanilla/texts/en_US.lang",
// 有三种编辑模式:append(追加), prepend(前置), replace(替换),默认值为 replace 。
// 如果你定义了一种不存在的模式,编辑将不起作用。
// append:在源文件后追加文本。
// prepend:在源文件前追加文本。
// replace: 用 NMod assets 中定义的新文本替换源文本。
// 在当前设置下,NModAPI 将会在默认文本(源文本)后追加要替换的文本。
"mode" : "append"
},
{
"path" : "resource_packs/vanilla/texts/zh_CN.lang",
"mode" : "append"
}
]*/
// 材质 Json 编辑 API
// json_edit 允许你编辑 Minecraft PE 中材质的 Json 文件。
/*
,
"json_edit" :
[
{
// assets 中要修改的 Json 文件路径。
// 要替换的文件与默认文件(源文件)必须同时在 NMod 与 Minecraft PE 的 assets 中定义。
// 在当前设置下,NModAPI 将会读取 resource_packs/vanilla/textures/item_texture.json
"path" : "resource_packs/vanilla/textures/item_texture.json",
// 有两种编辑模式:merge(合并),replace(替换),默认值为替换。
// 如果你定义了一种不存在的模式,编辑将不起作用。
// merge:合并两个 Json 文件。
// replace:用 NMod assets 中定义的新 Json 替换源 Json。
// 在当前情况下,NModAPI 将会合并两个 Json 为一个。
"mode" : "merge"
}
// 你还可以在此编辑更多的 Json
//,
//{
// "path" : "File Path",
// "mode" : "replace"
//}
]
*/
}
打包你的NMod[編輯]
打包成APK[編輯]
如果你的NMod被打包成一個APK檔案,它可以被Android軟件包管理器安裝且能被NModAPI讀取。
在這種情況下,nmod_manifest.json
應該放入assets
資料夾內。原生庫應該打包進lib/[对应的CPU架构]
內。
提示:
- NModAPI僅讀取兩種架構:
armeabi-v7a
以及x86
。 - 安裝新版本的NMod時,使用Android軟件包管理器的NMod可以自動更新。所以這種方式大部分用於開發NMod。
注意:
- 在
nmod_manifest.json
中定義的package_name
必須與AndroidManifest.xml
中定義的package
屬性一致。
打包成檔案[編輯]
不喜歡安裝APK?你還可以將你的NMod打包成一個檔案!它的副檔名可以為*.apk
, *.zip
, *.nmod
, *.mcnmod
。
在這種情況下,nmod_manifest.json
可以放入assets
資料夾或NMod的根目錄。
提示:
- 打包成檔案的NMod不能自動更新,所以這種方式大部分用於發布NMod。
注意:
- 不要在不同路徑中同時放置兩個
nmod_manifest.json
!
仍然不理解?[編輯]
- 查閱我們的範例! https://github.com/TimScriptov/NMOD-Examples
- 查閱NModAPI的源程式碼! https://github.com/TimScriptov/ModdedPE