Skip to content

Latest commit

 

History

12 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

SFS 资源管理器(SFS Resource Manager)

项目简介

SFS 资源管理器是一款专为游戏 Spaceflight Simulator(太空飞行模拟器,简称 SFS)设计的桌面端启动器和资源管理工具。基于 PySide6(Qt for Python)构建,提供游戏启动管理、多类型资源分类浏览、导入导出、插件扩展、主题切换等完整功能。

核心功能

  • 游戏启动管理:支持多游戏版本/整合包的启动、关闭、卸载,进程监控与优雅退出
  • 资源分类管理:覆盖 9 种资源类型——蓝图、模组、存档、星系、贴图、游戏、整合包、插件、主题
  • 多版本资源存储:每种资源支持多版本共存,目录结构为 资源名/版本号/内容,附版本兼容性测试数据
  • 智能索引系统:自动扫描文件系统构建索引,支持关键词搜索、分页浏览、分类筛选
  • 多种导入导出格式:支持 .sfs 私有格式、通用 .zip、社区压缩包格式(自动识别)、整合包导出
  • 插件系统:基于钩子(Hook)的微内核架构,支持类继承和函数导出两种开发模式
  • 主题切换:支持 light、dark、star lines 三套主题,通过 .ui 文件 + QSS 实现
  • 资源目录监测:游戏运行时后台自动检测玩家自创资源,迁移到存储并创建符号链接
  • UID 权限系统:基于用户唯一标识的编辑权限控制

技术栈

层面 技术
语言 Python 3.8+
UI 框架 PySide6 (Qt 6 for Python)
UI 设计 Qt Designer (.ui 文件) + QUiLoader 动态加载
样式 QSS (Qt Style Sheets) + QPalette
数据存储 JSON 文件(简介、索引、哈希表、配置)
压缩处理 zipfile (Python 内置) + 7-Zip 外部调用(.rar/.7z)
进程管理 subprocess + Windows API (ctypes)
符号链接 Windows Junction (mklink /J)
日志 自定义日志系统(logging 模块封装)
插件架构 钩子注册/触发模式 + 观察者模式

项目架构

架构分层

┌──────────────────────────────────────────────────────┐
│                   UI 层 (UI/)                         │
│   SFS_launcher.py  ui_loader.py  popup_dialogs.py    │
│   resource_browser.py  settings_page.py              │
│   res_sel_page.py  detail_test_ui.py                 │
├──────────────────────────────────────────────────────┤
│                 插件层 (plugins/)                      │
│   7个简介编辑器  mod_info_extractor  page_jump        │
│   _plugin_template (开发模板)                         │
├──────────────────────────────────────────────────────┤
│              插件框架层                                │
│   plugin_api.py  plugin_base.py  plugin_manager.py   │
│   context_menu_manager.py                            │
├──────────────────────────────────────────────────────┤
│              业务逻辑层                                │
│   resource_operations/  (资源磁盘操作)                 │
│   resource_loader/      (资源索引构建)                 │
│   resource_monitor.py   (游戏内资源监测)               │
│   game_manager.py       (游戏进程管理)                 │
│   index_update_manager.py (索引自动更新)               │
├──────────────────────────────────────────────────────┤
│              数据共享层                                │
│   share_data.py  resource_data_manager.py            │
│   resource_metadata.py  resource_type_manager.py     │
├──────────────────────────────────────────────────────┤
│              基础设施层                                │
│   files_operator.py  config_manager.py  logger.py    │
│   user_profile.py  app_settings.py                   │
├──────────────────────────────────────────────────────┤
│              数据存储层 (files/)                       │
│   Blueprints/ Mods/ Worlds/ Solar_Systems/           │
│   Texture_Packs/ games/ Mod_Pack/                    │
│   configs/ exports/ logs/                            │
└──────────────────────────────────────────────────────┘

