BWIKI 全站将于 9 月 3 日(全天)进行维护,期间无法编辑任何页面或发布新的评论。
模组:制作指南/APIs/Content Packs
← 模组:目录
内容包(content pack)是一种特殊的模组,它不直接由 SMAPI 运行,但包含您的模组可以读取的文件。
内容包格式
内容包是一个文件夹,它包含一个 manifest.json 文件,该文件的 ContentPackFor 列出了需要读取该内容包的模组(参见[[../Manifest|清单文件]])。除此之外的格式由您自定定义。例如,Content Patcher 需要一个 content.json 文件,但 SMAPI 并不会直接验证它。与之相对地,SMAPI 会提供一个接口,以让您从内容包中读取所需的其他文件。
参见模组:内容包以获取关于内容包的更多信息。
内容包接口
获取拥有的内容包
可以按如下方式获取针对您模组的、已安装的内容包(其中 Manifest 字段包含了内容包的完整清单信息):
foreach(IContentPack contentPack in this.Helper.ContentPacks.GetOwned())
{
this.Monitor.Log($"Reading content pack: {contentPack.Manifest.Name} {contentPack.Manifest.Version} from {contentPack.DirectoryPath}");
}
内容包会按照加载顺序列出,因此已经按照依赖关系排序。例如,如果内容包B 依赖于内容包A,则会按照 A → B 的顺序列出。
注意,您可以早在 ModEntry 中调用此方法,但是模组经常在 GameLoad 或 SaveLoaded 事件中调用此方法。
检查文件是否存在
您可以使用 HasFile 来检查内容包中是否存在某文件。可以使用相对路径,例如 data/content.json。
if (!contentPack.HasFile("content.json"))
{
// show 'required file missing' error
}
在部署时,如果有文件缺失,建议您提醒玩家(和使用您模组的开发者)。
读取 JSON 文件
您可以使用 ReadJsonFile 来把 JSON 文件读入数据模型(在下面的例子中,为 YourDataModel)。您可以使用相对路径,例如 data/content.json。如果文件不存在,则返回 null。
YourDataModel data = contentPack.ReadJsonFile<YourDataFile>("content.json");
写入 JSON 文件
您可以使用 WriteJsonFile 来把数据模型(在下面的例子中,为 YourDataModel)中的数据写入到 JSON 文件。您可以使用相对路径,例如 data/content.json(如果需要,会自动创建子目录)。若文件不存在,则会创建相应文件;若存在,则会覆写。
注意:这最好用于生成文件。不建议覆写文件,因为如果您的模组存在漏洞,则可能永久损坏内容包,使得玩家不得不重新安装。
YourDataModel data = new YourDataModel();
contentPack.WriteJsonFile("content.json", data);
读取内容素材
您可以使用 LoadAsset 从内容包文件夹中读取 内容素材。您可以指定相对路径以从子文件夹中读取。
Texture2D image = contentPack.ModContent.Load<Texture2D>("image.png");
如果您需要将某个素材名称传入游戏代码,您可以使用 GetActualAssetKey 方法:
tilesheet.ImageSource = contentPack.GetActualAssetKey("image.png");
获取翻译
您可以从内容包的 i18n 文件夹读取翻译。这与翻译接口相同,不同点在于调用的是 contentPack.Translations:
string text = contentPack.Translation.Get("item-type.label");
创建伪内容包
在某些特殊情况下,您可以在指定文件路径下创建临时内容包:
// create with random manifest data
IContentPack contentPack = this.Helper.ContentPacks.CreateFake(
directoryPath: Path.Combine(this.Helper.DirectoryPath, "content-pack"),
);
// create with given manifest fields
IContentPack contentPack = this.Helper.ContentPacks.CreateTemporary(
directoryPath: Path.Combine(this.Helper.DirectoryPath, "content-pack"),
id: Guid.NewGuid().ToString("N"),
name: "temporary content pack",
description: "...",
author: "...",
version: new SemanticVersion(1, 0, 0)
);