mirror of
https://github.com/DarkflameUniverse/DarkflameServer.git
synced 2024-11-25 15:07:28 +00:00
Address Docker issues and remove need to extract cdclient.fdb (#895)
* Implement a server res directory * Only convert if neither exist * Remove unzip, Update RegEx * readme updates Run setup after setting working dir Address several docker issues Revert "Run setup after setting working dir" This reverts commit fd2fb9228e82a350204c1ef61f7ba059479bb12f. Fix docker * Remove extra submodules * Rework logic * Switch if block * Remove need to extract fdb from client * Change log name * Update FdbToSqlite.cpp
This commit is contained in:
parent
7fcc8a6e84
commit
bad3845d83
6
.gitmodules
vendored
6
.gitmodules
vendored
@ -14,12 +14,6 @@
|
|||||||
path = thirdparty/mariadb-connector-cpp
|
path = thirdparty/mariadb-connector-cpp
|
||||||
url = https://github.com/mariadb-corporation/mariadb-connector-cpp.git
|
url = https://github.com/mariadb-corporation/mariadb-connector-cpp.git
|
||||||
ignore = dirty
|
ignore = dirty
|
||||||
[submodule "thirdparty/docker-utils"]
|
|
||||||
path = thirdparty/docker-utils
|
|
||||||
url = https://github.com/lcdr/utils.git
|
|
||||||
[submodule "thirdparty/LUnpack"]
|
|
||||||
path = thirdparty/LUnpack
|
|
||||||
url = https://github.com/Xiphoseer/LUnpack.git
|
|
||||||
[submodule "thirdparty/AccountManager"]
|
[submodule "thirdparty/AccountManager"]
|
||||||
path = thirdparty/AccountManager
|
path = thirdparty/AccountManager
|
||||||
url = https://github.com/DarkflameUniverse/AccountManager
|
url = https://github.com/DarkflameUniverse/AccountManager
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
- [Docker](https://docs.docker.com/get-docker/) (Docker Desktop or on Linux normal Docker)
|
- [Docker](https://docs.docker.com/get-docker/) (Docker Desktop or on Linux normal Docker)
|
||||||
- [Docker Compose](https://docs.docker.com/compose/install/) (Included in Docker Desktop)
|
- [Docker Compose](https://docs.docker.com/compose/install/) (Included in Docker Desktop)
|
||||||
- LEGO® Universe packed Client. Check the main [README](./README.md) for details on this.
|
- LEGO® Universe Client. Check the main [README](./README.md) for details on this.
|
||||||
|
|
||||||
## Run server inside Docker
|
## Run server inside Docker
|
||||||
|
|
||||||
|
@ -25,7 +25,7 @@
|
|||||||
11. Once the command has completed (you can see you path again and can enter commands), close the window.
|
11. Once the command has completed (you can see you path again and can enter commands), close the window.
|
||||||
12. Inside the downloaded folder, copy `.env.example` and name the copy `.env`
|
12. Inside the downloaded folder, copy `.env.example` and name the copy `.env`
|
||||||
13. Open `.env` with Notepad by right-clicking it and selecting _Open With_ -> _More apps_ -> _Notepad_.
|
13. Open `.env` with Notepad by right-clicking it and selecting _Open With_ -> _More apps_ -> _Notepad_.
|
||||||
14. Change the text after `CLIENT_PATH=` to the location of your client. The folder you are pointing to must contain a folder called `client` which should contain the client files.
|
14. Change the text after `CLIENT_PATH=` to the location of your client. This folder must contain either a folder `client` or `legouniverse.exe`.
|
||||||
> If you need the extra performance, place the client files in `\\wsl$\<your linux OS>\...` to avoid working across file systems, see [Docker Best Practices](https://docs.docker.com/desktop/windows/wsl/#best-practices) and [WSL documentation](https://docs.microsoft.com/en-us/windows/wsl/filesystems#file-storage-and-performance-across-file-systems).
|
> If you need the extra performance, place the client files in `\\wsl$\<your linux OS>\...` to avoid working across file systems, see [Docker Best Practices](https://docs.docker.com/desktop/windows/wsl/#best-practices) and [WSL documentation](https://docs.microsoft.com/en-us/windows/wsl/filesystems#file-storage-and-performance-across-file-systems).
|
||||||
|
|
||||||
15. Optionally, you can change the number after `BUILD_THREADS=` to the number of cores / threads your processor has. If your computer crashes while building, you can try to reduce this value.
|
15. Optionally, you can change the number after `BUILD_THREADS=` to the number of cores / threads your processor has. If your computer crashes while building, you can try to reduce this value.
|
||||||
|
@ -10,6 +10,7 @@
|
|||||||
#include "GeneralUtils.h"
|
#include "GeneralUtils.h"
|
||||||
#include "Game.h"
|
#include "Game.h"
|
||||||
#include "dLogger.h"
|
#include "dLogger.h"
|
||||||
|
#include "AssetManager.h"
|
||||||
|
|
||||||
#include "eSqliteDataType.h"
|
#include "eSqliteDataType.h"
|
||||||
|
|
||||||
@ -23,26 +24,23 @@ std::map<eSqliteDataType, std::string> FdbToSqlite::Convert::m_SqliteType = {
|
|||||||
{ eSqliteDataType::TEXT_8, "text_8"}
|
{ eSqliteDataType::TEXT_8, "text_8"}
|
||||||
};
|
};
|
||||||
|
|
||||||
FdbToSqlite::Convert::Convert(std::string basePath, std::string binaryOutPath) {
|
FdbToSqlite::Convert::Convert(std::string binaryOutPath) {
|
||||||
this->m_BasePath = basePath;
|
|
||||||
this->m_BinaryOutPath = binaryOutPath;
|
this->m_BinaryOutPath = binaryOutPath;
|
||||||
m_Fdb.open(m_BasePath + "/cdclient.fdb", std::ios::binary);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
FdbToSqlite::Convert::~Convert() {
|
bool FdbToSqlite::Convert::ConvertDatabase(AssetMemoryBuffer& buffer) {
|
||||||
this->m_Fdb.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool FdbToSqlite::Convert::ConvertDatabase() {
|
|
||||||
if (m_ConversionStarted) return false;
|
if (m_ConversionStarted) return false;
|
||||||
|
|
||||||
|
std::istream cdClientBuffer(&buffer);
|
||||||
|
|
||||||
this->m_ConversionStarted = true;
|
this->m_ConversionStarted = true;
|
||||||
try {
|
try {
|
||||||
CDClientDatabase::Connect(m_BinaryOutPath + "/CDServer.sqlite");
|
CDClientDatabase::Connect(m_BinaryOutPath + "/CDServer.sqlite");
|
||||||
|
|
||||||
CDClientDatabase::ExecuteQuery("BEGIN TRANSACTION;");
|
CDClientDatabase::ExecuteQuery("BEGIN TRANSACTION;");
|
||||||
|
|
||||||
int32_t numberOfTables = ReadInt32();
|
int32_t numberOfTables = ReadInt32(cdClientBuffer);
|
||||||
ReadTables(numberOfTables);
|
ReadTables(numberOfTables, cdClientBuffer);
|
||||||
|
|
||||||
CDClientDatabase::ExecuteQuery("COMMIT;");
|
CDClientDatabase::ExecuteQuery("COMMIT;");
|
||||||
} catch (CppSQLite3Exception& e) {
|
} catch (CppSQLite3Exception& e) {
|
||||||
@ -53,130 +51,130 @@ bool FdbToSqlite::Convert::ConvertDatabase() {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t FdbToSqlite::Convert::ReadInt32() {
|
int32_t FdbToSqlite::Convert::ReadInt32(std::istream& cdClientBuffer) {
|
||||||
int32_t nextInt{};
|
int32_t nextInt{};
|
||||||
BinaryIO::BinaryRead(m_Fdb, nextInt);
|
BinaryIO::BinaryRead(cdClientBuffer, nextInt);
|
||||||
return nextInt;
|
return nextInt;
|
||||||
}
|
}
|
||||||
|
|
||||||
int64_t FdbToSqlite::Convert::ReadInt64() {
|
int64_t FdbToSqlite::Convert::ReadInt64(std::istream& cdClientBuffer) {
|
||||||
int32_t prevPosition = SeekPointer();
|
int32_t prevPosition = SeekPointer(cdClientBuffer);
|
||||||
|
|
||||||
int64_t value{};
|
int64_t value{};
|
||||||
BinaryIO::BinaryRead(m_Fdb, value);
|
BinaryIO::BinaryRead(cdClientBuffer, value);
|
||||||
|
|
||||||
m_Fdb.seekg(prevPosition);
|
cdClientBuffer.seekg(prevPosition);
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string FdbToSqlite::Convert::ReadString() {
|
std::string FdbToSqlite::Convert::ReadString(std::istream& cdClientBuffer) {
|
||||||
int32_t prevPosition = SeekPointer();
|
int32_t prevPosition = SeekPointer(cdClientBuffer);
|
||||||
|
|
||||||
auto readString = BinaryIO::ReadString(m_Fdb);
|
auto readString = BinaryIO::ReadString(cdClientBuffer);
|
||||||
|
|
||||||
m_Fdb.seekg(prevPosition);
|
cdClientBuffer.seekg(prevPosition);
|
||||||
return readString;
|
return readString;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t FdbToSqlite::Convert::SeekPointer() {
|
int32_t FdbToSqlite::Convert::SeekPointer(std::istream& cdClientBuffer) {
|
||||||
int32_t position{};
|
int32_t position{};
|
||||||
BinaryIO::BinaryRead(m_Fdb, position);
|
BinaryIO::BinaryRead(cdClientBuffer, position);
|
||||||
int32_t prevPosition = m_Fdb.tellg();
|
int32_t prevPosition = cdClientBuffer.tellg();
|
||||||
m_Fdb.seekg(position);
|
cdClientBuffer.seekg(position);
|
||||||
return prevPosition;
|
return prevPosition;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string FdbToSqlite::Convert::ReadColumnHeader() {
|
std::string FdbToSqlite::Convert::ReadColumnHeader(std::istream& cdClientBuffer) {
|
||||||
int32_t prevPosition = SeekPointer();
|
int32_t prevPosition = SeekPointer(cdClientBuffer);
|
||||||
|
|
||||||
int32_t numberOfColumns = ReadInt32();
|
int32_t numberOfColumns = ReadInt32(cdClientBuffer);
|
||||||
std::string tableName = ReadString();
|
std::string tableName = ReadString(cdClientBuffer);
|
||||||
|
|
||||||
auto columns = ReadColumns(numberOfColumns);
|
auto columns = ReadColumns(numberOfColumns, cdClientBuffer);
|
||||||
std::string newTable = "CREATE TABLE IF NOT EXISTS '" + tableName + "' (" + columns + ");";
|
std::string newTable = "CREATE TABLE IF NOT EXISTS '" + tableName + "' (" + columns + ");";
|
||||||
CDClientDatabase::ExecuteDML(newTable);
|
CDClientDatabase::ExecuteDML(newTable);
|
||||||
|
|
||||||
m_Fdb.seekg(prevPosition);
|
cdClientBuffer.seekg(prevPosition);
|
||||||
|
|
||||||
return tableName;
|
return tableName;
|
||||||
}
|
}
|
||||||
|
|
||||||
void FdbToSqlite::Convert::ReadTables(int32_t& numberOfTables) {
|
void FdbToSqlite::Convert::ReadTables(int32_t& numberOfTables, std::istream& cdClientBuffer) {
|
||||||
int32_t prevPosition = SeekPointer();
|
int32_t prevPosition = SeekPointer(cdClientBuffer);
|
||||||
|
|
||||||
for (int32_t i = 0; i < numberOfTables; i++) {
|
for (int32_t i = 0; i < numberOfTables; i++) {
|
||||||
auto columnHeader = ReadColumnHeader();
|
auto columnHeader = ReadColumnHeader(cdClientBuffer);
|
||||||
ReadRowHeader(columnHeader);
|
ReadRowHeader(columnHeader, cdClientBuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_Fdb.seekg(prevPosition);
|
cdClientBuffer.seekg(prevPosition);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string FdbToSqlite::Convert::ReadColumns(int32_t& numberOfColumns) {
|
std::string FdbToSqlite::Convert::ReadColumns(int32_t& numberOfColumns, std::istream& cdClientBuffer) {
|
||||||
std::stringstream columnsToCreate;
|
std::stringstream columnsToCreate;
|
||||||
int32_t prevPosition = SeekPointer();
|
int32_t prevPosition = SeekPointer(cdClientBuffer);
|
||||||
|
|
||||||
std::string name{};
|
std::string name{};
|
||||||
eSqliteDataType dataType{};
|
eSqliteDataType dataType{};
|
||||||
for (int32_t i = 0; i < numberOfColumns; i++) {
|
for (int32_t i = 0; i < numberOfColumns; i++) {
|
||||||
if (i != 0) columnsToCreate << ", ";
|
if (i != 0) columnsToCreate << ", ";
|
||||||
dataType = static_cast<eSqliteDataType>(ReadInt32());
|
dataType = static_cast<eSqliteDataType>(ReadInt32(cdClientBuffer));
|
||||||
name = ReadString();
|
name = ReadString(cdClientBuffer);
|
||||||
columnsToCreate << "'" << name << "' " << FdbToSqlite::Convert::m_SqliteType[dataType];
|
columnsToCreate << "'" << name << "' " << FdbToSqlite::Convert::m_SqliteType[dataType];
|
||||||
}
|
}
|
||||||
|
|
||||||
m_Fdb.seekg(prevPosition);
|
cdClientBuffer.seekg(prevPosition);
|
||||||
return columnsToCreate.str();
|
return columnsToCreate.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
void FdbToSqlite::Convert::ReadRowHeader(std::string& tableName) {
|
void FdbToSqlite::Convert::ReadRowHeader(std::string& tableName, std::istream& cdClientBuffer) {
|
||||||
int32_t prevPosition = SeekPointer();
|
int32_t prevPosition = SeekPointer(cdClientBuffer);
|
||||||
|
|
||||||
int32_t numberOfAllocatedRows = ReadInt32();
|
int32_t numberOfAllocatedRows = ReadInt32(cdClientBuffer);
|
||||||
if (numberOfAllocatedRows != 0) assert((numberOfAllocatedRows & (numberOfAllocatedRows - 1)) == 0); // assert power of 2 allocation size
|
if (numberOfAllocatedRows != 0) assert((numberOfAllocatedRows & (numberOfAllocatedRows - 1)) == 0); // assert power of 2 allocation size
|
||||||
ReadRows(numberOfAllocatedRows, tableName);
|
ReadRows(numberOfAllocatedRows, tableName, cdClientBuffer);
|
||||||
|
|
||||||
m_Fdb.seekg(prevPosition);
|
cdClientBuffer.seekg(prevPosition);
|
||||||
}
|
}
|
||||||
|
|
||||||
void FdbToSqlite::Convert::ReadRows(int32_t& numberOfAllocatedRows, std::string& tableName) {
|
void FdbToSqlite::Convert::ReadRows(int32_t& numberOfAllocatedRows, std::string& tableName, std::istream& cdClientBuffer) {
|
||||||
int32_t prevPosition = SeekPointer();
|
int32_t prevPosition = SeekPointer(cdClientBuffer);
|
||||||
|
|
||||||
int32_t rowid = 0;
|
int32_t rowid = 0;
|
||||||
for (int32_t row = 0; row < numberOfAllocatedRows; row++) {
|
for (int32_t row = 0; row < numberOfAllocatedRows; row++) {
|
||||||
int32_t rowPointer = ReadInt32();
|
int32_t rowPointer = ReadInt32(cdClientBuffer);
|
||||||
if (rowPointer == -1) rowid++;
|
if (rowPointer == -1) rowid++;
|
||||||
else ReadRow(rowPointer, tableName);
|
else ReadRow(rowPointer, tableName, cdClientBuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_Fdb.seekg(prevPosition);
|
cdClientBuffer.seekg(prevPosition);
|
||||||
}
|
}
|
||||||
|
|
||||||
void FdbToSqlite::Convert::ReadRow(int32_t& position, std::string& tableName) {
|
void FdbToSqlite::Convert::ReadRow(int32_t& position, std::string& tableName, std::istream& cdClientBuffer) {
|
||||||
int32_t prevPosition = m_Fdb.tellg();
|
int32_t prevPosition = cdClientBuffer.tellg();
|
||||||
m_Fdb.seekg(position);
|
cdClientBuffer.seekg(position);
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
ReadRowInfo(tableName);
|
ReadRowInfo(tableName, cdClientBuffer);
|
||||||
int32_t linked = ReadInt32();
|
int32_t linked = ReadInt32(cdClientBuffer);
|
||||||
if (linked == -1) break;
|
if (linked == -1) break;
|
||||||
m_Fdb.seekg(linked);
|
cdClientBuffer.seekg(linked);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_Fdb.seekg(prevPosition);
|
cdClientBuffer.seekg(prevPosition);
|
||||||
}
|
}
|
||||||
|
|
||||||
void FdbToSqlite::Convert::ReadRowInfo(std::string& tableName) {
|
void FdbToSqlite::Convert::ReadRowInfo(std::string& tableName, std::istream& cdClientBuffer) {
|
||||||
int32_t prevPosition = SeekPointer();
|
int32_t prevPosition = SeekPointer(cdClientBuffer);
|
||||||
|
|
||||||
int32_t numberOfColumns = ReadInt32();
|
int32_t numberOfColumns = ReadInt32(cdClientBuffer);
|
||||||
ReadRowValues(numberOfColumns, tableName);
|
ReadRowValues(numberOfColumns, tableName, cdClientBuffer);
|
||||||
|
|
||||||
m_Fdb.seekg(prevPosition);
|
cdClientBuffer.seekg(prevPosition);
|
||||||
}
|
}
|
||||||
|
|
||||||
void FdbToSqlite::Convert::ReadRowValues(int32_t& numberOfColumns, std::string& tableName) {
|
void FdbToSqlite::Convert::ReadRowValues(int32_t& numberOfColumns, std::string& tableName, std::istream& cdClientBuffer) {
|
||||||
int32_t prevPosition = SeekPointer();
|
int32_t prevPosition = SeekPointer(cdClientBuffer);
|
||||||
|
|
||||||
int32_t emptyValue{};
|
int32_t emptyValue{};
|
||||||
int32_t intValue{};
|
int32_t intValue{};
|
||||||
@ -190,26 +188,26 @@ void FdbToSqlite::Convert::ReadRowValues(int32_t& numberOfColumns, std::string&
|
|||||||
|
|
||||||
for (int32_t i = 0; i < numberOfColumns; i++) {
|
for (int32_t i = 0; i < numberOfColumns; i++) {
|
||||||
if (i != 0) insertedRow << ", "; // Only append comma and space after first entry in row.
|
if (i != 0) insertedRow << ", "; // Only append comma and space after first entry in row.
|
||||||
switch (static_cast<eSqliteDataType>(ReadInt32())) {
|
switch (static_cast<eSqliteDataType>(ReadInt32(cdClientBuffer))) {
|
||||||
case eSqliteDataType::NONE:
|
case eSqliteDataType::NONE:
|
||||||
BinaryIO::BinaryRead(m_Fdb, emptyValue);
|
BinaryIO::BinaryRead(cdClientBuffer, emptyValue);
|
||||||
assert(emptyValue == 0);
|
assert(emptyValue == 0);
|
||||||
insertedRow << "NULL";
|
insertedRow << "NULL";
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case eSqliteDataType::INT32:
|
case eSqliteDataType::INT32:
|
||||||
intValue = ReadInt32();
|
intValue = ReadInt32(cdClientBuffer);
|
||||||
insertedRow << intValue;
|
insertedRow << intValue;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case eSqliteDataType::REAL:
|
case eSqliteDataType::REAL:
|
||||||
BinaryIO::BinaryRead(m_Fdb, floatValue);
|
BinaryIO::BinaryRead(cdClientBuffer, floatValue);
|
||||||
insertedRow << std::fixed << std::setprecision(34) << floatValue; // maximum precision of floating point number
|
insertedRow << std::fixed << std::setprecision(34) << floatValue; // maximum precision of floating point number
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case eSqliteDataType::TEXT_4:
|
case eSqliteDataType::TEXT_4:
|
||||||
case eSqliteDataType::TEXT_8: {
|
case eSqliteDataType::TEXT_8: {
|
||||||
stringValue = ReadString();
|
stringValue = ReadString(cdClientBuffer);
|
||||||
size_t position = 0;
|
size_t position = 0;
|
||||||
|
|
||||||
// Need to escape quote with a double of ".
|
// Need to escape quote with a double of ".
|
||||||
@ -225,12 +223,12 @@ void FdbToSqlite::Convert::ReadRowValues(int32_t& numberOfColumns, std::string&
|
|||||||
}
|
}
|
||||||
|
|
||||||
case eSqliteDataType::INT_BOOL:
|
case eSqliteDataType::INT_BOOL:
|
||||||
BinaryIO::BinaryRead(m_Fdb, boolValue);
|
BinaryIO::BinaryRead(cdClientBuffer, boolValue);
|
||||||
insertedRow << static_cast<bool>(boolValue);
|
insertedRow << static_cast<bool>(boolValue);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case eSqliteDataType::INT64:
|
case eSqliteDataType::INT64:
|
||||||
int64Value = ReadInt64();
|
int64Value = ReadInt64(cdClientBuffer);
|
||||||
insertedRow << std::to_string(int64Value);
|
insertedRow << std::to_string(int64Value);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -245,5 +243,5 @@ void FdbToSqlite::Convert::ReadRowValues(int32_t& numberOfColumns, std::string&
|
|||||||
|
|
||||||
auto copiedString = insertedRow.str();
|
auto copiedString = insertedRow.str();
|
||||||
CDClientDatabase::ExecuteDML(copiedString);
|
CDClientDatabase::ExecuteDML(copiedString);
|
||||||
m_Fdb.seekg(prevPosition);
|
cdClientBuffer.seekg(prevPosition);
|
||||||
}
|
}
|
||||||
|
@ -7,6 +7,8 @@
|
|||||||
#include <iosfwd>
|
#include <iosfwd>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
|
class AssetMemoryBuffer;
|
||||||
|
|
||||||
enum class eSqliteDataType : int32_t;
|
enum class eSqliteDataType : int32_t;
|
||||||
|
|
||||||
namespace FdbToSqlite {
|
namespace FdbToSqlite {
|
||||||
@ -18,33 +20,28 @@ namespace FdbToSqlite {
|
|||||||
* @param inputFile The file which ends in .fdb to be converted
|
* @param inputFile The file which ends in .fdb to be converted
|
||||||
* @param binaryPath The base path where the file will be saved
|
* @param binaryPath The base path where the file will be saved
|
||||||
*/
|
*/
|
||||||
Convert(std::string inputFile, std::string binaryOutPath);
|
Convert(std::string binaryOutPath);
|
||||||
|
|
||||||
/**
|
|
||||||
* Destroy the convert object and close the fdb file.
|
|
||||||
*/
|
|
||||||
~Convert();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Converts the input file to sqlite. Calling multiple times is safe.
|
* Converts the input file to sqlite. Calling multiple times is safe.
|
||||||
*
|
*
|
||||||
* @return true if the database was converted properly, false otherwise.
|
* @return true if the database was converted properly, false otherwise.
|
||||||
*/
|
*/
|
||||||
bool ConvertDatabase();
|
bool ConvertDatabase(AssetMemoryBuffer& buffer);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Reads a 32 bit int from the fdb file.
|
* @brief Reads a 32 bit int from the fdb file.
|
||||||
*
|
*
|
||||||
* @return The read value
|
* @return The read value
|
||||||
*/
|
*/
|
||||||
int32_t ReadInt32();
|
int32_t ReadInt32(std::istream& cdClientBuffer);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Reads a 64 bit integer from the fdb file.
|
* @brief Reads a 64 bit integer from the fdb file.
|
||||||
*
|
*
|
||||||
* @return The read value
|
* @return The read value
|
||||||
*/
|
*/
|
||||||
int64_t ReadInt64();
|
int64_t ReadInt64(std::istream& cdClientBuffer);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Reads a string from the fdb file.
|
* @brief Reads a string from the fdb file.
|
||||||
@ -53,28 +50,28 @@ namespace FdbToSqlite {
|
|||||||
*
|
*
|
||||||
* TODO This needs to be translated to latin-1!
|
* TODO This needs to be translated to latin-1!
|
||||||
*/
|
*/
|
||||||
std::string ReadString();
|
std::string ReadString(std::istream& cdClientBuffer);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Seeks to a pointer position.
|
* @brief Seeks to a pointer position.
|
||||||
*
|
*
|
||||||
* @return The previous position before the seek
|
* @return The previous position before the seek
|
||||||
*/
|
*/
|
||||||
int32_t SeekPointer();
|
int32_t SeekPointer(std::istream& cdClientBuffer);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Reads a column header from the fdb file and creates the table in the database
|
* @brief Reads a column header from the fdb file and creates the table in the database
|
||||||
*
|
*
|
||||||
* @return The table name
|
* @return The table name
|
||||||
*/
|
*/
|
||||||
std::string ReadColumnHeader();
|
std::string ReadColumnHeader(std::istream& cdClientBuffer);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Read the tables from the fdb file.
|
* @brief Read the tables from the fdb file.
|
||||||
*
|
*
|
||||||
* @param numberOfTables The number of tables to read
|
* @param numberOfTables The number of tables to read
|
||||||
*/
|
*/
|
||||||
void ReadTables(int32_t& numberOfTables);
|
void ReadTables(int32_t& numberOfTables, std::istream& cdClientBuffer);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Reads the columns from the fdb file.
|
* @brief Reads the columns from the fdb file.
|
||||||
@ -82,14 +79,14 @@ namespace FdbToSqlite {
|
|||||||
* @param numberOfColumns The number of columns to read
|
* @param numberOfColumns The number of columns to read
|
||||||
* @return All columns of the table formatted for a sql query
|
* @return All columns of the table formatted for a sql query
|
||||||
*/
|
*/
|
||||||
std::string ReadColumns(int32_t& numberOfColumns);
|
std::string ReadColumns(int32_t& numberOfColumns, std::istream& cdClientBuffer);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Reads the row header from the fdb file.
|
* @brief Reads the row header from the fdb file.
|
||||||
*
|
*
|
||||||
* @param tableName The tables name
|
* @param tableName The tables name
|
||||||
*/
|
*/
|
||||||
void ReadRowHeader(std::string& tableName);
|
void ReadRowHeader(std::string& tableName, std::istream& cdClientBuffer);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Read the rows from the fdb file.,
|
* @brief Read the rows from the fdb file.,
|
||||||
@ -97,7 +94,7 @@ namespace FdbToSqlite {
|
|||||||
* @param numberOfAllocatedRows The number of rows that were allocated. Always a power of 2!
|
* @param numberOfAllocatedRows The number of rows that were allocated. Always a power of 2!
|
||||||
* @param tableName The tables name.
|
* @param tableName The tables name.
|
||||||
*/
|
*/
|
||||||
void ReadRows(int32_t& numberOfAllocatedRows, std::string& tableName);
|
void ReadRows(int32_t& numberOfAllocatedRows, std::string& tableName, std::istream& cdClientBuffer);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Reads a row from the fdb file.
|
* @brief Reads a row from the fdb file.
|
||||||
@ -105,14 +102,14 @@ namespace FdbToSqlite {
|
|||||||
* @param position The position to seek in the fdb to
|
* @param position The position to seek in the fdb to
|
||||||
* @param tableName The tables name
|
* @param tableName The tables name
|
||||||
*/
|
*/
|
||||||
void ReadRow(int32_t& position, std::string& tableName);
|
void ReadRow(int32_t& position, std::string& tableName, std::istream& cdClientBuffer);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Reads the row info from the fdb file.
|
* @brief Reads the row info from the fdb file.
|
||||||
*
|
*
|
||||||
* @param tableName The tables name
|
* @param tableName The tables name
|
||||||
*/
|
*/
|
||||||
void ReadRowInfo(std::string& tableName);
|
void ReadRowInfo(std::string& tableName, std::istream& cdClientBuffer);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Reads each row and its values from the fdb file and inserts them into the database
|
* @brief Reads each row and its values from the fdb file and inserts them into the database
|
||||||
@ -120,7 +117,7 @@ namespace FdbToSqlite {
|
|||||||
* @param numberOfColumns The number of columns to read in
|
* @param numberOfColumns The number of columns to read in
|
||||||
* @param tableName The tables name
|
* @param tableName The tables name
|
||||||
*/
|
*/
|
||||||
void ReadRowValues(int32_t& numberOfColumns, std::string& tableName);
|
void ReadRowValues(int32_t& numberOfColumns, std::string& tableName, std::istream& cdClientBuffer);
|
||||||
private:
|
private:
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -133,11 +130,6 @@ namespace FdbToSqlite {
|
|||||||
*/
|
*/
|
||||||
std::string m_BasePath{};
|
std::string m_BasePath{};
|
||||||
|
|
||||||
/**
|
|
||||||
* ifstream containing the fdb file
|
|
||||||
*/
|
|
||||||
std::ifstream m_Fdb{};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Whether or not a conversion was started. If one was started, do not attempt to convert the file again.
|
* Whether or not a conversion was started. If one was started, do not attempt to convert the file again.
|
||||||
*/
|
*/
|
||||||
|
@ -45,9 +45,6 @@ AssetManager::AssetManager(const std::filesystem::path& path) {
|
|||||||
switch (m_AssetBundleType) {
|
switch (m_AssetBundleType) {
|
||||||
case eAssetBundleType::Packed: {
|
case eAssetBundleType::Packed: {
|
||||||
this->LoadPackIndex();
|
this->LoadPackIndex();
|
||||||
|
|
||||||
this->UnpackRequiredAssets();
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -160,31 +157,6 @@ AssetMemoryBuffer AssetManager::GetFileAsBuffer(const char* name) {
|
|||||||
return AssetMemoryBuffer(buf, len, success);
|
return AssetMemoryBuffer(buf, len, success);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AssetManager::UnpackRequiredAssets() {
|
|
||||||
if (std::filesystem::exists(m_ResPath / "cdclient.fdb")) return;
|
|
||||||
|
|
||||||
char* data;
|
|
||||||
uint32_t size;
|
|
||||||
|
|
||||||
bool success = this->GetFile("cdclient.fdb", &data, &size);
|
|
||||||
|
|
||||||
if (!success) {
|
|
||||||
Game::logger->Log("AssetManager", "Failed to extract required files from the packs.");
|
|
||||||
|
|
||||||
delete data;
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::ofstream cdclientOutput(m_ResPath / "cdclient.fdb", std::ios::out | std::ios::binary);
|
|
||||||
cdclientOutput.write(data, size);
|
|
||||||
cdclientOutput.close();
|
|
||||||
|
|
||||||
delete data;
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t AssetManager::crc32b(uint32_t base, uint8_t* message, size_t l) {
|
uint32_t AssetManager::crc32b(uint32_t base, uint8_t* message, size_t l) {
|
||||||
size_t i, j;
|
size_t i, j;
|
||||||
uint32_t crc, msb;
|
uint32_t crc, msb;
|
||||||
|
@ -60,7 +60,6 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
void LoadPackIndex();
|
void LoadPackIndex();
|
||||||
void UnpackRequiredAssets();
|
|
||||||
|
|
||||||
// Modified crc algorithm (mpeg2)
|
// Modified crc algorithm (mpeg2)
|
||||||
// Reference: https://stackoverflow.com/questions/54339800/how-to-modify-crc-32-to-crc-32-mpeg-2
|
// Reference: https://stackoverflow.com/questions/54339800/how-to-modify-crc-32-to-crc-32-mpeg-2
|
||||||
|
@ -156,22 +156,25 @@ int main(int argc, char** argv) {
|
|||||||
Game::logger->Log("MasterServer", "CDServer.sqlite is not located at resServer, but is located at res path. Copying file...");
|
Game::logger->Log("MasterServer", "CDServer.sqlite is not located at resServer, but is located at res path. Copying file...");
|
||||||
std::filesystem::copy_file(Game::assetManager->GetResPath() / "CDServer.sqlite", BinaryPathFinder::GetBinaryDir() / "resServer" / "CDServer.sqlite");
|
std::filesystem::copy_file(Game::assetManager->GetResPath() / "CDServer.sqlite", BinaryPathFinder::GetBinaryDir() / "resServer" / "CDServer.sqlite");
|
||||||
} else {
|
} else {
|
||||||
Game::logger->Log("WorldServer",
|
Game::logger->Log("MasterServer",
|
||||||
"%s could not be found in resServer or res. Looking for %s to convert to sqlite.",
|
"%s could not be found in resServer or res. Looking for %s to convert to sqlite.",
|
||||||
(BinaryPathFinder::GetBinaryDir() / "resServer" / "CDServer.sqlite").c_str(),
|
(BinaryPathFinder::GetBinaryDir() / "resServer" / "CDServer.sqlite").c_str(),
|
||||||
(Game::assetManager->GetResPath() / "cdclient.fdb").c_str());
|
(Game::assetManager->GetResPath() / "cdclient.fdb").c_str());
|
||||||
if (!fdbExists) {
|
|
||||||
Game::logger->Log("WorldServer",
|
AssetMemoryBuffer cdClientBuffer = Game::assetManager->GetFileAsBuffer("cdclient.fdb");
|
||||||
"%s could not be opened. Please move cdclient.fdb to %s",
|
if (!cdClientBuffer.m_Success) {
|
||||||
(Game::assetManager->GetResPath() / "cdclient.fdb").c_str(),
|
Game::logger->Log("MasterServer", "Failed to load %s", (Game::assetManager->GetResPath() / "cdclient.fdb").c_str());
|
||||||
(Game::assetManager->GetResPath().c_str()));
|
throw std::runtime_error("Aborting initialization due to missing cdclient.fdb.");
|
||||||
return FinalizeShutdown();
|
|
||||||
}
|
}
|
||||||
Game::logger->Log("WorldServer", "Found cdclient.fdb. Converting to SQLite");
|
|
||||||
if (FdbToSqlite::Convert(Game::assetManager->GetResPath().string(), (BinaryPathFinder::GetBinaryDir() / "resServer").string()).ConvertDatabase() == false) {
|
Game::logger->Log("MasterServer", "Found %s. Converting to SQLite", (Game::assetManager->GetResPath() / "cdclient.fdb").c_str());
|
||||||
|
Game::logger->Flush();
|
||||||
|
|
||||||
|
if (FdbToSqlite::Convert((BinaryPathFinder::GetBinaryDir() / "resServer").string()).ConvertDatabase(cdClientBuffer) == false) {
|
||||||
Game::logger->Log("MasterServer", "Failed to convert fdb to sqlite.");
|
Game::logger->Log("MasterServer", "Failed to convert fdb to sqlite.");
|
||||||
return FinalizeShutdown();
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
cdClientBuffer.close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6,7 +6,7 @@ RUN --mount=type=cache,id=build-apt-cache,target=/var/cache/apt \
|
|||||||
echo "Install build dependencies" && \
|
echo "Install build dependencies" && \
|
||||||
apt update && \
|
apt update && \
|
||||||
apt remove -y libmysqlcppconn7v5 libmysqlcppconn-dev && \
|
apt remove -y libmysqlcppconn7v5 libmysqlcppconn-dev && \
|
||||||
apt install cmake zlib1g zlib1g-dev unzip -yqq --no-install-recommends && \
|
apt install cmake zlib1g zlib1g-dev -yqq --no-install-recommends && \
|
||||||
rm -rf /var/lib/apt/lists/*
|
rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
COPY dAuthServer/ /build/dAuthServer
|
COPY dAuthServer/ /build/dAuthServer
|
||||||
@ -35,12 +35,11 @@ ARG BUILD_VERSION=171022
|
|||||||
RUN echo "Build server" && \
|
RUN echo "Build server" && \
|
||||||
mkdir -p cmake_build && \
|
mkdir -p cmake_build && \
|
||||||
cd cmake_build && \
|
cd cmake_build && \
|
||||||
sed -i -e "s/171022/${BUILD_VERSION}/g" ../CMakeVariables.txt && \
|
sed -i -e "s/NET_VERSION=.*/NET_VERSION=${BUILD_VERSION}/g" ../CMakeVariables.txt && \
|
||||||
|
sed -i -e "s/__maria_db_connector_compile_jobs__=.*/__maria_db_connector_compile_jobs__=${BUILD_THREADS}/g" ../CMakeVariables.txt && \
|
||||||
cmake .. -DCMAKE_BUILD_RPATH_USE_ORIGIN=TRUE && \
|
cmake .. -DCMAKE_BUILD_RPATH_USE_ORIGIN=TRUE && \
|
||||||
make -j $BUILD_THREADS
|
make -j $BUILD_THREADS
|
||||||
|
|
||||||
RUN unzip /build/resources/navmeshes.zip -d /build/cmake_build/res/maps
|
|
||||||
|
|
||||||
FROM gcc:11 as runtime
|
FROM gcc:11 as runtime
|
||||||
|
|
||||||
RUN --mount=type=cache,id=runtime-apt-cache,target=/var/cache/apt \
|
RUN --mount=type=cache,id=runtime-apt-cache,target=/var/cache/apt \
|
||||||
|
@ -1,22 +1,11 @@
|
|||||||
FROM rust:alpine3.14 as LUnpack
|
|
||||||
|
|
||||||
WORKDIR /build_LUnpack
|
|
||||||
|
|
||||||
COPY ./thirdparty/LUnpack .
|
|
||||||
|
|
||||||
RUN apk add musl-dev --no-cache && cargo build --release
|
|
||||||
|
|
||||||
FROM python:3.10-alpine3.14 as prep
|
FROM python:3.10-alpine3.14 as prep
|
||||||
|
|
||||||
RUN apk add sqlite bash --no-cache
|
RUN apk add bash --no-cache
|
||||||
|
|
||||||
WORKDIR /setup
|
WORKDIR /setup
|
||||||
|
|
||||||
# copy needed files from repo
|
# copy needed files from repo
|
||||||
COPY resources/ resources/
|
COPY resources/ resources/
|
||||||
COPY migrations/cdserver/ migrations/cdserver
|
|
||||||
COPY --from=LUnpack /build_LUnpack/target/release/lunpack /usr/local/bin/lunpack
|
|
||||||
ADD thirdparty/docker-utils/utils/*.py utils/
|
|
||||||
|
|
||||||
COPY docker/setup.sh /setup.sh
|
COPY docker/setup.sh /setup.sh
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@ function update_ini() {
|
|||||||
FILE="/docker/configs/$1"
|
FILE="/docker/configs/$1"
|
||||||
KEY=$2
|
KEY=$2
|
||||||
NEW_VALUE=$3
|
NEW_VALUE=$3
|
||||||
sed -i "/^$KEY=/s/=.*/=$NEW_VALUE/" $FILE
|
sed -i "s~$2=.*~$2=$3~" $FILE
|
||||||
}
|
}
|
||||||
|
|
||||||
function update_database_ini_values_for() {
|
function update_database_ini_values_for() {
|
||||||
@ -32,62 +32,11 @@ function update_ini_values() {
|
|||||||
cp resources/worldconfig.ini /docker/configs/
|
cp resources/worldconfig.ini /docker/configs/
|
||||||
cp resources/sharedconfig.ini /docker/configs/
|
cp resources/sharedconfig.ini /docker/configs/
|
||||||
|
|
||||||
update_ini worldconfig.ini chat_server_port $CHAT_SERVER_PORT
|
|
||||||
update_ini worldconfig.ini max_clients $MAX_CLIENTS
|
|
||||||
|
|
||||||
# always use the internal docker hostname
|
# always use the internal docker hostname
|
||||||
update_ini masterconfig.ini master_ip "darkflame"
|
update_ini masterconfig.ini master_ip "darkflame"
|
||||||
|
update_ini sharedconfig.ini client_location "/client"
|
||||||
|
|
||||||
update_database_ini_values_for sharedconfig.ini
|
update_database_ini_values_for sharedconfig.ini
|
||||||
}
|
}
|
||||||
|
|
||||||
function fdb_to_sqlite() {
|
|
||||||
echo "Run fdb_to_sqlite"
|
|
||||||
python3 utils/fdb_to_sqlite.py /client/client/res/cdclient.fdb --sqlite_path /client/client/res/CDServer.sqlite
|
|
||||||
|
|
||||||
(
|
|
||||||
cd migrations/cdserver
|
|
||||||
readarray -d '' entries < <(printf '%s\0' *.sql | sort -zV)
|
|
||||||
for entry in "${entries[@]}"; do
|
|
||||||
echo "Execute $entry"
|
|
||||||
sqlite3 /client/client/res/CDServer.sqlite < $entry
|
|
||||||
done
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
update_ini_values
|
update_ini_values
|
||||||
|
|
||||||
if [[ ! -d "/client" ]]; then
|
|
||||||
echo "Client not found."
|
|
||||||
echo "Did you forget to mount the client into the \"/client\" directory?"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ ! -f "/client/extracted" ]]; then
|
|
||||||
echo "Start client resource extraction"
|
|
||||||
|
|
||||||
touch globs.txt
|
|
||||||
|
|
||||||
echo "client/res/macros/**" >> globs.txt
|
|
||||||
echo "client/res/BrickModels/**" >> globs.txt
|
|
||||||
echo "client/res/maps/**" >> globs.txt
|
|
||||||
echo "*.fdb" >> globs.txt
|
|
||||||
|
|
||||||
lunpack -g ./globs.txt /client/
|
|
||||||
|
|
||||||
touch /client/extracted
|
|
||||||
else
|
|
||||||
echo "Client already extracted. Skip this step..."
|
|
||||||
echo "If you want to force a re-extract, just delete the file called \"extracted\" in the client directory"
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ ! -f "/client/migrated" ]]; then
|
|
||||||
echo "Start client db migration"
|
|
||||||
|
|
||||||
fdb_to_sqlite
|
|
||||||
|
|
||||||
touch /client/migrated
|
|
||||||
else
|
|
||||||
echo "Client db already migrated. Skip this step..."
|
|
||||||
echo "If you want to force a re-migrate, just delete the file called \"migrated\" in the client directory"
|
|
||||||
fi
|
|
||||||
|
27
docker/start_server.sh
Normal file → Executable file
27
docker/start_server.sh
Normal file → Executable file
@ -1,25 +1,5 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
function symlink_client_files() {
|
|
||||||
echo "Creating symlinks for client files"
|
|
||||||
ln -s /client/client/res/macros/ /app/res/macros
|
|
||||||
ln -s /client/client/res/BrickModels/ /app/res/BrickModels
|
|
||||||
ln -s /client/client/res/chatplus_en_us.txt /app/res/chatplus_en_us.txt
|
|
||||||
ln -s /client/client/res/names/ /app/res/names
|
|
||||||
ln -s /client/client/res/CDServer.sqlite /app/res/CDServer.sqlite
|
|
||||||
|
|
||||||
# need to create this file so the server knows the client is unpacked (see `dCommon/dClient/AssetManager.cpp`)
|
|
||||||
touch /app/res/cdclient.fdb
|
|
||||||
# need to iterate over entries in maps due to maps already being a directory with navmeshes/ in it
|
|
||||||
(
|
|
||||||
cd /client/client/res/maps
|
|
||||||
readarray -d '' entries < <(printf '%s\0' * | sort -zV)
|
|
||||||
for entry in "${entries[@]}"; do
|
|
||||||
ln -s /client/client/res/maps/$entry /app/res/maps/
|
|
||||||
done
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
function symlink_config_files() {
|
function symlink_config_files() {
|
||||||
echo "Creating symlinks for config files"
|
echo "Creating symlinks for config files"
|
||||||
rm /app/*.ini
|
rm /app/*.ini
|
||||||
@ -30,15 +10,8 @@ function symlink_config_files() {
|
|||||||
ln -s /shared_configs/configs/sharedconfig.ini /app/sharedconfig.ini
|
ln -s /shared_configs/configs/sharedconfig.ini /app/sharedconfig.ini
|
||||||
}
|
}
|
||||||
|
|
||||||
# check to make sure the setup has completed
|
|
||||||
while [ ! -f "/client/extracted" ] || [ ! -f "/client/migrated" ]; do
|
|
||||||
echo "Client setup not finished. Waiting for setup container to complete..."
|
|
||||||
sleep 5
|
|
||||||
done
|
|
||||||
|
|
||||||
if [[ ! -f "/app/initialized" ]]; then
|
if [[ ! -f "/app/initialized" ]]; then
|
||||||
# setup symlinks for volume files
|
# setup symlinks for volume files
|
||||||
symlink_client_files
|
|
||||||
symlink_config_files
|
symlink_config_files
|
||||||
# do not run symlinks more than once
|
# do not run symlinks more than once
|
||||||
touch /app/initialized
|
touch /app/initialized
|
||||||
|
1
thirdparty/LUnpack
vendored
1
thirdparty/LUnpack
vendored
@ -1 +0,0 @@
|
|||||||
Subproject commit f8d7e442a78910b298fe1cd5780f07c9c9285b8c
|
|
1
thirdparty/docker-utils
vendored
1
thirdparty/docker-utils
vendored
@ -1 +0,0 @@
|
|||||||
Subproject commit 3f0129e0939ce5ccf41f0808dcbbe71a6243e37f
|
|
Loading…
Reference in New Issue
Block a user