mirror of
				https://github.com/DarkflameUniverse/DarkflameServer.git
				synced 2025-11-04 06:32:00 +00:00 
			
		
		
		
	Merge remote-tracking branch 'upstream/main' into addSlashCommand
This commit is contained in:
		@@ -83,7 +83,7 @@ int main(int argc, char** argv) {
 | 
			
		||||
	if (config.GetValue("max_clients") != "") maxClients = std::stoi(config.GetValue("max_clients"));
 | 
			
		||||
	if (config.GetValue("port") != "") ourPort = std::atoi(config.GetValue("port").c_str());
 | 
			
		||||
 | 
			
		||||
	Game::server = new dServer(config.GetValue("external_ip"), ourPort, 0, maxClients, false, true, Game::logger, masterIP, masterPort, ServerType::Auth);
 | 
			
		||||
	Game::server = new dServer(config.GetValue("external_ip"), ourPort, 0, maxClients, false, true, Game::logger, masterIP, masterPort, ServerType::Auth, Game::config);
 | 
			
		||||
 | 
			
		||||
	//Run it until server gets a kill message from Master:
 | 
			
		||||
	auto t = std::chrono::high_resolution_clock::now();
 | 
			
		||||
 
 | 
			
		||||
@@ -103,7 +103,7 @@ int main(int argc, char** argv) {
 | 
			
		||||
	if (config.GetValue("max_clients") != "") maxClients = std::stoi(config.GetValue("max_clients"));
 | 
			
		||||
	if (config.GetValue("port") != "") ourPort = std::atoi(config.GetValue("port").c_str());
 | 
			
		||||
 | 
			
		||||
	Game::server = new dServer(config.GetValue("external_ip"), ourPort, 0, maxClients, false, true, Game::logger, masterIP, masterPort, ServerType::Chat);
 | 
			
		||||
	Game::server = new dServer(config.GetValue("external_ip"), ourPort, 0, maxClients, false, true, Game::logger, masterIP, masterPort, ServerType::Chat, Game::config);
 | 
			
		||||
 | 
			
		||||
	Game::chatFilter = new dChatFilter(Game::assetManager->GetResPath().string() + "/chatplus_en_us", bool(std::stoi(config.GetValue("dont_generate_dcf"))));
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -16,6 +16,7 @@ set(DCOMMON_SOURCES "AMFFormat.cpp"
 | 
			
		||||
		"ZCompression.cpp"
 | 
			
		||||
		"BrickByBrickFix.cpp"
 | 
			
		||||
		"BinaryPathFinder.cpp"
 | 
			
		||||
		"FdbToSqlite.cpp"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
add_subdirectory(dClient)
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										248
									
								
								dCommon/FdbToSqlite.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										248
									
								
								dCommon/FdbToSqlite.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,248 @@
 | 
			
		||||
#include "FdbToSqlite.h"
 | 
			
		||||
 | 
			
		||||
#include <map>
 | 
			
		||||
#include <fstream>
 | 
			
		||||
#include <cassert>
 | 
			
		||||
#include <iomanip>
 | 
			
		||||
 | 
			
		||||
#include "BinaryIO.h"
 | 
			
		||||
#include "CDClientDatabase.h"
 | 
			
		||||
#include "GeneralUtils.h"
 | 
			
		||||
#include "Game.h"
 | 
			
		||||
#include "dLogger.h"
 | 
			
		||||
 | 
			
		||||
#include "eSqliteDataType.h"
 | 
			
		||||
 | 
			
		||||
std::map<eSqliteDataType, std::string> FdbToSqlite::Convert::sqliteType = {
 | 
			
		||||
			{ eSqliteDataType::NONE, "none"},
 | 
			
		||||
			{ eSqliteDataType::INT32, "int32"},
 | 
			
		||||
			{ eSqliteDataType::REAL, "real"},
 | 
			
		||||
			{ eSqliteDataType::TEXT_4, "text_4"},
 | 
			
		||||
			{ eSqliteDataType::INT_BOOL, "int_bool"},
 | 
			
		||||
			{ eSqliteDataType::INT64, "int64"},
 | 
			
		||||
			{ eSqliteDataType::TEXT_8, "text_8"}
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
FdbToSqlite::Convert::Convert(std::string basePath) {
 | 
			
		||||
	this->basePath = basePath;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool FdbToSqlite::Convert::ConvertDatabase() {
 | 
			
		||||
	fdb.open(basePath + "/cdclient.fdb", std::ios::binary);
 | 
			
		||||
 | 
			
		||||
	try {
 | 
			
		||||
		CDClientDatabase::Connect(basePath + "/CDServer.sqlite");
 | 
			
		||||
 | 
			
		||||
		CDClientDatabase::ExecuteQuery("BEGIN TRANSACTION;");
 | 
			
		||||
 | 
			
		||||
		int32_t numberOfTables = ReadInt32();
 | 
			
		||||
		ReadTables(numberOfTables);
 | 
			
		||||
 | 
			
		||||
		CDClientDatabase::ExecuteQuery("COMMIT;");
 | 
			
		||||
	} catch (CppSQLite3Exception& e) {
 | 
			
		||||
		Game::logger->Log("FdbToSqlite", "Encountered error %s converting FDB to SQLite", e.errorMessage());
 | 
			
		||||
		return false;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	fdb.close();
 | 
			
		||||
	return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int32_t FdbToSqlite::Convert::ReadInt32() {
 | 
			
		||||
	uint32_t numberOfTables{};
 | 
			
		||||
	BinaryIO::BinaryRead(fdb, numberOfTables);
 | 
			
		||||
	return numberOfTables;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int64_t FdbToSqlite::Convert::ReadInt64() {
 | 
			
		||||
	int32_t prevPosition = SeekPointer();
 | 
			
		||||
 | 
			
		||||
	int64_t value{};
 | 
			
		||||
	BinaryIO::BinaryRead(fdb, value);
 | 
			
		||||
 | 
			
		||||
	fdb.seekg(prevPosition);
 | 
			
		||||
	return value;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
std::string FdbToSqlite::Convert::ReadString() {
 | 
			
		||||
	int32_t prevPosition = SeekPointer();
 | 
			
		||||
 | 
			
		||||
	auto readString = BinaryIO::ReadString(fdb);
 | 
			
		||||
 | 
			
		||||
	fdb.seekg(prevPosition);
 | 
			
		||||
	return readString;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int32_t FdbToSqlite::Convert::SeekPointer() {
 | 
			
		||||
	int32_t position{};
 | 
			
		||||
	BinaryIO::BinaryRead(fdb, position);
 | 
			
		||||
	int32_t prevPosition = fdb.tellg();
 | 
			
		||||
	fdb.seekg(position);
 | 
			
		||||
	return prevPosition;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
std::string FdbToSqlite::Convert::ReadColumnHeader() {
 | 
			
		||||
	int32_t prevPosition = SeekPointer();
 | 
			
		||||
 | 
			
		||||
	int32_t numberOfColumns = ReadInt32();
 | 
			
		||||
	std::string tableName = ReadString();
 | 
			
		||||
 | 
			
		||||
	auto columns = ReadColumns(numberOfColumns);
 | 
			
		||||
	std::string newTable = "CREATE TABLE IF NOT EXISTS '" + tableName + "' (" + columns + ");";
 | 
			
		||||
	CDClientDatabase::ExecuteDML(newTable);
 | 
			
		||||
 | 
			
		||||
	fdb.seekg(prevPosition);
 | 
			
		||||
 | 
			
		||||
	return tableName;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void FdbToSqlite::Convert::ReadTables(int32_t& numberOfTables) {
 | 
			
		||||
	int32_t prevPosition = SeekPointer();
 | 
			
		||||
 | 
			
		||||
	for (int32_t i = 0; i < numberOfTables; i++) {
 | 
			
		||||
		auto columnHeader = ReadColumnHeader();
 | 
			
		||||
		ReadRowHeader(columnHeader);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	fdb.seekg(prevPosition);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
std::string FdbToSqlite::Convert::ReadColumns(int32_t& numberOfColumns) {
 | 
			
		||||
	std::stringstream columnsToCreate;
 | 
			
		||||
	int32_t prevPosition = SeekPointer();
 | 
			
		||||
 | 
			
		||||
	std::string name{};
 | 
			
		||||
	eSqliteDataType dataType{};
 | 
			
		||||
	for (int32_t i = 0; i < numberOfColumns; i++) {
 | 
			
		||||
		if (i != 0) columnsToCreate << ", ";
 | 
			
		||||
		dataType = static_cast<eSqliteDataType>(ReadInt32());
 | 
			
		||||
		name = ReadString();
 | 
			
		||||
		columnsToCreate << "'" << name << "' " << FdbToSqlite::Convert::sqliteType[dataType];
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	fdb.seekg(prevPosition);
 | 
			
		||||
	return columnsToCreate.str();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void FdbToSqlite::Convert::ReadRowHeader(std::string& tableName) {
 | 
			
		||||
	int32_t prevPosition = SeekPointer();
 | 
			
		||||
 | 
			
		||||
	int32_t numberOfAllocatedRows = ReadInt32();
 | 
			
		||||
	if (numberOfAllocatedRows != 0) assert((numberOfAllocatedRows & (numberOfAllocatedRows - 1)) == 0);  // assert power of 2 allocation size
 | 
			
		||||
	ReadRows(numberOfAllocatedRows, tableName);
 | 
			
		||||
 | 
			
		||||
	fdb.seekg(prevPosition);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void FdbToSqlite::Convert::ReadRows(int32_t& numberOfAllocatedRows, std::string& tableName) {
 | 
			
		||||
	int32_t prevPosition = SeekPointer();
 | 
			
		||||
 | 
			
		||||
	int32_t rowid = 0;
 | 
			
		||||
	for (int32_t row = 0; row < numberOfAllocatedRows; row++) {
 | 
			
		||||
		int32_t rowPointer = ReadInt32();
 | 
			
		||||
		if (rowPointer == -1) rowid++;
 | 
			
		||||
		else ReadRow(rowid, rowPointer, tableName);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	fdb.seekg(prevPosition);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void FdbToSqlite::Convert::ReadRow(int32_t& rowid, int32_t& position, std::string& tableName) {
 | 
			
		||||
	int32_t prevPosition = fdb.tellg();
 | 
			
		||||
	fdb.seekg(position);
 | 
			
		||||
 | 
			
		||||
	while (true) {
 | 
			
		||||
		ReadRowInfo(tableName);
 | 
			
		||||
		int32_t linked = ReadInt32();
 | 
			
		||||
 | 
			
		||||
		rowid += 1;
 | 
			
		||||
 | 
			
		||||
		if (linked == -1) break;
 | 
			
		||||
 | 
			
		||||
		fdb.seekg(linked);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	fdb.seekg(prevPosition);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void FdbToSqlite::Convert::ReadRowInfo(std::string& tableName) {
 | 
			
		||||
	int32_t prevPosition = SeekPointer();
 | 
			
		||||
 | 
			
		||||
	int32_t numberOfColumns = ReadInt32();
 | 
			
		||||
	ReadRowValues(numberOfColumns, tableName);
 | 
			
		||||
 | 
			
		||||
	fdb.seekg(prevPosition);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void FdbToSqlite::Convert::ReadRowValues(int32_t& numberOfColumns, std::string& tableName) {
 | 
			
		||||
	int32_t prevPosition = SeekPointer();
 | 
			
		||||
 | 
			
		||||
	int32_t emptyValue{};
 | 
			
		||||
	int32_t intValue{};
 | 
			
		||||
	float_t floatValue{};
 | 
			
		||||
	std::string stringValue{};
 | 
			
		||||
	int32_t boolValue{};
 | 
			
		||||
	int64_t int64Value{};
 | 
			
		||||
	bool insertedFirstEntry = false;
 | 
			
		||||
	std::stringstream insertedRow;
 | 
			
		||||
	insertedRow << "INSERT INTO " << tableName << " values (";
 | 
			
		||||
 | 
			
		||||
	for (int32_t i = 0; i < numberOfColumns; i++) {
 | 
			
		||||
		if (i != 0) insertedRow << ", "; // Only append comma and space after first entry in row.
 | 
			
		||||
		switch (static_cast<eSqliteDataType>(ReadInt32())) {
 | 
			
		||||
		case eSqliteDataType::NONE:
 | 
			
		||||
			BinaryIO::BinaryRead(fdb, emptyValue);
 | 
			
		||||
			assert(emptyValue == 0);
 | 
			
		||||
			insertedRow << "\"\"";
 | 
			
		||||
			break;
 | 
			
		||||
 | 
			
		||||
		case eSqliteDataType::INT32:
 | 
			
		||||
			intValue = ReadInt32();
 | 
			
		||||
			insertedRow << intValue;
 | 
			
		||||
			break;
 | 
			
		||||
 | 
			
		||||
		case eSqliteDataType::REAL:
 | 
			
		||||
			BinaryIO::BinaryRead(fdb, floatValue);
 | 
			
		||||
			insertedRow << std::fixed << std::setprecision(34) << floatValue; // maximum precision of floating point number
 | 
			
		||||
			break;
 | 
			
		||||
 | 
			
		||||
		case eSqliteDataType::TEXT_4:
 | 
			
		||||
		case eSqliteDataType::TEXT_8: {
 | 
			
		||||
			stringValue = ReadString();
 | 
			
		||||
			size_t position = 0;
 | 
			
		||||
 | 
			
		||||
			// Need to escape quote with a double of ".
 | 
			
		||||
			while (position < stringValue.size()) {
 | 
			
		||||
				if (stringValue.at(position) == '\"') {
 | 
			
		||||
					stringValue.insert(position, "\"");
 | 
			
		||||
					position++;
 | 
			
		||||
				}
 | 
			
		||||
				position++;
 | 
			
		||||
			}
 | 
			
		||||
			insertedRow << "\"" << stringValue << "\"";
 | 
			
		||||
			break;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		case eSqliteDataType::INT_BOOL:
 | 
			
		||||
			BinaryIO::BinaryRead(fdb, boolValue);
 | 
			
		||||
			insertedRow << static_cast<bool>(boolValue);
 | 
			
		||||
			break;
 | 
			
		||||
 | 
			
		||||
		case eSqliteDataType::INT64:
 | 
			
		||||
			int64Value = ReadInt64();
 | 
			
		||||
			insertedRow << std::to_string(int64Value);
 | 
			
		||||
			break;
 | 
			
		||||
 | 
			
		||||
		default:
 | 
			
		||||
			throw std::invalid_argument("Unsupported SQLite type encountered.");
 | 
			
		||||
			break;
 | 
			
		||||
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	insertedRow << ");";
 | 
			
		||||
 | 
			
		||||
	auto copiedString = insertedRow.str();
 | 
			
		||||
	CDClientDatabase::ExecuteDML(copiedString);
 | 
			
		||||
	fdb.seekg(prevPosition);
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										49
									
								
								dCommon/FdbToSqlite.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										49
									
								
								dCommon/FdbToSqlite.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,49 @@
 | 
			
		||||
#ifndef __FDBTOSQLITE__H__
 | 
			
		||||
#define __FDBTOSQLITE__H__
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include <cstdint>
 | 
			
		||||
#include <iosfwd>
 | 
			
		||||
#include <map>
 | 
			
		||||
 | 
			
		||||
enum class eSqliteDataType : int32_t;
 | 
			
		||||
 | 
			
		||||
namespace FdbToSqlite {
 | 
			
		||||
	class Convert {
 | 
			
		||||
	public:
 | 
			
		||||
		Convert(std::string inputFile);
 | 
			
		||||
 | 
			
		||||
		bool ConvertDatabase();
 | 
			
		||||
 | 
			
		||||
		int32_t ReadInt32();
 | 
			
		||||
 | 
			
		||||
		int64_t ReadInt64();
 | 
			
		||||
 | 
			
		||||
		std::string ReadString();
 | 
			
		||||
 | 
			
		||||
		int32_t SeekPointer();
 | 
			
		||||
 | 
			
		||||
		std::string ReadColumnHeader();
 | 
			
		||||
 | 
			
		||||
		void ReadTables(int32_t& numberOfTables);
 | 
			
		||||
 | 
			
		||||
		std::string ReadColumns(int32_t& numberOfColumns);
 | 
			
		||||
 | 
			
		||||
		void ReadRowHeader(std::string& tableName);
 | 
			
		||||
 | 
			
		||||
		void ReadRows(int32_t& numberOfAllocatedRows, std::string& tableName);
 | 
			
		||||
 | 
			
		||||
		void ReadRow(int32_t& rowid, int32_t& position, std::string& tableName);
 | 
			
		||||
 | 
			
		||||
		void ReadRowInfo(std::string& tableName);
 | 
			
		||||
 | 
			
		||||
		void ReadRowValues(int32_t& numberOfColumns, std::string& tableName);
 | 
			
		||||
	private:
 | 
			
		||||
		static std::map<eSqliteDataType, std::string> sqliteType;
 | 
			
		||||
		std::string basePath{};
 | 
			
		||||
		std::ifstream fdb{};
 | 
			
		||||
	}; // class FdbToSqlite
 | 
			
		||||
}; //! namespace FdbToSqlite
 | 
			
		||||
 | 
			
		||||
#endif  //!__FDBTOSQLITE__H__
 | 
			
		||||
@@ -4,6 +4,8 @@
 | 
			
		||||
#include <cstdint>
 | 
			
		||||
#include <cassert>
 | 
			
		||||
#include <algorithm>
 | 
			
		||||
#include <filesystem>
 | 
			
		||||
#include <map>
 | 
			
		||||
 | 
			
		||||
template <typename T>
 | 
			
		||||
inline size_t MinSize(size_t size, const std::basic_string_view<T>& string) {
 | 
			
		||||
@@ -290,51 +292,30 @@ std::u16string GeneralUtils::ReadWString(RakNet::BitStream* inStream) {
 | 
			
		||||
	return string;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#ifdef _WIN32
 | 
			
		||||
#define WIN32_LEAN_AND_MEAN
 | 
			
		||||
#include <Windows.h>
 | 
			
		||||
 | 
			
		||||
std::vector<std::string> GeneralUtils::GetFileNamesFromFolder(const std::string& folder) {
 | 
			
		||||
	std::vector<std::string> names;
 | 
			
		||||
	std::string search_path = folder + "/*.*";
 | 
			
		||||
	WIN32_FIND_DATA fd;
 | 
			
		||||
	HANDLE hFind = ::FindFirstFile(search_path.c_str(), &fd);
 | 
			
		||||
	if (hFind != INVALID_HANDLE_VALUE) {
 | 
			
		||||
		do {
 | 
			
		||||
			if (!(fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
 | 
			
		||||
				names.push_back(fd.cFileName);
 | 
			
		||||
			}
 | 
			
		||||
		} while (::FindNextFile(hFind, &fd));
 | 
			
		||||
		::FindClose(hFind);
 | 
			
		||||
	}
 | 
			
		||||
	return names;
 | 
			
		||||
}
 | 
			
		||||
#else
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <dirent.h>
 | 
			
		||||
#include <sys/types.h>
 | 
			
		||||
#include <iostream>
 | 
			
		||||
#include <vector>
 | 
			
		||||
#include <cstring>
 | 
			
		||||
 | 
			
		||||
std::vector<std::string> GeneralUtils::GetFileNamesFromFolder(const std::string& folder) {
 | 
			
		||||
	std::vector<std::string> names;
 | 
			
		||||
	struct dirent* entry;
 | 
			
		||||
	DIR* dir = opendir(folder.c_str());
 | 
			
		||||
	if (dir == NULL) {
 | 
			
		||||
		return names;
 | 
			
		||||
std::vector<std::string> GeneralUtils::GetSqlFileNamesFromFolder(const std::string& folder) {
 | 
			
		||||
	// Because we dont know how large the initial number before the first _ is we need to make it a map like so.
 | 
			
		||||
    std::map<uint32_t, std::string> filenames{};
 | 
			
		||||
	for (auto& t : std::filesystem::directory_iterator(folder)) {
 | 
			
		||||
        auto filename = t.path().filename().string();
 | 
			
		||||
        auto index = std::stoi(GeneralUtils::SplitString(filename, '_').at(0));
 | 
			
		||||
        filenames.insert(std::make_pair(index, filename));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	while ((entry = readdir(dir)) != NULL) {
 | 
			
		||||
		std::string value(entry->d_name, strlen(entry->d_name));
 | 
			
		||||
		if (value == "." || value == "..") {
 | 
			
		||||
			continue;
 | 
			
		||||
	// Now sort the map by the oldest migration.
 | 
			
		||||
	std::vector<std::string> sortedFiles{};
 | 
			
		||||
    auto fileIterator = filenames.begin();
 | 
			
		||||
    std::map<uint32_t, std::string>::iterator oldest = filenames.begin();
 | 
			
		||||
    while (!filenames.empty()) {
 | 
			
		||||
		if (fileIterator == filenames.end()) {
 | 
			
		||||
            sortedFiles.push_back(oldest->second);
 | 
			
		||||
            filenames.erase(oldest);
 | 
			
		||||
            fileIterator = filenames.begin();
 | 
			
		||||
            oldest = filenames.begin();
 | 
			
		||||
            continue;
 | 
			
		||||
		}
 | 
			
		||||
		names.push_back(value);
 | 
			
		||||
        if (oldest->first > fileIterator->first) oldest = fileIterator;
 | 
			
		||||
        fileIterator++;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	closedir(dir);
 | 
			
		||||
 | 
			
		||||
	return names;
 | 
			
		||||
	return sortedFiles;
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 
 | 
			
		||||
@@ -12,6 +12,7 @@
 | 
			
		||||
#include <BitStream.h>
 | 
			
		||||
 | 
			
		||||
#include "Game.h"
 | 
			
		||||
#include "dLogger.h"
 | 
			
		||||
 | 
			
		||||
enum eInventoryType : uint32_t;
 | 
			
		||||
 | 
			
		||||
@@ -140,7 +141,7 @@ namespace GeneralUtils {
 | 
			
		||||
 | 
			
		||||
	std::vector<std::string> SplitString(const std::string& str, char delimiter);
 | 
			
		||||
 | 
			
		||||
	std::vector<std::string> GetFileNamesFromFolder(const std::string& folder);
 | 
			
		||||
	std::vector<std::string> GetSqlFileNamesFromFolder(const std::string& folder);
 | 
			
		||||
 | 
			
		||||
	template <typename T>
 | 
			
		||||
	T Parse(const char* value);
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										16
									
								
								dCommon/dEnums/eSqliteDataType.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								dCommon/dEnums/eSqliteDataType.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,16 @@
 | 
			
		||||
#ifndef __ESQLITEDATATYPE__H__
 | 
			
		||||
#define __ESQLITEDATATYPE__H__
 | 
			
		||||
 | 
			
		||||
#include <cstdint>
 | 
			
		||||
 | 
			
		||||
enum class eSqliteDataType : int32_t {
 | 
			
		||||
	NONE = 0,
 | 
			
		||||
	INT32,
 | 
			
		||||
	REAL = 3,
 | 
			
		||||
	TEXT_4,
 | 
			
		||||
	INT_BOOL,
 | 
			
		||||
	INT64,
 | 
			
		||||
	TEXT_8 = 8
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif  //!__ESQLITEDATATYPE__H__
 | 
			
		||||
@@ -38,7 +38,7 @@ void MigrationRunner::RunMigrations() {
 | 
			
		||||
 | 
			
		||||
	sql::SQLString finalSQL = "";
 | 
			
		||||
	bool runSd0Migrations = false;
 | 
			
		||||
	for (const auto& entry : GeneralUtils::GetFileNamesFromFolder((BinaryPathFinder::GetBinaryDir() / "./migrations/dlu/").string())) {
 | 
			
		||||
	for (const auto& entry : GeneralUtils::GetSqlFileNamesFromFolder((BinaryPathFinder::GetBinaryDir() / "./migrations/dlu/").string())) {
 | 
			
		||||
		auto migration = LoadMigration("dlu/" + entry);
 | 
			
		||||
 | 
			
		||||
		if (migration.data.empty()) {
 | 
			
		||||
@@ -102,7 +102,7 @@ void MigrationRunner::RunSQLiteMigrations() {
 | 
			
		||||
	stmt->execute();
 | 
			
		||||
	delete stmt;
 | 
			
		||||
 | 
			
		||||
	for (const auto& entry : GeneralUtils::GetFileNamesFromFolder((BinaryPathFinder::GetBinaryDir() / "migrations/cdserver/").string())) {
 | 
			
		||||
	for (const auto& entry : GeneralUtils::GetSqlFileNamesFromFolder((BinaryPathFinder::GetBinaryDir() / "migrations/cdserver/").string())) {
 | 
			
		||||
		auto migration = LoadMigration("cdserver/" + entry);
 | 
			
		||||
 | 
			
		||||
		if (migration.data.empty()) continue;
 | 
			
		||||
@@ -136,6 +136,7 @@ void MigrationRunner::RunSQLiteMigrations() {
 | 
			
		||||
		// Doing these 1 migration at a time since one takes a long time and some may think it is crashing.
 | 
			
		||||
		// This will at the least guarentee that the full migration needs to be run in order to be counted as "migrated".
 | 
			
		||||
		Game::logger->Log("MigrationRunner", "Executing migration: %s.  This may take a while.  Do not shut down server.", migration.name.c_str());
 | 
			
		||||
		CDClientDatabase::ExecuteQuery("BEGIN TRANSACTION;");
 | 
			
		||||
		for (const auto& dml : GeneralUtils::SplitString(migration.data, ';')) {
 | 
			
		||||
			if (dml.empty()) continue;
 | 
			
		||||
			try {
 | 
			
		||||
@@ -150,6 +151,7 @@ void MigrationRunner::RunSQLiteMigrations() {
 | 
			
		||||
		cdstmt.bind((int32_t) 1, migration.name.c_str());
 | 
			
		||||
		cdstmt.execQuery().finalize();
 | 
			
		||||
		cdstmt.finalize();
 | 
			
		||||
		CDClientDatabase::ExecuteQuery("COMMIT;");
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	Game::logger->Log("MigrationRunner", "CDServer database is up to date.");
 | 
			
		||||
 
 | 
			
		||||
@@ -1778,6 +1778,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
 | 
			
		||||
 | 
			
		||||
			scriptedActivityComponent->ReloadConfig();
 | 
			
		||||
		}
 | 
			
		||||
		Game::server->UpdateBandwidthLimit();
 | 
			
		||||
		ChatPackets::SendSystemMessage(sysAddr, u"Successfully reloaded config for world!");
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -40,6 +40,7 @@
 | 
			
		||||
#include "ObjectIDManager.h"
 | 
			
		||||
#include "PacketUtils.h"
 | 
			
		||||
#include "dMessageIdentifiers.h"
 | 
			
		||||
#include "FdbToSqlite.h"
 | 
			
		||||
 | 
			
		||||
namespace Game {
 | 
			
		||||
	dLogger* logger;
 | 
			
		||||
@@ -126,18 +127,9 @@ int main(int argc, char** argv) {
 | 
			
		||||
			return EXIT_FAILURE;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		Game::logger->Log("WorldServer", "Found cdclient.fdb.  Clearing cdserver migration_history then copying and converting to sqlite.");
 | 
			
		||||
		auto stmt = Database::CreatePreppedStmt(R"#(DELETE FROM migration_history WHERE name LIKE "%cdserver%";)#");
 | 
			
		||||
		stmt->executeUpdate();
 | 
			
		||||
		delete stmt;
 | 
			
		||||
		Game::logger->Log("WorldServer", "Found cdclient.fdb.  Converting to SQLite");
 | 
			
		||||
 | 
			
		||||
		std::string res = "python3 "
 | 
			
		||||
			+ (BinaryPathFinder::GetBinaryDir() / "../thirdparty/docker-utils/utils/fdb_to_sqlite.py").string()
 | 
			
		||||
			+ " --sqlite_path " + (Game::assetManager->GetResPath() / "CDServer.sqlite").string()
 | 
			
		||||
			+ " " + (Game::assetManager->GetResPath() / "cdclient.fdb").string();
 | 
			
		||||
 | 
			
		||||
		int result = system(res.c_str());
 | 
			
		||||
		if (result != 0) {
 | 
			
		||||
		if (FdbToSqlite::Convert(Game::assetManager->GetResPath().string()).ConvertDatabase() == false) {
 | 
			
		||||
			Game::logger->Log("MasterServer", "Failed to convert fdb to sqlite");
 | 
			
		||||
			return EXIT_FAILURE;
 | 
			
		||||
		}
 | 
			
		||||
@@ -224,7 +216,7 @@ int main(int argc, char** argv) {
 | 
			
		||||
	if (Game::config->GetValue("max_clients") != "") maxClients = std::stoi(Game::config->GetValue("max_clients"));
 | 
			
		||||
	if (Game::config->GetValue("port") != "") ourPort = std::stoi(Game::config->GetValue("port"));
 | 
			
		||||
 | 
			
		||||
	Game::server = new dServer(Game::config->GetValue("external_ip"), ourPort, 0, maxClients, true, false, Game::logger, "", 0, ServerType::Master);
 | 
			
		||||
	Game::server = new dServer(Game::config->GetValue("external_ip"), ourPort, 0, maxClients, true, false, Game::logger, "", 0, ServerType::Master, Game::config);
 | 
			
		||||
 | 
			
		||||
	//Query for the database for a server labeled "master"
 | 
			
		||||
	auto* masterLookupStatement = Database::CreatePreppedStmt("SELECT id FROM `servers` WHERE `name` = 'master'");
 | 
			
		||||
 
 | 
			
		||||
@@ -2,6 +2,7 @@
 | 
			
		||||
#include "dServer.h"
 | 
			
		||||
#include "dNetCommon.h"
 | 
			
		||||
#include "dLogger.h"
 | 
			
		||||
#include "dConfig.h"
 | 
			
		||||
 | 
			
		||||
#include "RakNetworkFactory.h"
 | 
			
		||||
#include "MessageIdentifiers.h"
 | 
			
		||||
@@ -35,7 +36,7 @@ public:
 | 
			
		||||
	}
 | 
			
		||||
} ReceiveDownloadCompleteCB;
 | 
			
		||||
 | 
			
		||||
dServer::dServer(const std::string& ip, int port, int instanceID, int maxConnections, bool isInternal, bool useEncryption, dLogger* logger, const std::string masterIP, int masterPort, ServerType serverType, unsigned int zoneID) {
 | 
			
		||||
dServer::dServer(const std::string& ip, int port, int instanceID, int maxConnections, bool isInternal, bool useEncryption, dLogger* logger, const std::string masterIP, int masterPort, ServerType serverType, dConfig* config, unsigned int zoneID) {
 | 
			
		||||
	mIP = ip;
 | 
			
		||||
	mPort = port;
 | 
			
		||||
	mZoneID = zoneID;
 | 
			
		||||
@@ -50,6 +51,7 @@ dServer::dServer(const std::string& ip, int port, int instanceID, int maxConnect
 | 
			
		||||
	mNetIDManager = nullptr;
 | 
			
		||||
	mReplicaManager = nullptr;
 | 
			
		||||
	mServerType = serverType;
 | 
			
		||||
	mConfig = config;
 | 
			
		||||
	//Attempt to start our server here:
 | 
			
		||||
	mIsOkay = Startup();
 | 
			
		||||
 | 
			
		||||
@@ -181,7 +183,7 @@ bool dServer::Startup() {
 | 
			
		||||
	if (mIsInternal) {
 | 
			
		||||
		mPeer->SetIncomingPassword("3.25 DARKFLAME1", 15);
 | 
			
		||||
	} else {
 | 
			
		||||
		//mPeer->SetPerConnectionOutgoingBandwidthLimit(800000); //100Kb/s
 | 
			
		||||
		UpdateBandwidthLimit();
 | 
			
		||||
		mPeer->SetIncomingPassword("3.25 ND1", 8);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@@ -191,6 +193,11 @@ bool dServer::Startup() {
 | 
			
		||||
	return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void dServer::UpdateBandwidthLimit() {
 | 
			
		||||
	auto newBandwidth = mConfig->GetValue("maximum_outgoing_bandwidth");
 | 
			
		||||
	mPeer->SetPerConnectionOutgoingBandwidthLimit(!newBandwidth.empty() ? std::stoi(newBandwidth) : 0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void dServer::Shutdown() {
 | 
			
		||||
	if (mPeer) {
 | 
			
		||||
		mPeer->Shutdown(1000);
 | 
			
		||||
 
 | 
			
		||||
@@ -5,6 +5,7 @@
 | 
			
		||||
#include "NetworkIDManager.h"
 | 
			
		||||
 | 
			
		||||
class dLogger;
 | 
			
		||||
class dConfig;
 | 
			
		||||
 | 
			
		||||
enum class ServerType : uint32_t {
 | 
			
		||||
	Master,
 | 
			
		||||
@@ -17,7 +18,7 @@ class dServer {
 | 
			
		||||
public:
 | 
			
		||||
	// Default constructor should only used for testing!
 | 
			
		||||
	dServer() {};
 | 
			
		||||
	dServer(const std::string& ip, int port, int instanceID, int maxConnections, bool isInternal, bool useEncryption, dLogger* logger, const std::string masterIP, int masterPort, ServerType serverType, unsigned int zoneID = 0);
 | 
			
		||||
	dServer(const std::string& ip, int port, int instanceID, int maxConnections, bool isInternal, bool useEncryption, dLogger* logger, const std::string masterIP, int masterPort, ServerType serverType, dConfig* config, unsigned int zoneID = 0);
 | 
			
		||||
	~dServer();
 | 
			
		||||
 | 
			
		||||
	Packet* ReceiveFromMaster();
 | 
			
		||||
@@ -42,6 +43,7 @@ public:
 | 
			
		||||
	const int GetInstanceID() const { return mInstanceID; }
 | 
			
		||||
	ReplicaManager* GetReplicaManager() { return mReplicaManager; }
 | 
			
		||||
	void UpdateReplica();
 | 
			
		||||
	void UpdateBandwidthLimit();
 | 
			
		||||
 | 
			
		||||
	int GetPing(const SystemAddress& sysAddr) const;
 | 
			
		||||
	int GetLatestPing(const SystemAddress& sysAddr) const;
 | 
			
		||||
@@ -58,6 +60,7 @@ private:
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
	dLogger* mLogger = nullptr;
 | 
			
		||||
	dConfig* mConfig = nullptr;
 | 
			
		||||
	RakPeerInterface* mPeer = nullptr;
 | 
			
		||||
	ReplicaManager* mReplicaManager = nullptr;
 | 
			
		||||
	NetworkIDManager* mNetIDManager = nullptr;
 | 
			
		||||
 
 | 
			
		||||
@@ -208,7 +208,7 @@ int main(int argc, char** argv) {
 | 
			
		||||
	LootGenerator::Instance();
 | 
			
		||||
	Game::chatFilter = new dChatFilter(Game::assetManager->GetResPath().string() + "/chatplus_en_us", bool(std::stoi(config.GetValue("dont_generate_dcf"))));
 | 
			
		||||
 | 
			
		||||
	Game::server = new dServer(masterIP, ourPort, instanceID, maxClients, false, true, Game::logger, masterIP, masterPort, ServerType::World, zoneID);
 | 
			
		||||
	Game::server = new dServer(masterIP, ourPort, instanceID, maxClients, false, true, Game::logger, masterIP, masterPort, ServerType::World, Game::config, zoneID);
 | 
			
		||||
 | 
			
		||||
	//Connect to the chat server:
 | 
			
		||||
	int chatPort = 1501;
 | 
			
		||||
 
 | 
			
		||||
@@ -25,3 +25,6 @@ dump_folder=
 | 
			
		||||
# The location of the client
 | 
			
		||||
# Either the folder with /res or with /client and /versions
 | 
			
		||||
client_location=
 | 
			
		||||
 | 
			
		||||
# The maximum outgoing bandwidth in bits
 | 
			
		||||
maximum_outgoing_bandwidth=80000
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user