3 个版本
新增 0.1.2 | 2024 年 8 月 17 日 |
---|---|
0.1.1 | 2024 年 3 月 11 日 |
0.1.0 | 2024 年 2 月 27 日 |
393 在 解析器实现 中
425 每月下载次数
用于 2 crates
240KB
5.5K SLoC
rosu-map
从 osu! 解密和编码 .osu
文件的库
是什么
在核心上,rosu-map
提供了 DecodeBeatmap
特性。该特性负责解码文件本身、错误处理和部分解析。实现者需要做的只是保持解析数据的当前状态,并根据部分和文本行修改该状态。
rosu-map
还提供了多个已实现此特性的类型,即每个部分的一个(见 Editor
、TimingPoints
、...),以及一个用于(几乎)全部内容的,Beatmap
。
为什么
通过特性公开功能,可以在决定解析哪些内容时提供灵活性,从而在不需要所有数据时提高效率。
如果只需要难度属性,通过 Difficulty
结构进行解析将丢弃 [Difficulty]
部分之外的所有内容。同样,如果只对艺术家、标题和版本感兴趣,可以使用 Metadata
结构。
此外,值得注意的是,Beatmap
解析(几乎)一切,这可能对许多用例来说过于冗余。解决方案是定义一个新的自定义类型,复制粘贴 Beatmap
的 DecodeBeatmap
实现并将其不需要的部分删除。
如何
使用类型的 DecodeBeatmap
实现的最简单方法是通过使用 rosu-map
的函数 from_bytes
、from_path
和 from_str
。
use rosu_map::section::difficulty::Difficulty;
let content = "[Difficulty]
ApproachRate: 9.2
SliderMultiplier: 1.9
[Metadata]
Creator: peppy";
let difficulty = rosu_map::from_str::<Difficulty>(content).unwrap();
assert_eq!(difficulty.approach_rate, 9.2);
let path = "./resources/Soleily - Renatus (Gamu) [Insane].osu";
let map = rosu_map::from_path::<Beatmap>(path).unwrap();
assert_eq!(map.audio_file, "03. Renatus - Soleily 192kbps.mp3");
有关在新的类型上实现 DecodeBeatmap
特性的信息,请查看特性的文档。例如,查看 General
或 HitObjects
如何实现该特性。
编码
Beatmap
结构体通过其 encode*
方法提供了一种将自身转换为 .osu
文件内容的方法。
let path = "./resources/Within Temptation - The Unforgiving (Armin) [Marathon].osu";
let mut map: Beatmap = rosu_map::from_path(path).unwrap();
map.approach_rate = 10.0;
map.encode_to_path("./new_file.osu").unwrap();
let metadata = rosu_map::section::metadata::Metadata {
title: "song title".to_string(),
artist: "artist name".to_string(),
..Default::default()
};
let content = Beatmap::from(metadata).encode_to_string().unwrap();
assert!(content.contains("Title: song title"));
特性
标志 | 描述 | 依赖 |
---|---|---|
默认 |
无特性 | |
跟踪 |
在解码过程中遇到的任何错误将通过 tracing::error 记录。如果此特性未启用,则错误将被忽略。 |
跟踪 |
其他
内部实现
rosu-map
的一部分是 osu!lazer 的 beatmap {de/en}coding 的移植。它的功能不仅反映了 osu!,而且还翻译了许多测试用例,即使在边缘情况下也提供了可靠的正确性。
异步
经过一些测试和基准测试,结果表明异步 IO 并没有在并发环境中提供任何改进或性能提升。事实上,常规顺序 IO 持续优于其异步对应物。因此,rosu-map
不提供异步接口。
故事板
rosu-map
不提供解析故事板的类型,但 crate rosu-storyboard
提供。