原生遊戲模組/N模組API

出自Minecraft基岩版开发Wiki
(重新導向自原生模组/NModAPI

NModAPI文件涵蓋了NModAPI的全部內容,且含有少許原生外掛編寫指南。它由ModelPart、int100和TimScriptov共同編寫,支援中文、英文與俄文,使用Apache 2.0許可在GitHub上發布。

本頁面是NModAPI的搬運,有少量修改[注 1]。經三位作者同意後,使用CC BY-NC-SA 4.0(即本Wiki的預設許可)授權。

文件中有些內容已經過時,僅供參考用。


NModAPI文件[編輯]

其它語言[編輯]

NMod是什麼?[編輯]

NMod的全稱是Native-ModNative-Mod透過原生程式碼(C/C++)來修改Minecraft,所以被稱為NMod。

眾所周知,MCPE主要由C++編寫。NMod比ModPE腳本有著更好的修改效果,為什麼不學著去做NMod呢?

但是,製作NMod不是一件易事,因為C++語言比JavaScript更難,以及原生修改方法的操作不是那麼容易理解的。以下的內容將告訴你如何開發NMod。

開發準備[編輯]

  1. C++基礎
  2. 一個支援NDK的Android IDE(如Android Studio, Eclipse, AIDE等)
  3. 知道如何構建Android原生庫(*.so
  4. 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

仍然不理解?[編輯]


註解[編輯]

  1. 修改僅限於使用wikitext排版、刪去中英文間空格和加入註解。主要內容的修改應提交至GitHub。
  2. 請注意,Cydia Substrate不支援64位Android。
  3. minecraft_version_name僅在藍版ModdedPE中可用。