poggers test commit

This commit is contained in:
Jett 2022-12-20 22:48:58 +00:00
parent 2fdcf62ec6
commit df21009672
8 changed files with 273 additions and 0 deletions

View File

@ -336,6 +336,7 @@ endif()
add_subdirectory(dWorldServer) add_subdirectory(dWorldServer)
add_subdirectory(dAuthServer) add_subdirectory(dAuthServer)
add_subdirectory(dChatServer) add_subdirectory(dChatServer)
add_subdirectory(dUgcServer)
add_subdirectory(dMasterServer) # Add MasterServer last so it can rely on the other binaries add_subdirectory(dMasterServer) # Add MasterServer last so it can rely on the other binaries
# Add our precompiled headers # Add our precompiled headers

View File

@ -8,6 +8,34 @@ namespace ZCompression {
return (nLenSrc + 6 + (n16kBlocks * 5)); return (nLenSrc + 6 + (n16kBlocks * 5));
} }
int32_t GZipCompress(const uint8_t* abSrc, int32_t nLenSrc, uint8_t* abDst, int32_t nLenDst) {
z_stream stream;
stream.next_in = (Bytef*)abSrc;
stream.avail_in = nLenSrc;
stream.next_out = (Bytef*)abDst;
stream.avail_out = nLenDst;
stream.zalloc = Z_NULL;
stream.zfree = Z_NULL;
stream.opaque = Z_NULL;
int32_t nErr, nRet = -1;
nErr = deflateInit2(&stream, Z_DEFAULT_COMPRESSION, Z_DEFLATED, -MAX_WBITS, 8, Z_DEFAULT_STRATEGY);
if (nErr == Z_OK) {
nErr = deflate(&stream, Z_FINISH);
if (nErr == Z_STREAM_END) {
nRet = stream.total_out;
} else {
deflateEnd(&stream);
return nErr;
}
} else {
return nErr;
}
nErr = deflateEnd(&stream);
return (nErr == Z_OK) ? nRet : nErr;
}
int32_t Compress(const uint8_t* abSrc, int32_t nLenSrc, uint8_t* abDst, int32_t nLenDst) { int32_t Compress(const uint8_t* abSrc, int32_t nLenSrc, uint8_t* abDst, int32_t nLenDst) {
z_stream zInfo = { 0 }; z_stream zInfo = { 0 };
zInfo.total_in = zInfo.avail_in = nLenSrc; zInfo.total_in = zInfo.avail_in = nLenSrc;

View File

@ -5,6 +5,7 @@
namespace ZCompression { namespace ZCompression {
int32_t GetMaxCompressedLength(int32_t nLenSrc); int32_t GetMaxCompressedLength(int32_t nLenSrc);
int32_t GZipCompress(const uint8_t* abSrc, int32_t nLenSrc, uint8_t* abDst, int32_t nLenDst);
int32_t Compress(const uint8_t* abSrc, int32_t nLenSrc, uint8_t* abDst, int32_t nLenDst); int32_t Compress(const uint8_t* abSrc, int32_t nLenSrc, uint8_t* abDst, int32_t nLenDst);
int32_t Decompress(const uint8_t* abSrc, int32_t nLenSrc, uint8_t* abDst, int32_t nLenDst, int32_t& nErr); int32_t Decompress(const uint8_t* abSrc, int32_t nLenSrc, uint8_t* abDst, int32_t nLenDst, int32_t& nErr);

10
dUgcServer/CMakeLists.txt Normal file
View File

@ -0,0 +1,10 @@
set(DUGCSERVER_SOURCES
"GZip.cpp"
)
add_library(dUgcServer ${DUGCSERVER_SOURCES})
add_executable(UgcServer "UgcServer.cpp")
target_link_libraries(dUgcServer ${COMMON_LIBRARIES})
target_link_libraries(UgcServer ${COMMON_LIBRARIES} httplib::httplib dUgcServer)

59
dUgcServer/GZip.cpp Normal file
View File

@ -0,0 +1,59 @@
#include "GZip.h"
#include <zlib.h>
#include "BinaryIO.h"
#include "ZCompression.h"
GZip::GZip(std::string filename, void* buffer, uint8_t size) {
m_FileName = filename;
m_InputSize = size;
size_t compressTheorySize = (size_t)ZCompression::GetMaxCompressedLength(size);
void* compressOut = malloc(compressTheorySize);
m_CompressedSize = ZCompression::GZipCompress((uint8_t*)buffer, size, (uint8_t*)compressOut, compressTheorySize);
m_FileData = malloc(CalculateSizeOfGZip());
std::memcpy(reinterpret_cast<void*>((size_t)m_FileData + (SizeOfHeader + m_FileName.length() + 1)), compressOut, m_CompressedSize);
free(compressOut);
// Configure File information
m_CompressionLevel = 8;
m_OperatingSystem = eGZipOs::Unknown;
SetFlag(eGZipFlag::FName, true);
m_MTime = time(NULL);
*reinterpret_cast<uint16_t*>(m_FileData) = m_ID;
*reinterpret_cast<uint8_t*>((size_t)m_FileData + 2) = m_CompressionLevel;
*reinterpret_cast<uint8_t*>((size_t)m_FileData + 3) = m_Flags;
*reinterpret_cast<uint32_t*>((size_t)m_FileData + 4) = m_MTime;
*reinterpret_cast<uint8_t*>((size_t)m_FileData + 8) = m_CompressionFlags;
*reinterpret_cast<uint8_t*>((size_t)m_FileData + 9) = (uint8_t)m_OperatingSystem;
for (int i = 0; i < m_FileName.length(); i++) {
*reinterpret_cast<char*>((size_t)m_FileData + SizeOfHeader + i) = m_FileName[i];
}
*reinterpret_cast<uint8_t*>((size_t)m_FileData + (SizeOfHeader + m_FileName.length())) = 0x00;
m_Crc = crc32(0, Z_NULL, 0);
m_Crc = crc32(m_Crc, (uint8_t*)buffer, size);
*reinterpret_cast<uint32_t*>((size_t)m_FileData + (CalculateSizeOfGZip() - 8)) = m_Crc;
*reinterpret_cast<uint32_t*>((size_t)m_FileData + (CalculateSizeOfGZip() - 4)) = m_InputSize;
m_FileSize = CalculateSizeOfGZip();
}
void GZip::WriteToFile(std::string outName) {
std::ofstream file(outName);
file.write((const char*)m_FileData, m_FileSize);
file.close();
}
GZip::~GZip() {
delete m_FileData;
}

78
dUgcServer/GZip.h Normal file
View File

@ -0,0 +1,78 @@
#pragma once
#include <cstdint>
#include <string>
// gaming.h
enum class eGZipFlag : uint8_t {
FText = 0,
FHCrc,
FExtra,
FName,
FComment,
};
enum class eGZipOs : uint8_t {
NT = 0,
Amiga,
VMS,
Unix,
CMS,
Atari,
HPFS,
Macintosh,
ZSystem,
CMP,
TOPS20,
NTFS,
QDOS,
AcornRiscos,
Unknown = 255
};
class GZip {
public:
GZip(std::string filename, void* buffer, uint8_t size);
~GZip();
void WriteToFile(std::string outName);
private:
// Constants
static constexpr uint32_t SizeOfHeader = 10;
static constexpr uint32_t SizeOfFooter = 8;
static constexpr uint16_t FileMagic = 0x8B1F;
size_t CalculateSizeOfGZip() {
return SizeOfHeader + m_FileName.length() + 1 + m_CompressedSize + SizeOfFooter;
}
void SetFlag(eGZipFlag flag, bool value) {
if (value) m_Flags |= 1 << (uint8_t)flag;
else m_Flags &= ~(1 << (uint8_t)flag);
}
void* m_FileData;
uint32_t m_FileSize;
uint32_t m_CompressedSize;
// https://www.ietf.org/rfc/rfc1952.txt
// Header
uint16_t m_ID = FileMagic;
uint8_t m_CompressionLevel = 0;
uint8_t m_Flags = 0;
uint32_t m_MTime = 0;
uint8_t m_CompressionFlags = 0;
eGZipOs m_OperatingSystem = eGZipOs::Unknown;
// Optional Data
std::string m_FileName;
// Footer
uint32_t m_Crc;
uint32_t m_InputSize;
};

94
dUgcServer/UgcServer.cpp Normal file
View File

@ -0,0 +1,94 @@
#include <httplib.h>
#include "Diagnostics.h"
#include "BinaryPathFinder.h"
#include "dLogger.h"
#include "Database.h"
#include "dConfig.h"
#include "dCommonVars.h"
#include "GZip.h"
#include "Game.h"
namespace Game {
dLogger* logger = nullptr;
dConfig* config = nullptr;
httplib::Server* httpServer = nullptr;
}
dLogger* SetupLogger();
void SetupRoutes();
int main(int argc, char** argv) {
Diagnostics::SetProcessName("UGC");
Diagnostics::SetProcessFileName(argv[0]);
Diagnostics::Initialize();
Game::logger = SetupLogger();
if (!Game::logger) return EXIT_FAILURE;
Game::config = new dConfig((BinaryPathFinder::GetBinaryDir() / "ugcconfig.ini").string());
Game::logger->SetLogToConsole(Game::config->GetValue("log_to_console") != "0");
Game::logger->SetLogDebugStatements(Game::config->GetValue("log_debug_statements") == "1");
Game::logger->Log("UgcServer", "Starting UGC server...");
Game::logger->Log("UgcServer", "Version: %i.%i", PROJECT_VERSION_MAJOR, PROJECT_VERSION_MINOR);
Game::logger->Log("UgcServer", "Compiled on: %s", __TIMESTAMP__);
try {
Database::Connect(
Game::config->GetValue("mysql_host"),
Game::config->GetValue("mysql_database"),
Game::config->GetValue("mysql_username"),
Game::config->GetValue("mysql_password")
);
} catch (sql::SQLException& ex) {
Game::logger->Log("UgcServer", "Got an error while connecting to the database: %s", ex.what());
Database::Destroy("UgcServer");
delete Game::logger;
return EXIT_FAILURE;
}
Game::httpServer = new httplib::Server();
SetupRoutes();
Game::logger->Log("UgcServer", "Starting web server...");
Game::httpServer->listen(Game::config->GetValue("external_ip").c_str(), 80);
}
void SetupRoutes() {
// Alternate routes, exceptions etc
Game::httpServer->set_error_handler([](const auto& req, auto& res) {
auto fmt = "<p>Error Status: <span style='color:red;'>%d</span></p>";
char buf[BUFSIZ];
snprintf(buf, sizeof(buf), fmt, res.status);
res.set_content(buf, "text/html");
});
Game::httpServer->Get(R"(/3dservices/UGCC150/(\w+).lxfml.gz)", [](const httplib::Request& req, httplib::Response& res) {
Game::logger->Log("UgcServer", "Receieved request for %s", req.matches[1].str().c_str());
LWOOBJID blueprintId = std::stoull(req.matches[1].str());
});
}
dLogger* SetupLogger() {
std::string logPath = (BinaryPathFinder::GetBinaryDir() / ("logs/UgcServer_" + std::to_string(time(nullptr)) + ".log")).string();
bool logToConsole, logDebugStatements = false;
#ifdef _DEBUG
logToConsole = true;
logDebugStatements = true;
#endif
return new dLogger(logPath, logToConsole, logDebugStatements);
}

View File

@ -25,6 +25,8 @@ include(CMakeMariaDBLists.txt)
# Create our third party library objects # Create our third party library objects
add_subdirectory(raknet) add_subdirectory(raknet)
add_subdirectory(cpp-httplib)
# Download Backtrace if configured # Download Backtrace if configured
if(UNIX AND NOT APPLE) if(UNIX AND NOT APPLE)
include(FetchContent) include(FetchContent)