Giter Club home page Giter Club logo

pk2's Introduction

pk2

Crates.io Docs.rs CI

A rust crate for reading and writing Silkroad Online's pk2 format.

By default the crate pulls in encoding_rs to properly work with the original pk2 files, since those use the EUC-KR encoding for file names. This dependency is feature gated behind the euc-kr feature.

pk2_mate

The pk2_mate binary contains 3 simplistic tools for working with pk2 archives.

  • extract - extracts all files of a pk2 archive
  • pack - packs all files of a directory into a new pk2 archive
  • repack - repacks a pk2 archive into a new one(this gets rid of possible fragmentation)

For usage extraction of a particular tool run pk2_mate 'tool' -h(or cargo run -p pk2_mate -- 'tool' -h via cargo) with 'tool' replaced by the name of the tool. If no pk2 key is specified the tools will use the international silkroad online blowfish key(169841) by default.

License

Licensed under the MIT license (LICENSE-MIT or http://opensource.org/licenses/MIT)

pk2's People

Contributors

veykril avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

pk2's Issues

Abstract the file field of the archive with a managing struct

currently there is a lot of unnecessary code repetition due to the borrow checker etc. Working with the os file in general creates a lot of unnecessary code that could be easily hidden behind a struct that abstracts this. This should also help reducing the size of the monolith function at

pk2/src/archive.rs

Lines 105 to 159 in 9d4e423

fn create_entry_at(&mut self, mut chain: u64, path: &Path) -> Result<(u64, usize)> {
let mut components = path.components().peekable();
while let Some(component) = components.next() {
if let Component::Normal(p) = component {
let block_chain = self.block_mgr.chains.get_mut(&chain).unwrap();
let idx = if let Some((idx, entry)) = block_chain.find_first_empty_mut() {
if components.peek().is_some() {
//allocate new blockchain
let mut file = self.file.borrow_mut();
let file_len = file.metadata()?.len();
*entry = PackEntry::new_directory(
p.to_str().unwrap().to_owned(),
file_len,
entry.next_chain(),
);
let offset = block_chain.get_file_offset_for_entry(idx).unwrap();
Self::write_entry_to_file_at(
&mut *file,
&mut self.bf,
offset,
&block_chain[idx],
)?;
let block =
Self::create_new_block_in_file_at(&mut *file, &mut self.bf, file_len)?;
self.block_mgr
.chains
.insert(file_len, PackBlockChain::new(vec![block]));
chain = file_len;
continue;
} else {
idx
}
} else {
let mut file = self.file.borrow_mut();
let offset = file.metadata()?.len();
let block =
Self::create_new_block_in_file_at(&mut *file, &mut self.bf, offset)?;
block_chain.as_mut().last_mut().unwrap()[PK2_FILE_BLOCK_ENTRY_COUNT - 1]
.set_next_chain(offset);
block_chain.push(block);
(block_chain.as_ref().len() - 1) * PK2_FILE_BLOCK_ENTRY_COUNT
};
return Ok((block_chain.offset(), idx));
} else {
return Err(io::Error::new(
io::ErrorKind::InvalidInput,
format!("{:?} unexpected", component),
));
}
}
Err(io::Error::new(
io::ErrorKind::AlreadyExists,
"Path already exists",
))
}

Create own error struct/enum

Currently the crate is just reusing the std::io::Error, while this works quite well since everything is pretty much io related its not that easy to match on those errors to transform errors into more specific ones with given knowledge. For example create_file will return the following error:

PackEntry::File { name, .. } if name == directory => Err(io::Error::new(
io::ErrorKind::Other,
"Expected a directory, found a file",
)),
when the file already exists which isnt really helpful.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.