mirror of
https://github.com/ddnet/ddnet.git
synced 2024-11-10 18:18:18 +00:00
restructured sqlconnection
reading from and writing to several different servers is now possible TODO: -handle Exceptions properly (try another sqlserver) -if everything fails while writing write the insert to a file
This commit is contained in:
parent
2d41ce3527
commit
1314085928
|
@ -166,10 +166,6 @@ public:
|
|||
|
||||
virtual int* GetIdMap(int ClientID) = 0;
|
||||
|
||||
#if defined (CONF_SQL)
|
||||
virtual class CSqlServer *SqlServer() = 0;
|
||||
virtual class CSqlServer **SqlMasterServers() = 0;
|
||||
#endif
|
||||
};
|
||||
|
||||
class IGameServer : public IInterface
|
||||
|
|
|
@ -42,6 +42,11 @@
|
|||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
#ifdef CONF_SQL
|
||||
CSqlServer** CSqlConnector::ms_ppSqlReadServers = 0;
|
||||
CSqlServer** CSqlConnector::ms_ppSqlWriteServers = 0;
|
||||
#endif
|
||||
|
||||
static const char *StrLtrim(const char *pStr)
|
||||
{
|
||||
while(*pStr)
|
||||
|
@ -302,10 +307,6 @@ CServer::CServer()
|
|||
|
||||
m_pGameServer = 0;
|
||||
|
||||
#if defined (CONF_SQL)
|
||||
m_pSqlServer = 0;
|
||||
#endif
|
||||
|
||||
m_CurrentGameTick = 0;
|
||||
m_RunServer = 1;
|
||||
|
||||
|
@ -326,8 +327,14 @@ CServer::CServer()
|
|||
m_ServerInfoHighLoad = false;
|
||||
|
||||
#if defined (CONF_SQL)
|
||||
for (int i = 0; i < MAX_SQLMASTERS; i++)
|
||||
m_apMasterSqlServers[i] = 0;
|
||||
for (int i = 0; i < MAX_SQLSERVERS; i++)
|
||||
{
|
||||
m_apSqlReadServers[i] = 0;
|
||||
m_apSqlWriteServers[i] = 0;
|
||||
}
|
||||
|
||||
CSqlConnector::SetReadServers(m_apSqlReadServers);
|
||||
CSqlConnector::SetWriteServers(m_apSqlWriteServers);
|
||||
#endif
|
||||
|
||||
Init();
|
||||
|
@ -1659,14 +1666,6 @@ int CServer::Run()
|
|||
str_format(aBuf, sizeof(aBuf), "server name is '%s'", g_Config.m_SvName);
|
||||
Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "server", aBuf);
|
||||
|
||||
#if defined (CONF_SQL)
|
||||
m_pSqlServer = new CSqlServer(g_Config.m_SvSqlDatabase, g_Config.m_SvSqlPrefix, g_Config.m_SvSqlUser, g_Config.m_SvSqlPw, g_Config.m_SvSqlIp, g_Config.m_SvSqlPort);
|
||||
|
||||
// create tables
|
||||
if(g_Config.m_SvSqlCreateTables)
|
||||
m_pSqlServer->CreateTables();
|
||||
#endif
|
||||
|
||||
GameServer()->OnInit();
|
||||
str_format(aBuf, sizeof(aBuf), "version %s", GameServer()->NetVersion());
|
||||
Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "server", aBuf);
|
||||
|
@ -1834,12 +1833,14 @@ int CServer::Run()
|
|||
mem_free(m_pCurrentMapData);
|
||||
|
||||
#if defined (CONF_SQL)
|
||||
if (m_pSqlServer)
|
||||
delete m_pSqlServer;
|
||||
for (int i = 0; i < MAX_SQLSERVERS; i++)
|
||||
{
|
||||
if (m_apSqlReadServers[i])
|
||||
delete m_apSqlReadServers[i];
|
||||
|
||||
for (int i = 0; i < MAX_SQLMASTERS; i++)
|
||||
if (m_apMasterSqlServers[i])
|
||||
delete m_apMasterSqlServers[i];
|
||||
if (m_apSqlWriteServers[i])
|
||||
delete m_apSqlWriteServers[i];
|
||||
}
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
|
@ -2019,30 +2020,34 @@ void CServer::ConLogout(IConsole::IResult *pResult, void *pUser)
|
|||
|
||||
#if defined (CONF_SQL)
|
||||
|
||||
void CServer::ConAddSqlMaster(IConsole::IResult *pResult, void *pUserData)
|
||||
void CServer::ConAddSqlServer(IConsole::IResult *pResult, void *pUserData)
|
||||
{
|
||||
CServer *pSelf = (CServer *)pUserData;
|
||||
|
||||
if (pResult->NumArguments() != 6)
|
||||
if (pResult->NumArguments() != 7)
|
||||
{
|
||||
pSelf->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "server", "6 arguments are required");
|
||||
pSelf->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "server", "7 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));
|
||||
bool ReadOnly = !pResult->GetInteger(0);
|
||||
|
||||
if(g_Config.m_SvSqlMastersCreateTables)
|
||||
CSqlServer** apSqlServers = ReadOnly ? pSelf->m_apSqlReadServers : pSelf->m_apSqlWriteServers;
|
||||
|
||||
for (int i = 0; i < MAX_SQLSERVERS; i++)
|
||||
{
|
||||
if (!apSqlServers[i])
|
||||
{
|
||||
apSqlServers[i] = new CSqlServer(pResult->GetString(1), pResult->GetString(2), pResult->GetString(3), pResult->GetString(4), pResult->GetString(5), pResult->GetInteger(6));
|
||||
|
||||
if(g_Config.m_SvSqlCreateTables == 3 || (g_Config.m_SvSqlCreateTables == 1 && ReadOnly) || (g_Config.m_SvSqlCreateTables == 2 && !ReadOnly))
|
||||
{
|
||||
void *TablesThread = thread_init(CreateTablesThread, pSelf->m_apMasterSqlServers[i]);
|
||||
void *TablesThread = thread_init(CreateTablesThread, apSqlServers[i]);
|
||||
thread_detach(TablesThread);
|
||||
}
|
||||
|
||||
char aBuf[512];
|
||||
str_format(aBuf, sizeof(aBuf), "Added new sqlmasterserver: %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());
|
||||
str_format(aBuf, sizeof(aBuf), "Added new Sql%sServer: %d: DB: '%s' Prefix: '%s' User: '%s' Pass: '%s' IP: '%s' Port: %d", ReadOnly ? "Read" : "Write", i, apSqlServers[i]->GetDatabase(), apSqlServers[i]->GetPrefix(), apSqlServers[i]->GetUser(), apSqlServers[i]->GetPass(), apSqlServers[i]->GetIP(), apSqlServers[i]->GetPort());
|
||||
pSelf->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "server", aBuf);
|
||||
return;
|
||||
}
|
||||
|
@ -2050,15 +2055,19 @@ void CServer::ConAddSqlMaster(IConsole::IResult *pResult, void *pUserData)
|
|||
pSelf->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "server", "failed to add new sqlmaster: limit of sqlmasters reached");
|
||||
}
|
||||
|
||||
void CServer::ConDumpSqlMaster(IConsole::IResult *pResult, void *pUserData)
|
||||
void CServer::ConDumpSqlServers(IConsole::IResult *pResult, void *pUserData)
|
||||
{
|
||||
CServer *pSelf = (CServer *)pUserData;
|
||||
|
||||
for (int i = 0; i < MAX_SQLMASTERS; i++)
|
||||
if (pSelf->m_apMasterSqlServers[i])
|
||||
bool ReadOnly = !pResult->GetInteger(0);
|
||||
|
||||
CSqlServer** apSqlServers = ReadOnly ? pSelf->m_apSqlReadServers : pSelf->m_apSqlWriteServers;
|
||||
|
||||
for (int i = 0; i < MAX_SQLSERVERS; i++)
|
||||
if (apSqlServers[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());
|
||||
str_format(aBuf, sizeof(aBuf), "SQL-%s %d: DB: '%s' Prefix: '%s' User: '%s' Pass: '%s' IP: '%s' Port: %d", ReadOnly ? "Read" : "Write", i, apSqlServers[i]->GetDatabase(), apSqlServers[i]->GetPrefix(), apSqlServers[i]->GetUser(), apSqlServers[i]->GetPass(), apSqlServers[i]->GetIP(), apSqlServers[i]->GetPort());
|
||||
pSelf->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "server", aBuf);
|
||||
}
|
||||
}
|
||||
|
@ -2201,8 +2210,8 @@ void CServer::RegisterCommands()
|
|||
|
||||
#if defined (CONF_SQL)
|
||||
|
||||
Console()->Register("add_sqlmaster", "sssssi", CFGFLAG_SERVER, ConAddSqlMaster, this, "add a sqlmasterserver <Database> <Prefix> <User> <Password> <IP> <Port>");
|
||||
Console()->Register("dump_sqlmaster", "", CFGFLAG_SERVER, ConDumpSqlMaster, this, "dumps all sqlmasterservers");
|
||||
Console()->Register("add_sqlserver", "isssssi", CFGFLAG_SERVER, ConAddSqlServer, this, "add a sqlserver <read = 0, write = 1> <Database> <Prefix> <User> <Password> <IP> <Port>");
|
||||
Console()->Register("dump_sqlservers", "i", CFGFLAG_SERVER, ConDumpSqlServers, this, "dumps all sqlservers readservers = 0, writeservers = 1");
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -18,7 +18,8 @@
|
|||
#include <engine/shared/netban.h>
|
||||
|
||||
#if defined (CONF_SQL)
|
||||
#include <game/server/score/sql_score.h>
|
||||
#include "sql_connector.h"
|
||||
#include "sql_server.h"
|
||||
#endif
|
||||
|
||||
class CSnapIDPool
|
||||
|
@ -81,8 +82,8 @@ class CServer : public IServer
|
|||
class IStorage *m_pStorage;
|
||||
|
||||
#if defined (CONF_SQL)
|
||||
CSqlServer* m_pSqlServer;
|
||||
CSqlServer* m_apMasterSqlServers[MAX_SQLMASTERS];
|
||||
CSqlServer* m_apSqlReadServers[MAX_SQLSERVERS];
|
||||
CSqlServer* m_apSqlWriteServers[MAX_SQLSERVERS];;
|
||||
#endif
|
||||
|
||||
public:
|
||||
|
@ -281,8 +282,8 @@ public:
|
|||
|
||||
#if defined (CONF_SQL)
|
||||
// console commands for sqlmasters
|
||||
static void ConAddSqlMaster(IConsole::IResult *pResult, void *pUserData);
|
||||
static void ConDumpSqlMaster(IConsole::IResult *pResult, void *pUserData);
|
||||
static void ConAddSqlServer(IConsole::IResult *pResult, void *pUserData);
|
||||
static void ConDumpSqlServers(IConsole::IResult *pResult, void *pUserData);
|
||||
|
||||
static void CreateTablesThread(void *pData);
|
||||
#endif
|
||||
|
@ -316,10 +317,6 @@ public:
|
|||
|
||||
virtual int* GetIdMap(int ClientID);
|
||||
|
||||
#if defined (CONF_SQL)
|
||||
CSqlServer *SqlServer() { return m_pSqlServer; }
|
||||
CSqlServer **SqlMasterServers() { return m_apMasterSqlServers; }
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
42
src/engine/server/sql_connector.cpp
Normal file
42
src/engine/server/sql_connector.cpp
Normal file
|
@ -0,0 +1,42 @@
|
|||
#if defined(CONF_SQL)
|
||||
|
||||
#include <base/system.h>
|
||||
|
||||
#include "sql_connector.h"
|
||||
|
||||
CSqlConnector::CSqlConnector() :
|
||||
m_pSqlServer(0),
|
||||
m_NumReadRetries(0),
|
||||
m_NumWriteRetries(0)
|
||||
{}
|
||||
|
||||
bool CSqlConnector::ConnectSqlServer(bool ReadOnly)
|
||||
{
|
||||
ReadOnly ? ++m_NumReadRetries : ++m_NumWriteRetries;
|
||||
|
||||
bool passedOldServer = !m_pSqlServer;
|
||||
|
||||
for (int i = 0; i < MAX_SQLSERVERS && SqlServer(i, ReadOnly); i++)
|
||||
{
|
||||
|
||||
if (!passedOldServer)
|
||||
{
|
||||
if (m_pSqlServer == SqlServer(i, ReadOnly))
|
||||
passedOldServer = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (SqlServer(i, ReadOnly) && SqlServer(i, ReadOnly)->Connect())
|
||||
{
|
||||
m_pSqlServer = SqlServer(i, ReadOnly);
|
||||
return true;
|
||||
}
|
||||
if (SqlServer())
|
||||
dbg_msg("SQL", "Warning: Unable to connect to Sql%sServer %d ('%s'), trying next...", ReadOnly ? "read" : "write", i, SqlServer()->GetIP());
|
||||
}
|
||||
dbg_msg("SQL", "ERROR: No Sql%sServers available", ReadOnly ? "Read" : "Write");
|
||||
m_pSqlServer = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
#endif
|
39
src/engine/server/sql_connector.h
Normal file
39
src/engine/server/sql_connector.h
Normal file
|
@ -0,0 +1,39 @@
|
|||
#ifndef ENGINE_SERVER_SQL_CONNECTOR_H
|
||||
#define ENGINE_SERVER_SQL_CONNECTOR_H
|
||||
|
||||
#include "sql_server.h"
|
||||
|
||||
enum
|
||||
{
|
||||
MAX_SQLSERVERS=15
|
||||
};
|
||||
|
||||
// implementation to provide sqlservers
|
||||
class CSqlConnector
|
||||
{
|
||||
public:
|
||||
CSqlConnector();
|
||||
|
||||
CSqlServer* SqlServer(int i, bool ReadOnly = true) { return ReadOnly ? ms_ppSqlReadServers[i] : ms_ppSqlWriteServers[i]; }
|
||||
|
||||
// always returns the last connected sql-server
|
||||
CSqlServer* SqlServer() { return m_pSqlServer; }
|
||||
|
||||
static void SetReadServers(CSqlServer** ppReadServers) { ms_ppSqlReadServers = ppReadServers; }
|
||||
static void SetWriteServers(CSqlServer** ppWriteServers) { ms_ppSqlWriteServers = ppWriteServers; }
|
||||
|
||||
bool ConnectSqlServer(bool ReadOnly = true);
|
||||
|
||||
bool MaxTriesReached(bool ReadOnly = true) { return ReadOnly ? m_NumReadRetries : m_NumWriteRetries >= MAX_SQLSERVERS; }
|
||||
|
||||
private:
|
||||
|
||||
CSqlServer *m_pSqlServer;
|
||||
static CSqlServer **ms_ppSqlReadServers;
|
||||
static CSqlServer **ms_ppSqlWriteServers;
|
||||
|
||||
int m_NumReadRetries;
|
||||
int m_NumWriteRetries;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -1,5 +1,5 @@
|
|||
#ifndef GAME_SERVER_SQL_SERVER_H
|
||||
#define GAME_SERVER_SQL_SERVER_H
|
||||
#ifndef ENGINE_SERVER_SQL_SERVER_H
|
||||
#define ENGINE_SERVER_SQL_SERVER_H
|
||||
|
||||
#include <mysql_connection.h>
|
||||
|
||||
|
@ -7,11 +7,6 @@
|
|||
#include <cppconn/exception.h>
|
||||
#include <cppconn/statement.h>
|
||||
|
||||
enum
|
||||
{
|
||||
MAX_SQLMASTERS=10
|
||||
};
|
||||
|
||||
class CSqlServer
|
||||
{
|
||||
public:
|
|
@ -1,5 +1,5 @@
|
|||
#ifndef GAME_SERVER_SQL_STRING_HELPERS_H
|
||||
#define GAME_SERVER_SQL_STRING_HELPERS_H
|
||||
#ifndef ENGINE_SERVER_SQL_STRING_HELPERS_H
|
||||
#define ENGINE_SERVER_SQL_STRING_HELPERS_H
|
||||
|
||||
#include <base/system.h>
|
||||
|
|
@ -217,19 +217,10 @@ MACRO_CONFIG_STR(SvScoreFolder, sv_score_folder, 32, "records", CFGFLAG_SERVER,
|
|||
|
||||
#if defined(CONF_SQL)
|
||||
MACRO_CONFIG_INT(SvUseSQL, sv_use_sql, 0, 0, 1, CFGFLAG_SERVER, "Enables SQL DB instead of record file")
|
||||
MACRO_CONFIG_STR(SvSqlUser, sv_sql_user, 32, "nameless", CFGFLAG_SERVER, "SQL User")
|
||||
MACRO_CONFIG_STR(SvSqlPw, sv_sql_pw, 32, "tee", CFGFLAG_SERVER, "SQL Password")
|
||||
MACRO_CONFIG_STR(SvSqlIp, sv_sql_ip, 32, "127.0.0.1", CFGFLAG_SERVER, "SQL Database IP")
|
||||
MACRO_CONFIG_INT(SvSqlPort, sv_sql_port, 3306, 0, 65535, CFGFLAG_SERVER, "SQL Database port")
|
||||
MACRO_CONFIG_INT(SvSqlCreateTables, sv_sql_create_tables, 1, 0, 1, CFGFLAG_SERVER, "Try to create the SQL tables when starting")
|
||||
MACRO_CONFIG_STR(SvSqlDatabase, sv_sql_database, 16, "teeworlds", CFGFLAG_SERVER, "SQL Database name")
|
||||
MACRO_CONFIG_INT(SvSqlCreateTables, sv_sql_create_tables, 0, 0, 3, CFGFLAG_SERVER, "Try to create the SQL tables when starting (O = never, 1 = readserver, 2 = write server, 3 = both)")
|
||||
MACRO_CONFIG_STR(SvSqlServerName, sv_sql_servername, 5, "UNK", CFGFLAG_SERVER, "SQL Server name that is inserted into record table")
|
||||
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")
|
||||
MACRO_CONFIG_INT(SvSqlMastersCreateTables, sv_sqlmasters_create_tables, 0, 0, 1, CFGFLAG_SERVER, "Try to create the SQL tables when starting")
|
||||
#endif
|
||||
|
||||
MACRO_CONFIG_INT(SvDDRaceRules, sv_ddrace_rules, 1, 0, 1, CFGFLAG_SERVER, "Whether the default mod rules are displayed or not")
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -5,23 +5,20 @@
|
|||
#define GAME_SERVER_SQLSCORE_H
|
||||
|
||||
#include <engine/console.h>
|
||||
#include <engine/server/sql_connector.h>
|
||||
|
||||
#include "sql_server.h"
|
||||
#include "../score.h"
|
||||
|
||||
class CSqlScore: public IScore
|
||||
{
|
||||
CGameContext *GameServer() { return m_pGameServer; }
|
||||
IServer *Server() { return m_pServer; }
|
||||
inline CSqlServer *SqlServer() { return m_pServer->SqlServer(); }
|
||||
inline CSqlServer *SqlMasterServer(int i) { return m_pServer->SqlMasterServers()[i]; }
|
||||
inline CSqlServer **SqlMasterServers() { return m_pServer->SqlMasterServers(); }
|
||||
|
||||
void Init();
|
||||
|
||||
CGameContext *m_pGameServer;
|
||||
IServer *m_pServer;
|
||||
|
||||
void Init();
|
||||
|
||||
char m_aMap[64];
|
||||
|
||||
static void MapInfoThread(void *pUser);
|
||||
|
@ -68,51 +65,18 @@ public:
|
|||
virtual void LoadTeam(const char* Code, int ClientID);
|
||||
};
|
||||
|
||||
// generic implementation to provide sqlserver, gameserver and server
|
||||
// generic implementation to provide gameserver and server
|
||||
struct CSqlData
|
||||
{
|
||||
CSqlData() : m_pSqlServer(ms_pSqlServer), m_ActiveMaster(-1) {}
|
||||
|
||||
CGameContext* GameServer() { return ms_pGameServer; }
|
||||
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; }
|
||||
int ActiveMasterID() { return m_ActiveMaster; }
|
||||
|
||||
void ConnectSqlServer(bool useMasters = false, int skipCount = 0)
|
||||
{
|
||||
if (useMasters)
|
||||
{
|
||||
m_pSqlServer = 0;
|
||||
for (int i = skipCount; i < MAX_SQLMASTERS; i++)
|
||||
{
|
||||
if (SqlMasterServer(i) && SqlMasterServer(i)->Connect())
|
||||
{
|
||||
m_pSqlServer = SqlMasterServer(i);
|
||||
m_ActiveMaster = 0;
|
||||
return;
|
||||
}
|
||||
if (SqlMasterServer(i))
|
||||
dbg_msg("SQL", "Warning: Unable to connect to sqlmaster %d ('%s'), trying next...", i, SqlMasterServer(i)->GetIP());
|
||||
}
|
||||
dbg_msg("SQL", "ERROR: No sqlmasterservers available");
|
||||
m_ActiveMaster = -1;
|
||||
}
|
||||
else if (!SqlServer()->Connect())
|
||||
m_pSqlServer = 0;
|
||||
}
|
||||
|
||||
static CGameContext *ms_pGameServer;
|
||||
static IServer *ms_pServer;
|
||||
static CPlayerData *ms_pPlayerData;
|
||||
static const char *ms_pMap;
|
||||
static CSqlServer *ms_pSqlServer;
|
||||
static CSqlServer **ms_pMasterSqlServers;
|
||||
|
||||
CSqlServer *m_pSqlServer;
|
||||
int m_ActiveMaster;
|
||||
};
|
||||
|
||||
struct CSqlMapData : CSqlData
|
||||
|
|
Loading…
Reference in a new issue