ggpkviewer contains various tools for reading ggpk files:
- ggpklib - Rust library that implements logic for parsing files
- ggpkcli - CLI tool for getting files from ggpk or straight from patch servers
Add library as dependency:
[dependencies]
ggpklib = { git = "https://github.com/shadr/ggpkviewer.git" }
To get files first we need to create instance of our virtual file system
use ggpklib::poefs::{PoeFS, LocalSource, OnlineSource};
// Create source for file system from local GGPK file
let source = LocalSource::new(path).unwrap();
// Or from patch server
let source = Online::new().unwrap();
let poe_fs = PoeFS::new(source);
For example we want to get Mods.dat64 file, using PoeFS
function get_file
we can get uncompressed bytes of wanted file
note: currently you need to specify file path in lowercase only, with extension and starting with /
let mods_bytes = poe_fs.get_file("/data/mods.dat64").unwrap();
Bytes of dat files are not very usefull without knowing how to read them, we need to parse those bytes using SchemaFile
schema is reverse engineered by community members and availabe in poe-tool-dev/dat-schema repo
let file_dat = DatFile::new(mods_bytes);
let schema_content = std::fs::read_to_string("schema.min.json").unwrap();
let schema: SchemaFile = serde_json::from_str(&schema_content).unwrap();
// Find schema for wanted table by its name, case insensitive
let file_schema = schema.find_table("mods").unwrap();
// Get column definitions
let file_columns = &file_schema.columns;
for row in file_dat.iter_rows_map(&file_columns){
// `row` is HashMap<String, DatValue>
println!("{}", row["Id"].as_string()) // casting DatValue to String using `as_string`
}
You can see supported commands by using:
ggpkcli --help
Save dat64 file from local GGPK file to csv:
ggpkcli --ggpk /path/to/ggpk/file get /data/mods.dat64 mods.csv
Print list of paths from online file:
ggpkcli --online list-paths
Use tools like grep
to filter paths:
ggpkcli --online list-paths | grep mods.dat
Thanks to these libraries and their contributors because half of this project is based on them: