diff --git a/CMakeLists.txt b/CMakeLists.txt
index 865603b34..9e7d6c57c 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1834,11 +1834,14 @@ set_src(ANTIBOT_SRC GLOB src/antibot
antibot_null.cpp
)
-set_src(ENGINE_SERVER GLOB src/engine/server
+set_src(ENGINE_SERVER GLOB_RECURSE src/engine/server
antibot.cpp
antibot.h
authmanager.cpp
authmanager.h
+ databases/connection.h
+ databases/mysql.cpp
+ databases/mysql.h
name_ban.cpp
name_ban.h
register.cpp
diff --git a/src/engine/server/databases/connection.h b/src/engine/server/databases/connection.h
new file mode 100644
index 000000000..8a5d990b2
--- /dev/null
+++ b/src/engine/server/databases/connection.h
@@ -0,0 +1,58 @@
+#ifndef ENGINE_SERVER_DATABASES_CONNECTION_H
+#define ENGINE_SERVER_DATABASES_CONNECTION_H
+
+#include
+
+// can hold one PreparedStatement with Results
+class IDbConnection
+{
+public:
+ IDbConnection(const char *pPrefix)
+ {
+ str_copy(m_aPrefix, pPrefix, sizeof(m_aPrefix));
+ }
+ virtual ~IDbConnection() {}
+
+ // copies the credentials, not the active connection
+ virtual IDbConnection *Copy() = 0;
+
+ // returns the database prefix
+ const char *GetPrefix() { return m_aPrefix; }
+
+ enum Status
+ {
+ IN_USE,
+ SUCCESS,
+ ERROR,
+ };
+ // returns true if connection was established
+ virtual Status Connect() = 0;
+ virtual void Disconnect() = 0;
+
+ // get exclusive read/write access to the database
+ virtual void Lock() = 0;
+ virtual void Unlock() = 0;
+
+ // ? for Placeholders, connection has to be established, can overwrite previous prepared statements
+ virtual void PrepareStatement(const char *pStmt) = 0;
+
+ // PrepareStatement has to be called beforehand,
+ virtual void BindString(int Idx, const char *pString) = 0;
+ virtual void BindInt(int Idx, int Value) = 0;
+
+ virtual void Execute() = 0;
+
+ // if true if another result row exists and selects it
+ virtual bool Step() = 0;
+
+ virtual int GetInt(int Col) const = 0;
+ // ensures that the string is null terminated
+ virtual void GetString(int Col, char *pBuffer, int BufferSize) const = 0;
+ // returns number of bytes read into the buffer
+ virtual int GetBlob(int Col, unsigned char *pBuffer, int BufferSize) const = 0;
+
+protected:
+ char m_aPrefix[64];
+};
+
+#endif // ENGINE_SERVER_DATABASES_CONNECTION_H
diff --git a/src/engine/server/databases/mysql.cpp b/src/engine/server/databases/mysql.cpp
new file mode 100644
index 000000000..cebce7127
--- /dev/null
+++ b/src/engine/server/databases/mysql.cpp
@@ -0,0 +1,88 @@
+#include "mysql.h"
+
+#include
+
+CMysqlConnection::CMysqlConnection(
+ const char *pDatabase,
+ const char *pPrefix,
+ const char *pUser,
+ const char *pPass,
+ const char *pIp,
+ int Port,
+ bool Setup) :
+ IDbConnection(pPrefix),
+ m_pDriver(nullptr),
+ m_Port(Port),
+ m_Setup(Setup),
+ m_InUse(false)
+{
+ str_copy(m_aDatabase, pDatabase, sizeof(m_aDatabase));
+ str_copy(m_aUser, pUser, sizeof(m_aUser));
+ str_copy(m_aPass, pPass, sizeof(m_aPass));
+ str_copy(m_aIp, pIp, sizeof(m_aIp));
+}
+
+CMysqlConnection::~CMysqlConnection()
+{
+}
+
+CMysqlConnection *CMysqlConnection::Copy()
+{
+ return new CMysqlConnection(m_aDatabase, m_aPrefix, m_aUser, m_aPass, m_aIp, m_Port, m_Setup);
+}
+
+IDbConnection::Status CMysqlConnection::Connect()
+{
+ if(m_InUse.exchange(true))
+ return Status::IN_USE;
+
+ return Status::ERROR;
+}
+
+void CMysqlConnection::Disconnect()
+{
+ m_InUse.store(false);
+}
+
+void CMysqlConnection::Lock()
+{
+}
+
+void CMysqlConnection::Unlock()
+{
+}
+
+void CMysqlConnection::PrepareStatement(const char *pStmt)
+{
+}
+
+void CMysqlConnection::BindString(int Idx, const char *pString)
+{
+}
+
+void CMysqlConnection::BindInt(int Idx, int Value)
+{
+}
+
+void CMysqlConnection::Execute()
+{
+}
+
+bool CMysqlConnection::Step()
+{
+ return false;
+}
+
+int CMysqlConnection::GetInt(int Col) const
+{
+ return 0;
+}
+
+void CMysqlConnection::GetString(int Col, char *pBuffer, int BufferSize) const
+{
+}
+
+int CMysqlConnection::GetBlob(int Col, unsigned char *pBuffer, int BufferSize) const
+{
+ return 0;
+}
diff --git a/src/engine/server/databases/mysql.h b/src/engine/server/databases/mysql.h
new file mode 100644
index 000000000..f9885569b
--- /dev/null
+++ b/src/engine/server/databases/mysql.h
@@ -0,0 +1,67 @@
+#ifndef ENGINE_SERVER_DATABASES_MYSQL_H
+#define ENGINE_SERVER_DATABASES_MYSQL_H
+
+#include "connection.h"
+#include
+#include
+
+#include
+#include
+#include
+
+namespace sql {
+class Driver;
+} /* namespace sql */
+
+class CMysqlConnection : public IDbConnection
+{
+public:
+ CMysqlConnection(
+ const char *pDatabase,
+ const char *pPrefix,
+ const char *pUser,
+ const char *pPass,
+ const char *pIp,
+ int Port,
+ bool Setup);
+ virtual ~CMysqlConnection();
+
+ virtual CMysqlConnection *Copy();
+
+ virtual Status Connect();
+ virtual void Disconnect();
+
+ virtual void Lock();
+ virtual void Unlock();
+
+ virtual void PrepareStatement(const char *pStmt);
+
+ virtual void BindString(int Idx, const char *pString);
+ virtual void BindInt(int Idx, int Value);
+
+ virtual void Execute();
+
+ virtual bool Step();
+
+ virtual int GetInt(int Col) const;
+ virtual void GetString(int Col, char *pBuffer, int BufferSize) const;
+ virtual int GetBlob(int Col, unsigned char *pBuffer, int BufferSize) const;
+
+private:
+ std::unique_ptr m_pConnection;
+ sql::Driver *m_pDriver;
+ std::unique_ptr m_pPreparedStmt;
+ std::unique_ptr m_pResults;
+
+ // copy of config vars
+ char m_aDatabase[64];
+ char m_aUser[64];
+ char m_aPass[64];
+ char m_aIp[64];
+ int m_Port;
+ bool m_Setup;
+
+ std::atomic_bool m_InUse;
+};
+
+#endif // ENGINE_SERVER_DATABASES_MYSQL_H