// Metin2 地图文本格式的通用解析 —— 对标原客户端 EterBase `LoadMultipleTextData` + // `CTokenVectorMap`(`GameLib/Area.cpp`、`PRTerrainLib/TextureSet.cpp` 都用它)。 // // 语义: // - 以空白分隔 token;`"..."` 为单 token;`#` 或 `//` 到行尾是注释。 // - 顶层行 `key v1 v2 ...` -> map[lower(key)] = [v1, v2, ...] // - `Start ` ... `End []` -> map[lower(Name)] = [块内所有 token 展平] // - 重复 key:保留第一个,`dup_count` 记录冲突数(W0 报告用)。 // // 无 godot 依赖,纯 C++20,走 CTest。SHINSOO §9-W0 / §5。 #pragma once #include #include #include namespace fmt { struct TokVecMap { std::map> m; int dup_count = 0; // 重复 key 次数 std::vector dup_keys; // 重复的 key 名(去重后) bool has(const std::string& key) const; // key 已小写 const std::vector* find(const std::string& key) const; // 便捷取值(key 传入时大小写不敏感) std::string str(const std::string& key, const std::string& def = "") const; long inum(const std::string& key, long def = 0) const; double num(const std::string& key, double def = 0) const; }; // 解析整段文本。语法层面不会失败(宽容解析);err 仅在明显结构错误时写。 bool parse_tokvec(const std::string& text, TokVecMap& out, std::string* err); bool parse_tokvec_file(const std::string& path, TokVecMap& out, std::string* err); // 小工具:整文件读入字符串。失败返回 false。 // Whole-file read used by every fmt loader. By default std::ifstream; the host // app can install a reader that pulls from res:// (Godot PCK on iOS/Android) via // set_file_reader(). The standalone CTests leave it unset -> plain ifstream. using FileReader = bool (*)(const std::string& path, std::string& out); void set_file_reader(FileReader r); // nullptr resets to the ifstream default bool read_file(const std::string& path, std::string& out); } // namespace fmt