-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
mw_dataformat + mw_datatool: general encoding/decoding roundtrip for …
…IS and files!!
- Loading branch information
Showing
26 changed files
with
2,028 additions
and
30 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
use std::io::{Read, Seek, SeekFrom, Write}; | ||
|
||
use mw_dataformat::read::MwFileReader; | ||
|
||
use crate::prelude::*; | ||
use crate::{CommonArgs, ChecksumFixArgs}; | ||
|
||
pub fn main(common: &CommonArgs, _args: &ChecksumFixArgs) -> AnyResult<()> { | ||
match (&common.input, &common.output) { | ||
(Some(in_path), None) => { | ||
let file = std::fs::OpenOptions::new() | ||
.read(true) | ||
.write(true) | ||
.truncate(false) | ||
.create(false) | ||
.open(in_path) | ||
.context("Cannot open input file!")?; | ||
let (file, headerdata) = gen_new_headerdata(file)?; | ||
write_new_headerdata(file, &headerdata)?; | ||
} | ||
(Some(in_path), Some(out_path)) => { | ||
std::fs::copy(in_path, out_path) | ||
.context("Failed to copy data from input to output file!")?; | ||
let in_file = std::fs::OpenOptions::new() | ||
.read(true) | ||
.open(in_path) | ||
.context("Cannot open input file!")?; | ||
let out_file = std::fs::OpenOptions::new() | ||
.write(true) | ||
.truncate(false) | ||
.create(false) | ||
.open(out_path) | ||
.context("Cannot open output file!")?; | ||
let (_, headerdata) = gen_new_headerdata(in_file)?; | ||
write_new_headerdata(out_file, &headerdata)?; | ||
} | ||
(None, _) => { | ||
bail!("Input filename must be specified!"); | ||
} | ||
} | ||
|
||
Ok(()) | ||
} | ||
|
||
fn gen_new_headerdata<R: Read + Seek>(reader: R) -> AnyResult<(R, Vec<u8>)> { | ||
let mut buf = Vec::new(); | ||
|
||
let mut mfr = MwFileReader::new(reader, &mut buf) | ||
.context("Failed to load input file as a MineWars format file!")?; | ||
|
||
mfr.compute_and_force_update_checksums()?; | ||
|
||
let mut buf = vec![]; | ||
mfr.file_header().serialize(&mut buf); | ||
|
||
Ok((mfr.into_inner(), buf)) | ||
} | ||
|
||
fn write_new_headerdata<W: Write + Seek>(mut writer: W, headerdata: &[u8]) -> AnyResult<W> { | ||
writer.seek(SeekFrom::Start(0))?; | ||
writer.write_all(&headerdata)?; | ||
Ok(writer) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
use mw_dataformat::read::MwFileReader; | ||
|
||
use crate::prelude::*; | ||
use crate::{CommonArgs, ChecksumVerifyArgs}; | ||
|
||
pub fn main(common: &CommonArgs, _args: &ChecksumVerifyArgs) -> AnyResult<()> { | ||
let file = if let Some(in_path) = &common.input { | ||
std::fs::OpenOptions::new() | ||
.read(true) | ||
.open(in_path) | ||
.context("Cannot open input file!")? | ||
} else { | ||
bail!("Input filename must be specified!"); | ||
}; | ||
let mut buf = Vec::new(); | ||
|
||
let mut mfr = MwFileReader::new(file, &mut buf) | ||
.context("Failed to load input file as a MineWars format file!")?; | ||
|
||
let mut all_good = true; | ||
|
||
let checksum_expected = mfr.file_header().checksum_header; | ||
match mfr.compute_new_checksum_header() { | ||
Ok(checksum) => { | ||
if checksum == checksum_expected { | ||
eprintln!("Header checksum: {:016x} (ok!)", checksum); | ||
} else { | ||
eprintln!("Header checksum: {:016x} (BAD! Expected: {:016x})", checksum, checksum_expected); | ||
all_good = false; | ||
} | ||
} | ||
Err(e) => { | ||
eprintln!("Header checksum: Expected: {:016x} Cannot verify! Error: {:#}", checksum_expected, e); | ||
all_good = false; | ||
} | ||
} | ||
let checksum_expected = mfr.file_header().checksum_is; | ||
match mfr.compute_new_checksum_isdata() { | ||
Ok(checksum) => { | ||
if checksum == checksum_expected { | ||
eprintln!("ISData checksum: {:016x} (ok!)", checksum); | ||
} else { | ||
eprintln!("ISData checksum: {:016x} (BAD! Expected: {:016x})", checksum, checksum_expected); | ||
all_good = false; | ||
} | ||
} | ||
Err(e) => { | ||
eprintln!("ISData checksum: Expected: {:016x} Cannot verify! Error: {:#}", checksum_expected, e); | ||
all_good = false; | ||
} | ||
} | ||
let checksum_expected = mfr.file_header().checksum_framedata; | ||
match mfr.compute_new_checksum_framedata() { | ||
Ok(checksum) => { | ||
if checksum == checksum_expected { | ||
eprintln!("Frames checksum: {:016x} (ok!)", checksum); | ||
} else { | ||
eprintln!("Frames checksum: {:016x} (BAD! Expected: {:016x})", checksum, checksum_expected); | ||
all_good = false; | ||
} | ||
} | ||
Err(e) => { | ||
eprintln!("Frames checksum: Expected: {:016x} Cannot verify! Error: {:#}", checksum_expected, e); | ||
all_good = false; | ||
} | ||
} | ||
|
||
if all_good { | ||
Ok(()) | ||
} else { | ||
bail!("Checksum verification failed!"); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
use std::io::BufWriter; | ||
|
||
use mw_common::{game::{MapGenTileData, TileKind}, grid::*}; | ||
|
||
use crate::prelude::*; | ||
use crate::{CommonArgs, GenMapArgs}; | ||
|
||
pub fn main(common: &CommonArgs, args: &GenMapArgs) -> AnyResult<()> { | ||
let file = if let Some(out_path) = &common.output { | ||
std::fs::OpenOptions::new() | ||
.write(true) | ||
.create(true) | ||
.truncate(true) | ||
.open(out_path) | ||
.context("Cannot create output file!")? | ||
} else { | ||
bail!("Output filename must be specified!"); | ||
}; | ||
let mut buf = Vec::new(); | ||
let mut scratch = Vec::new(); | ||
let mut tile = MapGenTileData::default(); | ||
tile.set_kind(TileKind::Regular); | ||
tile.set_region(0xFF); | ||
let map: MapData<Hex, _> = MapData::new(args.size, tile); | ||
|
||
let bufwriter = BufWriter::new(file); | ||
let (b_file, b_is) = mw_dataformat::write::MwFileBuilder::new(bufwriter, &mut buf)? | ||
.start_is()?; | ||
let is = b_is | ||
.with_map_lz4compressed(&map, true, &mut scratch)? | ||
.with_cits([Pos(12, 17), Pos(7, 3)])? | ||
.with_named_players(["iyes", "georgie", "gr.NET"])? | ||
.finish()?; | ||
let b_file = b_file.with_is(is)?; | ||
b_file.finish()?; | ||
|
||
Ok(()) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
use mw_dataformat::read::MwFileReader; | ||
|
||
use crate::prelude::*; | ||
use crate::{CommonArgs, InfoArgs}; | ||
|
||
pub fn main(common: &CommonArgs, args: &InfoArgs) -> AnyResult<()> { | ||
let file = if let Some(in_path) = &common.input { | ||
std::fs::OpenOptions::new() | ||
.read(true) | ||
.open(in_path) | ||
.context("Cannot read input file!")? | ||
} else { | ||
bail!("Input filename must be specified!"); | ||
}; | ||
let mut buf = Vec::new(); | ||
|
||
let mut mfr = MwFileReader::new(file, &mut buf) | ||
.context("Failed to load input file as a MineWars format file!")?; | ||
|
||
if !args.ignore_checksums { | ||
mfr.verify_checksums() | ||
.context("Checksum verification failed!")?; | ||
} | ||
|
||
eprintln!("File Header:"); | ||
let checksum_header = mfr.file_header().checksum_header; | ||
eprintln!("Header checksum: {:016x}", checksum_header); | ||
let checksum_is = mfr.file_header().checksum_is; | ||
eprintln!("ISData checksum: {:016x}", checksum_is); | ||
let checksum_framedata = mfr.file_header().checksum_framedata; | ||
eprintln!("Frames checksum: {:016x}", checksum_framedata); | ||
eprintln!("FrameData is compressed?: {}", mfr.is_framedata_compressed()); | ||
eprintln!("FrameData length (compressed): {}", mfr.file_header().len_framedata_compressed()); | ||
eprintln!("FrameData length (raw): {}", mfr.file_header().len_framedata_raw()); | ||
|
||
let (_, mut isr) = mfr.read_is() | ||
.context("Cannot read IS")?; | ||
|
||
eprintln!(); | ||
eprintln!("IS Header:"); | ||
eprintln!("Map Topology: {:?}", isr.map_topology()); | ||
eprintln!("Map Size: {}", isr.map_size()); | ||
eprintln!("Number of map regions: {}", isr.n_regions()); | ||
eprintln!("MapData is compressed?: {}", isr.is_mapdata_compressed()); | ||
eprintln!("MapData length (compressed): {}", isr.header().len_mapdata_compressed()); | ||
eprintln!("MapData length (raw): {}", isr.header().len_mapdata_raw()); | ||
eprintln!("Number of players: {}", isr.n_players()); | ||
eprintln!("Player names anonymized?: {}", isr.header().len_playerdata() == 0); | ||
eprintln!("PlayerData length: {}", isr.header().len_playerdata()); | ||
eprintln!("RulesData length: {}", isr.header().len_rules()); | ||
|
||
eprintln!(); | ||
eprintln!("Player Names:"); | ||
for (i, name) in isr.read_players()?.enumerate() { | ||
eprintln!("{}: {:?}", i, name); | ||
} | ||
|
||
Ok(()) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
use mw_common::game::{MapGenTileData, TileKind}; | ||
use mw_common::grid::{Coord, MapDataTopo, Pos}; | ||
use mw_dataformat::read::MwFileReader; | ||
|
||
use crate::prelude::*; | ||
use crate::{CommonArgs, MapAsciiArgs}; | ||
|
||
pub fn main(common: &CommonArgs, _args: &MapAsciiArgs) -> AnyResult<()> { | ||
let file = if let Some(in_path) = &common.input { | ||
std::fs::OpenOptions::new() | ||
.read(true) | ||
.open(in_path) | ||
.context("Cannot open input file!")? | ||
} else { | ||
bail!("Input filename must be specified!"); | ||
}; | ||
let mut buf = Vec::new(); | ||
let mut scratch = Vec::new(); | ||
|
||
let mfr = MwFileReader::new(file, &mut buf) | ||
.context("Failed to load input file as a MineWars format file!")?; | ||
|
||
let (_, mut isr) = mfr.read_is()?; | ||
let map: MapDataTopo<MapGenTileData> = isr.read_map_dyntopo(Some(&mut scratch), false)?; | ||
let cits = isr.read_cits()?; | ||
|
||
fn f_tile_ascii(cits: &[Pos], pos: Pos, kind: TileKind) -> u8 { | ||
if cits.iter().position(|p| *p == pos).is_some() { | ||
b'C' | ||
} else { | ||
match kind { | ||
TileKind::Water => b'~', | ||
TileKind::Regular => b'.', | ||
TileKind::Fertile => b',', | ||
TileKind::Forest => b'i', | ||
TileKind::Mountain => b'm', | ||
TileKind::Destroyed => b'+', | ||
TileKind::FoundationRoad => b'x', | ||
TileKind::FoundationStruct => b'_', | ||
} | ||
} | ||
} | ||
|
||
match map { | ||
MapDataTopo::Hex(map) => { | ||
map.ascii_art(&mut std::io::stdout().lock(), |c, d| f_tile_ascii(cits, c.into(), d.kind()))?; | ||
} | ||
MapDataTopo::Sq(map) => { | ||
map.ascii_art(&mut std::io::stdout().lock(), |c, d| f_tile_ascii(cits, c.into(), d.kind()))?; | ||
} | ||
} | ||
|
||
Ok(()) | ||
} |
Oops, something went wrong.