Skip to content

zh_cn_module

KlparetlR edited this page Sep 16, 2024 · 2 revisions

模块文件

模块文件是一个数组,数组中包含若干的对象。

第一个对象是且仅是模块信息。剩下的则是翻译信息

模块信息(ModuleInfo)

模块信息,用于描述该模块的详细信息。

其中有5个键值,如下所示:

  • name,字符串,代表该模块的名称。
  • desc,字符串,代表该模块的描述信息。
  • authors,字符串,代表编写该模块的作者。
  • mods,字符串,代表该模块应该是应用于哪个模组上的。
  • dynamic,布尔型,代表该模块是否为动态替换,true为是,false为不是。如果一个模块是动态替换,那么它在获取替换后的值时是遍历键值对数组,而不是直接从原值映射到替换后的值,这是为了半匹配服务的。
  • i18n,布尔型,代表该模块是否要使用i18n服务,该服务会对存入的值根据所选语言替换为对应的值。

翻译信息(TranslationInfo)

翻译信息包含如下内容

  • pairs,数组,代表该翻译信息的键值对数组。(必选)

    本质上是一个Map。数组中可以有若个键值对,每个键值对包含keyvalue两个键,分别代表原值替换后的值,在替换时从key映射到value

    对于每个value的值,如果该模块是动态替换,并且value的首字母是@,那么该键值对会自动优化为半匹配键值对,会替换整个字符串中与value的值相匹配的那部分内容;如果value的首字母不是@,则该键值对属于全匹配键值对,如果整个字符串与value的值相匹配,则进行替换。

    对于半匹配键值对,VP会从其中找到符合条件的键值对,将与key匹配的部分字符串替换为value(不含首字母@);对于全匹配键值对,直接将与key匹配的整个字符串替换为value。如果要表示首字母为@value,那么请写成@@的形式。

    PS:如果你的pairs仅有一个键值对,那么你可以不需要使用pairs,转而变为keyvalue。如下面示范的第二个"target_class"所在位置

  • target_class,对象,代表该翻译信息的目标类,包含4个键:(必选)

    1. name代表将被替换的文本所在的类的类名。(在ASM模式下必填,否则替换不会生效;在动态替换模式下,那么它可以被省略,但要有一个空的target_class。)

    2. method代表将被替换的文本所在的方法,如果是字段,那么请忽略它。VP不考虑方法重载的问题,只要是与该值相等的方法名均会进行替换。(可选)

    3. local代表将要被替换的文本是哪个方法的返回值或局部变量的名称,这适用于一些仅在运行时得知具体值的场景下,以标志+目标为填写标准。(仅ASM模式,可选)

      • 方法调用:如果标志M,那么目标是将要替换的方法的名称。

        代码逻辑:替换一个方法的返回值,name.method(); -> vp_replace(name.method());

      • 局部变量:如果标志V,那么目标是将要替换该方法体内局部变量(局部变量包括实参)的名称。

        代码逻辑:在写入与读取前替换,this.name = lname; -> this.name = vp_replace(lname);lname = anotherName; -> lname = vp_replace(anotherName);

      • 方法返回:如果标志R,那么目标是将要替换的方法的名称。

        代码逻辑:替换该方法体内的返回值,return var; -> return vp_replace(var);

      • 全局变量:如果标志G,那么目标是将要替换是字段的名称。

        代码逻辑:与标志V相同。

    4. ordinal代表此替换操作的操作序数,操作序数是该指令在方法体所有指令的索引,例如第一条指令为1,第二条指令为2,具体数值可使用debug输出查看。与当前指令不匹配的,VP不会替换,最大限度的缩小替换范围。(仅ASM模式,可选)

    对于多个target_class中需要用的同一个pairs的情况,可以转而使用target_classes。该值是一个数组,包含若干个target_class对象,每个target_class对象都会对应到该pairs

    注意:对于同一个类被多个翻译信息引用的情况,只有最后被加载的翻译信息会生效。

Ps:此外,它们还有自己的首字母缩写名,分别为key->kvalue->vtarget_class->tname->nmethod->mlocal->lpairs->ptarget_glasses->sordinal->o,这样你可以缩小文件的大小,VP一样可以读取它们。

示例

下面是一个示例模块文件:

[
  {
    "authors": "",
    "name": "汉化包",
    "desc": "只是汉化而已",
    "mods": "XXXX",
    "dynamic": false
  },
  {
    "target_class": {
      "name": "com.robertx22.age_of_exile.vanilla_mc.items.misc.RarityStoneItem",
      "method": ""
    },
    "pairs": [
      {
        "key": " durability.",
        "value": "点耐久。"
      }
    ]
  },
  {
    "target_class": {
      "name": "com.robertx22.age_of_exile.uncommon.utilityclasses.TooltipUtils",
      "method": ""
    },
    "key": "[Drag onto gear to use]",
    "value": "[放在装备上以使用]"
  },
  {
    "target_class": {
      "name": "iskallia.vault.gear.VaultGearRarity",
      "method": "getDisplayName",
      "local": "Mcapitalize"
    },
    "pairs": [
      {
        "key": "Scrappy",
        "value": "破烂"
      },
      {
        "key": "Common",
        "value": "普通"
      },
      {
        "key": "Rare",
        "value": "稀有"
      }
    ]
  },
  {
    "target_classes": [
      {
        "name": "com.example.mod.SomethingClass",
        "method": "doSomething",
        "local": "Lsomething",
        "ordinal": 209
      },
      {
        "name": "com.example.mod.AnotherClass",
        "method": "doAnotherSomething",
        "local": "LAnothersomething",
        "ordinal": 222
      }
    ],
    "pairs": [
      {
        "key": "xxx",
        "value": "xxx"
      }
    ]
  }
]