核心设计模式

  1. 单例模式(Singleton)RESOURCEREACTORPluginAPIPluginManagerConfigManagerAppSettingsUserProfileContextMenuRegistry 等核心组件均采用单例模式,全局唯一访问点。

  2. 观察者模式(Observer)ResourceManagerShareData 维护 ObservedEvent 类型的事件订阅表。UI 组件(SFSMainWindowResourceBrowser)继承 ProjectObserver 并订阅事件,数据变更时自动刷新界面。

  3. 元数据驱动(Metadata-Driven)resource_metadata.py 是所有资源类型定义的唯一来源。ResourceLoaderResourceDataManagerResourceOperationsResourceImportScanner 等模块均通过 type_id 查表获取行为参数,彻底消除了按类型硬编码分支。

  4. 钩子模式(Hook):插件通过 api.register_hook(hook_name, callback) 注册生命周期钩子,框架在特定时机触发。支持 on_app_starton_ui_readyon_data_loadedon_context_menu_showon_resource_importedon_resource_deletedon_font_changed 等钩子。


完整目录结构

sfs_start_pyside/
│
├── main.py                          # 程序入口:初始化各组件、加载数据、创建主窗口
├── share_data.py                    # 全局数据共享单例 (RESOURCEREACTOR)
├── plugin_api.py                    # 插件开发 API 单例 (PluginAPI)
├── plugin_base.py                   # 插件基类 (PluginBase / DataPluginBase / UIPluginBase)
├── plugin_manager.py                # 插件管理器:发现、加载、卸载、启停插件
├── files_operator.py                # 文件系统操作工具集 (读/写/复制/移动/删除/哈希)
├── config_manager.py                # 配置管理器单例:JSON 配置读写与缓存
├── game_manager.py                  # 游戏进程管理器:启动/关闭/卸载/进程检测
├── resource_monitor.py              # 资源目录后台监测线程
├── resource_metadata.py             # 资源类型元数据中心 (METADATA 唯一真相来源)
├── resource_data_manager.py         # 通用资源数据管理器 (替代 6 个重复 Mixin)
├── resource_type_manager.py         # 资源类型 OOP 封装 (ResourceType / ResourceManager)
├── user_profile.py                  # 用户档案:用户名/UID/编辑权限
├── app_settings.py                  # 应用设置单例:主题/游戏/显示/自启动等
├── logger.py                        # 日志系统:按模块创建独立日志文件
├── index_update_manager.py          # 索引自动更新管理器 (定时/手动)
├── context_menu_manager.py          # 右键菜单系统:身份匹配 + 插件注入
│
├── UI/                              # ═══ 用户界面层 ═══
│   ├── SFS_launcher.py              # 主窗口:导航、游戏控制、首页展示
│   ├── ui_loader.py                 # 主题加载器:加载 .ui 文件 + QSS 样式
│   ├── resource_browser.py          # 资源浏览页:分类/搜索/分页
│   ├── settings_page.py             # 设置页:主题/游戏/显示/字体等
│   ├── res_sel_page.py              # 资源选择页:导出/导入/添加到游戏
│   ├── popup_dialogs.py             # 弹窗合集:详情/提示/确认/进度/输入
│   ├── window_manager.py            # 统一窗口管理器:加载/配置/样式/窗口按钮
│   ├── detail_test_ui.py            # 兼容性测试动态 UI 构建
│   ├── Blueprints_detail.py         # 蓝图详情(委托 popup_dialogs)
│   ├── Mods_detail.py               # 模组详情
│   ├── Galaxies_detail.py           # 星系详情
│   ├── Worlds_detail.py             # 存档详情
│   ├── Textures_detail.py           # 贴图详情
│   ├── Games_detail.py              # 游戏详情
│   ├── setting.json                 # 应用配置文件
│   ├── SFS-Launcher-UI.pro          # Qt Designer 项目文件
│   ├── light/                       # 亮色主题 UI 文件
│   ├── dark/                        # 暗色主题 UI 文件
│   └── Nebula Purple/               # 星云紫主题 UI 文件 (默认主题)
│
├── resource_loader/                 # ═══ 资源加载器层 ═══
│   ├── __init__.py                  # 统一入口 start_load() + 全局 Loader 实例
│   ├── resource_loader.py           # 通用资源加载器 (索引/哈希表构建)
│   └── ui_utils.py                  # UI 工具:QUiLoader/字体缩放/QSS 应用
│
├── resource_operations/             # ═══ 资源操作层 ═══
│   ├── __init__.py                  # 统一入口 + ResourceOperations 类 + 导出函数
│   ├── resource_importer.py         # 资源导入扫描器 (多格式检测)
│   ├── intro_generator.py           # 简介.json 自动生成
│   ├── game_ops.py                  # 游戏专用操作 (导入/导出/链接/转换)
│   ├── compatibility_checker.py     # 版本兼容性批量检查与切换
│   └── community_format_detector.py # 社区压缩包格式自动识别
│
├── plugins/                         # ═══ 插件目录 ═══
│   ├── _plugin_template/            # 插件开发标准模板
│   ├── blueprint_intro_editor/      # 蓝图简介编辑器
│   ├── mod_intro_editor/            # 模组简介编辑器
│   ├── solar_system_intro_editor/   # 星系简介编辑器
│   ├── texture_pack_intro_editor/   # 贴图简介编辑器
│   ├── world_intro_editor/          # 存档简介编辑器
│   ├── exten_intro_editor/          # 拓展(插件/主题)简介编辑器
│   ├── modpack_intro_editor/        # 整合包简介编辑器
│   ├── mod_info_extractor/          # 模组 DLL 元数据提取器
│   └── page_jump/                   # 页码跳转增强
│
├── files/                           # ═══ 数据存储层 ═══
│   ├── Blueprints/                  # 蓝图资源 (含 index.json + hash_table.json)
│   ├── Mods/                        # 模组资源
│   ├── Solar_Systems/               # 星系资源
│   ├── Texture_Packs/               # 贴图资源
│   ├── Worlds/                      # 存档资源
│   ├── games/                       # 游戏安装目录 (含 my_games/)
│   ├── Mod_Pack/                    # 整合包资源
│   ├── configs/                     # 配置文件 (plugin_states.json 等)
│   ├── exports/                     # 默认导出目录
│   └── logs/                        # 日志文件
│
├── intro_templates/                 # ═══ 简介模板 ═══
│   ├── Blueprints/简介.json         # 蓝图简介标准模板
│   ├── Mods/简介.json               # 模组简介标准模板
│   ├── Solar_Systems/简介.json      # 星系简介标准模板
│   ├── Texture_Packs/简介.json      # 贴图简介标准模板
│   ├── Worlds/简介.json             # 存档简介标准模板
│   ├── games/简介.json              # 游戏简介标准模板
│   └── Mod_Pack/简介.json           # 整合包简介标准模板
│
├── docs/                            # 文档
│   └── 资源类型管理系统.md           # 资源类型管理设计文档
│
├── .vscode/                         # VS Code 配置
├── .claude/                         # Claude Code 配置
└── README.md                        # 本文件

