Repository navigation
Development
HiLodve edited this page Jun 29, 2026
·
1 revision
GFAM/
├── .github/workflows/ # GitHub Actions 工作流
├── assets/ # GUI 图标和图片资源
├── cache/ # 运行时缓存(.gitkeep 保留目录)
├── data/ # 静态数据字典(gun.json, equip.json)
├── docs/ # 文档和更新日志
│ └── reference/ # 参考资料(夜战装备 ID 映射等)
├── examples/ # 配置示例
├── libs/ZIRC/src/core/gflzirc/ # 内置通信库
│ ├── __init__.py # 导出:GFLClient, GFLProxy, SERVERS, 常量
│ ├── client.py # HTTP 客户端(加密请求/响应)
│ ├── constants.py # 服务器 URL、API 端点、静态密钥
│ ├── crypto.py # RC4 变体加密(gf_authcode)
│ └── proxy.py # MITM 代理 + Windows 系统代理管理
├── modules/ # 功能模块(核心代码)
│ ├── epa_plus.py # EPA 打捞(5833 行)
│ ├── gfam_13_4.py # 13-4 关卡(6215 行)
│ ├── gfam_a10_resource.py # A-10 资源(888 行)
│ ├── gfam_greyzone_halloween.py # 灰域彩蛋(2093 行)
│ ├── gfam_smart_epa.py # 一键打捞(6143 行)
│ ├── f2p.py / f2p_pr.py # 零元购(~1300 行/个)
│ ├── pick_and_train.py # 训练资料(3362 行)
│ ├── gfam_factory_auto.py # 跟随制造后台(1391 行)
│ ├── gfam_factory_config.py # 制造配置(2375 行)
│ ├── gfam_fairy_auto.py # 妖精自动后台(1071 行)
│ ├── gfam_fairy_stats.py # 妖精统计(509 行)
│ ├── gfam_auth_capture.py # 认证获取(118 行)
│ ├── gfam_index_cache.py # Index 缓存(385 行)
│ ├── gfam_api_lock.py # API 锁(164 行)
│ ├── gfam_crossprocess_lock.py # 拆解锁(115 行)
│ ├── gfam_common.py # 通用工具(78 行)
│ └── gfam_greyzone_data.py # 灰域静态数据(64 行)
├── tools/ # GUI 和构建工具
│ ├── gfam_gui_launcher.py # GUI 主程序(4015 行)
│ ├── build_gfam_gui_exe.py # PyInstaller 打包
│ ├── build_portable_package.py # 便携包打包
│ └── start_gfam_background.ps1 # 后台进程启动
├── main.js # Node.js 主菜单入口
├── run_windows.bat # Windows 主启动脚本
├── setup_windows.ps1 # 环境检查脚本
├── gfam_gha.py # GHA 入口
└── gha_manual_runner.py # GHA 非交互控制器
每个功能模块遵循统一结构:
# 1. 导入和路径设置
ROOT_DIR = Path(__file__).resolve().parents[1]
GFLZIRC_CORE_DIR = ROOT_DIR / "libs" / "ZIRC" / "src" / "core"
sys.path.insert(0, str(GFLZIRC_CORE_DIR))
# 2. 可选模块导入(容错)
try:
from gfam_index_cache import IndexCacheManager
except ImportError:
IndexCacheManager = None
try:
from gfam_api_lock import patch_gfl_client
patch_gfl_client()
except Exception:
pass
# 3. CONFIG 字典
CONFIG = {
"SERVER_NAME": "",
"MODE_NAME": "single",
...
}
# 4. 业务函数
def farm_worker():
...
# 5. 菜单和入口
def print_menu():
...
def main():
...
if __name__ == "__main__":
sys.exit(main())- 模块文件:
gfam_<功能>.py(如gfam_a10_resource.py) - 内部函数:
_<name>前缀(如_farm_worker_impl) - 跨模块函数:
gfam_前缀(如gfam_request_index_for_storage) - CONFIG 键:大写蛇形(如
MACRO_LOOPS) - 运行时缓存文件:
.gfam_<用途>.json(如.gfam_index_cache.json) - 摘要文件:
.gfam_<模块>_summary.json
- 服务器请求:统一通过
check_step_error()检查 - 自适应延迟:错误时自动增加延迟,成功时逐步衰减
- 连续失败:达到
MAX_CONSECUTIVE_FAILURES时安全退出 - 拆解响应未知:保留待拆 UID 队列,不丢弃
新模块如需与服务器通信,应按以下顺序接入:
# 1. 接入全局 API 锁(模块导入时)
try:
from gfam_api_lock import patch_gfl_client
patch_gfl_client()
except Exception:
pass
# 2. 接入 Index 缓存(按需)
try:
from gfam_index_cache import IndexCacheManager
except ImportError:
IndexCacheManager = None
_index_mgr = None
def request_index(client, label="Index/index", *, bypass=False):
global _index_mgr
if _index_mgr is None and IndexCacheManager is not None:
_index_mgr = IndexCacheManager(client, ttl=60, label="<模块名>",
shared_file=".gfam_index_cache.json")
if _index_mgr is not None:
if bypass:
return _index_mgr.bypass(client, reason=label)
return _index_mgr.get(reason=label)
# 降级:直接请求
resp = client.send_request(API_INDEX_INDEX, {"time": int(time.time()), "furniture_data": False})
return resp if not check_step_error(resp, label) else None
# 3. 拆解操作使用拆解锁
try:
from gfam_crossprocess_lock import RetireLock
except ImportError:
RetireLock = None
def retire_guns(client, uids):
lock = RetireLock() if RetireLock else None
if lock:
lock.acquire()
try:
resp = client.send_request(API_GUN_RETIRE, {"gun_ids": uids})
...
finally:
if lock:
lock.release()模块运行结束时生成摘要文件供 GUI 弹窗使用:
def print_run_summary():
_summary = {
"kind": "<模块标识>",
"title": "<显示标题>",
"elapsed_seconds": elapsed,
"macro": MACRO_COUNT,
"total_drops": DROP_COUNT,
"stop_reason": STOP_REASON,
"resource_start": start_inv,
"resource_end": end_inv,
}
# 妖精状态(可选)
try:
_fs = read_fairy_snapshot()
if _fs:
_summary["fairy"] = _fs
except Exception:
pass
# 跟随制造统计(可选)
try:
_factory_cache_path = os.path.join(_gfam_root, ".gfam_factory_auto_cache.json")
if os.path.exists(_factory_cache_path):
with open(_factory_cache_path, "r", encoding="utf-8") as _fc:
_factory_cache = json.load(_fc)
_factory_data = {}
for _fk in ("doll", "equip"):
_fstats = _factory_cache.get("%s_stats" % _fk)
if _fstats and int(_fstats.get("build_attempts", 0)) > 0:
_factory_data[_fk] = {"formula_name": ..., "stats": dict(_fstats)}
if _factory_data:
_summary["factory"] = _factory_data
except Exception:
pass
# 写入文件并打印标记
with open(os.path.join(_gfam_root, ".gfam_<模块>_summary.json"), "w", encoding="utf-8") as _f:
json.dump(_summary, _f, ensure_ascii=False, indent=2)
print("[SUMMARY] <模块> 统计报告已生成。")GUI 端通过检测 stdout 中的 [SUMMARY] 标记来触发弹窗。
- 核心战斗流程不做大范围重写:已跑通的 mission 执行逻辑保持稳定
- 最小化 Index/index 请求:能通过本地缓存、安全计数或服务器返回值推导的状态,不重复请求
- 运行结束只拆遗留掉落:不全仓库扫描,只处理本次运行记录的 UID
- 占位值保护:用户隐私/账号相关配置默认使用占位值
-
容错导入:跨模块依赖使用
try/except包装,降级到无该功能状态
set GFAM_DEBUG=1
set GFAM_SAVE_DEBUG_JSON=1
run_windows_debug.bat# Index 缓存
cat .gfam_index_cache.json | python -m json.tool
# 制造缓存
cat .gfam_factory_auto_cache.json | python -m json.tool
# 妖精缓存
cat .gfam_fairy_auto_cache.json | python -m json.tool如果遇到 DLL 冲突或子进程异常,检查 _launch_gfam_backend() 中的 PATH 清理和 _MEIPASS 清除逻辑。