removed idlib (very very very early idmangler-lib) directory
This commit is contained in:
parent
e1298accb4
commit
f658a1b7f3
18 changed files with 1 additions and 818 deletions
|
@ -1,6 +0,0 @@
|
||||||
[package]
|
|
||||||
name = "idlib"
|
|
||||||
version = "0.1.0"
|
|
||||||
edition = "2021"
|
|
||||||
|
|
||||||
[dependencies]
|
|
|
@ -1,36 +0,0 @@
|
||||||
use crate::types::transform::TransformVersion;
|
|
||||||
|
|
||||||
use super::{DataDecoder, DataEncoder, DataTransformerTypes, TransformId};
|
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
|
||||||
pub struct EndData;
|
|
||||||
|
|
||||||
impl TransformId for EndData {
|
|
||||||
fn get_id() -> u8 {
|
|
||||||
DataTransformerTypes::EndDataTransformer as u8
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl DataEncoder for EndData {
|
|
||||||
fn encode_data(
|
|
||||||
&self,
|
|
||||||
_ver: TransformVersion,
|
|
||||||
_out: &mut Vec<u8>,
|
|
||||||
) -> Result<(), super::DataTransformError> {
|
|
||||||
// end data is always empty
|
|
||||||
return Ok(());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<B: Iterator<Item = u8>> DataDecoder<B> for EndData {
|
|
||||||
fn decode_data(
|
|
||||||
_bytes: &mut B,
|
|
||||||
_ver: TransformVersion,
|
|
||||||
) -> Result<Self, super::DataTransformError>
|
|
||||||
where
|
|
||||||
Self: Sized,
|
|
||||||
{
|
|
||||||
// end data is always empty
|
|
||||||
return Ok(Self);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,175 +0,0 @@
|
||||||
use crate::{
|
|
||||||
data_transformer::DataTransformError,
|
|
||||||
encoding::{decode_varint, encode_varint},
|
|
||||||
types::{
|
|
||||||
stat::{RollType, Stat, StatId},
|
|
||||||
transform::TransformVersion,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
use super::{DataDecoder, DataEncoder, DataTransformerTypes, TransformId};
|
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
|
||||||
pub struct IdentificationData {
|
|
||||||
pub identifications: Vec<Stat>,
|
|
||||||
pub extended_encoding: bool,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl TransformId for IdentificationData {
|
|
||||||
fn get_id() -> u8 {
|
|
||||||
DataTransformerTypes::IdentificationDataTransformer as u8
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl DataEncoder for IdentificationData {
|
|
||||||
fn encode_data(
|
|
||||||
&self,
|
|
||||||
ver: TransformVersion,
|
|
||||||
out: &mut Vec<u8>,
|
|
||||||
) -> Result<(), super::DataTransformError> {
|
|
||||||
match ver {
|
|
||||||
TransformVersion::Version1 => {
|
|
||||||
if self.identifications.len() > 255 {
|
|
||||||
return Err(DataTransformError::TooManyIdentifications);
|
|
||||||
}
|
|
||||||
|
|
||||||
let encoded_id_count: u8 = self
|
|
||||||
.identifications
|
|
||||||
.iter()
|
|
||||||
.filter(|id| !id.pre_identified())
|
|
||||||
.count() as u8;
|
|
||||||
|
|
||||||
out.push(encoded_id_count);
|
|
||||||
out.push(self.extended_encoding as u8);
|
|
||||||
|
|
||||||
self.encode_individual_idents(out)?;
|
|
||||||
|
|
||||||
return Ok(());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn should_encode_data(&self, ver: TransformVersion) -> bool {
|
|
||||||
match ver {
|
|
||||||
TransformVersion::Version1 => {
|
|
||||||
if self.extended_encoding {
|
|
||||||
return self.identifications.len() != 0;
|
|
||||||
} else {
|
|
||||||
return self
|
|
||||||
.identifications
|
|
||||||
.iter()
|
|
||||||
.any(|id: &Stat| !id.pre_identified());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl IdentificationData {
|
|
||||||
fn encode_individual_idents(&self, bytes: &mut Vec<u8>) -> Result<(), DataTransformError> {
|
|
||||||
// encode the static values if extended encoding is used
|
|
||||||
if self.extended_encoding {
|
|
||||||
let preid_stats: Vec<_> = self
|
|
||||||
.identifications
|
|
||||||
.iter()
|
|
||||||
.filter(|id| id.pre_identified())
|
|
||||||
.collect();
|
|
||||||
|
|
||||||
bytes.push(preid_stats.len() as u8);
|
|
||||||
|
|
||||||
for stat in preid_stats {
|
|
||||||
// first add the id of the ident
|
|
||||||
bytes.push(stat.kind.0);
|
|
||||||
|
|
||||||
// then add the basevalue
|
|
||||||
bytes.append(&mut encode_varint(
|
|
||||||
stat.base.ok_or(DataTransformError::NoBasevalueForIdent)? as i64,
|
|
||||||
));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for ident in self.identifications.iter() {
|
|
||||||
// only handle non preids since preids are encoded using the earlier system
|
|
||||||
if let RollType::Value(roll_val) = ident.roll {
|
|
||||||
// add id of the ident
|
|
||||||
bytes.push(ident.kind.0);
|
|
||||||
|
|
||||||
if self.extended_encoding {
|
|
||||||
// push the baseval
|
|
||||||
bytes.append(&mut encode_varint(
|
|
||||||
ident.base.ok_or(DataTransformError::NoBasevalueForIdent)? as i64,
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
bytes.push(roll_val);
|
|
||||||
} else {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<B: Iterator<Item = u8>> DataDecoder<B> for IdentificationData {
|
|
||||||
fn decode_data(bytes: &mut B, ver: TransformVersion) -> Result<Self, super::DataTransformError>
|
|
||||||
where
|
|
||||||
Self: Sized,
|
|
||||||
{
|
|
||||||
match ver {
|
|
||||||
TransformVersion::Version1 => {
|
|
||||||
let mut idents = Vec::new();
|
|
||||||
|
|
||||||
// first byte is the number of identifications
|
|
||||||
let ident_count = bytes.next().unwrap();
|
|
||||||
|
|
||||||
// second byte is whether or not extended coding is used
|
|
||||||
let extended_encoding = bytes.next().unwrap() == 1;
|
|
||||||
|
|
||||||
let mut preid_count = 0;
|
|
||||||
if extended_encoding {
|
|
||||||
// count of preid idents
|
|
||||||
preid_count = bytes.next().unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
for i in 0..(ident_count + preid_count) {
|
|
||||||
// id of the ident
|
|
||||||
let id = bytes.next().unwrap();
|
|
||||||
|
|
||||||
let preid = i < preid_count;
|
|
||||||
|
|
||||||
// decode the possible baseval if using extended coding
|
|
||||||
let baseval = if extended_encoding {
|
|
||||||
Some(decode_varint(bytes) as i32)
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
};
|
|
||||||
|
|
||||||
// if preid skip decoding the value
|
|
||||||
if preid {
|
|
||||||
idents.push(Stat {
|
|
||||||
kind: StatId(id),
|
|
||||||
base: baseval,
|
|
||||||
roll: RollType::PreIdentified,
|
|
||||||
});
|
|
||||||
continue;
|
|
||||||
} else {
|
|
||||||
// decode the roll
|
|
||||||
let introll = bytes.next().unwrap();
|
|
||||||
|
|
||||||
idents.push(Stat {
|
|
||||||
kind: StatId(id),
|
|
||||||
base: baseval,
|
|
||||||
roll: RollType::Value(introll),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(Self {
|
|
||||||
identifications: idents,
|
|
||||||
extended_encoding,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,130 +0,0 @@
|
||||||
use enddata::EndData;
|
|
||||||
use identdata::IdentificationData;
|
|
||||||
use namedata::NameData;
|
|
||||||
use powderdata::PowderData;
|
|
||||||
use rerolldata::RerollData;
|
|
||||||
use startdata::StartData;
|
|
||||||
use typedata::TypeData;
|
|
||||||
|
|
||||||
use crate::types::transform::TransformVersion;
|
|
||||||
|
|
||||||
pub mod enddata;
|
|
||||||
pub mod identdata;
|
|
||||||
pub mod namedata;
|
|
||||||
pub mod powderdata;
|
|
||||||
pub mod rerolldata;
|
|
||||||
pub mod shinydata;
|
|
||||||
pub mod startdata;
|
|
||||||
pub mod typedata;
|
|
||||||
|
|
||||||
pub trait TransformId {
|
|
||||||
fn get_id() -> u8;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub trait DataEncoder: TransformId {
|
|
||||||
fn encode(&self, ver: TransformVersion, out: &mut Vec<u8>) -> Result<(), DataTransformError> {
|
|
||||||
// skip encoding data which should not be encoded
|
|
||||||
if !self.should_encode_data(ver) {
|
|
||||||
return Ok(());
|
|
||||||
}
|
|
||||||
|
|
||||||
// encode the id
|
|
||||||
out.push(Self::get_id());
|
|
||||||
|
|
||||||
// encode the data
|
|
||||||
self.encode_data(ver, out)?;
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn encode_data(
|
|
||||||
&self,
|
|
||||||
ver: TransformVersion,
|
|
||||||
out: &mut Vec<u8>,
|
|
||||||
) -> Result<(), DataTransformError>;
|
|
||||||
|
|
||||||
fn should_encode_data(&self, _ver: TransformVersion) -> bool {
|
|
||||||
true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub trait DataDecoder<B: Iterator<Item = u8>>: TransformId {
|
|
||||||
fn decode_data(bytes: &mut B, ver: TransformVersion) -> Result<Self, DataTransformError>
|
|
||||||
where
|
|
||||||
Self: Sized;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn decode<B: Iterator<Item = u8>>(bytes: &mut B) -> Result<Vec<AnyData>, DataTransformError> {
|
|
||||||
let mut out = Vec::new();
|
|
||||||
|
|
||||||
// decode the start byte and version
|
|
||||||
let ver = StartData::decode_start_bytes(bytes)?;
|
|
||||||
|
|
||||||
while let Some(id) = bytes.next() {
|
|
||||||
match id {
|
|
||||||
0 => return Err(DataTransformError::StartReparse),
|
|
||||||
1 => out.push(AnyData::TypeData(TypeData::decode_data(bytes, ver)?)),
|
|
||||||
2 => out.push(AnyData::NameData(NameData::decode_data(bytes, ver)?)),
|
|
||||||
3 => out.push(AnyData::IdentificationData(
|
|
||||||
IdentificationData::decode_data(bytes, ver)?,
|
|
||||||
)),
|
|
||||||
// TODO
|
|
||||||
255 => out.push(AnyData::EndData(EndData::decode_data(bytes, ver)?)),
|
|
||||||
_ => return Err(DataTransformError::UnknownTransformer(id)),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(out)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub enum DataTransformError {
|
|
||||||
NoStartBlock,
|
|
||||||
UnknownVersion(u8),
|
|
||||||
/// Attempt to parse start data. Start data is specially handled.
|
|
||||||
StartReparse,
|
|
||||||
|
|
||||||
InvalidTypeError,
|
|
||||||
|
|
||||||
BadString,
|
|
||||||
|
|
||||||
TooManyIdentifications,
|
|
||||||
NoBasevalueForIdent,
|
|
||||||
NoPotentialValuesForIdent,
|
|
||||||
InvalidIntRoll,
|
|
||||||
|
|
||||||
UnexpectedEndOfBytes,
|
|
||||||
UnknownTransformer(u8),
|
|
||||||
}
|
|
||||||
|
|
||||||
pub enum DataTransformerTypes {
|
|
||||||
StartDataTransformer = 0,
|
|
||||||
TypeDataTransformer = 1,
|
|
||||||
NameDataTransformer = 2,
|
|
||||||
IdentificationDataTransformer = 3,
|
|
||||||
PowderDataTransformer = 4,
|
|
||||||
RerollDataTransformer = 5,
|
|
||||||
ShinyDataTransformer = 6,
|
|
||||||
CustomGearTypeTransformer = 7,
|
|
||||||
DurabilityDataTransformer = 8,
|
|
||||||
RequirementsDataTransformer = 9,
|
|
||||||
DamageDataTransformer = 10,
|
|
||||||
DefenseDataTransformer = 11,
|
|
||||||
CustomIdentificationDataTransformer = 12,
|
|
||||||
CustomConsumableTypeDataTransformer = 13,
|
|
||||||
UsesDataTransformer = 14,
|
|
||||||
EffectsDataTransformer = 15,
|
|
||||||
EndDataTransformer = 255,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub enum AnyData {
|
|
||||||
StartData(StartData),
|
|
||||||
TypeData(TypeData),
|
|
||||||
NameData(NameData),
|
|
||||||
IdentificationData(IdentificationData),
|
|
||||||
PowderData(PowderData),
|
|
||||||
RerollData(RerollData),
|
|
||||||
// TODO
|
|
||||||
EndData(EndData),
|
|
||||||
}
|
|
|
@ -1,54 +0,0 @@
|
||||||
use crate::{data_transformer::DataTransformError, types::transform::TransformVersion};
|
|
||||||
|
|
||||||
use super::{DataDecoder, DataEncoder, DataTransformerTypes, TransformId};
|
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
|
||||||
pub struct NameData(pub String);
|
|
||||||
|
|
||||||
impl TransformId for NameData {
|
|
||||||
fn get_id() -> u8 {
|
|
||||||
DataTransformerTypes::NameDataTransformer as u8
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl DataEncoder for NameData {
|
|
||||||
fn encode_data(
|
|
||||||
&self,
|
|
||||||
ver: TransformVersion,
|
|
||||||
out: &mut Vec<u8>,
|
|
||||||
) -> Result<(), super::DataTransformError> {
|
|
||||||
match ver {
|
|
||||||
TransformVersion::Version1 => {
|
|
||||||
// check that the string is valid ascii
|
|
||||||
if self.0.chars().any(|c| !c.is_ascii()) {
|
|
||||||
return Err(DataTransformError::BadString);
|
|
||||||
}
|
|
||||||
|
|
||||||
// push the bytes
|
|
||||||
out.extend_from_slice(self.0.as_bytes());
|
|
||||||
// push the null terminator
|
|
||||||
out.push(0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<B: Iterator<Item = u8>> DataDecoder<B> for NameData {
|
|
||||||
fn decode_data(bytes: &mut B, ver: TransformVersion) -> Result<Self, super::DataTransformError>
|
|
||||||
where
|
|
||||||
Self: Sized,
|
|
||||||
{
|
|
||||||
match ver {
|
|
||||||
TransformVersion::Version1 => {
|
|
||||||
let b: Vec<u8> = bytes.take_while(|b| *b != 0).collect();
|
|
||||||
|
|
||||||
// UTF-8 and ASCII share the same set of characters
|
|
||||||
Ok(NameData(
|
|
||||||
String::from_utf8(b).map_err(|_| DataTransformError::BadString)?,
|
|
||||||
))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,59 +0,0 @@
|
||||||
use crate::types::{powder::Powders, transform::TransformVersion};
|
|
||||||
|
|
||||||
use super::{DataEncoder, DataTransformerTypes, TransformId};
|
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
|
||||||
pub struct PowderData {
|
|
||||||
pub powder_slots: u8,
|
|
||||||
pub powders: Vec<(Powders, u8)>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl TransformId for PowderData {
|
|
||||||
fn get_id() -> u8 {
|
|
||||||
DataTransformerTypes::PowderDataTransformer as u8
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl DataEncoder for PowderData {
|
|
||||||
fn encode_data(
|
|
||||||
&self,
|
|
||||||
ver: TransformVersion,
|
|
||||||
out: &mut Vec<u8>,
|
|
||||||
) -> Result<(), super::DataTransformError> {
|
|
||||||
match ver {
|
|
||||||
TransformVersion::Version1 => {
|
|
||||||
let bits_needed = self.powders.len() * 5;
|
|
||||||
let total_bits = (bits_needed + 7) / 8;
|
|
||||||
|
|
||||||
let mut powder_data = vec![0u8; total_bits];
|
|
||||||
|
|
||||||
for (i, pow) in self.powders.iter().enumerate() {
|
|
||||||
let elem = pow.0 as u8;
|
|
||||||
// TODO: figure out if wynntils fixes this and make the tier be encoded correctly
|
|
||||||
let tier = 0; //pow.1;
|
|
||||||
|
|
||||||
// calculate the 5 bit powder value
|
|
||||||
let powder_num = (elem * 6 + tier) & 0b00011111;
|
|
||||||
|
|
||||||
// bit position where this specific powder starts
|
|
||||||
let powder_idx = i * 5;
|
|
||||||
|
|
||||||
// set the values
|
|
||||||
for j in 0..5 {
|
|
||||||
// calculate the bit position of this bit
|
|
||||||
let idx = powder_idx + j;
|
|
||||||
let bit = (powder_num >> (4 - j)) & 0b1;
|
|
||||||
powder_data[idx / 8] |= bit << (7 - (idx % 8));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
out.push(self.powder_slots);
|
|
||||||
out.push(self.powders.len() as u8);
|
|
||||||
|
|
||||||
out.append(&mut powder_data);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,41 +0,0 @@
|
||||||
use crate::types::transform::TransformVersion;
|
|
||||||
|
|
||||||
use super::{DataDecoder, DataEncoder, DataTransformError, DataTransformerTypes, TransformId};
|
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
|
||||||
pub struct RerollData(pub u8);
|
|
||||||
|
|
||||||
impl TransformId for RerollData {
|
|
||||||
fn get_id() -> u8 {
|
|
||||||
DataTransformerTypes::RerollDataTransformer as u8
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl DataEncoder for RerollData {
|
|
||||||
fn encode_data(
|
|
||||||
&self,
|
|
||||||
ver: crate::types::transform::TransformVersion,
|
|
||||||
out: &mut Vec<u8>,
|
|
||||||
) -> Result<(), super::DataTransformError> {
|
|
||||||
match ver {
|
|
||||||
TransformVersion::Version1 => out.push(self.0),
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<B: Iterator<Item = u8>> DataDecoder<B> for RerollData {
|
|
||||||
fn decode_data(bytes: &mut B, ver: TransformVersion) -> Result<Self, super::DataTransformError>
|
|
||||||
where
|
|
||||||
Self: Sized,
|
|
||||||
{
|
|
||||||
match ver {
|
|
||||||
TransformVersion::Version1 => Ok(Self(
|
|
||||||
bytes
|
|
||||||
.next()
|
|
||||||
.ok_or(DataTransformError::UnexpectedEndOfBytes)?,
|
|
||||||
)),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,31 +0,0 @@
|
||||||
use crate::{encoding::encode_varint, types::transform::TransformVersion};
|
|
||||||
|
|
||||||
use super::{DataEncoder, DataTransformerTypes, TransformId};
|
|
||||||
|
|
||||||
pub struct ShinyData {
|
|
||||||
pub id: u8,
|
|
||||||
pub val: i64,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl TransformId for ShinyData {
|
|
||||||
fn get_id() -> u8 {
|
|
||||||
DataTransformerTypes::ShinyDataTransformer as u8
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl DataEncoder for ShinyData {
|
|
||||||
fn encode_data(
|
|
||||||
&self,
|
|
||||||
ver: crate::types::transform::TransformVersion,
|
|
||||||
out: &mut Vec<u8>,
|
|
||||||
) -> Result<(), super::DataTransformError> {
|
|
||||||
match ver {
|
|
||||||
TransformVersion::Version1 => {
|
|
||||||
out.push(self.id);
|
|
||||||
out.append(&mut encode_varint(self.val));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,42 +0,0 @@
|
||||||
use crate::types::transform::TransformVersion;
|
|
||||||
|
|
||||||
use super::{DataEncoder, DataTransformError, DataTransformerTypes, TransformId};
|
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
|
||||||
pub struct StartData(pub TransformVersion);
|
|
||||||
|
|
||||||
impl TransformId for StartData {
|
|
||||||
fn get_id() -> u8 {
|
|
||||||
DataTransformerTypes::StartDataTransformer as u8
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl DataEncoder for StartData {
|
|
||||||
fn encode_data(
|
|
||||||
&self,
|
|
||||||
ver: TransformVersion,
|
|
||||||
out: &mut Vec<u8>,
|
|
||||||
) -> Result<(), DataTransformError> {
|
|
||||||
match ver {
|
|
||||||
TransformVersion::Version1 => out.push(self.0.version()),
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl StartData {
|
|
||||||
/// Special case function for parsing the start bytes
|
|
||||||
pub(crate) fn decode_start_bytes<B: Iterator<Item = u8>>(
|
|
||||||
bytes: &mut B,
|
|
||||||
) -> Result<TransformVersion, DataTransformError> {
|
|
||||||
let idbyte = bytes.next().unwrap();
|
|
||||||
if idbyte != DataTransformerTypes::StartDataTransformer as u8 {
|
|
||||||
return Err(DataTransformError::NoStartBlock);
|
|
||||||
}
|
|
||||||
|
|
||||||
let verbyte = bytes.next().unwrap();
|
|
||||||
|
|
||||||
TransformVersion::from_u8(verbyte).map_err(|_| DataTransformError::UnknownVersion(verbyte))
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,43 +0,0 @@
|
||||||
use crate::types::{itemtype::ItemType, transform::TransformVersion};
|
|
||||||
|
|
||||||
use super::{DataDecoder, DataEncoder, DataTransformError, DataTransformerTypes, TransformId};
|
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
|
||||||
pub struct TypeData(pub ItemType);
|
|
||||||
|
|
||||||
impl TransformId for TypeData {
|
|
||||||
fn get_id() -> u8 {
|
|
||||||
DataTransformerTypes::TypeDataTransformer as u8
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl DataEncoder for TypeData {
|
|
||||||
fn encode_data(
|
|
||||||
&self,
|
|
||||||
ver: TransformVersion,
|
|
||||||
out: &mut Vec<u8>,
|
|
||||||
) -> Result<(), super::DataTransformError> {
|
|
||||||
match ver {
|
|
||||||
TransformVersion::Version1 => out.push(self.0.into()),
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<B: Iterator<Item = u8>> DataDecoder<B> for TypeData {
|
|
||||||
fn decode_data(bytes: &mut B, ver: TransformVersion) -> Result<Self, super::DataTransformError>
|
|
||||||
where
|
|
||||||
Self: Sized,
|
|
||||||
{
|
|
||||||
match ver {
|
|
||||||
TransformVersion::Version1 => {
|
|
||||||
let b = bytes.next().unwrap();
|
|
||||||
|
|
||||||
Ok(Self(
|
|
||||||
ItemType::try_from(b).map_err(|_| DataTransformError::InvalidTypeError)?,
|
|
||||||
))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,112 +0,0 @@
|
||||||
/// Encode bytes into a string using the wynntils byte encoding scheme
|
|
||||||
///
|
|
||||||
/// https://github.com/Wynntils/Wynntils/blob/main/common/src/main/java/com/wynntils/utils/EncodedByteBuffer.java#L87
|
|
||||||
pub fn encode_string(data: &[u8]) -> String {
|
|
||||||
let mut out = String::new();
|
|
||||||
|
|
||||||
for d in data.chunks(2) {
|
|
||||||
if d.len() == 2 {
|
|
||||||
if d[0] == 255 && d[1] >= 254 {
|
|
||||||
out.push(char::from_u32(0x100000 + ((d[1] - 254) as u32)).unwrap());
|
|
||||||
} else {
|
|
||||||
out.push(char::from_u32(0xF0000 + ((d[0] as u32) << 8) + d[1] as u32).unwrap());
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// encode leftover singular bits with the seperate encoding
|
|
||||||
out.push(char::from_u32(0x100000 + ((d[0] as u32) << 8) + 0xEE).unwrap());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
out
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Decodes the bytes of a wynntils private area encoded string
|
|
||||||
///
|
|
||||||
/// This function does not check whether or not the encoded data is valid
|
|
||||||
///
|
|
||||||
/// https://github.com/Wynntils/Wynntils/blob/main/common/src/main/java/com/wynntils/utils/EncodedByteBuffer.java#L33
|
|
||||||
pub fn decode_string(data: &str) -> Vec<u8> {
|
|
||||||
let mut out = Vec::new();
|
|
||||||
|
|
||||||
for c in data.chars() {
|
|
||||||
let n: u32 = c.into();
|
|
||||||
|
|
||||||
// special case Private use area B
|
|
||||||
if n > 0x100000 {
|
|
||||||
// single byte
|
|
||||||
if n & 0xFF == 0xEE {
|
|
||||||
out.push(((n & 0xFF00) >> 8) as u8);
|
|
||||||
|
|
||||||
assert!(((n & 0xFF00) >> 8) <= 255, "Invalid codepoint: {n:06X}");
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// two bytes
|
|
||||||
|
|
||||||
out.push(255);
|
|
||||||
out.push((254 + (n & 0xFF)) as u8);
|
|
||||||
|
|
||||||
// Only 0x100000-0x100001 are used
|
|
||||||
assert!(n < 0x100002, "Invalid codepoint: {n:06X}");
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
out.push(((n & 0xFF00) >> 8) as u8);
|
|
||||||
out.push((n & 0x00FF) as u8);
|
|
||||||
}
|
|
||||||
|
|
||||||
out
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn encode_varint(value: i64) -> Vec<u8> {
|
|
||||||
// zigzag encoding magic
|
|
||||||
// removes sign bit so values are only positive
|
|
||||||
let value = ((value << 1) ^ (value >> 63)) as u64;
|
|
||||||
|
|
||||||
// 7 bits per byte
|
|
||||||
// highest bit is used to indicate end of encoding
|
|
||||||
|
|
||||||
// calulate number of bytes needed
|
|
||||||
let mut numofbytes = 1;
|
|
||||||
let mut temp = value >> 7;
|
|
||||||
while temp != 0 {
|
|
||||||
// println!("{temp}");
|
|
||||||
numofbytes += 1;
|
|
||||||
temp >>= 7;
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut outbytes = Vec::new();
|
|
||||||
for i in 0..numofbytes {
|
|
||||||
let mut next = (value >> (7 * i)) as u8 & 0x7F;
|
|
||||||
|
|
||||||
// indicate that we are **not** done by setting the highest bit
|
|
||||||
if i < numofbytes - 1 {
|
|
||||||
next |= 0b10000000;
|
|
||||||
}
|
|
||||||
|
|
||||||
outbytes.push(next);
|
|
||||||
}
|
|
||||||
|
|
||||||
outbytes
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn decode_varint<B: Iterator<Item = u8>>(bytes: &mut B) -> i64 {
|
|
||||||
let mut value = 0;
|
|
||||||
|
|
||||||
let mut data = Vec::new();
|
|
||||||
loop {
|
|
||||||
let b = bytes.next().unwrap();
|
|
||||||
|
|
||||||
data.push(b);
|
|
||||||
|
|
||||||
if (b & 0b10000000) == 0 {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i, n) in data.into_iter().enumerate() {
|
|
||||||
value |= ((n & 0b01111111) as i64) << (7 * i);
|
|
||||||
}
|
|
||||||
|
|
||||||
return (value >> 1) ^ -(value & 1);
|
|
||||||
}
|
|
|
@ -1,3 +0,0 @@
|
||||||
pub mod data_transformer;
|
|
||||||
pub mod encoding;
|
|
||||||
pub mod types;
|
|
|
@ -1,31 +0,0 @@
|
||||||
#[repr(u8)]
|
|
||||||
#[derive(Clone, Copy, Debug)]
|
|
||||||
pub enum ItemType {
|
|
||||||
Gear = 0,
|
|
||||||
Tome = 1,
|
|
||||||
Charm = 2,
|
|
||||||
CraftedGear = 3,
|
|
||||||
CraftedConsu = 4,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Into<u8> for ItemType {
|
|
||||||
fn into(self) -> u8 {
|
|
||||||
self as u8
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl TryFrom<u8> for ItemType {
|
|
||||||
type Error = ();
|
|
||||||
|
|
||||||
fn try_from(value: u8) -> Result<Self, Self::Error> {
|
|
||||||
match value {
|
|
||||||
0 => Ok(Self::Gear),
|
|
||||||
1 => Ok(Self::Tome),
|
|
||||||
2 => Ok(Self::Charm),
|
|
||||||
3 => Ok(Self::CraftedGear),
|
|
||||||
4 => Ok(Self::CraftedConsu),
|
|
||||||
|
|
||||||
_ => Err(()),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,4 +0,0 @@
|
||||||
pub mod itemtype;
|
|
||||||
pub mod powder;
|
|
||||||
pub mod stat;
|
|
||||||
pub mod transform;
|
|
|
@ -1,9 +0,0 @@
|
||||||
/// Powder types
|
|
||||||
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
|
|
||||||
pub enum Powders {
|
|
||||||
EARTH = 1,
|
|
||||||
THUNDER = 2,
|
|
||||||
WATER = 3,
|
|
||||||
FIRE = 4,
|
|
||||||
AIR = 5,
|
|
||||||
}
|
|
|
@ -1,24 +0,0 @@
|
||||||
#[derive(Eq, PartialEq, Hash, Clone, Copy, Debug)]
|
|
||||||
pub struct StatId(pub u8);
|
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
|
||||||
pub struct Stat {
|
|
||||||
pub kind: StatId,
|
|
||||||
pub base: Option<i32>,
|
|
||||||
pub roll: RollType,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
|
||||||
pub enum RollType {
|
|
||||||
Value(u8),
|
|
||||||
PreIdentified,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Stat {
|
|
||||||
pub fn pre_identified(&self) -> bool {
|
|
||||||
match self.roll {
|
|
||||||
RollType::Value(_) => false,
|
|
||||||
RollType::PreIdentified => true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,17 +0,0 @@
|
||||||
#[derive(Clone, Copy, Debug)]
|
|
||||||
pub enum TransformVersion {
|
|
||||||
Version1 = 0,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl TransformVersion {
|
|
||||||
pub fn version(&self) -> u8 {
|
|
||||||
*self as u8
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn from_u8(byte: u8) -> Result<Self, ()> {
|
|
||||||
match byte {
|
|
||||||
0 => Ok(Self::Version1),
|
|
||||||
_ => Err(()),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -5,7 +5,7 @@
|
||||||
],
|
],
|
||||||
"name":"Singularity",
|
"name":"Singularity",
|
||||||
"shiny": {
|
"shiny": {
|
||||||
"key": "mobsKilled",
|
"key": "raidsWon",
|
||||||
"value": 69
|
"value": 69
|
||||||
},
|
},
|
||||||
"ids": [
|
"ids": [
|
||||||
|
|
Loading…
Reference in a new issue