|
|
|
@ -2,8 +2,10 @@ |
|
|
|
|
#include <cstddef> |
|
|
|
|
#include <fstream> |
|
|
|
|
#include <iostream> |
|
|
|
|
#include <string> |
|
|
|
|
|
|
|
|
|
typedef std::byte byte; |
|
|
|
|
typedef char sbyte; |
|
|
|
|
|
|
|
|
|
class SHNFile{ |
|
|
|
|
std::vector<byte>cryptHeader; |
|
|
|
@ -39,7 +41,7 @@ class SHNFile{ |
|
|
|
|
} |
|
|
|
|
int marker=0; |
|
|
|
|
std::vector<byte>ReadBytes(int bytes){ |
|
|
|
|
std::vector<byte>byteArr; |
|
|
|
|
std::vector<byte>byteArr={}; |
|
|
|
|
for(int i=0;i<bytes;i++){ |
|
|
|
|
if(marker<data.size()){ |
|
|
|
|
byteArr.push_back(data[marker]); |
|
|
|
@ -50,6 +52,24 @@ class SHNFile{ |
|
|
|
|
} |
|
|
|
|
return byteArr; |
|
|
|
|
} |
|
|
|
|
byte ReadByte(){ |
|
|
|
|
std::vector<byte>b=ReadBytes(1); |
|
|
|
|
if(b.size()>0){ |
|
|
|
|
return b[0]; |
|
|
|
|
} 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]); |
|
|
|
|
return numb; |
|
|
|
|
} |
|
|
|
|
int16_t ReadInt16(){ |
|
|
|
|
std::vector<byte>intBytes=ReadBytes(2); |
|
|
|
|
int16_t numb = int16_t(intBytes[1])<<8|int16_t(intBytes[0]); |
|
|
|
|
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]); |
|
|
|
@ -62,19 +82,146 @@ class SHNFile{ |
|
|
|
|
} |
|
|
|
|
struct Column{ |
|
|
|
|
std::string name; |
|
|
|
|
uint32_t type; |
|
|
|
|
int length; |
|
|
|
|
uint32_t type=0; |
|
|
|
|
int length=0; |
|
|
|
|
}; |
|
|
|
|
std::string ReadString(int bytes){ |
|
|
|
|
std::vector<byte>strBytes=ReadBytes(bytes); |
|
|
|
|
std::string str; |
|
|
|
|
std::string str=""; |
|
|
|
|
for(int i=0;i<strBytes.size();i++){ |
|
|
|
|
str+=unsigned char(strBytes[i]); |
|
|
|
|
if(strBytes[i]!=byte(0)){ |
|
|
|
|
str+=unsigned char(strBytes[i]); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
return str; |
|
|
|
|
} |
|
|
|
|
float ReadSingle(){ |
|
|
|
|
std::vector<byte>strBytes=ReadBytes(4); |
|
|
|
|
byte bytes[]={strBytes[0],strBytes[1],strBytes[2],strBytes[3]}; |
|
|
|
|
float f; |
|
|
|
|
memcpy(&f,&bytes,sizeof(float)); |
|
|
|
|
return f; |
|
|
|
|
} |
|
|
|
|
sbyte ReadSByte(){ |
|
|
|
|
return sbyte(ReadBytes(1)[0]); |
|
|
|
|
} |
|
|
|
|
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]); |
|
|
|
|
}else{ |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
return str; |
|
|
|
|
} |
|
|
|
|
uint32_t header,recordCount,defaultRecordLength,columnCount; |
|
|
|
|
std::vector<Column>columns; |
|
|
|
|
public: |
|
|
|
|
struct Data{ |
|
|
|
|
std::shared_ptr<void>data; |
|
|
|
|
int type=0; |
|
|
|
|
Data(byte b){ |
|
|
|
|
std::shared_ptr<byte>ptr=std::make_shared<byte>(byte(b)); |
|
|
|
|
data=std::static_pointer_cast<byte>(ptr); |
|
|
|
|
type=1; |
|
|
|
|
} |
|
|
|
|
Data(sbyte b){ |
|
|
|
|
std::shared_ptr<sbyte>ptr=std::make_shared<sbyte>(sbyte(b)); |
|
|
|
|
data=std::static_pointer_cast<sbyte>(ptr); |
|
|
|
|
type=7; |
|
|
|
|
} |
|
|
|
|
Data(uint16_t n){ |
|
|
|
|
std::shared_ptr<uint16_t>ptr=std::make_shared<uint16_t>(uint16_t(n)); |
|
|
|
|
data=std::static_pointer_cast<uint16_t>(ptr); |
|
|
|
|
type=2; |
|
|
|
|
} |
|
|
|
|
Data(int16_t n){ |
|
|
|
|
std::shared_ptr<int16_t>ptr=std::make_shared<int16_t>(int16_t(n)); |
|
|
|
|
data=std::static_pointer_cast<int16_t>(ptr); |
|
|
|
|
type=6; |
|
|
|
|
} |
|
|
|
|
Data(uint32_t n){ |
|
|
|
|
std::shared_ptr<uint32_t>ptr=std::make_shared<uint32_t>(uint32_t(n)); |
|
|
|
|
data=std::static_pointer_cast<uint32_t>(ptr); |
|
|
|
|
type=3; |
|
|
|
|
} |
|
|
|
|
Data(int32_t n){ |
|
|
|
|
std::shared_ptr<int32_t>ptr=std::make_shared<int32_t>(int32_t(n)); |
|
|
|
|
data=std::static_pointer_cast<int32_t>(ptr); |
|
|
|
|
type=8; |
|
|
|
|
} |
|
|
|
|
Data(float n){ |
|
|
|
|
std::shared_ptr<float>ptr=std::make_shared<float>(float(n)); |
|
|
|
|
data=std::static_pointer_cast<float>(ptr); |
|
|
|
|
type=4; |
|
|
|
|
} |
|
|
|
|
Data(std::string str){ |
|
|
|
|
std::shared_ptr<std::string>ptr=std::make_shared<std::string>(str); |
|
|
|
|
data=std::static_pointer_cast<std::string>(ptr); |
|
|
|
|
type=5; |
|
|
|
|
} |
|
|
|
|
byte GetByte(){ |
|
|
|
|
return *std::static_pointer_cast<byte>(data); |
|
|
|
|
} |
|
|
|
|
uint16_t GetUInt16(){ |
|
|
|
|
return *std::static_pointer_cast<uint16_t>(data); |
|
|
|
|
} |
|
|
|
|
int16_t GetInt16(){ |
|
|
|
|
return *std::static_pointer_cast<int16_t>(data); |
|
|
|
|
} |
|
|
|
|
sbyte GetSByte(){ |
|
|
|
|
return *std::static_pointer_cast<sbyte>(data); |
|
|
|
|
} |
|
|
|
|
uint32_t GetUInt32(){ |
|
|
|
|
return *std::static_pointer_cast<uint32_t>(data); |
|
|
|
|
} |
|
|
|
|
int32_t GetInt32(){ |
|
|
|
|
return *std::static_pointer_cast<int32_t>(data); |
|
|
|
|
} |
|
|
|
|
float GetFloat(){ |
|
|
|
|
return *std::static_pointer_cast<float>(data); |
|
|
|
|
} |
|
|
|
|
std::string GetString(){ |
|
|
|
|
return *std::static_pointer_cast<std::string>(data); |
|
|
|
|
} |
|
|
|
|
std::string GetDisplayText(){ |
|
|
|
|
switch(type){ |
|
|
|
|
case 1:{ |
|
|
|
|
return std::to_string(int(GetByte())); |
|
|
|
|
}break; |
|
|
|
|
case 7:{ |
|
|
|
|
return std::to_string(int(GetSByte())); |
|
|
|
|
}break; |
|
|
|
|
case 2:{ |
|
|
|
|
return std::to_string(GetUInt16()); |
|
|
|
|
}break; |
|
|
|
|
case 6:{ |
|
|
|
|
return std::to_string(GetInt16()); |
|
|
|
|
}break; |
|
|
|
|
case 3:{ |
|
|
|
|
return std::to_string(GetUInt32()); |
|
|
|
|
}break; |
|
|
|
|
case 8:{ |
|
|
|
|
return std::to_string(GetInt32()); |
|
|
|
|
}break; |
|
|
|
|
case 4:{ |
|
|
|
|
return std::to_string(GetFloat()); |
|
|
|
|
}break; |
|
|
|
|
case 5:{ |
|
|
|
|
return GetString(); |
|
|
|
|
}break; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
}; |
|
|
|
|
private: |
|
|
|
|
std::vector<std::vector<Data>>contents; |
|
|
|
|
friend std::ostream&operator<<(std::ostream&out,SHNFile::Data&d){ |
|
|
|
|
out<<d.GetDisplayText(); |
|
|
|
|
return out; |
|
|
|
|
} |
|
|
|
|
public: |
|
|
|
|
SHNFile(std::string file){ |
|
|
|
|
std::ifstream f(file,std::ios::binary); |
|
|
|
@ -95,8 +242,58 @@ public: |
|
|
|
|
num2+=columnData.length; |
|
|
|
|
columns.push_back(columnData); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
for(int i=0;i<recordCount;i++){ |
|
|
|
|
ReadUInt16(); |
|
|
|
|
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; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
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; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
}; |
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
int main(){ |
|
|
|
|
SHNFile shn("AbState.shn"); |
|
|
|
|