mirror of
https://github.com/DarkflameUniverse/DarkflameServer.git
synced 2025-05-16 03:21:18 +00:00

* Add utilities for formats * Normalize model positions when placing in the world Have tested that placing a small and very large model both place and are located at the correct position. * add migration * Update Logger.cpp * add some notes and remove some logs * change arguments and add eof check Revert "fix: buff station cycling and dying too soon" This reverts commit 1c6cb2921e10eb2000ac40007d0c2636ba2ac151. fix: buff station cycling and dying too soon Tested that the buff station now only cycles after it has been built and has been alive for 25 seconds.
122 lines
3.0 KiB
C++
122 lines
3.0 KiB
C++
#include "Pack.h"
|
|
|
|
#include "BinaryIO.h"
|
|
#include "Sd0.h"
|
|
#include "ZCompression.h"
|
|
|
|
Pack::Pack(const std::filesystem::path& filePath) {
|
|
m_FilePath = filePath;
|
|
|
|
if (!std::filesystem::exists(filePath)) {
|
|
return;
|
|
}
|
|
|
|
m_FileStream = std::ifstream(filePath, std::ios::in | std::ios::binary);
|
|
|
|
m_FileStream.read(m_Version, 7);
|
|
|
|
m_FileStream.seekg(-8, std::ios::end); // move file pointer to 8 bytes before the end (location of the address of the record count)
|
|
|
|
uint32_t recordCountPos = 0;
|
|
BinaryIO::BinaryRead<uint32_t>(m_FileStream, recordCountPos);
|
|
|
|
m_FileStream.seekg(recordCountPos, std::ios::beg);
|
|
|
|
uint32_t recordCount = 0;
|
|
BinaryIO::BinaryRead<uint32_t>(m_FileStream, recordCount);
|
|
|
|
m_Records.reserve(recordCount);
|
|
std::generate_n(std::back_inserter(m_Records), recordCount, [&] {
|
|
PackRecord record;
|
|
BinaryIO::BinaryRead<PackRecord>(m_FileStream, record);
|
|
return record;
|
|
});
|
|
|
|
m_FileStream.close();
|
|
}
|
|
|
|
bool Pack::HasFile(const uint32_t crc) const {
|
|
for (const auto& record : m_Records) {
|
|
if (record.m_Crc == crc) {
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
bool Pack::ReadFileFromPack(const uint32_t crc, char** data, uint32_t* len) const {
|
|
// Time for some wacky C file reading for speed reasons
|
|
|
|
PackRecord pkRecord{};
|
|
|
|
for (const auto& record : m_Records) {
|
|
if (record.m_Crc == crc) {
|
|
pkRecord = record;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (pkRecord.m_Crc == 0) return false;
|
|
|
|
size_t pos = 0;
|
|
pos += pkRecord.m_FilePointer;
|
|
|
|
bool isCompressed = (pkRecord.m_IsCompressed & 0xff) > 0;
|
|
auto inPackSize = isCompressed ? pkRecord.m_CompressedSize : pkRecord.m_UncompressedSize;
|
|
|
|
FILE* file;
|
|
#ifdef _WIN32
|
|
fopen_s(&file, m_FilePath.string().c_str(), "rb");
|
|
#elif __APPLE__
|
|
// macOS has 64bit file IO by default
|
|
file = fopen(m_FilePath.string().c_str(), "rb");
|
|
#else
|
|
file = fopen64(m_FilePath.string().c_str(), "rb");
|
|
#endif
|
|
|
|
fseek(file, pos, SEEK_SET);
|
|
|
|
if (!isCompressed) {
|
|
char* tempData = static_cast<char*>(malloc(pkRecord.m_UncompressedSize));
|
|
int32_t readInData = fread(tempData, sizeof(uint8_t), pkRecord.m_UncompressedSize, file);
|
|
|
|
*data = tempData;
|
|
*len = pkRecord.m_UncompressedSize;
|
|
fclose(file);
|
|
|
|
return true;
|
|
}
|
|
|
|
pos += 5; // skip header
|
|
|
|
fseek(file, pos, SEEK_SET);
|
|
|
|
char* decompressedData = static_cast<char*>(malloc(pkRecord.m_UncompressedSize));
|
|
uint32_t currentReadPos = 0;
|
|
|
|
while (true) {
|
|
if (currentReadPos >= pkRecord.m_UncompressedSize) break;
|
|
|
|
uint32_t size;
|
|
int32_t readInData = fread(&size, sizeof(uint32_t), 1, file);
|
|
pos += 4; // Move pointer position 4 to the right
|
|
|
|
char* chunk = static_cast<char*>(malloc(size));
|
|
int32_t readInData2 = fread(chunk, sizeof(int8_t), size, file);
|
|
pos += size; // Move pointer position the amount of bytes read to the right
|
|
|
|
int32_t err;
|
|
currentReadPos += ZCompression::Decompress(reinterpret_cast<uint8_t*>(chunk), size, reinterpret_cast<uint8_t*>(decompressedData + currentReadPos), Sd0::MAX_UNCOMPRESSED_CHUNK_SIZE, err);
|
|
|
|
free(chunk);
|
|
}
|
|
|
|
*data = decompressedData;
|
|
*len = pkRecord.m_UncompressedSize;
|
|
|
|
fclose(file);
|
|
|
|
return true;
|
|
}
|