removed idlib (very very very early idmangler-lib) directory

This commit is contained in:
endernon 2024-09-11 19:21:54 +01:00
parent e1298accb4
commit f658a1b7f3
18 changed files with 1 additions and 818 deletions

View file

@ -1,6 +0,0 @@
[package]
name = "idlib"
version = "0.1.0"
edition = "2021"
[dependencies]

View file

@ -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);
}
}

View file

@ -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,
})
}
}
}
}

View file

@ -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),
}

View file

@ -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)?,
))
}
}
}
}

View file

@ -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(())
}
}

View file

@ -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)?,
)),
}
}
}

View file

@ -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(())
}
}

View file

@ -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))
}
}

View file

@ -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)?,
))
}
}
}
}

View file

@ -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);
}

View file

@ -1,3 +0,0 @@
pub mod data_transformer;
pub mod encoding;
pub mod types;

View file

@ -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(()),
}
}
}

View file

@ -1,4 +0,0 @@
pub mod itemtype;
pub mod powder;
pub mod stat;
pub mod transform;

View file

@ -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,
}

View file

@ -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,
}
}
}

View file

@ -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(()),
}
}
}

View file

@ -5,7 +5,7 @@
], ],
"name":"Singularity", "name":"Singularity",
"shiny": { "shiny": {
"key": "mobsKilled", "key": "raidsWon",
"value": 69 "value": 69
}, },
"ids": [ "ids": [