核心模块详解

1. 程序入口 — main.py

  • 初始化 QApplication,设置高 DPI 缩放属性
  • 按序初始化:UserProfileAppSettingsPluginAPIConfigManagerPluginManager
  • 调用 resource_loader.start_load() 加载所有资源索引
  • 创建 SFSMainWindow 主窗口并显示
  • 支持 --startup 参数(开机自启动场景)
  • 处理首次运行的用户名输入和 UUID 迁移
  • 退出时触发 on_app_exit 钩子,关闭所有插件

2. 数据共享中心 — share_data.py

ResourceManagerShareData 是全局单例(RESOURCEREACTOR),管理所有运行时数据:

  • _managers{type_id: ResourceDataManager} — 每类资源一个数据管理器
  • _paths{type_id: str} — 每类资源的磁盘目录
  • selected_resources:当前被右键选中的资源 {type_id, name, widget}
  • pending_imports:待导入的资源列表

观察者事件类型 (ObservedEvent):

事件 触发时机 订阅者
INDEX_CHANGED 资源索引数据变更 ResourceBrowser 自动刷新
PATHS_CHANGED 资源目录路径变更 UI 更新路径显示
FONT_CHANGED 字体大小变更 所有需要字体缩放的控件
HOME_PAGE_CHANGED 首页数据需要刷新 SFSMainWindow 刷新首页
SELECTION_CHANGED 当前选中资源变更 右键菜单相关
PENDING_IMPORTS_CHANGED 待导入列表变更 导入相关 UI

3. 资源元数据中心 — resource_metadata.py

METADATA 字典定义了全部 9 种资源类型的元信息,是系统中所有资源类型判断的唯一来源。每个条目包含:

