Merge branch 'main' into cdclient-rework

This commit is contained in:
Wincent Holm
2022-07-18 16:44:53 +02:00
73 changed files with 1959 additions and 903 deletions

13
dDatabase/CMakeLists.txt Normal file
View File

@@ -0,0 +1,13 @@
set(DDATABASE_SOURCES "CDClientDatabase.cpp"
"CDClientManager.cpp"
"Database.cpp"
"MigrationRunner.cpp")
add_subdirectory(Tables)
foreach(file ${DDATABASE_TABLES_SOURCES})
set(DDATABASE_SOURCES ${DDATABASE_SOURCES} "Tables/${file}")
endforeach()
add_library(dDatabase STATIC ${DDATABASE_SOURCES})
target_link_libraries(dDatabase sqlite3 mariadbConnCpp)

View File

@@ -8,6 +8,8 @@ using namespace std;
sql::Driver * Database::driver;
sql::Connection * Database::con;
sql::Properties Database::props;
std::string Database::database;
void Database::Connect(const string& host, const string& database, const string& username, const string& password) {
@@ -25,14 +27,26 @@ void Database::Connect(const string& host, const string& database, const string&
properties["user"] = szUsername;
properties["password"] = szPassword;
properties["autoReconnect"] = "true";
con = driver->connect(properties);
con->setSchema(szDatabase);
} //Connect
void Database::Destroy(std::string source) {
Database::props = properties;
Database::database = database;
Database::Connect();
}
void Database::Connect() {
con = driver->connect(Database::props);
con->setSchema(Database::database);
}
void Database::Destroy(std::string source, bool log) {
if (!con) return;
if (source != "") Game::logger->Log("Database", "Destroying MySQL connection from %s!\n", source.c_str());
else Game::logger->Log("Database", "Destroying MySQL connection!\n");
if (log) {
if (source != "") Game::logger->Log("Database", "Destroying MySQL connection from %s!\n", source.c_str());
else Game::logger->Log("Database", "Destroying MySQL connection!\n");
}
con->close();
delete con;
} //Destroy
@@ -48,13 +62,7 @@ sql::PreparedStatement* Database::CreatePreppedStmt(const std::string& query) {
sql::SQLString str(test, size);
if (!con) {
//Connect to the MySQL Database
std::string mysql_host = Game::config->GetValue("mysql_host");
std::string mysql_database = Game::config->GetValue("mysql_database");
std::string mysql_username = Game::config->GetValue("mysql_username");
std::string mysql_password = Game::config->GetValue("mysql_password");
Connect(mysql_host, mysql_database, mysql_username, mysql_password);
Connect();
Game::logger->Log("Database", "Trying to reconnect to MySQL\n");
}
@@ -64,13 +72,7 @@ sql::PreparedStatement* Database::CreatePreppedStmt(const std::string& query) {
con = nullptr;
//Connect to the MySQL Database
std::string mysql_host = Game::config->GetValue("mysql_host");
std::string mysql_database = Game::config->GetValue("mysql_database");
std::string mysql_username = Game::config->GetValue("mysql_username");
std::string mysql_password = Game::config->GetValue("mysql_password");
Connect(mysql_host, mysql_database, mysql_username, mysql_password);
Connect();
Game::logger->Log("Database", "Trying to reconnect to MySQL from invalid or closed connection\n");
}
@@ -79,3 +81,6 @@ sql::PreparedStatement* Database::CreatePreppedStmt(const std::string& query) {
return stmt;
} //CreatePreppedStmt
void Database::Commit() {
Database::con->commit();
}

View File

@@ -13,10 +13,17 @@ class Database {
private:
static sql::Driver *driver;
static sql::Connection *con;
static sql::Properties props;
static std::string database;
public:
static void Connect(const std::string& host, const std::string& database, const std::string& username, const std::string& password);
static void Destroy(std::string source="");
static void Connect();
static void Destroy(std::string source = "", bool log = true);
static sql::Statement* CreateStmt();
static sql::PreparedStatement* CreatePreppedStmt(const std::string& query);
static void Commit();
static std::string GetDatabase() { return database; }
static sql::Properties GetProperties() { return props; }
};

View File

@@ -0,0 +1,78 @@
#include "MigrationRunner.h"
#include "GeneralUtils.h"
#include <fstream>
#include <algorithm>
#include <thread>
void MigrationRunner::RunMigrations() {
auto stmt = Database::CreatePreppedStmt("CREATE TABLE IF NOT EXISTS migration_history (name TEXT NOT NULL, date TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP());");
stmt->executeQuery();
delete stmt;
sql::SQLString finalSQL = "";
Migration checkMigration{};
for (const auto& entry : GeneralUtils::GetFileNamesFromFolder("./migrations/")) {
auto migration = LoadMigration(entry);
if (migration.data.empty()) {
continue;
}
checkMigration = migration;
stmt = Database::CreatePreppedStmt("SELECT name FROM migration_history WHERE name = ?;");
stmt->setString(1, migration.name);
auto res = stmt->executeQuery();
bool doExit = res->next();
delete res;
delete stmt;
if (doExit) continue;
Game::logger->Log("MigrationRunner", "Running migration: " + migration.name + "\n");
finalSQL.append(migration.data);
finalSQL.append('\n');
stmt = Database::CreatePreppedStmt("INSERT INTO migration_history (name) VALUES (?);");
stmt->setString(1, entry);
stmt->execute();
delete stmt;
}
if (!finalSQL.empty()) {
try {
auto simpleStatement = Database::CreateStmt();
simpleStatement->execute(finalSQL);
delete simpleStatement;
}
catch (sql::SQLException e) {
Game::logger->Log("MigrationRunner", std::string("Encountered error running migration: ") + e.what() + "\n");
}
}
}
Migration MigrationRunner::LoadMigration(std::string path) {
Migration migration{};
std::ifstream file("./migrations/" + path);
if (file.is_open()) {
std::hash<std::string> hash;
std::string line;
std::string total = "";
while (std::getline(file, line)) {
total += line;
}
file.close();
migration.name = path;
migration.data = total;
}
return migration;
}

View File

@@ -0,0 +1,19 @@
#pragma once
#include "Database.h"
#include "dCommonVars.h"
#include "Game.h"
#include "dCommonVars.h"
#include "dLogger.h"
struct Migration {
std::string data;
std::string name;
};
class MigrationRunner {
public:
static void RunMigrations();
static Migration LoadMigration(std::string path);
};

View File

@@ -24,7 +24,13 @@ CDBehaviorTemplateTable::CDBehaviorTemplateTable(void) {
entry.behaviorID = tableData.getIntField(0, -1);
entry.templateID = tableData.getIntField(1, -1);
entry.effectID = tableData.getIntField(2, -1);
entry.effectHandle = tableData.getStringField(3, "");
auto candidateToAdd = tableData.getStringField(3, "");
auto parameter = m_EffectHandles.find(candidateToAdd);
if (parameter != m_EffectHandles.end()) {
entry.effectHandle = parameter;
} else {
entry.effectHandle = m_EffectHandles.insert(candidateToAdd).first;
}
this->entries.push_back(entry);
this->entriesMappedByBehaviorID.insert(std::make_pair(entry.behaviorID, entry));
@@ -62,7 +68,8 @@ const CDBehaviorTemplate CDBehaviorTemplateTable::GetByBehaviorID(uint32_t behav
if (entry == this->entriesMappedByBehaviorID.end()) {
CDBehaviorTemplate entryToReturn;
entryToReturn.behaviorID = 0;
entryToReturn.effectHandle = "";
entryToReturn.effectHandle = m_EffectHandles.end();
entryToReturn.effectID = 0;
return entryToReturn;
} else {
return entry->second;

View File

@@ -3,6 +3,7 @@
// Custom Classes
#include "CDTable.h"
#include <unordered_map>
#include <unordered_set>
/*!
\file CDBehaviorTemplateTable.hpp
@@ -11,10 +12,10 @@
//! BehaviorTemplate Entry Struct
struct CDBehaviorTemplate {
unsigned int behaviorID; //!< The Behavior ID
unsigned int templateID; //!< The Template ID (LOT)
unsigned int effectID; //!< The Effect ID attached
std::string effectHandle; //!< The effect handle
unsigned int behaviorID; //!< The Behavior ID
unsigned int templateID; //!< The Template ID (LOT)
unsigned int effectID; //!< The Effect ID attached
std::unordered_set<std::string>::iterator effectHandle; //!< The effect handle
};
@@ -23,6 +24,7 @@ class CDBehaviorTemplateTable : public CDTable {
private:
std::vector<CDBehaviorTemplate> entries;
std::unordered_map<uint32_t, CDBehaviorTemplate> entriesMappedByBehaviorID;
std::unordered_set<std::string> m_EffectHandles;
public:
//! Constructor

View File

@@ -0,0 +1,38 @@
set(DDATABASE_TABLES_SOURCES "CDActivitiesTable.cpp"
"CDActivityRewardsTable.cpp"
"CDAnimationsTable.cpp"
"CDBehaviorParameterTable.cpp"
"CDBehaviorTemplateTable.cpp"
"CDBrickIDTableTable.cpp"
"CDComponentsRegistryTable.cpp"
"CDCurrencyTableTable.cpp"
"CDDestructibleComponentTable.cpp"
"CDEmoteTable.cpp"
"CDFeatureGatingTable.cpp"
"CDInventoryComponentTable.cpp"
"CDItemComponentTable.cpp"
"CDItemSetSkillsTable.cpp"
"CDItemSetsTable.cpp"
"CDLevelProgressionLookupTable.cpp"
"CDLootMatrixTable.cpp"
"CDLootTableTable.cpp"
"CDMissionEmailTable.cpp"
"CDMissionNPCComponentTable.cpp"
"CDMissionsTable.cpp"
"CDMissionTasksTable.cpp"
"CDMovementAIComponentTable.cpp"
"CDObjectSkillsTable.cpp"
"CDObjectsTable.cpp"
"CDPackageComponentTable.cpp"
"CDPhysicsComponentTable.cpp"
"CDPropertyEntranceComponentTable.cpp"
"CDPropertyTemplateTable.cpp"
"CDProximityMonitorComponentTable.cpp"
"CDRailActivatorComponent.cpp"
"CDRarityTableTable.cpp"
"CDRebuildComponentTable.cpp"
"CDRewardsTable.cpp"
"CDScriptComponentTable.cpp"
"CDSkillBehaviorTable.cpp"
"CDVendorComponentTable.cpp"
"CDZoneTableTable.cpp" PARENT_SCOPE)