config: harden admin page secrets
This commit is contained in:
@@ -1,4 +1,8 @@
|
||||
#include "stdafx.h"
|
||||
#include <array>
|
||||
#include <cerrno>
|
||||
#include <cstdlib>
|
||||
#include <limits>
|
||||
#include <sstream>
|
||||
#ifndef OS_WINDOWS
|
||||
#include <ifaddrs.h>
|
||||
@@ -20,6 +24,161 @@
|
||||
|
||||
using std::string;
|
||||
|
||||
namespace
|
||||
{
|
||||
enum class ESqlConfigIndex : size_t
|
||||
{
|
||||
Account = 0,
|
||||
Player = 1,
|
||||
Common = 2,
|
||||
Count = 3
|
||||
};
|
||||
|
||||
struct SqlConnectionConfig
|
||||
{
|
||||
std::string host;
|
||||
std::string user;
|
||||
std::string password;
|
||||
std::string database;
|
||||
int port = 0;
|
||||
|
||||
bool IsConfigured() const
|
||||
{
|
||||
return !host.empty() && !user.empty() && !password.empty() && !database.empty();
|
||||
}
|
||||
};
|
||||
|
||||
bool ReadEnvString(const char* envName, std::string& output)
|
||||
{
|
||||
const char* envValue = std::getenv(envName);
|
||||
if (!envValue || !*envValue)
|
||||
return false;
|
||||
|
||||
output = envValue;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ReadEnvPort(const char* envName, int& output)
|
||||
{
|
||||
const char* envValue = std::getenv(envName);
|
||||
if (!envValue || !*envValue)
|
||||
return false;
|
||||
|
||||
errno = 0;
|
||||
char* end = nullptr;
|
||||
unsigned long parsed = std::strtoul(envValue, &end, 10);
|
||||
if (errno != 0 || end == envValue || *end != '\0' || parsed > std::numeric_limits<uint16_t>::max())
|
||||
{
|
||||
fprintf(stderr, "Invalid %s value: %s\n", envName, envValue);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
output = static_cast<int>(parsed);
|
||||
return true;
|
||||
}
|
||||
|
||||
void LogEnvOverride(const char* envName)
|
||||
{
|
||||
fprintf(stdout, "CONFIG: using %s override\n", envName);
|
||||
}
|
||||
|
||||
void ApplySqlEnvOverrides(const char* prefix, SqlConnectionConfig& config)
|
||||
{
|
||||
char envName[64];
|
||||
|
||||
snprintf(envName, sizeof(envName), "METIN2_%s_HOST", prefix);
|
||||
if (ReadEnvString(envName, config.host))
|
||||
LogEnvOverride(envName);
|
||||
|
||||
snprintf(envName, sizeof(envName), "METIN2_%s_USER", prefix);
|
||||
if (ReadEnvString(envName, config.user))
|
||||
LogEnvOverride(envName);
|
||||
|
||||
snprintf(envName, sizeof(envName), "METIN2_%s_PASSWORD", prefix);
|
||||
if (ReadEnvString(envName, config.password))
|
||||
LogEnvOverride(envName);
|
||||
|
||||
snprintf(envName, sizeof(envName), "METIN2_%s_DATABASE", prefix);
|
||||
if (ReadEnvString(envName, config.database))
|
||||
LogEnvOverride(envName);
|
||||
|
||||
snprintf(envName, sizeof(envName), "METIN2_%s_PORT", prefix);
|
||||
if (ReadEnvPort(envName, config.port))
|
||||
LogEnvOverride(envName);
|
||||
}
|
||||
|
||||
void ParseSqlConfigOrExit(const char* tokenName, const char* value, SqlConnectionConfig& config)
|
||||
{
|
||||
char host[64];
|
||||
char user[64];
|
||||
char password[64];
|
||||
char database[64];
|
||||
int port = 0;
|
||||
|
||||
*host = '\0';
|
||||
*user = '\0';
|
||||
*password = '\0';
|
||||
*database = '\0';
|
||||
|
||||
const char* line = two_arguments(value, host, sizeof(host), user, sizeof(user));
|
||||
line = two_arguments(line, password, sizeof(password), database, sizeof(database));
|
||||
|
||||
if (line[0])
|
||||
{
|
||||
char portBuffer[32];
|
||||
one_argument(line, portBuffer, sizeof(portBuffer));
|
||||
str_to_number(port, portBuffer);
|
||||
}
|
||||
|
||||
if (!*host || !*user || !*password || !*database)
|
||||
{
|
||||
fprintf(stderr, "%s syntax: %s <host user password db [port]>\n", tokenName, tokenName);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
config.host = host;
|
||||
config.user = user;
|
||||
config.password = password;
|
||||
config.database = database;
|
||||
config.port = port;
|
||||
}
|
||||
|
||||
void ValidateSqlConfigOrExit(const char* label, const SqlConnectionConfig& config)
|
||||
{
|
||||
if (config.IsConfigured())
|
||||
return;
|
||||
|
||||
fprintf(stderr, "%s must be configured as <host user password db [port]>\n", label);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
void ApplyAdminPagePasswordEnvOverride()
|
||||
{
|
||||
if (ReadEnvString("METIN2_ADMINPAGE_PASSWORD", g_stAdminPagePassword))
|
||||
LogEnvOverride("METIN2_ADMINPAGE_PASSWORD");
|
||||
}
|
||||
|
||||
void ValidateAdminPageConfigOrExit()
|
||||
{
|
||||
if (!IsAdminPageEnabled())
|
||||
{
|
||||
if (!g_stAdminPageIP.empty())
|
||||
{
|
||||
fprintf(stderr, "ADMIN_PAGE_PASSWORD must be configured when adminpage_ip is set\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
fprintf(stdout, "ADMIN_PAGE: disabled\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (g_stAdminPageIP.empty())
|
||||
fprintf(stdout, "ADMIN_PAGE: enabled without IP restriction\n");
|
||||
else
|
||||
fprintf(stdout, "ADMIN_PAGE: enabled for %zu IP entries\n", g_stAdminPageIP.size());
|
||||
}
|
||||
}
|
||||
|
||||
BYTE g_bChannel = 0;
|
||||
WORD mother_port = 50080;
|
||||
int passes_per_sec = 25;
|
||||
@@ -75,7 +234,7 @@ string g_stDefaultQuestObjectDir = "./quest/object";
|
||||
std::set<string> g_setQuestObjectDir;
|
||||
|
||||
std::vector<std::string> g_stAdminPageIP;
|
||||
std::string g_stAdminPagePassword = "SHOWMETHEMONEY";
|
||||
std::string g_stAdminPagePassword;
|
||||
|
||||
string g_stBlockDate = "30000705";
|
||||
|
||||
@@ -195,7 +354,12 @@ static void FN_log_adminpage()
|
||||
++iter;
|
||||
}
|
||||
|
||||
sys_log(1, "ADMIN_PAGE_PASSWORD = %s", g_stAdminPagePassword.c_str());
|
||||
sys_log(1, "ADMIN_PAGE_PASSWORD = %s", IsAdminPageEnabled() ? "[configured]" : "[disabled]");
|
||||
}
|
||||
|
||||
bool IsAdminPageEnabled()
|
||||
{
|
||||
return !g_stAdminPagePassword.empty();
|
||||
}
|
||||
|
||||
|
||||
@@ -340,35 +504,14 @@ void config_init(const string& st_localeServiceName)
|
||||
exit(1);
|
||||
}
|
||||
|
||||
char db_host[3][64], db_user[3][64], db_pwd[3][64], db_db[3][64];
|
||||
// ... 아... db_port는 이미 있는데... 네이밍 어찌해야함...
|
||||
int mysql_db_port[3];
|
||||
|
||||
for (int n = 0; n < 3; ++n)
|
||||
{
|
||||
*db_host[n] = '\0';
|
||||
*db_user[n] = '\0';
|
||||
*db_pwd[n]= '\0';
|
||||
*db_db[n]= '\0';
|
||||
mysql_db_port[n] = 0;
|
||||
}
|
||||
|
||||
char log_host[64], log_user[64], log_pwd[64], log_db[64];
|
||||
int log_port = 0;
|
||||
|
||||
*log_host = '\0';
|
||||
*log_user = '\0';
|
||||
*log_pwd = '\0';
|
||||
*log_db = '\0';
|
||||
std::array<SqlConnectionConfig, static_cast<size_t>(ESqlConfigIndex::Count)> dbConfig;
|
||||
SqlConnectionConfig logConfig;
|
||||
|
||||
|
||||
// DB에서 로케일정보를 세팅하기위해서는 다른 세팅값보다 선행되어서
|
||||
// DB정보만 읽어와 로케일 세팅을 한후 다른 세팅을 적용시켜야한다.
|
||||
// 이유는 로케일관련된 초기화 루틴이 곳곳에 존재하기 때문.
|
||||
|
||||
bool isCommonSQL = false;
|
||||
bool isPlayerSQL = false;
|
||||
|
||||
FILE* fp_common;
|
||||
if (!(fp_common = fopen("conf/game.txt", "r")))
|
||||
{
|
||||
@@ -381,96 +524,25 @@ void config_init(const string& st_localeServiceName)
|
||||
|
||||
TOKEN("account_sql")
|
||||
{
|
||||
const char* line = two_arguments(value_string, db_host[0], sizeof(db_host[0]), db_user[0], sizeof(db_user[0]));
|
||||
line = two_arguments(line, db_pwd[0], sizeof(db_pwd[0]), db_db[0], sizeof(db_db[0]));
|
||||
|
||||
if (line[0])
|
||||
{
|
||||
char buf[256];
|
||||
one_argument(line, buf, sizeof(buf));
|
||||
str_to_number(mysql_db_port[0], buf);
|
||||
}
|
||||
|
||||
if (!*db_host[0] || !*db_user[0] || !*db_pwd[0] || !*db_db[0])
|
||||
{
|
||||
fprintf(stderr, "PLAYER_SQL syntax: logsql <host user password db>\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
char buf[1024];
|
||||
snprintf(buf, sizeof(buf), "PLAYER_SQL: %s %s %s %s %d", db_host[0], db_user[0], db_pwd[0], db_db[0], mysql_db_port[0]);
|
||||
isPlayerSQL = true;
|
||||
ParseSqlConfigOrExit("account_sql", value_string, dbConfig[static_cast<size_t>(ESqlConfigIndex::Account)]);
|
||||
continue;
|
||||
}
|
||||
|
||||
TOKEN("player_sql")
|
||||
{
|
||||
const char* line = two_arguments(value_string, db_host[1], sizeof(db_host[1]), db_user[1], sizeof(db_user[1]));
|
||||
line = two_arguments(line, db_pwd[1], sizeof(db_pwd[1]), db_db[1], sizeof(db_db[1]));
|
||||
|
||||
if (line[0])
|
||||
{
|
||||
char buf[256];
|
||||
one_argument(line, buf, sizeof(buf));
|
||||
str_to_number(mysql_db_port[1], buf);
|
||||
}
|
||||
|
||||
if (!*db_host[1] || !*db_user[1] || !*db_pwd[1] || !*db_db[1])
|
||||
{
|
||||
fprintf(stderr, "PLAYER_SQL syntax: logsql <host user password db>\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
char buf[1024];
|
||||
snprintf(buf, sizeof(buf), "PLAYER_SQL: %s %s %s %s %d", db_host[1], db_user[1], db_pwd[1], db_db[1], mysql_db_port[1]);
|
||||
isPlayerSQL = true;
|
||||
ParseSqlConfigOrExit("player_sql", value_string, dbConfig[static_cast<size_t>(ESqlConfigIndex::Player)]);
|
||||
continue;
|
||||
}
|
||||
|
||||
TOKEN("common_sql")
|
||||
{
|
||||
const char* line = two_arguments(value_string, db_host[2], sizeof(db_host[2]), db_user[2], sizeof(db_user[2]));
|
||||
line = two_arguments(line, db_pwd[2], sizeof(db_pwd[2]), db_db[2], sizeof(db_db[2]));
|
||||
|
||||
if (line[0])
|
||||
{
|
||||
char buf[256];
|
||||
one_argument(line, buf, sizeof(buf));
|
||||
str_to_number(mysql_db_port[2], buf);
|
||||
}
|
||||
|
||||
if (!*db_host[2] || !*db_user[2] || !*db_pwd[2] || !*db_db[2])
|
||||
{
|
||||
fprintf(stderr, "COMMON_SQL syntax: logsql <host user password db>\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
char buf[1024];
|
||||
snprintf(buf, sizeof(buf), "COMMON_SQL: %s %s %s %s %d", db_host[2], db_user[2], db_pwd[2], db_db[2], mysql_db_port[2]);
|
||||
isCommonSQL = true;
|
||||
ParseSqlConfigOrExit("common_sql", value_string, dbConfig[static_cast<size_t>(ESqlConfigIndex::Common)]);
|
||||
continue;
|
||||
}
|
||||
|
||||
TOKEN("log_sql")
|
||||
{
|
||||
const char* line = two_arguments(value_string, log_host, sizeof(log_host), log_user, sizeof(log_user));
|
||||
line = two_arguments(line, log_pwd, sizeof(log_pwd), log_db, sizeof(log_db));
|
||||
|
||||
if (line[0])
|
||||
{
|
||||
char buf[256];
|
||||
one_argument(line, buf, sizeof(buf));
|
||||
str_to_number(log_port, buf);
|
||||
}
|
||||
|
||||
if (!*log_host || !*log_user || !*log_pwd || !*log_db)
|
||||
{
|
||||
fprintf(stderr, "LOG_SQL syntax: logsql <host user password db>\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
char buf[1024];
|
||||
snprintf(buf, sizeof(buf), "LOG_SQL: %s %s %s %s %d", log_host, log_user, log_pwd, log_db, log_port);
|
||||
ParseSqlConfigOrExit("log_sql", value_string, logConfig);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -753,6 +825,12 @@ void config_init(const string& st_localeServiceName)
|
||||
}
|
||||
fclose(fp_common);
|
||||
|
||||
ApplySqlEnvOverrides("ACCOUNT_SQL", dbConfig[static_cast<size_t>(ESqlConfigIndex::Account)]);
|
||||
ApplySqlEnvOverrides("PLAYER_SQL", dbConfig[static_cast<size_t>(ESqlConfigIndex::Player)]);
|
||||
ApplySqlEnvOverrides("COMMON_SQL", dbConfig[static_cast<size_t>(ESqlConfigIndex::Common)]);
|
||||
ApplySqlEnvOverrides("LOG_SQL", logConfig);
|
||||
ApplyAdminPagePasswordEnvOverride();
|
||||
|
||||
FILE* fpOnlyForDB;
|
||||
|
||||
if (!(fpOnlyForDB = fopen(st_configFileName.c_str(), "r")))
|
||||
@@ -814,31 +892,15 @@ void config_init(const string& st_localeServiceName)
|
||||
//처리가 끝났으니 파일을 닫자.
|
||||
fclose(fpOnlyForDB);
|
||||
|
||||
// CONFIG_SQL_INFO_ERROR
|
||||
if (!isCommonSQL)
|
||||
{
|
||||
puts("LOAD_COMMON_SQL_INFO_FAILURE:");
|
||||
puts("");
|
||||
puts("CONFIG:");
|
||||
puts("------------------------------------------------");
|
||||
puts("COMMON_SQL: HOST USER PASSWORD DATABASE");
|
||||
puts("");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (!isPlayerSQL)
|
||||
{
|
||||
puts("LOAD_PLAYER_SQL_INFO_FAILURE:");
|
||||
puts("");
|
||||
puts("CONFIG:");
|
||||
puts("------------------------------------------------");
|
||||
puts("PLAYER_SQL: HOST USER PASSWORD DATABASE");
|
||||
puts("");
|
||||
exit(1);
|
||||
}
|
||||
ValidateSqlConfigOrExit("COMMON_SQL", dbConfig[static_cast<size_t>(ESqlConfigIndex::Common)]);
|
||||
ValidateSqlConfigOrExit(g_bAuthServer ? "ACCOUNT_SQL" : "PLAYER_SQL", dbConfig[static_cast<size_t>(g_bAuthServer ? ESqlConfigIndex::Account : ESqlConfigIndex::Player)]);
|
||||
if (!g_bAuthServer)
|
||||
ValidateSqlConfigOrExit("LOG_SQL", logConfig);
|
||||
ValidateAdminPageConfigOrExit();
|
||||
|
||||
// Common DB 가 Locale 정보를 가지고 있기 때문에 가장 먼저 접속해야 한다.
|
||||
AccountDB::instance().Connect(db_host[2], mysql_db_port[2], db_user[2], db_pwd[2], db_db[2]);
|
||||
const SqlConnectionConfig& commonDb = dbConfig[static_cast<size_t>(ESqlConfigIndex::Common)];
|
||||
AccountDB::instance().Connect(commonDb.host.c_str(), commonDb.port, commonDb.user.c_str(), commonDb.password.c_str(), commonDb.database.c_str());
|
||||
|
||||
if (false == AccountDB::instance().IsConnected())
|
||||
{
|
||||
@@ -884,13 +946,14 @@ void config_init(const string& st_localeServiceName)
|
||||
|
||||
AccountDB::instance().SetLocale(g_stLocale);
|
||||
|
||||
AccountDB::instance().ConnectAsync(db_host[2], mysql_db_port[2], db_user[2], db_pwd[2], db_db[2], g_stLocale.c_str());
|
||||
AccountDB::instance().ConnectAsync(commonDb.host.c_str(), commonDb.port, commonDb.user.c_str(), commonDb.password.c_str(), commonDb.database.c_str(), g_stLocale.c_str());
|
||||
|
||||
// Player DB 접속
|
||||
const SqlConnectionConfig& playerDb = dbConfig[static_cast<size_t>(g_bAuthServer ? ESqlConfigIndex::Account : ESqlConfigIndex::Player)];
|
||||
if (g_bAuthServer)
|
||||
DBManager::instance().Connect(db_host[0], mysql_db_port[0], db_user[0], db_pwd[0], db_db[0]);
|
||||
DBManager::instance().Connect(playerDb.host.c_str(), playerDb.port, playerDb.user.c_str(), playerDb.password.c_str(), playerDb.database.c_str());
|
||||
else
|
||||
DBManager::instance().Connect(db_host[1], mysql_db_port[1], db_user[1], db_pwd[1], db_db[1]);
|
||||
DBManager::instance().Connect(playerDb.host.c_str(), playerDb.port, playerDb.user.c_str(), playerDb.password.c_str(), playerDb.database.c_str());
|
||||
|
||||
if (!DBManager::instance().IsConnected())
|
||||
{
|
||||
@@ -903,7 +966,7 @@ void config_init(const string& st_localeServiceName)
|
||||
if (false == g_bAuthServer) // 인증 서버가 아닐 경우
|
||||
{
|
||||
// Log DB 접속
|
||||
LogManager::instance().Connect(log_host, log_port, log_user, log_pwd, log_db);
|
||||
LogManager::instance().Connect(logConfig.host.c_str(), logConfig.port, logConfig.user.c_str(), logConfig.password.c_str(), logConfig.database.c_str());
|
||||
|
||||
if (!LogManager::instance().IsConnected())
|
||||
{
|
||||
@@ -1238,4 +1301,3 @@ bool IsValidFileCRC(DWORD dwCRC)
|
||||
return s_set_dwFileCRC.find(dwCRC) != s_set_dwFileCRC.end();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@ enum
|
||||
void config_init(const std::string& st_localeServiceName); // default "" is CONFIG
|
||||
|
||||
extern char sql_addr[256];
|
||||
bool IsAdminPageEnabled();
|
||||
|
||||
extern WORD mother_port;
|
||||
extern WORD p2p_port;
|
||||
@@ -106,4 +107,3 @@ extern int gPlayerMaxLevel;
|
||||
extern bool g_BlockCharCreation;
|
||||
|
||||
#endif /* __INC_METIN_II_GAME_CONFIG_H__ */
|
||||
|
||||
|
||||
@@ -18,19 +18,35 @@
|
||||
|
||||
extern time_t get_global_time();
|
||||
|
||||
bool IsEmptyAdminPage()
|
||||
namespace
|
||||
{
|
||||
return g_stAdminPageIP.empty();
|
||||
}
|
||||
|
||||
bool IsAdminPage(const char * ip)
|
||||
{
|
||||
for (size_t n = 0; n < g_stAdminPageIP.size(); ++n)
|
||||
bool IsEmptyAdminPage()
|
||||
{
|
||||
if (g_stAdminPageIP[n] == ip)
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
return g_stAdminPageIP.empty();
|
||||
}
|
||||
|
||||
bool IsAdminPage(const char * ip)
|
||||
{
|
||||
for (size_t n = 0; n < g_stAdminPageIP.size(); ++n)
|
||||
{
|
||||
if (g_stAdminPageIP[n] == ip)
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool HasAdminPageIpAccess(const char* ip)
|
||||
{
|
||||
if (!IsAdminPageEnabled())
|
||||
return false;
|
||||
|
||||
return IsEmptyAdminPage() || IsAdminPage(ip);
|
||||
}
|
||||
|
||||
bool IsAdminCommandAuthorized(LPDESC d)
|
||||
{
|
||||
return d->IsAdminMode();
|
||||
}
|
||||
}
|
||||
|
||||
CInputProcessor::CInputProcessor() : m_pPacketInfo(NULL), m_iBufferLeft(0)
|
||||
@@ -245,14 +261,15 @@ int CInputHandshake::HandleText(LPDESC d, const char * c_pData)
|
||||
stResult = "YES";
|
||||
}
|
||||
//else if (!stBuf.compare("SHOWMETHEMONEY"))
|
||||
else if (stBuf == g_stAdminPagePassword)
|
||||
else if (IsAdminPageEnabled() && stBuf == g_stAdminPagePassword)
|
||||
{
|
||||
const char* hostIp = inet_ntoa(d->GetAddr().sin_addr);
|
||||
if (!IsEmptyAdminPage())
|
||||
{
|
||||
if (!IsAdminPage(inet_ntoa(d->GetAddr().sin_addr)))
|
||||
if (!IsAdminPage(hostIp))
|
||||
{
|
||||
char szTmp[64];
|
||||
snprintf(szTmp, sizeof(szTmp), "WEBADMIN : Wrong Connector : %s", inet_ntoa(d->GetAddr().sin_addr));
|
||||
snprintf(szTmp, sizeof(szTmp), "WEBADMIN : Wrong Connector : %s", hostIp);
|
||||
stResult += szTmp;
|
||||
}
|
||||
else
|
||||
@@ -270,21 +287,14 @@ int CInputHandshake::HandleText(LPDESC d, const char * c_pData)
|
||||
else if (!stBuf.compare("USER_COUNT"))
|
||||
{
|
||||
char szTmp[64];
|
||||
const char* hostIp = inet_ntoa(d->GetAddr().sin_addr);
|
||||
|
||||
if (!IsEmptyAdminPage())
|
||||
if (!HasAdminPageIpAccess(hostIp))
|
||||
{
|
||||
if (!IsAdminPage(inet_ntoa(d->GetAddr().sin_addr)))
|
||||
{
|
||||
snprintf(szTmp, sizeof(szTmp), "WEBADMIN : Wrong Connector : %s", inet_ntoa(d->GetAddr().sin_addr));
|
||||
}
|
||||
if (IsAdminPageEnabled())
|
||||
snprintf(szTmp, sizeof(szTmp), "WEBADMIN : Wrong Connector : %s", hostIp);
|
||||
else
|
||||
{
|
||||
int iTotal;
|
||||
int * paiEmpireUserCount;
|
||||
int iLocal;
|
||||
DESC_MANAGER::instance().GetUserCount(iTotal, &paiEmpireUserCount, iLocal);
|
||||
snprintf(szTmp, sizeof(szTmp), "%d %d %d %d %d", iTotal, paiEmpireUserCount[1], paiEmpireUserCount[2], paiEmpireUserCount[3], iLocal);
|
||||
}
|
||||
strlcpy(szTmp, "WEBADMIN : Disabled", sizeof(szTmp));
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -298,48 +308,68 @@ int CInputHandshake::HandleText(LPDESC d, const char * c_pData)
|
||||
}
|
||||
else if (!stBuf.compare("CHECK_P2P_CONNECTIONS"))
|
||||
{
|
||||
std::ostringstream oss(std::ostringstream::out);
|
||||
|
||||
oss << "P2P CONNECTION NUMBER : " << P2P_MANAGER::instance().GetDescCount() << "\n";
|
||||
std::string hostNames;
|
||||
P2P_MANAGER::Instance().GetP2PHostNames(hostNames);
|
||||
oss << hostNames;
|
||||
stResult = oss.str();
|
||||
TPacketGGCheckAwakeness packet;
|
||||
packet.header = GG::CHECK_AWAKENESS;
|
||||
packet.length = sizeof(packet);
|
||||
if (!IsAdminCommandAuthorized(d))
|
||||
stResult = "UNKNOWN";
|
||||
else
|
||||
{
|
||||
std::ostringstream oss(std::ostringstream::out);
|
||||
|
||||
P2P_MANAGER::instance().Send(&packet, sizeof(packet));
|
||||
oss << "P2P CONNECTION NUMBER : " << P2P_MANAGER::instance().GetDescCount() << "\n";
|
||||
std::string hostNames;
|
||||
P2P_MANAGER::Instance().GetP2PHostNames(hostNames);
|
||||
oss << hostNames;
|
||||
stResult = oss.str();
|
||||
TPacketGGCheckAwakeness packet;
|
||||
packet.header = GG::CHECK_AWAKENESS;
|
||||
packet.length = sizeof(packet);
|
||||
|
||||
P2P_MANAGER::instance().Send(&packet, sizeof(packet));
|
||||
}
|
||||
}
|
||||
else if (!stBuf.compare("PACKET_INFO"))
|
||||
{
|
||||
m_pMainPacketInfo->Log("packet_info.txt");
|
||||
stResult = "OK";
|
||||
if (!IsAdminCommandAuthorized(d))
|
||||
stResult = "UNKNOWN";
|
||||
else
|
||||
{
|
||||
m_pMainPacketInfo->Log("packet_info.txt");
|
||||
stResult = "OK";
|
||||
}
|
||||
}
|
||||
else if (!stBuf.compare("PROFILE"))
|
||||
{
|
||||
CProfiler::instance().Log("profile.txt");
|
||||
stResult = "OK";
|
||||
if (!IsAdminCommandAuthorized(d))
|
||||
stResult = "UNKNOWN";
|
||||
else
|
||||
{
|
||||
CProfiler::instance().Log("profile.txt");
|
||||
stResult = "OK";
|
||||
}
|
||||
}
|
||||
//gift notify delete command
|
||||
else if (!stBuf.compare(0,15,"DELETE_AWARDID "))
|
||||
{
|
||||
char szTmp[64];
|
||||
std::string msg = stBuf.substr(15,26); // item_award의 id범위?
|
||||
|
||||
TPacketDeleteAwardID p;
|
||||
p.dwID = (DWORD)(atoi(msg.c_str()));
|
||||
snprintf(szTmp,sizeof(szTmp),"Sent to DB cache to delete ItemAward, id: %d",p.dwID);
|
||||
//sys_log(0,"%d",p.dwID);
|
||||
// strlcpy(p.login, msg.c_str(), sizeof(p.login));
|
||||
db_clientdesc->DBPacket(GD::DELETE_AWARDID, 0, &p, sizeof(p));
|
||||
stResult += szTmp;
|
||||
if (!IsAdminCommandAuthorized(d))
|
||||
stResult = "UNKNOWN";
|
||||
else
|
||||
{
|
||||
char szTmp[64];
|
||||
std::string msg = stBuf.substr(15,26); // item_award의 id범위?
|
||||
|
||||
TPacketDeleteAwardID p;
|
||||
p.dwID = (DWORD)(atoi(msg.c_str()));
|
||||
snprintf(szTmp,sizeof(szTmp),"Sent to DB cache to delete ItemAward, id: %d",p.dwID);
|
||||
//sys_log(0,"%d",p.dwID);
|
||||
// strlcpy(p.login, msg.c_str(), sizeof(p.login));
|
||||
db_clientdesc->DBPacket(GD::DELETE_AWARDID, 0, &p, sizeof(p));
|
||||
stResult += szTmp;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
stResult = "UNKNOWN";
|
||||
|
||||
if (d->IsAdminMode())
|
||||
else
|
||||
{
|
||||
stResult = "UNKNOWN";
|
||||
|
||||
if (d->IsAdminMode())
|
||||
{
|
||||
// 어드민 명령들
|
||||
if (!stBuf.compare(0, 7, "NOTICE "))
|
||||
|
||||
Reference in New Issue
Block a user