Changed from vectors to lists for performance gains.

master
sigonasr2 1 year ago
parent 8e86f3149b
commit 3a0d73eb79
  1. BIN
      SHNFileDecryptor/AbState.shn.bak
  2. 183
      SHNFileDecryptor/SHNFileDecryptor.cpp

Binary file not shown.

@ -3,13 +3,13 @@
#include <fstream>
#include <iostream>
#include <string>
#include <chrono>
#include <list>
typedef std::byte byte;
typedef char sbyte;
class SHNFile{
std::vector<byte>cryptHeader;
std::vector<byte>data;
std::vector<byte>ReadBytes(std::ifstream&file,int bytes){
std::vector<byte>byteArr;
for(int i=0;i<bytes;i++){
@ -39,9 +39,8 @@ class SHNFile{
num = num3;
}
}
int marker=0;
std::vector<byte>ReadBytes(int bytes){
std::vector<byte>byteArr={};
std::list<byte>ReadBytes(int bytes){
std::list<byte>byteArr={};
for(int i=0;i<bytes;i++){
if(marker<data.size()){
byteArr.push_back(data[marker]);
@ -53,31 +52,47 @@ class SHNFile{
return byteArr;
}
byte ReadByte(){
std::vector<byte>b=ReadBytes(1);
std::list<byte>b=ReadBytes(1);
if(b.size()>0){
return b[0];
return b.front();
} else {
return byte(0);
}
}
uint16_t ReadUInt16(){
std::vector<byte>intBytes=ReadBytes(2);
uint16_t numb = uint16_t(intBytes[1])<<8|uint16_t(intBytes[0]);
std::list<byte>intBytes=ReadBytes(2);
uint16_t numb = uint16_t(intBytes.back())<<8;
intBytes.pop_back();
numb |= uint16_t(intBytes.back());
return numb;
}
int16_t ReadInt16(){
std::vector<byte>intBytes=ReadBytes(2);
int16_t numb = int16_t(intBytes[1])<<8|int16_t(intBytes[0]);
std::list<byte>intBytes=ReadBytes(2);
int16_t numb = int16_t(intBytes.back())<<8;
intBytes.pop_back();
numb |= int16_t(intBytes.back());
return numb;
}
uint32_t ReadUInt32(){
std::vector<byte>intBytes=ReadBytes(4);
uint32_t numb = uint32_t(intBytes[3])<<24|uint32_t(intBytes[2])<<16|uint32_t(intBytes[1])<<8|uint32_t(intBytes[0]);
std::list<byte>intBytes=ReadBytes(4);
uint32_t numb = uint32_t(intBytes.back())<<24;
intBytes.pop_back();
numb |= uint32_t(intBytes.back())<<16;
intBytes.pop_back();
numb |= uint32_t(intBytes.back())<<8;
intBytes.pop_back();
numb |= uint32_t(intBytes.back());
return numb;
}
int ReadInt32(){
std::vector<byte>intBytes=ReadBytes(4);
int numb = int(intBytes[3])<<24|int(intBytes[2])<<16|int(intBytes[1])<<8|int(intBytes[0]);
std::list<byte>intBytes=ReadBytes(4);
int numb = int(intBytes.back())<<24;
intBytes.pop_back();
numb |= int(intBytes.back())<<16;
intBytes.pop_back();
numb |= int(intBytes.back())<<8;
intBytes.pop_back();
numb |= int(intBytes.back());
return numb;
}
struct Column{
@ -86,39 +101,44 @@ class SHNFile{
int length=0;
};
std::string ReadString(int bytes){
std::vector<byte>strBytes=ReadBytes(bytes);
std::list<byte>strBytes=ReadBytes(bytes);
std::string str="";
for(int i=0;i<strBytes.size();i++){
if(strBytes[i]!=byte(0)){
str+=unsigned char(strBytes[i]);
for(auto it=strBytes.begin();it!=strBytes.end();++it){
if(*it!=byte(0)){
str+=unsigned char(*it);
}
}
return str;
}
float ReadSingle(){
std::vector<byte>strBytes=ReadBytes(4);
byte bytes[]={strBytes[0],strBytes[1],strBytes[2],strBytes[3]};
std::list<byte>strBytes=ReadBytes(4);
byte bytes[4];
bytes[0]=strBytes.front();
strBytes.pop_front();
bytes[1]=strBytes.front();
strBytes.pop_front();
bytes[2]=strBytes.front();
strBytes.pop_front();
bytes[3]=strBytes.front();
float f;
memcpy(&f,&bytes,sizeof(float));
return f;
}
sbyte ReadSByte(){
return sbyte(ReadBytes(1)[0]);
return sbyte(ReadBytes(1).front());
}
std::string ReadString(){
std::string str="";
while(true){
std::vector<byte>byteArr=ReadBytes(1);
if(byteArr.size()>0&&byteArr[0]!=byte(0)){
str+=unsigned char(byteArr[0]);
std::list<byte>byteArr=ReadBytes(1);
if(byteArr.size()>0&&byteArr.front()!=byte(0)){
str+=unsigned char(byteArr.front());
}else{
break;
}
}
return str;
}
uint32_t header,recordCount,defaultRecordLength,columnCount;
std::vector<Column>columns;
public:
struct Data{
std::shared_ptr<void>data;
@ -217,14 +237,28 @@ class SHNFile{
}
};
private:
std::vector<std::vector<Data>>contents;
friend std::ostream&operator<<(std::ostream&out,SHNFile::Data&d){
out<<d.GetDisplayText();
return out;
}
int marker=0;
std::vector<byte>cryptHeader;
std::vector<byte>data;
uint32_t header=0,recordCount=0,defaultRecordLength=0,columnCount=0;
std::vector<Column>columns;
std::vector<std::vector<Data>>contents;
std::string filename;
public:
SHNFile(std::string file){
std::ifstream f(file,std::ios::binary);
void Load(std::string file){
cryptHeader.clear();
data.clear();
header=recordCount=defaultRecordLength=columnCount=0;
columns.clear();
contents.clear();
marker=0;
std::chrono::time_point<std::chrono::high_resolution_clock>timer=std::chrono::high_resolution_clock::now();
filename=file;
std::ifstream f(filename,std::ios::binary);
cryptHeader=ReadBytes(f,0x20);
data=ReadBytes(f,ReadInt32(f)-0x24);
Decrypt();
@ -248,53 +282,62 @@ public:
std::vector<Data>row;
for(int j=0;j<columns.size();j++){
switch(columns[j].type){
case 1:
case 12:
case 0x10:{
row.push_back(ReadByte());
}break;
case 2:{
row.push_back(ReadUInt16());
}break;
case 3:
case 11:
case 0x12:
case 0x1b:{
row.push_back(ReadUInt32());
}break;
case 5:{
row.push_back(ReadSingle());
}break;
case 9:
case 0x18:{
row.push_back(ReadString(columns[j].length));
}break;
case 13:
case 0x15:{
row.push_back(ReadInt16());
}break;
case 20:{
row.push_back(ReadSByte());
}break;
case 0x16:{
row.push_back(ReadInt32());
}break;
case 0x1a:{
row.push_back(ReadString());
}break;
case 1:
case 12:
case 0x10:{
row.push_back(ReadByte());
}break;
case 2:{
row.push_back(ReadUInt16());
}break;
case 3:
case 11:
case 0x12:
case 0x1b:{
row.push_back(ReadUInt32());
}break;
case 5:{
row.push_back(ReadSingle());
}break;
case 9:
case 0x18:{
row.push_back(ReadString(columns[j].length));
}break;
case 13:
case 0x15:{
row.push_back(ReadInt16());
}break;
case 20:{
row.push_back(ReadSByte());
}break;
case 0x16:{
row.push_back(ReadInt32());
}break;
case 0x1a:{
row.push_back(ReadString());
}break;
}
}
contents.push_back(row);
}
for(int i=0;i<contents.size();i++){
for(int j=0;j<contents[i].size();j++){
std::cout<<contents[i][j]<<'\t';
}
std::cout<<std::endl;
std::chrono::duration<float>dur=std::chrono::high_resolution_clock::now()-timer;
std::cout<<"Loaded "<<contents.size()<<" rows, "<<contents.size()*columnCount<<" columns, "<<dur.count()<<"s"<<std::endl;
}
void Save(){
std::ofstream fBackup(filename+".bak",std::ios::binary);
std::cout<<"Saving a backup to "<<filename+".bak"<<std::endl;
for(int i=0;i<data.size();i++){
fBackup<<unsigned char(data[i]);
}
std::cout<<"Saving new file..."<<std::endl;
//std::ofstream f("save_"+filename,std::ios::binary);
}
SHNFile(){}
};
int main(){
SHNFile shn("AbState.shn");
SHNFile shn;
shn.Load("AbState.shn");
shn.Load("AbState.shn");
shn.Save();
}
Loading…
Cancel
Save