mirror of
https://github.com/ddnet/ddnet.git
synced 2024-11-10 10:08:18 +00:00
mastersqlservers are working now
TODO: move the sqlserver objects somewhere else so they wont be destroyed on every reload
This commit is contained in:
parent
5e4456584f
commit
6ba10d2719
|
@ -227,6 +227,8 @@ MACRO_CONFIG_STR(SvSqlServerName, sv_sql_servername, 5, "UNK", CFGFLAG_SERVER, "
|
|||
MACRO_CONFIG_STR(SvSqlPrefix, sv_sql_prefix, 16, "record", CFGFLAG_SERVER, "SQL Database table prefix")
|
||||
MACRO_CONFIG_INT(SvSaveGames, sv_savegames, 1, 0, 1, CFGFLAG_SERVER, "Enables savegames (/save and /load)")
|
||||
MACRO_CONFIG_INT(SvSaveGamesDelay, sv_savegames_delay, 60, 0, 10000, CFGFLAG_SERVER, "Delay in seconds for loading a savegame")
|
||||
|
||||
MACRO_CONFIG_INT(SvUseSQLMasters, sv_use_sqlmasters, 0, 0, 1, CFGFLAG_SERVER, "Redirects all writes to the specified masterservers")
|
||||
#endif
|
||||
|
||||
MACRO_CONFIG_INT(SvDDRaceRules, sv_ddrace_rules, 1, 0, 1, CFGFLAG_SERVER, "Whether the default mod rules are displayed or not")
|
||||
|
|
|
@ -30,6 +30,9 @@ CSqlScore::CSqlScore(CGameContext *pGameServer) : m_pGameServer(pGameServer),
|
|||
str_copy(m_aMap, g_Config.m_SvMap, sizeof(m_aMap));
|
||||
ClearString(m_aMap);
|
||||
|
||||
for (int i = 0; i < MAX_SQLMASTERS; i++)
|
||||
m_apMasterSqlServers[i] = 0;
|
||||
|
||||
CSqlData::ms_pGameServer = m_pGameServer;
|
||||
CSqlData::ms_pServer = m_pServer;
|
||||
CSqlData::ms_pPlayerData = PlayerData(0);
|
||||
|
@ -37,6 +40,9 @@ CSqlScore::CSqlScore(CGameContext *pGameServer) : m_pGameServer(pGameServer),
|
|||
CSqlData::ms_pSqlServer = &m_SqlServer;
|
||||
CSqlData::ms_pMasterSqlServers = m_apMasterSqlServers;
|
||||
|
||||
GameServer()->Console()->Register("add_sqlmaster", "sssssi", CFGFLAG_SERVER, ConAddSqlMaster, this, "add a sqlmasterserver <Database> <Prefix> <User> <Password> <IP> <Port>");
|
||||
GameServer()->Console()->Register("dump_sqlmaster", "", CFGFLAG_SERVER, ConDumpSqlMaster, this, "dumps all sqlmasterservers");
|
||||
|
||||
if(gs_SqlLock == 0)
|
||||
gs_SqlLock = lock_create();
|
||||
|
||||
|
@ -47,6 +53,50 @@ CSqlScore::~CSqlScore()
|
|||
{
|
||||
lock_wait(gs_SqlLock);
|
||||
lock_unlock(gs_SqlLock);
|
||||
for (int i = 0; i < MAX_SQLMASTERS; i++)
|
||||
if (m_apMasterSqlServers[i])
|
||||
delete m_apMasterSqlServers[i];
|
||||
}
|
||||
|
||||
void CSqlScore::ConAddSqlMaster(IConsole::IResult *pResult, void *pUserData)
|
||||
{
|
||||
CSqlScore *pSelf = (CSqlScore *)pUserData;
|
||||
|
||||
if (pResult->NumArguments() != 6)
|
||||
{
|
||||
pSelf->GameServer()->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "server", "6 arguments are required");
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = 0; i < MAX_SQLMASTERS; i++)
|
||||
{
|
||||
if (!pSelf->m_apMasterSqlServers[i])
|
||||
pSelf->m_apMasterSqlServers[i] = new CSqlServer(pResult->GetString(0), pResult->GetString(1), pResult->GetString(2), pResult->GetString(3), pResult->GetString(4), pResult->GetInteger(5));
|
||||
|
||||
if(g_Config.m_SvSqlCreateTables)
|
||||
{
|
||||
pSelf->m_apMasterSqlServers[i]->Connect();
|
||||
pSelf->m_apMasterSqlServers[i]->CreateTables();
|
||||
pSelf->m_apMasterSqlServers[i]->Disconnect();
|
||||
}
|
||||
|
||||
pSelf->GameServer()->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "server", "Added new sqlmasterserver");
|
||||
return;
|
||||
}
|
||||
pSelf->GameServer()->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "server", "failed to add new sqlmaster: limit of sqlmasters reached");
|
||||
}
|
||||
|
||||
void CSqlScore::ConDumpSqlMaster(IConsole::IResult *pResult, void *pUserData)
|
||||
{
|
||||
CSqlScore *pSelf = (CSqlScore *)pUserData;
|
||||
|
||||
for (int i = 0; i < MAX_SQLMASTERS; i++)
|
||||
if (pSelf->m_apMasterSqlServers[i])
|
||||
{
|
||||
char aBuf[512];
|
||||
str_format(aBuf, sizeof(aBuf), "SQL-Master %d: DB: '%s' Prefix: '%s' User: '%s' Pass: '%s' IP: '%s' Port: %d", i, pSelf->m_apMasterSqlServers[i]->GetDatabase(), pSelf->m_apMasterSqlServers[i]->GetPrefix(), pSelf->m_apMasterSqlServers[i]->GetUser(), pSelf->m_apMasterSqlServers[i]->GetPass(), pSelf->m_apMasterSqlServers[i]->GetIP(), pSelf->m_apMasterSqlServers[i]->GetPort());
|
||||
pSelf->GameServer()->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "server", aBuf);
|
||||
}
|
||||
}
|
||||
|
||||
// create tables... should be done only once
|
||||
|
@ -161,7 +211,9 @@ void CSqlScore::SaveTeamScoreThread(void *pUser)
|
|||
CSqlTeamScoreData *pData = (CSqlTeamScoreData *)pUser;
|
||||
|
||||
// Connect to database
|
||||
if(pData->SqlServer()->Connect())
|
||||
pData->ConnectSqlServer(g_Config.m_SvUseSQLMasters);
|
||||
|
||||
if(pData->SqlServer())
|
||||
{
|
||||
try
|
||||
{
|
||||
|
@ -269,6 +321,10 @@ void CSqlScore::SaveTeamScoreThread(void *pUser)
|
|||
// disconnect from database
|
||||
pData->SqlServer()->Disconnect();
|
||||
}
|
||||
else
|
||||
{
|
||||
dbg_msg("SQL", "ERROR: Could not connect to SQL-Server");
|
||||
}
|
||||
|
||||
delete pData;
|
||||
|
||||
|
@ -478,7 +534,9 @@ void CSqlScore::SaveScoreThread(void *pUser)
|
|||
CSqlScoreData *pData = (CSqlScoreData *)pUser;
|
||||
|
||||
// Connect to database
|
||||
if(pData->SqlServer()->Connect())
|
||||
pData->ConnectSqlServer(g_Config.m_SvUseSQLMasters);
|
||||
|
||||
if(pData->SqlServer())
|
||||
{
|
||||
try
|
||||
{
|
||||
|
@ -527,6 +585,11 @@ void CSqlScore::SaveScoreThread(void *pUser)
|
|||
// disconnect from database
|
||||
pData->SqlServer()->Disconnect();
|
||||
}
|
||||
else
|
||||
{
|
||||
dbg_msg("SQL", "ERROR: Could not connect to SQL-Server");
|
||||
pData->GameServer()->SendChatTarget(pData->m_ClientID, "ERROR: Could NOT connect to SQL-server, this rank is lost.");
|
||||
}
|
||||
|
||||
delete pData;
|
||||
|
||||
|
|
|
@ -4,7 +4,9 @@
|
|||
#ifndef GAME_SERVER_SQLSCORE_H
|
||||
#define GAME_SERVER_SQLSCORE_H
|
||||
|
||||
#include "sqlserver.h"
|
||||
#include <engine/console.h>
|
||||
|
||||
#include "sql_server.h"
|
||||
#include "../score.h"
|
||||
|
||||
enum
|
||||
|
@ -45,6 +47,10 @@ class CSqlScore: public IScore
|
|||
static void SaveTeamThread(void *pUser);
|
||||
static void LoadTeamThread(void *pUser);
|
||||
|
||||
// console commands for sqlmasters
|
||||
static void ConAddSqlMaster(IConsole::IResult *pResult, void *pUserData);
|
||||
static void ConDumpSqlMaster(IConsole::IResult *pResult, void *pUserData);
|
||||
|
||||
public:
|
||||
|
||||
CSqlScore(CGameContext *pGameServer);
|
||||
|
@ -82,8 +88,27 @@ struct CSqlData
|
|||
IServer* Server() { return ms_pServer; }
|
||||
CPlayerData* PlayerData(int ID) { return &ms_pPlayerData[ID]; }
|
||||
const char* MapName() { return ms_pMap; }
|
||||
CSqlServer* SqlMasterServer(int i) { return ms_pMasterSqlServers[i]; }
|
||||
CSqlServer* SqlServer() { return m_pSqlServer; }
|
||||
|
||||
void ConnectSqlServer(bool useMasters = false)
|
||||
{
|
||||
if (useMasters)
|
||||
{
|
||||
m_pSqlServer = 0;
|
||||
for (int i = 0; i < MAX_SQLMASTERS; i++)
|
||||
{
|
||||
if (SqlMasterServer(i) && SqlMasterServer(i)->Connect())
|
||||
{
|
||||
m_pSqlServer = SqlMasterServer(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (!SqlServer()->Connect())
|
||||
m_pSqlServer = 0;
|
||||
}
|
||||
|
||||
static CGameContext *ms_pGameServer;
|
||||
static IServer *ms_pServer;
|
||||
static CPlayerData *ms_pPlayerData;
|
||||
|
|
|
@ -8,13 +8,14 @@
|
|||
|
||||
|
||||
CSqlServer::CSqlServer(const char* pDatabase, const char* pPrefix, const char* pUser, const char* pPass, const char* pIp, int Port) :
|
||||
m_pDatabase(pDatabase),
|
||||
m_pPrefix(pPrefix),
|
||||
m_pUser(pUser),
|
||||
m_pPass(pPass),
|
||||
m_pIp(pIp),
|
||||
m_Port(Port)
|
||||
{
|
||||
str_copy(m_aDatabase, pDatabase, sizeof(m_aDatabase));
|
||||
str_copy(m_aPrefix, pPrefix, sizeof(m_aPrefix));
|
||||
str_copy(m_aUser, pUser, sizeof(m_aUser));
|
||||
str_copy(m_aPass, pPass, sizeof(m_aPass));
|
||||
str_copy(m_aIp, pIp, sizeof(m_aIp));
|
||||
|
||||
m_pDriver = 0;
|
||||
m_pConnection = 0;
|
||||
m_pResults = 0;
|
||||
|
@ -44,7 +45,7 @@ bool CSqlServer::Connect()
|
|||
try
|
||||
{
|
||||
// Connect to specific database
|
||||
m_pConnection->setSchema(m_pDatabase);
|
||||
m_pConnection->setSchema(m_aDatabase);
|
||||
}
|
||||
catch (sql::SQLException &e)
|
||||
{
|
||||
|
@ -65,10 +66,10 @@ bool CSqlServer::Connect()
|
|||
m_pStatement = 0;
|
||||
|
||||
sql::ConnectOptionsMap connection_properties;
|
||||
connection_properties["hostName"] = sql::SQLString(m_pIp);
|
||||
connection_properties["hostName"] = sql::SQLString(m_aIp);
|
||||
connection_properties["port"] = m_Port;
|
||||
connection_properties["userName"] = sql::SQLString(m_pUser);
|
||||
connection_properties["password"] = sql::SQLString(m_pPass);
|
||||
connection_properties["userName"] = sql::SQLString(m_aUser);
|
||||
connection_properties["password"] = sql::SQLString(m_aPass);
|
||||
connection_properties["OPT_RECONNECT"] = true;
|
||||
|
||||
// Create connection
|
||||
|
@ -78,8 +79,16 @@ bool CSqlServer::Connect()
|
|||
// Create Statement
|
||||
m_pStatement = m_pConnection->createStatement();
|
||||
|
||||
if (g_Config.m_SvSqlCreateTables)
|
||||
{
|
||||
char aBuf[256];
|
||||
// create database
|
||||
str_format(aBuf, sizeof(aBuf), "CREATE DATABASE IF NOT EXISTS %s", m_aDatabase);
|
||||
m_pStatement->execute(aBuf);
|
||||
}
|
||||
|
||||
// Connect to specific database
|
||||
m_pConnection->setSchema(m_pDatabase);
|
||||
m_pConnection->setSchema(m_aDatabase);
|
||||
dbg_msg("SQL", "SQL connection established");
|
||||
return true;
|
||||
}
|
||||
|
@ -142,24 +151,20 @@ void CSqlServer::CreateTables()
|
|||
{
|
||||
char aBuf[1024];
|
||||
|
||||
// create database
|
||||
str_format(aBuf, sizeof(aBuf), "CREATE DATABASE IF NOT EXISTS %s", m_pDatabase);
|
||||
m_pStatement->execute(aBuf);
|
||||
|
||||
// create tables
|
||||
str_format(aBuf, sizeof(aBuf), "CREATE TABLE IF NOT EXISTS %s_race (Map VARCHAR(128) BINARY NOT NULL, Name VARCHAR(%d) BINARY NOT NULL, Timestamp TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP , Time FLOAT DEFAULT 0, Server CHAR(4), cp1 FLOAT DEFAULT 0, cp2 FLOAT DEFAULT 0, cp3 FLOAT DEFAULT 0, cp4 FLOAT DEFAULT 0, cp5 FLOAT DEFAULT 0, cp6 FLOAT DEFAULT 0, cp7 FLOAT DEFAULT 0, cp8 FLOAT DEFAULT 0, cp9 FLOAT DEFAULT 0, cp10 FLOAT DEFAULT 0, cp11 FLOAT DEFAULT 0, cp12 FLOAT DEFAULT 0, cp13 FLOAT DEFAULT 0, cp14 FLOAT DEFAULT 0, cp15 FLOAT DEFAULT 0, cp16 FLOAT DEFAULT 0, cp17 FLOAT DEFAULT 0, cp18 FLOAT DEFAULT 0, cp19 FLOAT DEFAULT 0, cp20 FLOAT DEFAULT 0, cp21 FLOAT DEFAULT 0, cp22 FLOAT DEFAULT 0, cp23 FLOAT DEFAULT 0, cp24 FLOAT DEFAULT 0, cp25 FLOAT DEFAULT 0, KEY (Map, Name)) CHARACTER SET utf8 ;", m_pPrefix, MAX_NAME_LENGTH);
|
||||
str_format(aBuf, sizeof(aBuf), "CREATE TABLE IF NOT EXISTS %s_race (Map VARCHAR(128) BINARY NOT NULL, Name VARCHAR(%d) BINARY NOT NULL, Timestamp TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP , Time FLOAT DEFAULT 0, Server CHAR(4), cp1 FLOAT DEFAULT 0, cp2 FLOAT DEFAULT 0, cp3 FLOAT DEFAULT 0, cp4 FLOAT DEFAULT 0, cp5 FLOAT DEFAULT 0, cp6 FLOAT DEFAULT 0, cp7 FLOAT DEFAULT 0, cp8 FLOAT DEFAULT 0, cp9 FLOAT DEFAULT 0, cp10 FLOAT DEFAULT 0, cp11 FLOAT DEFAULT 0, cp12 FLOAT DEFAULT 0, cp13 FLOAT DEFAULT 0, cp14 FLOAT DEFAULT 0, cp15 FLOAT DEFAULT 0, cp16 FLOAT DEFAULT 0, cp17 FLOAT DEFAULT 0, cp18 FLOAT DEFAULT 0, cp19 FLOAT DEFAULT 0, cp20 FLOAT DEFAULT 0, cp21 FLOAT DEFAULT 0, cp22 FLOAT DEFAULT 0, cp23 FLOAT DEFAULT 0, cp24 FLOAT DEFAULT 0, cp25 FLOAT DEFAULT 0, KEY (Map, Name)) CHARACTER SET utf8 ;", m_aPrefix, MAX_NAME_LENGTH);
|
||||
executeSql(aBuf);
|
||||
|
||||
str_format(aBuf, sizeof(aBuf), "CREATE TABLE IF NOT EXISTS %s_teamrace (Map VARCHAR(128) BINARY NOT NULL, Name VARCHAR(%d) BINARY NOT NULL, Timestamp TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, Time FLOAT DEFAULT 0, ID VARBINARY(16) NOT NULL, KEY Map (Map)) CHARACTER SET utf8 ;", m_pPrefix, MAX_NAME_LENGTH);
|
||||
str_format(aBuf, sizeof(aBuf), "CREATE TABLE IF NOT EXISTS %s_teamrace (Map VARCHAR(128) BINARY NOT NULL, Name VARCHAR(%d) BINARY NOT NULL, Timestamp TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, Time FLOAT DEFAULT 0, ID VARBINARY(16) NOT NULL, KEY Map (Map)) CHARACTER SET utf8 ;", m_aPrefix, MAX_NAME_LENGTH);
|
||||
executeSql(aBuf);
|
||||
|
||||
str_format(aBuf, sizeof(aBuf), "CREATE TABLE IF NOT EXISTS %s_maps (Map VARCHAR(128) BINARY NOT NULL, Server VARCHAR(32) BINARY NOT NULL, Mapper VARCHAR(128) BINARY NOT NULL, Points INT DEFAULT 0, Stars INT DEFAULT 0, Timestamp TIMESTAMP, UNIQUE KEY Map (Map)) CHARACTER SET utf8 ;", m_pPrefix);
|
||||
str_format(aBuf, sizeof(aBuf), "CREATE TABLE IF NOT EXISTS %s_maps (Map VARCHAR(128) BINARY NOT NULL, Server VARCHAR(32) BINARY NOT NULL, Mapper VARCHAR(128) BINARY NOT NULL, Points INT DEFAULT 0, Stars INT DEFAULT 0, Timestamp TIMESTAMP, UNIQUE KEY Map (Map)) CHARACTER SET utf8 ;", m_aPrefix);
|
||||
executeSql(aBuf);
|
||||
|
||||
str_format(aBuf, sizeof(aBuf), "CREATE TABLE IF NOT EXISTS %s_saves (Savegame TEXT CHARACTER SET utf8 BINARY NOT NULL, Map VARCHAR(128) BINARY NOT NULL, Code VARCHAR(128) BINARY NOT NULL, Timestamp TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, Server CHAR(4), UNIQUE KEY (Map, Code)) CHARACTER SET utf8 ;", m_pPrefix);
|
||||
str_format(aBuf, sizeof(aBuf), "CREATE TABLE IF NOT EXISTS %s_saves (Savegame TEXT CHARACTER SET utf8 BINARY NOT NULL, Map VARCHAR(128) BINARY NOT NULL, Code VARCHAR(128) BINARY NOT NULL, Timestamp TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, Server CHAR(4), UNIQUE KEY (Map, Code)) CHARACTER SET utf8 ;", m_aPrefix);
|
||||
executeSql(aBuf);
|
||||
|
||||
str_format(aBuf, sizeof(aBuf), "CREATE TABLE IF NOT EXISTS %s_points (Name VARCHAR(%d) BINARY NOT NULL, Points INT DEFAULT 0, UNIQUE KEY Name (Name)) CHARACTER SET utf8 ;", m_pPrefix, MAX_NAME_LENGTH);
|
||||
str_format(aBuf, sizeof(aBuf), "CREATE TABLE IF NOT EXISTS %s_points (Name VARCHAR(%d) BINARY NOT NULL, Points INT DEFAULT 0, UNIQUE KEY Name (Name)) CHARACTER SET utf8 ;", m_aPrefix, MAX_NAME_LENGTH);
|
||||
executeSql(aBuf);
|
||||
|
||||
dbg_msg("SQL", "Tables were created successfully");
|
||||
|
@ -185,14 +190,4 @@ void CSqlServer::executeSqlQuery(const char *pQuery)
|
|||
m_pResults = m_pStatement->executeQuery(pQuery);
|
||||
}
|
||||
|
||||
sql::ResultSet* CSqlServer::GetResults()
|
||||
{
|
||||
return m_pResults;
|
||||
}
|
||||
|
||||
const char* CSqlServer::GetPrefix()
|
||||
{
|
||||
return m_pPrefix;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -19,21 +19,29 @@ public:
|
|||
|
||||
void executeSql(const char* pCommand);
|
||||
void executeSqlQuery(const char* pQuery);
|
||||
sql::ResultSet* GetResults();
|
||||
|
||||
const char* GetPrefix();
|
||||
sql::ResultSet* GetResults() { return m_pResults; }
|
||||
|
||||
const char* GetDatabase() { return m_aDatabase; }
|
||||
const char* GetPrefix() { return m_aPrefix; }
|
||||
const char* GetUser() { return m_aUser; }
|
||||
const char* GetPass() { return m_aPass; }
|
||||
const char* GetIP() { return m_aIp; }
|
||||
int GetPort() { return m_Port; }
|
||||
|
||||
|
||||
private:
|
||||
sql::Driver *m_pDriver;
|
||||
sql::Connection *m_pConnection;
|
||||
sql::Statement *m_pStatement;
|
||||
sql::ResultSet *m_pResults;
|
||||
|
||||
// copy of config vars
|
||||
const char* m_pDatabase;
|
||||
const char* m_pPrefix;
|
||||
const char* m_pUser;
|
||||
const char* m_pPass;
|
||||
const char* m_pIp;
|
||||
char m_aDatabase[64];
|
||||
char m_aPrefix[64];
|
||||
char m_aUser[64];
|
||||
char m_aPass[64];
|
||||
char m_aIp[64];
|
||||
int m_Port;
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in a new issue