modified: Cargo.lock
modified: Cargo.toml modified: src/main.rs
This commit is contained in:
parent
d458a84d4d
commit
b94a19b192
34
Cargo.lock
generated
34
Cargo.lock
generated
@ -1,6 +1,6 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 4
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "aho-corasick"
|
||||
@ -47,9 +47,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "bytes"
|
||||
version = "1.9.0"
|
||||
version = "1.10.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "325918d6fe32f23b19878fe4b34794ae41fc19ddbe53b10571a4874d44ffd39b"
|
||||
checksum = "f61dac84819c6588b558454b194026eb1f09c293b9036ae9b159e74e73ab6cf9"
|
||||
|
||||
[[package]]
|
||||
name = "env_logger"
|
||||
@ -93,9 +93,9 @@ checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4"
|
||||
|
||||
[[package]]
|
||||
name = "indexmap"
|
||||
version = "2.7.0"
|
||||
version = "2.7.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "62f822373a4fe84d4bb149bf54e584a7f4abec90e072ed49cda0edea5b95471f"
|
||||
checksum = "8c9c992b02b5b4c94ea26e32fe5bccb7aa7d9f390ab5c1221ff895bc7ea8b652"
|
||||
dependencies = [
|
||||
"equivalent",
|
||||
"hashbrown",
|
||||
@ -118,9 +118,9 @@ checksum = "b5aba8db14291edd000dfcc4d620c7ebfb122c613afb886ca8803fa4e128a20a"
|
||||
|
||||
[[package]]
|
||||
name = "log"
|
||||
version = "0.4.22"
|
||||
version = "0.4.25"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24"
|
||||
checksum = "04cbf5b083de1c7e0222a7a51dbfdba1cbe1c6ab0b15e29fff3f6c077fd9cd9f"
|
||||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
@ -235,9 +235,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rkyv"
|
||||
version = "0.8.9"
|
||||
version = "0.8.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b11a153aec4a6ab60795f8ebe2923c597b16b05bb1504377451e705ef1a45323"
|
||||
checksum = "1e147371c75553e1e2fcdb483944a8540b8438c31426279553b9a8182a9b7b65"
|
||||
dependencies = [
|
||||
"bytecheck",
|
||||
"bytes",
|
||||
@ -254,9 +254,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rkyv_derive"
|
||||
version = "0.8.9"
|
||||
version = "0.8.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "beb382a4d9f53bd5c0be86b10d8179c3f8a14c30bf774ff77096ed6581e35981"
|
||||
checksum = "246b40ac189af6c675d124b802e8ef6d5246c53e17367ce9501f8f66a81abb7a"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@ -271,9 +271,9 @@ checksum = "e3a9fe34e3e7a50316060351f37187a3f546bce95496156754b601a5fa71b76e"
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.96"
|
||||
version = "2.0.98"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d5d0adab1ae378d7f53bdebc67a39f1f151407ef230f0ce2883572f5d8985c80"
|
||||
checksum = "36147f1a48ae0ec2b5b3bc5b537d267457555a10dc06f3dbc8cb11ba3006d3b1"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@ -306,15 +306,15 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.14"
|
||||
version = "1.0.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "adb9e6ca4f869e1180728b7950e35922a7fc6397f7b641499e8f3ef06e50dc83"
|
||||
checksum = "a210d160f08b701c8721ba1c726c11662f877ea6b7094007e1ca9a1041945034"
|
||||
|
||||
[[package]]
|
||||
name = "uuid"
|
||||
version = "1.12.0"
|
||||
version = "1.12.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "744018581f9a3454a9e15beb8a33b017183f1e7c0cd170232a2d1453b23a51c4"
|
||||
checksum = "b3758f5e68192bb96cc8f9b7e2c2cfdabb435499a28499a42f8f984092adad4b"
|
||||
|
||||
[[package]]
|
||||
name = "winapi"
|
||||
|
@ -6,4 +6,4 @@ edition = "2021"
|
||||
[dependencies]
|
||||
env_logger = "0.9"
|
||||
log = "0.4.20"
|
||||
rkyv = { version = "0.8.9", features = ["unaligned", "little_endian"] }
|
||||
rkyv = { version = "0.8.10", features = ["unaligned", "big_endian"]}
|
||||
|
118
src/main.rs
118
src/main.rs
@ -19,13 +19,13 @@ enum ChunkType {
|
||||
impl From<[u8; 4]> for ChunkType {
|
||||
fn from(value: [u8; 4]) -> Self {
|
||||
match value {
|
||||
[109, 104, 98, 100] => ChunkType::Database,
|
||||
[109, 104, 115, 100] => ChunkType::DataSet,
|
||||
[109, 104, 105, 97] => ChunkType::AlbumList,
|
||||
[109, 104, 108, 97] => ChunkType::AlbumItem,
|
||||
[109, 104, 108, 116] => ChunkType::TrackList,
|
||||
[109, 104, 105, 116] => ChunkType::TrackItem,
|
||||
[109, 104, 111, 100] => ChunkType::StringTypes,
|
||||
[0x6D, 0x68, 0x62, 0x64] => ChunkType::Database,
|
||||
[0x6D, 0x68, 0x73, 0x64] => ChunkType::DataSet,
|
||||
[0x6D, 0x68, 0x69, 0x61] => ChunkType::AlbumList,
|
||||
[0x6D, 0x68, 0x6C, 0x61] => ChunkType::AlbumItem,
|
||||
[0x6D, 0x68, 0x6C, 0x74] => ChunkType::TrackList,
|
||||
[0x6D, 0x68, 0x69, 0x74] => ChunkType::TrackItem,
|
||||
[0x6D, 0x68, 0x6F, 0x64] => ChunkType::StringTypes,
|
||||
[0x6D, 0x68, 0x6C, 0x70] => ChunkType::PlaylistList,
|
||||
[0x6D, 0x68, 0x79, 0x70] => ChunkType::Playlist,
|
||||
_ => ChunkType::Unknown
|
||||
@ -33,17 +33,11 @@ impl From<[u8; 4]> for ChunkType {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Archive, Deserialize, Serialize, Debug, PartialEq)]
|
||||
#[rkyv(compare(PartialEq), derive(Debug))]
|
||||
struct ChunkHeader {
|
||||
chunk_type: [u8; 4],
|
||||
end_of_chunk: u32,
|
||||
children_count: u32
|
||||
}
|
||||
|
||||
#[derive(Archive, Deserialize, Serialize, Debug, PartialEq)]
|
||||
#[rkyv(compare(PartialEq), derive(Debug))]
|
||||
struct Database {
|
||||
header_length: u32,
|
||||
total_length: u32,
|
||||
unknown: u32,
|
||||
version: u32,
|
||||
children_count: u32,
|
||||
@ -57,12 +51,16 @@ struct Database {
|
||||
#[derive(Archive, Deserialize, Serialize, Debug, PartialEq)]
|
||||
#[rkyv(compare(PartialEq), derive(Debug))]
|
||||
struct DataSet {
|
||||
header_length: u32,
|
||||
total_length: u32,
|
||||
data_type: u32
|
||||
}
|
||||
|
||||
#[derive(Archive, Deserialize, Serialize, Debug, PartialEq)]
|
||||
#[rkyv(compare(PartialEq), derive(Debug))]
|
||||
struct AlbumItem {
|
||||
header_length: u32,
|
||||
total_length: u32, // length of header + all child records
|
||||
number_of_strings: u32,
|
||||
unknown: u16,
|
||||
album_id_for_track: u16,
|
||||
@ -73,6 +71,8 @@ struct AlbumItem {
|
||||
#[derive(Archive, Deserialize, Serialize, Debug, PartialEq)]
|
||||
#[rkyv(compare(PartialEq), derive(Debug))]
|
||||
struct TrackItem {
|
||||
header_length: u32,
|
||||
total_length: u32, // length of header + all child records
|
||||
number_of_strings: u32, // number of mhod's count
|
||||
unique_id: u32,
|
||||
visible: u32,
|
||||
@ -148,6 +148,8 @@ struct TrackItem {
|
||||
#[derive(Archive, Deserialize, Serialize, Debug, PartialEq)]
|
||||
#[rkyv(compare(PartialEq), derive(Debug))]
|
||||
struct Entry { // mhod
|
||||
header_length: u32,
|
||||
total_length: u32,
|
||||
entry_type: u32,
|
||||
unk1: u32,
|
||||
unk2: u32,
|
||||
@ -160,6 +162,8 @@ struct Entry { // mhod
|
||||
#[derive(Archive, Deserialize, Serialize, Debug, PartialEq)]
|
||||
#[rkyv(compare(PartialEq), derive(Debug))]
|
||||
struct Playlist {
|
||||
header_length: u32,
|
||||
total_length: u32, // length of header + all child records
|
||||
data_object_child_count: u32,
|
||||
playlist_item_count: u32,
|
||||
is_master_playlist_flag: u8,
|
||||
@ -172,6 +176,13 @@ struct Playlist {
|
||||
list_sort_order: u32
|
||||
}
|
||||
|
||||
#[derive(Archive, Deserialize, Serialize, Debug, PartialEq)]
|
||||
#[rkyv(compare(PartialEq), derive(Debug))]
|
||||
struct Header {
|
||||
header_length: u32,
|
||||
total_length: u32
|
||||
}
|
||||
|
||||
enum ChunkState {
|
||||
Header,
|
||||
Data
|
||||
@ -179,50 +190,55 @@ enum ChunkState {
|
||||
|
||||
fn db(data: &[u8]) {
|
||||
let mut state = ChunkState::Header;
|
||||
let mut chunk_header = None;
|
||||
let mut chunk_type = None;
|
||||
let mut i = 0;
|
||||
while i < data.len() {
|
||||
state = match state {
|
||||
ChunkState::Header => {
|
||||
chunk_header = Some(rkyv::access::<ArchivedChunkHeader, Error>(&data[i..i+12]).unwrap());
|
||||
//info!("header: {:?}", chunk_header);
|
||||
i += 12;
|
||||
let a: [u8; 4] = data[i..i+4].try_into().unwrap();
|
||||
chunk_type = Some(ChunkType::from(a));
|
||||
i += 4;
|
||||
ChunkState::Data
|
||||
},
|
||||
ChunkState::Data => {
|
||||
let header = chunk_header.unwrap();
|
||||
let mut u = 0;
|
||||
// usize::try_from(header.end_of_chunk).unwrap() - 12
|
||||
match header.chunk_type {
|
||||
[109, 104, 98, 100] => { //mhbd
|
||||
u = usize::try_from(header.end_of_chunk).unwrap() - 12;
|
||||
info!("val: {:?}", rkyv::access::<ArchivedDatabase, Error>(&data[i..i+u]).unwrap());
|
||||
match chunk_type.unwrap() {
|
||||
ChunkType::Database => {
|
||||
let db = rkyv::access::<ArchivedDatabase, Error>(&data[i..i+std::mem::size_of::<Database>()]).unwrap();
|
||||
info!("val: {:?}", db);
|
||||
info!("i: {}", data[i]);
|
||||
u = usize::try_from(db.header_length).unwrap() - 4;
|
||||
},
|
||||
[109, 104, 115, 100] => { //mhsd
|
||||
u = usize::try_from(header.end_of_chunk).unwrap() - 12;
|
||||
info!("val: {:?}", rkyv::access::<ArchivedDataSet, Error>(&data[i..i+u]).unwrap());
|
||||
ChunkType::DataSet => {
|
||||
let ds = rkyv::access::<ArchivedDataSet, Error>(&data[i..i+std::mem::size_of::<DataSet>()]).unwrap();
|
||||
info!("val: {:?}", ds);
|
||||
u = usize::try_from(ds.total_length).unwrap() - 4;
|
||||
},
|
||||
[109, 104, 105, 97] => { // mhla
|
||||
ChunkType::AlbumList => {
|
||||
info!("AlbumList");
|
||||
u = usize::try_from(header.end_of_chunk).unwrap() - 12;
|
||||
let header = rkyv::access::<ArchivedHeader, Error>(&data[i..i+std::mem::size_of::<Header>()]).unwrap();
|
||||
u = usize::try_from(header.total_length).unwrap() - 4;
|
||||
},
|
||||
[109, 104, 108, 97] => { // mhia
|
||||
u = usize::try_from(header.end_of_chunk).unwrap() - 12;
|
||||
info!("val: {:?}", rkyv::access::<ArchivedAlbumItem, Error>(&data[i..i+u]).unwrap());
|
||||
ChunkType::AlbumItem => {
|
||||
let ai = rkyv::access::<ArchivedAlbumItem, Error>(&data[i..i+std::mem::size_of::<AlbumItem>()]).unwrap();
|
||||
info!("val: {:?}", ai);
|
||||
u = usize::try_from(ai.total_length).unwrap() - 4;
|
||||
},
|
||||
[109, 104, 108, 116] => { // mhlt
|
||||
ChunkType::TrackList => {
|
||||
info!("TrackList");
|
||||
u = usize::try_from(header.end_of_chunk).unwrap() - 12;
|
||||
let header = rkyv::access::<ArchivedHeader, Error>(&data[i..i+std::mem::size_of::<Header>()]).unwrap();
|
||||
u = usize::try_from(header.total_length).unwrap() - 4;
|
||||
},
|
||||
[109, 104, 105, 116] => { // mhit
|
||||
//info!("head: {}, {}", header.end_of_chunk, header.children_count);
|
||||
u = usize::try_from(header.end_of_chunk).unwrap() - 12;
|
||||
info!("val: {:?}", rkyv::access::<ArchivedTrackItem, Error>(&data[i..i+u]).unwrap());
|
||||
ChunkType::TrackItem => {
|
||||
let ti = rkyv::access::<ArchivedTrackItem, Error>(&data[i..i+std::mem::size_of::<TrackItem>()]).unwrap();
|
||||
info!("val: {:?}", ti);
|
||||
u = usize::try_from(ti.total_length).unwrap() - 4;
|
||||
},
|
||||
[109, 104, 111, 100] => { // mhod
|
||||
u = usize::try_from(header.children_count).unwrap() - 12;
|
||||
let header_offset: usize = (header.end_of_chunk + 4) as usize;
|
||||
let str_end: usize = (header.children_count - 12) as usize;
|
||||
ChunkType::StringTypes => {
|
||||
let header = rkyv::access::<ArchivedHeader, Error>(&data[i..i+std::mem::size_of::<Header>()]).unwrap();
|
||||
u = usize::try_from(header.header_length).unwrap() - 4;
|
||||
let header_offset: usize = (header.total_length + 4) as usize;
|
||||
let str_end: usize = (header.header_length - 4) as usize;
|
||||
let entry = rkyv::access::<ArchivedEntry, Error>(&data[i..i+28]).unwrap();
|
||||
info!("val: {:?}", &entry);
|
||||
let mut bytes = Vec::new();
|
||||
@ -237,20 +253,20 @@ fn db(data: &[u8]) {
|
||||
let g = String::from_utf8(bytes).unwrap();
|
||||
info!("str: {}", g);
|
||||
},
|
||||
[0x6D, 0x68, 0x6C, 0x70] => { // mhlp
|
||||
//info!("head: {}, {}", header.end_of_chunk, header.children_count);
|
||||
info!("Playlists count: {}", header.children_count);
|
||||
u = usize::try_from(header.end_of_chunk).unwrap() - 12;
|
||||
ChunkType::PlaylistList => {
|
||||
let header = rkyv::access::<ArchivedHeader, Error>(&data[i..i+std::mem::size_of::<Header>()]).unwrap();
|
||||
info!("Playlists count: {}", header.header_length);
|
||||
u = usize::try_from(header.total_length).unwrap() - 4;
|
||||
},
|
||||
[0x6D, 0x68, 0x79, 0x70] => { // mhyp
|
||||
u = usize::try_from(header.end_of_chunk).unwrap() - 12;
|
||||
let playlist = rkyv::access::<ArchivedPlaylist, Error>(&data[i..i+u]).unwrap();
|
||||
ChunkType::Playlist => {
|
||||
let playlist = rkyv::access::<ArchivedPlaylist, Error>(&data[i..i+std::mem::size_of::<Playlist>()]).unwrap();
|
||||
info!("playlist: {:?}", playlist);
|
||||
u = usize::try_from(playlist.total_length).unwrap() - 4;
|
||||
},
|
||||
_ => return
|
||||
}
|
||||
i += u;
|
||||
chunk_header = None;
|
||||
chunk_type = None;
|
||||
ChunkState::Header
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user