资讯动态

RPFM 插件脚本实战指南:用 Python 与 Lua 对 Pack 文件执行批量编辑

发布时间:2026/10/14 3:08:59 来源:尧图企业网站定制
游戏开发桌面应用开发工具MCP 服务【免费下载链接】rpfmRusted PackFile Manager (RPFM) is a... reimplementation in Rust and Qt6 of PackFile Manager (PFM), one of the best modding tools for Total War Games.项目地址https://gitcode.com/gh_mirrors/rp/rpfm点击查看免费下载RPFMRusted PackFile Manager的插件脚本Plugin Scripts功能允许你用自己编写的 Python 或 Lua 脚本直接对 Pack 树中选中的文件执行批量处理——无论是给所有 Loc 词条批量加前缀、跨表批量重写某一列还是成批重命名引用都能在脚本层面自动化完成。本文将完整讲解脚本的安装、触发、执行机制与 TSV 数据交换格式并结合仓库源码与官方示例深入剖析底层调用链帮助你快速写出可复用、可调试的批量处理脚本。功能定位为重复性批量编辑而生在制作 Total War 模组时大量操作是机械而重复的为某个 Loc 文件的全部词条加上统一前缀、把某张 DB 表的一列批量改写、成组重命名引用路径等。逐个手工操作既耗时又容易遗漏。插件脚本正是为此设计的实验性Experimental功能——它的工作方式是把你在 Pack 树中选中的文件提取到临时目录调用外部解释器执行你的脚本再把可能被修改过的文件读回 Pack 内部。需要特别注意该功能目前仍标记为Experimental脚本的调用方式与数据传递形式在未来版本中仍可能发生变化。在编写大批量依赖脚本前建议先关注项目更新日志。从源码调用链看该功能横跨 UI、IPC 与 Server 三层UI 层rpfm_ui/src/packfile_contents_ui/slots.rs负责构建右键菜单rpfm_ui/src/packfile_contents_ui/mod.rs中的run_plugin_script方法负责发送命令IPC 层rpfm_ipc/src/messages.rs定义了RunPluginScript(String, PathBuf, VecContainerPath)命令消息Server 层rpfm_server/src/background_thread.rs中的对应分支负责提取、执行与回读。安装脚本把.py/.lua放进scripts文件夹插件脚本的安装非常简单把脚本文件丢进 RPFM配置文件夹config folder下的scripts子目录即可。RPFM 在首次需要时就会为你创建这个文件夹无需手动新建。如何找到配置文件夹配置文件夹的位置取决于操作系统详情见 settings 文档 的 Where settings live on disk 一节Linux 上通常为~/.config/rpfm/Windows 上通常为%AppData%\rpfm\Debug 构建则使用程序工作目录另外两种快速定位方式在 UI 中通过Game Selected → Open RPFMs Config Folder菜单直接打开该动作的实现位于 rpfm_ui/src/app_ui/slots.rs 的game_selected_open_config_folder槽内部调用config_path()后交由系统文件管理器打开在偏好设置中指定Custom config folder自定义配置文件夹整个配置树会随之迁移。从源码看scripts文件夹是配置树的标准子目录之一rpfm_server/src/settings.rs中的init_config_path()在初始化配置目录时就会调用scripts_path()并递归创建它config_path()?.join(scripts)与autosaves、schemas、table_patches等子目录一并就绪。解释器选择规则RPFM根据文件扩展名选择解释器扩展名解释器说明.pypython须存在于系统PATH中.lualua须存在于系统PATH中官方示例兼容 Lua 5.1 ~ 5.4其他不支持不会被列入 Run Script 菜单这一映射实现在rpfm_server/src/background_thread.rs的plugin_script_interpreter()函数中Some(py) Some(python)、Some(lua) Some(lua)其余返回None。返回None的脚本不会被菜单列出若强行运行会收到Unsupported plugin script type错误。仓库自带两个开箱即用的示例位于examples/plugin_scripts/目录可直接复制进scripts文件夹使用examples/plugin_scripts/add_emojis_to_loc.pyPython 版examples/plugin_scripts/add_emojis_to_loc.luaLua 版这两个脚本的功能是把每个 Loc 词条text值的前后各加上一个火焰 emoji是理解 TSV 处理规范的最佳范例下文详解。运行脚本Pack 树右键菜单三步走运行脚本的完整操作流程在Pack 树Pack tree即显示每个已打开 Pack 内容的左侧面板参见 pack-tree.md中选中一个或多个文件/文件夹支持Shift范围多选与Ctrl加选右键打开上下文菜单进入Run Script子菜单——它会列出scripts文件夹中的全部脚本若文件夹为空则显示No scripts found中文界面为未找到脚本点击某个脚本RPFM 随即执行它并把结果读回 Pack。该菜单在 UI 层的构建逻辑位于rpfm_ui/src/packfile_contents_ui/slots.rscontextual_menu_run_script_about_to_show约第 1125 行在子菜单即将弹出时扫描配置文件夹中的脚本并动态填充菜单项contextual_menu_run_script约第 1155 行在用户选中某个脚本后调用PackFileContentsUI::run_plugin_script真正执行菜单文案通过 locale 本地化context_menu_run_script 运行脚本、context_menu_run_script_no_scripts 未找到脚本。脚本执行机制提取 → 执行 → 回读理解底层执行机制有助于你写出符合预期的脚本。整个流程在rpfm_server/src/background_thread.rs的Command::RunPluginScript分支中实现分为三步第一步提取到临时文件夹选中的文件被提取到一个临时文件夹且保持其在 Pack 内的目录结构这样脚本看到的路径与 Pack 内的容器路径一致。临时目录形如系统临时目录/rpfm_plugins/pack文件名/每次运行前会先清空重建。提取时的格式规则如下DB 表与 Loc 表以TSV制表符分隔、关闭引号格式写出与常规的Extract动作完全一致其他所有文件以原始二进制raw binary写出。提取时还会带入两个相关设置tables_use_old_column_order_for_tsv决定 TSV 是否使用旧版列顺序即主键列是否前置disable_uuid_regeneration_on_db_tables决定回写 DB 表时是否重新生成 UUID。第二步以文件路径为参数启动脚本脚本通过系统命令启动提取出的文件路径作为命令行参数传入python script paths... lua script paths...即解释器按扩展名选出 脚本自身路径 所有被提取文件的磁盘路径。工作目录被设置为临时文件夹。Server 侧使用std::process::Command::new(interpreter).arg(script_path).args(extracted_paths).current_dir(base_folder)同步等待脚本结束。第三步读回修改脚本结束后RPFM 把可能被修改过的文件读回 Pack仍存在的文件会通过encode_from_external_data重新编码进 Pack脚本删除的文件保持原样不动回读时发现磁盘文件已不存在则跳过脚本新建的文件被忽略——只有最初选中的那些文件才会被读回发生变化的文件其已打开的视图会被重新加载reload失败的视图会被关闭同时 Pack 被标记为已修改MarkAlwaysModifiedPack 树的对应条目出现修改标记。注意 TSV 文件在磁盘上带有.tsv后缀回读时 Server 会先按原名查找找不到再剥离.tsv后缀还原为真实容器路径见background_thread.rs中container_path_from_disk_path与strip_suffix(.tsv)的逻辑。UI 侧run_plugin_scriptrpfm_ui/src/packfile_contents_ui/mod.rs在发送命令前还会先把当前已打开且未保存的 Pack 文件刷入后端避免脚本基于过期数据运行——这是容易被忽略的重要细节。TSV 格式两行表头 \r\n行尾当脚本接收到 DB 表或 Loc 文件时拿到的是一个带两行表头的 TSV。以 Loc 为例keyTABtextTABtooltip - 第一行列名 #Loc;1;text/db/mymod.locTABTAB - 第二行元数据 #表类型;版本;路径 mymod_key1TABHello worldTABfalse第一行是列名第二行是元数据格式为#table_type;version;path——分别对应表类型、schema 版本号、以及该文件在 Pack 内的路径数据行紧随其后行尾统一为\r\nCRLF且值从不加引号因此值内部不能包含制表符或换行编辑时必须保持两行表头完整不动否则 RPFM 将无法把表格读回。这个两行表头的生成逻辑位于rpfm_lib/src/files/table/local.rs的tsv_export()第一行写出排序后的字段名第二行写#表名;版本;路径元数据行其余单元格填空字符串随后逐行写出每个条目的data_to_string()结果。表类型识别TSV 元数据第一段#之后、;之前是表类型名。对 Loc 而言常见的有Loc与历史导出格式Loc PackedFileDB 表则以其定义名称为类型。示例脚本正是通过解析该字段判断当前文件是否为 Loc TSV。实战范例逐行解析官方示例脚本仓库自带的add_emojis_to_loc示例是学习插件脚本 API 的最佳教材Python 与 Lua 双版本行为一致。下面拆解其关键实现。公共约定两个版本都遵循同一套约定只处理.tsv文件遍历sys.argv[1:]Python或argLua传入的路径仅对以.tsv结尾的文件调用处理函数校验两行表头行数不足 2 直接跳过解析第二行元数据Loc/Loc PackedFile之外的类型打印跳过提示定位text列从第一行列名中找到text的列索引保持表头原样第 0/1 行列名行与元数据行逐字保留从第 2 行Python/第 3 行Lua1 起始索引起才是数据行匹配 RPFM 的行尾约定写回时用\r\n连接各行并补上末尾行终止符。Python 版要点examples/plugin_scripts/add_emojis_to_loc.py中值得注意的实现细节使用open(path, r, encodingutf-8, newline)以 UTF-8 读取并禁用换行转换再通过splitlines()同时兼容\n与\r\n行尾emoji 用码点\U0001F525书写使文件本身不携带 emoji 字形规避编码问题通过lines[1].lstrip(#).split(;)解析元数据行metadata[0]即为表类型写回时使用newline避免平台自动转换保证严格输出\r\n。Lua 版要点examples/plugin_scripts/add_emojis_to_loc.lua展示了如何兼容 Lua 5.1~5.4emoji 直接写成原始 UTF-8 字节串\240\159\148\165U1F525 的 UTF-8 编码仅做字节拼接无需 utf8 库即可跨版本运行自定义split()函数按单字符分隔符切分并保留空字段Lua 5.1 没有string.split用io.open(path, rb)/wb二进制模式读写配合gmatch按行拆分并剥掉\r兼容两种行尾。这两个示例的运行入口都是把print输出打到 stdout——这些输出会被 RPFM 记录到日志中见下一节。调试last_run.log与 stderr 对话框每次运行脚本RPFM 都会把这次执行的信息写入scripts文件夹下的last_run.log每次运行覆盖上次内容其中包含脚本路径Script退出状态Status即进程退出码完整的 stdout 与 stderr 输出。此外若脚本以非零状态码退出RPFM 会弹出一个对话框展示其 stderr并提示查阅last_run.log同样的输出也会进入RPFM Server 终端的日志stdout 走info级别非空 stderr 额外以warn级别记录。从源码看background_thread.rs约第 2009~2037 行每次运行都会组装一份Script / Status / stdout / stderr报告写入scripts_path()?.join(last_run.log)运行失败如解释器不存在则直接回传Failed to run the plugin script错误并在 Server 侧记error日志。排查建议脚本毫无反应先确认.py/.lua解释器在PATH中且扩展名正确plugin_script_interpreter只认py与lua表格读不回去检查是否误删/误改了两行表头或值中混入了制表符/换行TSV 值不允许修改不生效确认你修改的是最初被选中的文件——新建文件会被忽略删除文件不会在 Pack 中生效想看到详细输出打开scripts/last_run.log或查看 RPFM Server 终端日志。编写插件脚本的注意事项脚本必须自行处理路径参数RPFM 不做任何过滤所有被提取文件的路径都会原样传入建议像官方示例一样按扩展名或元数据行自行筛选目标文件。文本编码统一为 UTF-8官方示例对 TSV 采用 UTF-8 读写Lua 版用字节级操作规避了 utf8 库的版本差异。尊重\r\n行尾写回 TSV 时若使用平台默认行尾如 Linux 的\n可能导致表格解析异常。保持表头完整两行表头是 RPFM 回读表格的依据编辑时务必逐字保留。非表格文件按二进制处理除 DB/Loc 外的文件都是原始二进制若需修改请按二进制 I/O 处理。该功能是实验性的脚本调用约定未来可能调整正式使用前请关注版本更新说明。延伸阅读Pack 树与右键菜单Run Script 菜单所在的上层交互入口Settings 与配置文件夹config 目录的确切位置与自定义配置文件夹官方示例脚本add_emojis_to_loc.py/.lua的完整说明源码索引UI 菜单构建、UI 执行入口、Server 执行引擎、scripts 路径定义、TSV 导出实现赞分享游戏开发桌面应用开发工具MCP 服务【免费下载链接】rpfmRusted PackFile Manager (RPFM) is a... reimplementation in Rust and Qt6 of PackFile Manager (PFM), one of the best modding tools for Total War Games.项目地址https://gitcode.com/gh_mirrors/rp/rpfm点击查看免费下载相关推荐micro 编辑器插件开发完全指南Lua 回调、运行时文件与插件管理器实战micro 编辑器插件开发完全指南Lua 回调、运行时文件与插件管理器实战 本篇技术指南聚焦 microA modern and intuitive ter开发工具CLI三步永久保存微信聊天记录WeChatMsg免费完整指南三步永久保存微信聊天记录WeChatMsg免费完整指南 你是否曾担心珍贵的微信聊天记录会随着时间流逝而消失那些承载着重要回忆、工作沟通和情感交流的对话难道终极指南如何编写Python脚本批量执行Arjun参数发现Arjun是一款强大的HTTP参数发现工具能够自动探测Web应用程序中隐藏的URL参数。对于安全测试人员和开发者来说掌握如何通过Python脚本批量执行Ar网络安全应用安全渗透测试上一篇Dapr 1.5.1 版本解析Cosmos DB 重试、订阅 CRD 转换与稳定性修复全解读下一篇SeaweedFS Volume Server Go 到 Rust 的移植执行计划深度解析创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