字段 说明 示例(blueprint)
type_id 内部标识 'blueprint'
cn_name 中文名称 '蓝图'
folder_name 磁盘文件夹名 'Blueprints'
name_field 简介中名称字段 '蓝图名称'
author_field 简介中作者字段 '蓝图作者'
uid_field 简介中 UID 字段 'UID'
intro_field 简介中介绍字段 '蓝图简介'
version_field 简介中版本列表字段 '蓝图版本'
test_field 兼容性测试字段 '兼容版本'
search_fields 可搜索字段列表 ['蓝图名称', '蓝图版本', '蓝图作者']
my_category 我的XX分类名 '我的蓝图'
detail_ui 详情 UI 文件名 'Blueprints_detail.ui'

同时派生多个便捷映射:ID_TO_FOLDERFOLDER_TO_IDID_TO_CNCN_TO_IDCN_TO_RESOURCE_METANAME_FIELD_TO_IDID_TO_VERSION_FIELDID_TO_TEST_FIELD 等。

9 种资源类型中,前 5 种(blueprint/mod/solar_system/texture_pack/world)是可多版本资源,game 和 modpack 是含资源目录的特殊类型,plugin 和 theme 是拓展类型(无"我的XX")。

4. 资源数据管理器 — resource_data_manager.py

ResourceDataManager 是通用参数化数据管理器,通过 type_id 初始化后提供统一的数据访问接口:

  • set_index(data) / set_hash_table(data) — 写入数据并通知观察者
  • get_info(name) — 按名称查找资源(支持 Category/Name 格式)
  • get_intro_path(name) — 查找资源的 简介.json 磁盘路径
  • load_intro_data(name) — 加载完整简介内容
  • get_categories() — 获取所有分类("我的XX"优先,其他收尾)
  • get_paginated(page, page_size) / get_by_category_paginated(...) — 分页查询
  • search(keyword) — 跨分类关键词搜索
  • get_now_playing_game() / set_now_playing_game() — 当前游戏(仅 game 类型)

5. 文件操作工具 — files_operator.py

纯函数式模块,所有函数统一返回 (success: bool, data_or_error: str)

函数 功能
read_json(path) 读取 JSON 文件
write_json(path, data) 写入 JSON 文件(自动创建目录)
read_txt(path) / write_txt(path, content) 文本文件读写
copy_dir(src, dst) 递归复制目录
delete_dir(path) 递归删除目录
move_file(src, dst, overwrite) 移动文件/目录(支持覆盖)
rename_file(src, dst) 重命名
generate_folder_hash(path, exclude_files) 递归计算文件夹哈希(SHA256)
get_all_dirs(path) / get_all_files(path) 列出子目录/文件
sort_files(paths, key) 文件排序(名称/修改时间)
open_folder_in_explorer(path) 在资源管理器中打开
check_file_exists(path) / get_file_size(path) / get_file_modify_time(path) 文件信息

6. 资源加载器 — resource_loader/

ResourceLoader(type_id) 负责从磁盘构建资源索引:

  • load_all()_load_or_build_index() + _load_or_build_hash_table()
  • index.json 存在则直接加载,否则扫描目录构建
  • rebuild_index_and_hash_table() 支持用户手动触发全量重建
  • check_duplicate_import(hash_value) 基于哈希表检测重复导入
  • 子类:ModpackLoader(跳过哈希表,文件过大)、GameLoader(游戏专用索引结构 + 图标提取)

7. 资源操作 — resource_operations/

ResourceOperations(type_id) — 通用资源磁盘操作:

  • install_to_game(game_intro, res_intro, force) — 安装资源到游戏目录:找兼容版本 → 复制内容 → 生成 版本.json。整合包同时记录到追踪文件
  • link_to_game(game_intro, res_intro) — 通过 Junction 软链接安装(用于"我的XX"资源)
  • export_as_archive(res_intro, version, export_dir) — 导出单版本为 zip
  • delete_resource(res_intro) — 删除整个资源目录并清理索引/哈希表
  • get_versions(name_or_intro) — 获取资源所有版本号

ResourceImportScanner — 多格式导入扫描器:

  • .sfs — 期望内部 files/<Folder>/<Category>/<Name>/ 结构
  • 标准 zip — 期望顶层 <ResourceName>/简介.json
  • 社区格式 — 自动通过 community_format_detector 识别并生成简介

community_format_detector.py — 社区压缩包格式识别(基于文件特征签名):

资源类型 识别特征
蓝图 Blueprint.txt(JSON 含 parts 键)
星系 Import_Settings.txt + Planet Data/Heightmap Data/
贴图 pack_info.txt + Textures/Color Textures/
存档 WorldSettings.txtSolar System.txt + Persistent/
模组 .dll 文件 或 .pack (Unity AssetBundle)

game_ops.py — 游戏专用操作:

  • _create_symlink(target, link) — Windows Junction 创建(mklink /J
  • import_resource() — 导入游戏时自动分离资源到"我的XX"并创建符号链接
  • export_resource() / export_as_modpack() — 游戏/整合包导出

compatibility_checker.py — 版本兼容性批量检查:

  • 检查所有"我的XX"资源与目标游戏版本的兼容性
  • 返回 {compatible, need_switch, incompatible} 分类
  • 支持一键切换资源版本

8. 游戏进程管理 — game_manager.py

GameManager(QObject) — 管理游戏进程生命周期:

  • 启动:读取简介 → 定位 exe → subprocess.Popen 启动 → 启动资源监测线程
  • 关闭:优雅关闭(WM_CLOSE,最多等待 3 秒)→ 强制关闭(taskkill /F /T
  • 运行检测is_game_running() 先检查 Popen handle,再通过 tasklist 搜索进程名
  • 卸载:删除游戏目录 → 清理配置 → 通知观察者刷新 UI
  • 信号game_startedgame_stoppedgame_deletedgame_error

9. 资源目录监测 — resource_monitor.py

ResourceMonitor(threading.Thread) — 后台守护线程:

  • 游戏运行时每 1 秒轮询资源目录,检测新增文件夹
  • 游戏模式:所有新增文件夹均为玩家自创,直接迁移
  • 整合包模式:先检查是否为依赖声明或追踪文件中的已知资源,跳过已知,处理新增
  • 处理流程:移动内容 → 生成简介 → 计算哈希 → 创建 版本.json → 创建 Junction → 更新索引
  • 重名处理:基于文件夹内容 SHA256 计算唯一标识
  • update_tracking_file() 供外部调用,记录用户导入的资源

10. 索引自动更新 — index_update_manager.py

  • 定时器驱动,按配置的间隔(分钟)自动刷新资源索引
  • 也支持手动触发全量重建
  • 间隔从 AppSettings 读取

资源管理系统

资源存储三层结构

【存储层】files/<Folder>/<Category>/<ResourceName>/
    ├── 简介.json            # 多版本元数据(所有版本列表 + 公共信息)
    ├── 版本.json            # 当前活跃版本号
    ├── 1.0/                  # 版本内容目录
    │   └── <content>
    └── 2.0/
        └── <content>

【我的XX层】files/<Folder>/<我的XX>/<ResourceName>/
    ├── 简介.json            # 从存储层复制(多版本)
    ├── 版本.json            # 当前链接到游戏的版本
    ├── 1.0/ → (Junction)    # 符号链接指向存储层版本
    └── ...

【游戏内层】<GameDir>/<ResourceDir>/<ResourceName>/
    ├── 简介.json            # 单版本(整合包)或多版本(游戏)
    ├── 版本.json            # 当前版本号
    └── <content>            # 实际文件内容

资源身份标识

右键菜单等上下文场景使用 domain:res_type:identifier 格式:

  • resource:blueprint:我的蓝图/飞行器V2 — 资源域,蓝图类型,分类/名称
  • resource:mod:模组名 — 直呼名称(无分类前缀时匹配所有分类)

插件系统

架构

基于**钩子(Hook)**模式的微内核架构:

PluginManager  → 发现、加载、管理插件生命周期
PluginAPI      → 向插件暴露核心能力(data / config / logger / ui / hooks)
PluginBase     → 插件基类,封装生命周期方法
ContextMenuRegistry → 右键菜单注册与分发

插件目录结构

plugins/插件名/
    ├── config.json          # 插件元数据(必须)
    ├── __init__.py          # 入口文件(必须)
    ├── dialog.ui            # Qt Designer UI 文件
    ├── my_module.py         # 自定义模块
    └── resources/           # 图标等资源文件

两种开发模式

模式一:类继承(推荐)

from plugin_base import PluginBase

class MyPlugin(PluginBase):
    def on_initialize(self) -> bool:
        self.api.register_hook('on_ui_ready', self._on_ui_ready)
        return True

    def _on_ui_ready(self, main_window):
        self.log("主窗口已就绪")

    def on_shutdown(self):
        pass

PLUGIN_CLASS = MyPlugin

模式二:函数导出(兼容旧方式)

def initialize(api):
    api.register_hook('on_ui_ready', _on_ui_ready)

def shutdown():
    pass

可用钩子

钩子名 参数 触发时机
on_app_start 应用启动完成后
on_ui_ready main_window: SFSMainWindow 主窗口 UI 就绪
on_app_exit 应用退出前
on_data_loaded share_data 资源数据加载完成
on_context_menu_show widget, identity, items 右键菜单弹出前(可注入菜单项)
on_resource_imported type_id, name, success 资源导入完成后
on_resource_deleted type_id, name 资源删除完成后
on_font_changed new_font_size: int 全局字体大小变更

API 体系

api.data      # 数据访问:资源 CRUD、选中管理、简介加载/保存
api.config    # 配置读写:JSON 配置文件读写
api.logger    # 日志模块:创建插件的独立日志文件
api.plugin_dir # 当前插件目录路径
api.ui        # UI 操作:上下文菜单注入、主窗口访问、对话框创建
api.hooks     # 钩子系统:注册/触发钩子、暴露函数供其他插件调用

右键菜单注入

from context_menu_manager import ContextMenuRegistry
registry = ContextMenuRegistry.get_instance()
registry.register_pattern("resource:*:*", [
    ("自定义菜单项", on_custom_action, True),  # (文本, 回调, 是否启用)
])

函数暴露

插件可以通过 api.expose_function(name, func) 向全局暴露函数,其他插件通过 api.get_exposed_function(name) 调用。例如 mod_info_extractor 暴露了 extract_mod_infoextract_mod_info_batchmerge_info_to_introenhance_mod_intro 四个函数。


UI / 主题系统

主题加载

UIThemeLoader 单例负责:

  1. UI/<theme_name>/theme.json 读取主题配置
  2. 加载 GlobalStyle.ui 提取 QSS 样式表
  3. 若主题类型为 palette,额外应用 QPalette 颜色方案
  4. 主题切换时触发 on_font_changed 钩子通知所有插件

当前主题

主题 目录 类型
Nebula Purple UI/Nebula Purple/ qss(默认主题,星云紫)
dark UI/dark/ qss(暗色主题)
light UI/light/ qss(亮色主题)

UI 文件加载

所有 .ui 文件通过 PySide6.QtUiTools.QUiLoader 在运行时动态加载,不使用 pyside6-uic 预编译。这意味着修改 .ui 文件后无需重新编译即可生效。


数据流概览

应用启动流程

main.py
  ├── UserProfile()          # 加载用户身份
  ├── AppSettings()          # 加载应用配置
  ├── PluginAPI.get_instance() # 初始化插件 API
  ├── PluginManager.load_all() # 发现并加载所有插件
  ├── resource_loader.start_load()  # 构建所有资源索引
  │     └── ResourceLoader.load_all()
  │           ├── _load_or_build_index()    → index.json
  │           └── _load_or_build_hash_table() → hash_table.json
  ├── SFSMainWindow()        # 创建主窗口
  └── app.exec()             # 进入事件循环

资源导入流程

用户选择文件
  → ResourceImportScanner.scan_archive()
      ├── .sfs 格式 → 验证内部结构 → 复制到存储
      ├── 标准 zip → 检测简介.json → 复制到存储
      └── 社区格式 → community_format_detector → 生成简介 → 复制到存储
  → ResourceLoader.rebuild_index_and_hash_table()
  → RESOURCEREACTOR.notify(INDEX_CHANGED)
  → UI 自动刷新

启动游戏流程

用户点击启动
  → GameManager.start_game()
      ├── 读取游戏简介 → 定位 exe 路径
      ├── subprocess.Popen 启动进程
      ├── game_started 信号 → UI 更新状态
      └── ResourceMonitor.start() → 后台监测资源目录

用户身份与权限

UserProfile

  • 数据存储在 C:\ProgramData\SFS_Launcher\user_profile.json(软件卸载后仍保留)
  • 首次运行时自动生成 UUID 作为唯一用户标识
  • can_edit(intro_uid) 方法:比对简介中的 UID 与当前用户 UID,决定编辑权限
  • master_edit_override 标志允许超级用户绕过 UID 检查

简介编辑权限

编辑任何资源的 简介.json 前,系统会检查:

  1. 简介中记录的 UID 字段
  2. 若 UID 为空(未设置),允许编辑
  3. 若 UID 与当前用户匹配,允许编辑
  4. 否则弹出"无编辑权限"警告

应用配置系统

UI/setting.json 结构

{
    "theme": {"current": "star lines"},
    "game": {"now_playing_games": "games/my_games/..."},
    "display": {
        "page_size": 10,
        "font_size": 12,
        "auto_remember": true,
        "info_pop": true
    },
    "app": {
        "version": "1.0.0",
        "log_dir": "files/logs",
        "export_dir": "files/exports",
        "auto_start": false,
        "index_update_frequency": 30
    },
    "user": {"username": "", "uuid": ""}
}

AppSettings

  • discover_themes() — 扫描 UI/ 目录下的主题子目录
  • register_auto_start() / unregister_auto_start() — 通过 Windows 注册表管理开机自启
  • get_intro_path(root_path) — 从 now_playing_games 推导出游戏简介路径
  • get_game_root_dir(root_path) — 从 now_playing_games 推导出游戏根目录

日志系统

logger.py 提供 setup_logger(log_dir_path, log_filename) 函数:

  • 创建独立的命名 logger,同时输出到控制台和文件
  • 基于 (dir, filename) 缓存复用,避免重复创建 handler
  • 日志文件按月轮转

主要日志文件:

日志文件 对应模块
main.log 主程序
game_manager.log 游戏进程管理
resource_monitor.log 资源目录监测
resource_ops.log 资源磁盘操作
blueprint_loader.log 各资源加载器

关键技术细节

为什么不用 pyside6-uic 预编译

项目使用 QUiLoader 在运行时动态加载 .ui 文件。这使得:

  • 修改 .ui 文件后无需重新编译即可生效
  • 主题切换时只需加载不同目录下的同名 .ui 文件
  • 插件可以自带 .ui 文件,无需编译步骤

为什么用 Junction 而不是复制

"我的XX"中的资源通过 Windows Junction(目录符号链接)连接到游戏目录,而非复制文件。优点:

  • 存储中的资源保持唯一,节省磁盘空间
  • 游戏内修改直接反映到存储中
  • 卸载游戏时只需删除链接,不丢失资源数据

简介.json 版本列表设计

每种资源类型有两个层级的版本概念:

  1. 多版本存储简介.json 中的版本列表记录所有历史版本及兼容性测试数据
  2. 活跃版本版本.json 记录当前在游戏中使用(链接)的版本号

整合包依赖追踪

整合包有三类资源来源,系统通过不同机制区分:

  1. 自带资源(依赖声明)→ 简介.json 中的 整合包依赖 字段
  2. 用户导入资源.sfs_tracked_imports.json 追踪文件
  3. 玩家自创资源ResourceMonitor 自动检测并迁移

开发指南

环境搭建

# 安装依赖
pip install PySide6 Pillow

# 可选:7-Zip 支持 .rar/.7z 解压
# 下载安装 7-Zip 并确保 7z.exe 在 PATH 中

# 运行
python main.py

添加新资源类型

  1. resource_metadata.pyMETADATA 中添加新条目
  2. intro_templates/<Folder>/ 中放置标准 简介.json 模板
  3. 若需要专门的处理逻辑,在 resource_loader/resource_operations/ 中添加子类
  4. UI/ 各主题目录下添加对应的详情 UI 文件

添加新主题

  1. UI/ 下创建新目录
  2. 编写 theme.json(指定类型:qsspalette
  3. 放置需要的 UI 文件
  4. 主题会自动被 discover_themes() 发现

开发插件

参考 plugins/_plugin_template/ 中的完整模板,或阅读现有 7 个简介编辑器插件的实现。

打包发布

# 使用 PyInstaller
pip install pyinstaller
pyinstaller --onefile --windowed --name "SFS-Launcher" main.py

许可证

本项目仅供学习和研究使用。


作者

srcEcho

About

SFS-Launcger

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages