mirror of
https://github.com/EQEmu/Server.git
synced 2025-12-13 18:51:29 +00:00
[Feature] Client Checksum Verification (Resubmit old 1678) (#1922)
* [Feature] Client Checksum Verification (Resubmit old 1678) * Updated db version * Add new updatechecksum to CmakeLists.txt * Removed magic number and used constant * Fix new command to have access to worldserver * spacing, more venbose desc and remove unneeded check * Cleanup, refactoring Co-authored-by: Akkadius <akkadius1@gmail.com>
This commit is contained in:
parent
eca2ed0321
commit
2a5ddde78a
@ -997,6 +997,18 @@ bool Database::SetVariable(const std::string varname, const std::string &varvalu
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Database::SetAccountCRCField(uint32 account_id, std::string field_name, uint64 checksum)
|
||||||
|
{
|
||||||
|
QueryDatabase(
|
||||||
|
fmt::format(
|
||||||
|
"UPDATE `account` SET `{}` = '{}' WHERE `id` = {}",
|
||||||
|
field_name,
|
||||||
|
checksum,
|
||||||
|
account_id
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
// Get zone starting points from DB
|
// Get zone starting points from DB
|
||||||
bool Database::GetSafePoints(const char* zone_short_name, uint32 instance_version, float* safe_x, float* safe_y, float* safe_z, float* safe_heading, int16* min_status, uint8* min_level, char *flag_needed) {
|
bool Database::GetSafePoints(const char* zone_short_name, uint32 instance_version, float* safe_x, float* safe_y, float* safe_z, float* safe_heading, int16* min_status, uint8* min_level, char *flag_needed) {
|
||||||
|
|
||||||
@ -2285,7 +2297,7 @@ void Database::SetIPExemption(std::string account_ip, int exemption_amount) {
|
|||||||
auto row = results.begin();
|
auto row = results.begin();
|
||||||
exemption_id = atoi(row[0]);
|
exemption_id = atoi(row[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
query = fmt::format(
|
query = fmt::format(
|
||||||
"INSERT INTO `ip_exemptions` (`exemption_ip`, `exemption_amount`) VALUES ('{}', {})",
|
"INSERT INTO `ip_exemptions` (`exemption_ip`, `exemption_amount`) VALUES ('{}', {})",
|
||||||
account_ip,
|
account_ip,
|
||||||
|
|||||||
@ -190,6 +190,8 @@ public:
|
|||||||
|
|
||||||
int16 CheckStatus(uint32 account_id);
|
int16 CheckStatus(uint32 account_id);
|
||||||
|
|
||||||
|
void SetAccountCRCField(uint32 account_id, std::string field_name, uint64 checksum);
|
||||||
|
|
||||||
uint32 CheckLogin(const char* name, const char* password, const char *loginserver, int16* oStatus = 0);
|
uint32 CheckLogin(const char* name, const char* password, const char *loginserver, int16* oStatus = 0);
|
||||||
uint32 CreateAccount(const char* name, const char* password, int16 status, const char* loginserver, uint32 lsaccount_id);
|
uint32 CreateAccount(const char* name, const char* password, int16 status, const char* loginserver, uint32 lsaccount_id);
|
||||||
uint32 GetAccountIDFromLSID(const std::string& in_loginserver_id, uint32 in_loginserver_account_id, char* in_account_name = 0, int16* in_status = 0);
|
uint32 GetAccountIDFromLSID(const std::string& in_loginserver_id, uint32 in_loginserver_account_id, char* in_account_name = 0, int16* in_status = 0);
|
||||||
|
|||||||
@ -558,6 +558,7 @@ N(OP_WhoAllRequest),
|
|||||||
N(OP_WhoAllResponse),
|
N(OP_WhoAllResponse),
|
||||||
N(OP_World_Client_CRC1),
|
N(OP_World_Client_CRC1),
|
||||||
N(OP_World_Client_CRC2),
|
N(OP_World_Client_CRC2),
|
||||||
|
N(OP_World_Client_CRC3),
|
||||||
N(OP_WorldClientReady),
|
N(OP_WorldClientReady),
|
||||||
N(OP_WorldComplete),
|
N(OP_WorldComplete),
|
||||||
N(OP_WorldLogout),
|
N(OP_WorldLogout),
|
||||||
|
|||||||
@ -5582,6 +5582,11 @@ struct SayLinkBodyFrame_Struct {
|
|||||||
/*056*/
|
/*056*/
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct Checksum_Struct {
|
||||||
|
uint64 checksum;
|
||||||
|
uint8 data[2048];
|
||||||
|
};
|
||||||
|
|
||||||
struct UpdateMovementEntry {
|
struct UpdateMovementEntry {
|
||||||
/* 00 */ float Y;
|
/* 00 */ float Y;
|
||||||
/* 04 */ float X;
|
/* 04 */ float X;
|
||||||
|
|||||||
@ -116,22 +116,24 @@ EQEmuLogSys *EQEmuLogSys::LoadLogSettingsDefaults()
|
|||||||
/**
|
/**
|
||||||
* Set Defaults
|
* Set Defaults
|
||||||
*/
|
*/
|
||||||
log_settings[Logs::WorldServer].log_to_console = static_cast<uint8>(Logs::General);
|
log_settings[Logs::WorldServer].log_to_console = static_cast<uint8>(Logs::General);
|
||||||
log_settings[Logs::ZoneServer].log_to_console = static_cast<uint8>(Logs::General);
|
log_settings[Logs::ZoneServer].log_to_console = static_cast<uint8>(Logs::General);
|
||||||
log_settings[Logs::QSServer].log_to_console = static_cast<uint8>(Logs::General);
|
log_settings[Logs::QSServer].log_to_console = static_cast<uint8>(Logs::General);
|
||||||
log_settings[Logs::UCSServer].log_to_console = static_cast<uint8>(Logs::General);
|
log_settings[Logs::UCSServer].log_to_console = static_cast<uint8>(Logs::General);
|
||||||
log_settings[Logs::Crash].log_to_console = static_cast<uint8>(Logs::General);
|
log_settings[Logs::Crash].log_to_console = static_cast<uint8>(Logs::General);
|
||||||
log_settings[Logs::MySQLError].log_to_console = static_cast<uint8>(Logs::General);
|
log_settings[Logs::MySQLError].log_to_console = static_cast<uint8>(Logs::General);
|
||||||
log_settings[Logs::Loginserver].log_to_console = static_cast<uint8>(Logs::General);
|
log_settings[Logs::Loginserver].log_to_console = static_cast<uint8>(Logs::General);
|
||||||
log_settings[Logs::HeadlessClient].log_to_console = static_cast<uint8>(Logs::General);
|
log_settings[Logs::HeadlessClient].log_to_console = static_cast<uint8>(Logs::General);
|
||||||
log_settings[Logs::NPCScaling].log_to_gmsay = static_cast<uint8>(Logs::General);
|
log_settings[Logs::NPCScaling].log_to_gmsay = static_cast<uint8>(Logs::General);
|
||||||
log_settings[Logs::HotReload].log_to_gmsay = static_cast<uint8>(Logs::General);
|
log_settings[Logs::HotReload].log_to_gmsay = static_cast<uint8>(Logs::General);
|
||||||
log_settings[Logs::HotReload].log_to_console = static_cast<uint8>(Logs::General);
|
log_settings[Logs::HotReload].log_to_console = static_cast<uint8>(Logs::General);
|
||||||
log_settings[Logs::Loot].log_to_gmsay = static_cast<uint8>(Logs::General);
|
log_settings[Logs::Loot].log_to_gmsay = static_cast<uint8>(Logs::General);
|
||||||
log_settings[Logs::Scheduler].log_to_console = static_cast<uint8>(Logs::General);
|
log_settings[Logs::Scheduler].log_to_console = static_cast<uint8>(Logs::General);
|
||||||
log_settings[Logs::Cheat].log_to_console = static_cast<uint8>(Logs::General);
|
log_settings[Logs::Cheat].log_to_console = static_cast<uint8>(Logs::General);
|
||||||
log_settings[Logs::HTTP].log_to_console = static_cast<uint8>(Logs::General);
|
log_settings[Logs::HTTP].log_to_console = static_cast<uint8>(Logs::General);
|
||||||
log_settings[Logs::HTTP].log_to_gmsay = static_cast<uint8>(Logs::General);
|
log_settings[Logs::HTTP].log_to_gmsay = static_cast<uint8>(Logs::General);
|
||||||
|
log_settings[Logs::ChecksumVerification].log_to_console = static_cast<uint8>(Logs::General);
|
||||||
|
log_settings[Logs::ChecksumVerification].log_to_gmsay = static_cast<uint8>(Logs::General);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* RFC 5424
|
* RFC 5424
|
||||||
@ -241,7 +243,7 @@ void EQEmuLogSys::ProcessGMSay(
|
|||||||
*/
|
*/
|
||||||
if (EQEmuLogSys::log_platform == EQEmuExePlatform::ExePlatformZone ||
|
if (EQEmuLogSys::log_platform == EQEmuExePlatform::ExePlatformZone ||
|
||||||
EQEmuLogSys::log_platform == EQEmuExePlatform::ExePlatformWorld
|
EQEmuLogSys::log_platform == EQEmuExePlatform::ExePlatformWorld
|
||||||
) {
|
) {
|
||||||
on_log_gmsay_hook(log_category, message);
|
on_log_gmsay_hook(log_category, message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -127,6 +127,7 @@ namespace Logs {
|
|||||||
DiaWind,
|
DiaWind,
|
||||||
HTTP,
|
HTTP,
|
||||||
Saylink,
|
Saylink,
|
||||||
|
ChecksumVerification,
|
||||||
MaxCategoryID /* Don't Remove this */
|
MaxCategoryID /* Don't Remove this */
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -212,6 +213,7 @@ namespace Logs {
|
|||||||
"DialogueWindow",
|
"DialogueWindow",
|
||||||
"HTTP",
|
"HTTP",
|
||||||
"Saylink",
|
"Saylink",
|
||||||
|
"ChecksumVerification",
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -696,6 +696,16 @@
|
|||||||
OutF(LogSys, Logs::Detail, Logs::Saylink, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
OutF(LogSys, Logs::Detail, Logs::Saylink, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
|
#define LogChecksumVerification(message, ...) do {\
|
||||||
|
if (LogSys.log_settings[Logs::ChecksumVerification].is_category_enabled == 1)\
|
||||||
|
OutF(LogSys, Logs::General, Logs::ChecksumVerification, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define LogChecksumVerificationDetail(message, ...) do {\
|
||||||
|
if (LogSys.log_settings[Logs::ChecksumVerification].is_category_enabled == 1)\
|
||||||
|
OutF(LogSys, Logs::Detail, Logs::ChecksumVerification, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||||
|
} while (0)
|
||||||
|
|
||||||
#define Log(debug_level, log_category, message, ...) do {\
|
#define Log(debug_level, log_category, message, ...) do {\
|
||||||
if (LogSys.log_settings[log_category].is_category_enabled == 1)\
|
if (LogSys.log_settings[log_category].is_category_enabled == 1)\
|
||||||
LogSys.Out(debug_level, log_category, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
LogSys.Out(debug_level, log_category, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||||
@ -1092,6 +1102,18 @@
|
|||||||
#define LogHTTPDetail(message, ...) do {\
|
#define LogHTTPDetail(message, ...) do {\
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
|
#define LogSaylink(message, ...) do {\
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define LogSaylinkDetail(message, ...) do {\
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define LogChecksumVerification(message, ...) do {\
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define LogChecksumVerificationDetail(message, ...) do {\
|
||||||
|
} while (0)
|
||||||
|
|
||||||
#define Log(debug_level, log_category, message, ...) do {\
|
#define Log(debug_level, log_category, message, ...) do {\
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
|
|||||||
@ -5218,6 +5218,11 @@ struct SayLinkBodyFrame_Struct {
|
|||||||
/*056*/
|
/*056*/
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct Checksum_Struct {
|
||||||
|
uint64_t checksum;
|
||||||
|
uint8_t data[2048];
|
||||||
|
};
|
||||||
|
|
||||||
}; /*structs*/
|
}; /*structs*/
|
||||||
|
|
||||||
}; /*RoF2*/
|
}; /*RoF2*/
|
||||||
|
|||||||
@ -14,6 +14,7 @@
|
|||||||
|
|
||||||
#include "../../database.h"
|
#include "../../database.h"
|
||||||
#include "../../string_util.h"
|
#include "../../string_util.h"
|
||||||
|
#include <ctime>
|
||||||
|
|
||||||
class BaseAccountRepository {
|
class BaseAccountRepository {
|
||||||
public:
|
public:
|
||||||
@ -32,11 +33,14 @@ public:
|
|||||||
std::string minilogin_ip;
|
std::string minilogin_ip;
|
||||||
int hideme;
|
int hideme;
|
||||||
int rulesflag;
|
int rulesflag;
|
||||||
std::string suspendeduntil;
|
time_t suspendeduntil;
|
||||||
int time_creation;
|
int time_creation;
|
||||||
int expansion;
|
int expansion;
|
||||||
std::string ban_reason;
|
std::string ban_reason;
|
||||||
std::string suspend_reason;
|
std::string suspend_reason;
|
||||||
|
std::string crc_eqgame;
|
||||||
|
std::string crc_skillcaps;
|
||||||
|
std::string crc_basedata;
|
||||||
};
|
};
|
||||||
|
|
||||||
static std::string PrimaryKey()
|
static std::string PrimaryKey()
|
||||||
@ -66,6 +70,37 @@ public:
|
|||||||
"expansion",
|
"expansion",
|
||||||
"ban_reason",
|
"ban_reason",
|
||||||
"suspend_reason",
|
"suspend_reason",
|
||||||
|
"crc_eqgame",
|
||||||
|
"crc_skillcaps",
|
||||||
|
"crc_basedata",
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::vector<std::string> SelectColumns()
|
||||||
|
{
|
||||||
|
return {
|
||||||
|
"id",
|
||||||
|
"name",
|
||||||
|
"charname",
|
||||||
|
"sharedplat",
|
||||||
|
"password",
|
||||||
|
"status",
|
||||||
|
"ls_id",
|
||||||
|
"lsaccount_id",
|
||||||
|
"gmspeed",
|
||||||
|
"revoked",
|
||||||
|
"karma",
|
||||||
|
"minilogin_ip",
|
||||||
|
"hideme",
|
||||||
|
"rulesflag",
|
||||||
|
"UNIX_TIMESTAMP(suspendeduntil)",
|
||||||
|
"time_creation",
|
||||||
|
"expansion",
|
||||||
|
"ban_reason",
|
||||||
|
"suspend_reason",
|
||||||
|
"crc_eqgame",
|
||||||
|
"crc_skillcaps",
|
||||||
|
"crc_basedata",
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -74,6 +109,11 @@ public:
|
|||||||
return std::string(implode(", ", Columns()));
|
return std::string(implode(", ", Columns()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static std::string SelectColumnsRaw()
|
||||||
|
{
|
||||||
|
return std::string(implode(", ", SelectColumns()));
|
||||||
|
}
|
||||||
|
|
||||||
static std::string TableName()
|
static std::string TableName()
|
||||||
{
|
{
|
||||||
return std::string("account");
|
return std::string("account");
|
||||||
@ -83,7 +123,7 @@ public:
|
|||||||
{
|
{
|
||||||
return fmt::format(
|
return fmt::format(
|
||||||
"SELECT {} FROM {}",
|
"SELECT {} FROM {}",
|
||||||
ColumnsRaw(),
|
SelectColumnsRaw(),
|
||||||
TableName()
|
TableName()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -115,11 +155,14 @@ public:
|
|||||||
entry.minilogin_ip = "";
|
entry.minilogin_ip = "";
|
||||||
entry.hideme = 0;
|
entry.hideme = 0;
|
||||||
entry.rulesflag = 0;
|
entry.rulesflag = 0;
|
||||||
entry.suspendeduntil = "0000-00-00 00:00:00";
|
entry.suspendeduntil = 0;
|
||||||
entry.time_creation = 0;
|
entry.time_creation = 0;
|
||||||
entry.expansion = 0;
|
entry.expansion = 0;
|
||||||
entry.ban_reason = "";
|
entry.ban_reason = "";
|
||||||
entry.suspend_reason = "";
|
entry.suspend_reason = "";
|
||||||
|
entry.crc_eqgame = "";
|
||||||
|
entry.crc_skillcaps = "";
|
||||||
|
entry.crc_basedata = "";
|
||||||
|
|
||||||
return entry;
|
return entry;
|
||||||
}
|
}
|
||||||
@ -169,11 +212,14 @@ public:
|
|||||||
entry.minilogin_ip = row[11] ? row[11] : "";
|
entry.minilogin_ip = row[11] ? row[11] : "";
|
||||||
entry.hideme = atoi(row[12]);
|
entry.hideme = atoi(row[12]);
|
||||||
entry.rulesflag = atoi(row[13]);
|
entry.rulesflag = atoi(row[13]);
|
||||||
entry.suspendeduntil = row[14] ? row[14] : "";
|
entry.suspendeduntil = strtoll(row[14] ? row[14] : "-1", nullptr, 10);
|
||||||
entry.time_creation = atoi(row[15]);
|
entry.time_creation = atoi(row[15]);
|
||||||
entry.expansion = atoi(row[16]);
|
entry.expansion = atoi(row[16]);
|
||||||
entry.ban_reason = row[17] ? row[17] : "";
|
entry.ban_reason = row[17] ? row[17] : "";
|
||||||
entry.suspend_reason = row[18] ? row[18] : "";
|
entry.suspend_reason = row[18] ? row[18] : "";
|
||||||
|
entry.crc_eqgame = row[19] ? row[19] : "";
|
||||||
|
entry.crc_skillcaps = row[20] ? row[20] : "";
|
||||||
|
entry.crc_basedata = row[21] ? row[21] : "";
|
||||||
|
|
||||||
return entry;
|
return entry;
|
||||||
}
|
}
|
||||||
@ -220,11 +266,14 @@ public:
|
|||||||
update_values.push_back(columns[11] + " = '" + EscapeString(account_entry.minilogin_ip) + "'");
|
update_values.push_back(columns[11] + " = '" + EscapeString(account_entry.minilogin_ip) + "'");
|
||||||
update_values.push_back(columns[12] + " = " + std::to_string(account_entry.hideme));
|
update_values.push_back(columns[12] + " = " + std::to_string(account_entry.hideme));
|
||||||
update_values.push_back(columns[13] + " = " + std::to_string(account_entry.rulesflag));
|
update_values.push_back(columns[13] + " = " + std::to_string(account_entry.rulesflag));
|
||||||
update_values.push_back(columns[14] + " = '" + EscapeString(account_entry.suspendeduntil) + "'");
|
update_values.push_back(columns[14] + " = FROM_UNIXTIME(" + (account_entry.suspendeduntil > 0 ? std::to_string(account_entry.suspendeduntil) : "null") + ")");
|
||||||
update_values.push_back(columns[15] + " = " + std::to_string(account_entry.time_creation));
|
update_values.push_back(columns[15] + " = " + std::to_string(account_entry.time_creation));
|
||||||
update_values.push_back(columns[16] + " = " + std::to_string(account_entry.expansion));
|
update_values.push_back(columns[16] + " = " + std::to_string(account_entry.expansion));
|
||||||
update_values.push_back(columns[17] + " = '" + EscapeString(account_entry.ban_reason) + "'");
|
update_values.push_back(columns[17] + " = '" + EscapeString(account_entry.ban_reason) + "'");
|
||||||
update_values.push_back(columns[18] + " = '" + EscapeString(account_entry.suspend_reason) + "'");
|
update_values.push_back(columns[18] + " = '" + EscapeString(account_entry.suspend_reason) + "'");
|
||||||
|
update_values.push_back(columns[19] + " = '" + EscapeString(account_entry.crc_eqgame) + "'");
|
||||||
|
update_values.push_back(columns[20] + " = '" + EscapeString(account_entry.crc_skillcaps) + "'");
|
||||||
|
update_values.push_back(columns[21] + " = '" + EscapeString(account_entry.crc_basedata) + "'");
|
||||||
|
|
||||||
auto results = db.QueryDatabase(
|
auto results = db.QueryDatabase(
|
||||||
fmt::format(
|
fmt::format(
|
||||||
@ -260,11 +309,14 @@ public:
|
|||||||
insert_values.push_back("'" + EscapeString(account_entry.minilogin_ip) + "'");
|
insert_values.push_back("'" + EscapeString(account_entry.minilogin_ip) + "'");
|
||||||
insert_values.push_back(std::to_string(account_entry.hideme));
|
insert_values.push_back(std::to_string(account_entry.hideme));
|
||||||
insert_values.push_back(std::to_string(account_entry.rulesflag));
|
insert_values.push_back(std::to_string(account_entry.rulesflag));
|
||||||
insert_values.push_back("'" + EscapeString(account_entry.suspendeduntil) + "'");
|
insert_values.push_back("FROM_UNIXTIME(" + (account_entry.suspendeduntil > 0 ? std::to_string(account_entry.suspendeduntil) : "null") + ")");
|
||||||
insert_values.push_back(std::to_string(account_entry.time_creation));
|
insert_values.push_back(std::to_string(account_entry.time_creation));
|
||||||
insert_values.push_back(std::to_string(account_entry.expansion));
|
insert_values.push_back(std::to_string(account_entry.expansion));
|
||||||
insert_values.push_back("'" + EscapeString(account_entry.ban_reason) + "'");
|
insert_values.push_back("'" + EscapeString(account_entry.ban_reason) + "'");
|
||||||
insert_values.push_back("'" + EscapeString(account_entry.suspend_reason) + "'");
|
insert_values.push_back("'" + EscapeString(account_entry.suspend_reason) + "'");
|
||||||
|
insert_values.push_back("'" + EscapeString(account_entry.crc_eqgame) + "'");
|
||||||
|
insert_values.push_back("'" + EscapeString(account_entry.crc_skillcaps) + "'");
|
||||||
|
insert_values.push_back("'" + EscapeString(account_entry.crc_basedata) + "'");
|
||||||
|
|
||||||
auto results = db.QueryDatabase(
|
auto results = db.QueryDatabase(
|
||||||
fmt::format(
|
fmt::format(
|
||||||
@ -308,11 +360,14 @@ public:
|
|||||||
insert_values.push_back("'" + EscapeString(account_entry.minilogin_ip) + "'");
|
insert_values.push_back("'" + EscapeString(account_entry.minilogin_ip) + "'");
|
||||||
insert_values.push_back(std::to_string(account_entry.hideme));
|
insert_values.push_back(std::to_string(account_entry.hideme));
|
||||||
insert_values.push_back(std::to_string(account_entry.rulesflag));
|
insert_values.push_back(std::to_string(account_entry.rulesflag));
|
||||||
insert_values.push_back("'" + EscapeString(account_entry.suspendeduntil) + "'");
|
insert_values.push_back("FROM_UNIXTIME(" + (account_entry.suspendeduntil > 0 ? std::to_string(account_entry.suspendeduntil) : "null") + ")");
|
||||||
insert_values.push_back(std::to_string(account_entry.time_creation));
|
insert_values.push_back(std::to_string(account_entry.time_creation));
|
||||||
insert_values.push_back(std::to_string(account_entry.expansion));
|
insert_values.push_back(std::to_string(account_entry.expansion));
|
||||||
insert_values.push_back("'" + EscapeString(account_entry.ban_reason) + "'");
|
insert_values.push_back("'" + EscapeString(account_entry.ban_reason) + "'");
|
||||||
insert_values.push_back("'" + EscapeString(account_entry.suspend_reason) + "'");
|
insert_values.push_back("'" + EscapeString(account_entry.suspend_reason) + "'");
|
||||||
|
insert_values.push_back("'" + EscapeString(account_entry.crc_eqgame) + "'");
|
||||||
|
insert_values.push_back("'" + EscapeString(account_entry.crc_skillcaps) + "'");
|
||||||
|
insert_values.push_back("'" + EscapeString(account_entry.crc_basedata) + "'");
|
||||||
|
|
||||||
insert_chunks.push_back("(" + implode(",", insert_values) + ")");
|
insert_chunks.push_back("(" + implode(",", insert_values) + ")");
|
||||||
}
|
}
|
||||||
@ -360,11 +415,14 @@ public:
|
|||||||
entry.minilogin_ip = row[11] ? row[11] : "";
|
entry.minilogin_ip = row[11] ? row[11] : "";
|
||||||
entry.hideme = atoi(row[12]);
|
entry.hideme = atoi(row[12]);
|
||||||
entry.rulesflag = atoi(row[13]);
|
entry.rulesflag = atoi(row[13]);
|
||||||
entry.suspendeduntil = row[14] ? row[14] : "";
|
entry.suspendeduntil = strtoll(row[14] ? row[14] : "-1", nullptr, 10);
|
||||||
entry.time_creation = atoi(row[15]);
|
entry.time_creation = atoi(row[15]);
|
||||||
entry.expansion = atoi(row[16]);
|
entry.expansion = atoi(row[16]);
|
||||||
entry.ban_reason = row[17] ? row[17] : "";
|
entry.ban_reason = row[17] ? row[17] : "";
|
||||||
entry.suspend_reason = row[18] ? row[18] : "";
|
entry.suspend_reason = row[18] ? row[18] : "";
|
||||||
|
entry.crc_eqgame = row[19] ? row[19] : "";
|
||||||
|
entry.crc_skillcaps = row[20] ? row[20] : "";
|
||||||
|
entry.crc_basedata = row[21] ? row[21] : "";
|
||||||
|
|
||||||
all_entries.push_back(entry);
|
all_entries.push_back(entry);
|
||||||
}
|
}
|
||||||
@ -403,11 +461,14 @@ public:
|
|||||||
entry.minilogin_ip = row[11] ? row[11] : "";
|
entry.minilogin_ip = row[11] ? row[11] : "";
|
||||||
entry.hideme = atoi(row[12]);
|
entry.hideme = atoi(row[12]);
|
||||||
entry.rulesflag = atoi(row[13]);
|
entry.rulesflag = atoi(row[13]);
|
||||||
entry.suspendeduntil = row[14] ? row[14] : "";
|
entry.suspendeduntil = strtoll(row[14] ? row[14] : "-1", nullptr, 10);
|
||||||
entry.time_creation = atoi(row[15]);
|
entry.time_creation = atoi(row[15]);
|
||||||
entry.expansion = atoi(row[16]);
|
entry.expansion = atoi(row[16]);
|
||||||
entry.ban_reason = row[17] ? row[17] : "";
|
entry.ban_reason = row[17] ? row[17] : "";
|
||||||
entry.suspend_reason = row[18] ? row[18] : "";
|
entry.suspend_reason = row[18] ? row[18] : "";
|
||||||
|
entry.crc_eqgame = row[19] ? row[19] : "";
|
||||||
|
entry.crc_skillcaps = row[20] ? row[20] : "";
|
||||||
|
entry.crc_basedata = row[21] ? row[21] : "";
|
||||||
|
|
||||||
all_entries.push_back(entry);
|
all_entries.push_back(entry);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -242,6 +242,7 @@ RULE_INT(GM, MinStatusToSummonItem, 250, "Minimum required status to summon item
|
|||||||
RULE_INT(GM, MinStatusToZoneAnywhere, 250, "Minimum required status to zone anywhere")
|
RULE_INT(GM, MinStatusToZoneAnywhere, 250, "Minimum required status to zone anywhere")
|
||||||
RULE_INT(GM, MinStatusToLevelTarget, 100, "Minimum required status to set the level of a player")
|
RULE_INT(GM, MinStatusToLevelTarget, 100, "Minimum required status to set the level of a player")
|
||||||
RULE_INT(GM, MinStatusToBypassLockedServer, 100, "Players >= this status can log in to the server even when it is locked")
|
RULE_INT(GM, MinStatusToBypassLockedServer, 100, "Players >= this status can log in to the server even when it is locked")
|
||||||
|
RULE_INT(GM, MinStatusToBypassCheckSumVerification, 100, "Players >= this status can bypass the eqgame.exe and spells_us.txt checksum verification")
|
||||||
RULE_CATEGORY_END()
|
RULE_CATEGORY_END()
|
||||||
|
|
||||||
RULE_CATEGORY(World)
|
RULE_CATEGORY(World)
|
||||||
@ -275,6 +276,7 @@ RULE_INT (World, TellQueueSize, 20, "Maximum tell queue size")
|
|||||||
RULE_BOOL(World, StartZoneSameAsBindOnCreation, true, "Should the start zone always be the same location as your bind?")
|
RULE_BOOL(World, StartZoneSameAsBindOnCreation, true, "Should the start zone always be the same location as your bind?")
|
||||||
RULE_BOOL(World, EnforceCharacterLimitAtLogin, false, "Enforce the limit for characters that are online at login")
|
RULE_BOOL(World, EnforceCharacterLimitAtLogin, false, "Enforce the limit for characters that are online at login")
|
||||||
RULE_BOOL(World, EnableDevTools, true, "Enable or Disable the Developer Tools globally (Most of the time you want this enabled)")
|
RULE_BOOL(World, EnableDevTools, true, "Enable or Disable the Developer Tools globally (Most of the time you want this enabled)")
|
||||||
|
RULE_BOOL(World, EnableChecksumVerification, false, "Enable or Disable the Checksum Verification for eqgame.exe and spells_us.txt")
|
||||||
RULE_CATEGORY_END()
|
RULE_CATEGORY_END()
|
||||||
|
|
||||||
RULE_CATEGORY(Zone)
|
RULE_CATEGORY(Zone)
|
||||||
|
|||||||
@ -227,6 +227,7 @@
|
|||||||
#define ServerOP_HotReloadQuests 0x4011
|
#define ServerOP_HotReloadQuests 0x4011
|
||||||
#define ServerOP_UpdateSchedulerEvents 0x4012
|
#define ServerOP_UpdateSchedulerEvents 0x4012
|
||||||
#define ServerOP_ReloadContentFlags 0x4013
|
#define ServerOP_ReloadContentFlags 0x4013
|
||||||
|
#define ServerOP_ReloadVariablesWorld 0x4014
|
||||||
|
|
||||||
#define ServerOP_CZDialogueWindow 0x4500
|
#define ServerOP_CZDialogueWindow 0x4500
|
||||||
#define ServerOP_CZLDoNUpdate 0x4501
|
#define ServerOP_CZLDoNUpdate 0x4501
|
||||||
|
|||||||
@ -34,7 +34,7 @@
|
|||||||
* Manifest: https://github.com/EQEmu/Server/blob/master/utils/sql/db_update_manifest.txt
|
* Manifest: https://github.com/EQEmu/Server/blob/master/utils/sql/db_update_manifest.txt
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define CURRENT_BINARY_DATABASE_VERSION 9175
|
#define CURRENT_BINARY_DATABASE_VERSION 9176
|
||||||
|
|
||||||
#ifdef BOTS
|
#ifdef BOTS
|
||||||
#define CURRENT_BINARY_BOTS_DATABASE_VERSION 9028
|
#define CURRENT_BINARY_BOTS_DATABASE_VERSION 9028
|
||||||
|
|||||||
@ -22,8 +22,9 @@ OP_ExpansionInfo=0x590d
|
|||||||
OP_GuildsList=0x507a
|
OP_GuildsList=0x507a
|
||||||
OP_EnterWorld=0x578f
|
OP_EnterWorld=0x578f
|
||||||
OP_PostEnterWorld=0x6259
|
OP_PostEnterWorld=0x6259
|
||||||
OP_World_Client_CRC1=0x12cc
|
OP_World_Client_CRC1=0x0f13
|
||||||
OP_World_Client_CRC2=0x0f13
|
OP_World_Client_CRC2=0x4b8d
|
||||||
|
OP_World_Client_CRC3=0x298d
|
||||||
OP_SendSpellChecksum=0x0000
|
OP_SendSpellChecksum=0x0000
|
||||||
OP_SendSkillCapsChecksum=0x0000
|
OP_SendSkillCapsChecksum=0x0000
|
||||||
|
|
||||||
|
|||||||
@ -249,6 +249,11 @@ foreach my $table_to_generate (@tables) {
|
|||||||
$default_value = '""';
|
$default_value = '""';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# for datetime values that set default value all zeroed out
|
||||||
|
if ($default_value =~ /0000-00-00 00:00:00/i) {
|
||||||
|
$default_value = 0;
|
||||||
|
}
|
||||||
|
|
||||||
my $struct_data_type = translate_mysql_data_type_to_c($data_type);
|
my $struct_data_type = translate_mysql_data_type_to_c($data_type);
|
||||||
|
|
||||||
# struct
|
# struct
|
||||||
|
|||||||
@ -429,6 +429,7 @@
|
|||||||
9173|2021_09_14_zone_lava_damage.sql|SHOW COLUMNS FROM `zone` LIKE 'lava_damage'|empty|
|
9173|2021_09_14_zone_lava_damage.sql|SHOW COLUMNS FROM `zone` LIKE 'lava_damage'|empty|
|
||||||
9174|2021_10_09_not_null_door_columns.sql|SELECT * FROM db_version WHERE version >= 9174|empty|
|
9174|2021_10_09_not_null_door_columns.sql|SELECT * FROM db_version WHERE version >= 9174|empty|
|
||||||
9175|2022_01_02_expansion_default_value_all.sql|SHOW COLUMNS FROM `forage` LIKE 'min_expansion'|contains|unsigned
|
9175|2022_01_02_expansion_default_value_all.sql|SHOW COLUMNS FROM `forage` LIKE 'min_expansion'|contains|unsigned
|
||||||
|
9176|2022_01_10_checksum_verification.sql|SHOW COLUMNS FROM `account` LIKE 'checksum_crc1_eqgame'|empty|
|
||||||
|
|
||||||
# Upgrade conditions:
|
# Upgrade conditions:
|
||||||
# This won't be needed after this system is implemented, but it is used database that are not
|
# This won't be needed after this system is implemented, but it is used database that are not
|
||||||
|
|||||||
10
utils/sql/git/required/2022_01_10_checksum_verification.sql
Normal file
10
utils/sql/git/required/2022_01_10_checksum_verification.sql
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
INSERT INTO `variables` (`varname`, `value`, `information`, `ts`) VALUES ('crc_eqgame', '0', 'Client CRC64 Checksum on: eqgame.exe', '2021-09-23 14:16:27');
|
||||||
|
INSERT INTO `variables` (`varname`, `value`, `information`, `ts`) VALUES ('crc_skillcaps', '0', 'Client CRC64 Checksum on: SkillCaps.txt', '2021-09-23 14:16:21');
|
||||||
|
INSERT INTO `variables` (`varname`, `value`, `information`, `ts`) VALUES ('crc_basedata', '0', 'Client CRC64 Checksum on: BaseData.txt','2021-09-23 14:16:21');
|
||||||
|
|
||||||
|
ALTER TABLE `account`
|
||||||
|
ADD COLUMN `crc_eqgame` TEXT NULL AFTER `suspend_reason`,
|
||||||
|
ADD COLUMN `crc_skillcaps` TEXT NULL AFTER `crc_eqgame`,
|
||||||
|
ADD COLUMN `crc_basedata` TEXT NULL AFTER `crc_skillcaps`;
|
||||||
|
|
||||||
|
ALTER TABLE account` CHANGE `suspendeduntil` `suspendeduntil` datetime NULL COMMENT '';
|
||||||
150
world/client.cpp
150
world/client.cpp
@ -47,6 +47,7 @@
|
|||||||
#include "wguild_mgr.h"
|
#include "wguild_mgr.h"
|
||||||
#include "sof_char_create_data.h"
|
#include "sof_char_create_data.h"
|
||||||
#include "world_store.h"
|
#include "world_store.h"
|
||||||
|
#include "../common/repositories/account_repository.h"
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <iomanip>
|
#include <iomanip>
|
||||||
@ -1013,15 +1014,18 @@ bool Client::HandlePacket(const EQApplicationPacket *app) {
|
|||||||
|
|
||||||
switch(opcode)
|
switch(opcode)
|
||||||
{
|
{
|
||||||
case OP_World_Client_CRC1:
|
case OP_World_Client_CRC1: // eqgame.exe
|
||||||
case OP_World_Client_CRC2:
|
case OP_World_Client_CRC2: // SkillCaps.txt
|
||||||
|
case OP_World_Client_CRC3: // BaseData.txt
|
||||||
{
|
{
|
||||||
// There is no obvious entry in the CC struct to indicate that the 'Start Tutorial button
|
// There is no obvious entry in the CC struct to indicate that the 'Start Tutorial button
|
||||||
// is selected when a character is created. I have observed that in this case, OP_EnterWorld is sent
|
// is selected when a character is created. I have observed that in this case, OP_EnterWorld is sent
|
||||||
// before OP_World_Client_CRC1. Therefore, if we receive OP_World_Client_CRC1 before OP_EnterWorld,
|
// before OP_World_Client_CRC1. Therefore, if we receive OP_World_Client_CRC1 before OP_EnterWorld,
|
||||||
// then 'Start Tutorial' was not chosen.
|
// then 'Start Tutorial' was not chosen.
|
||||||
StartInTutorial = false;
|
StartInTutorial = false;
|
||||||
return true;
|
|
||||||
|
return HandleChecksumPacket(app);
|
||||||
|
|
||||||
}
|
}
|
||||||
case OP_SendLoginInfo:
|
case OP_SendLoginInfo:
|
||||||
{
|
{
|
||||||
@ -1142,6 +1146,146 @@ bool Client::Process() {
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Client::HandleChecksumPacket(const EQApplicationPacket *app)
|
||||||
|
{
|
||||||
|
// Is checksum verification turned on
|
||||||
|
if (!RuleB(World, EnableChecksumVerification)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get packet structure
|
||||||
|
auto *cs = (Checksum_Struct *)app->pBuffer;
|
||||||
|
|
||||||
|
// Determine which checksum to process
|
||||||
|
switch (app->GetOpcode()) {
|
||||||
|
case OP_World_Client_CRC1: // eqgame.exe
|
||||||
|
{
|
||||||
|
bool passes_checksum_validation = (
|
||||||
|
ChecksumVerificationCRCEQGame(cs->checksum) ||
|
||||||
|
(GetAdmin() >= RuleI(GM, MinStatusToBypassCheckSumVerification))
|
||||||
|
);
|
||||||
|
|
||||||
|
LogChecksumVerification(
|
||||||
|
"eqgame.exe validation [{}] client [{}] ({}) has [{}] status [{}]",
|
||||||
|
passes_checksum_validation ? "Passed" : "Failed",
|
||||||
|
GetAccountName(),
|
||||||
|
GetAccountID(),
|
||||||
|
cs->checksum,
|
||||||
|
GetAdmin()
|
||||||
|
);
|
||||||
|
|
||||||
|
return passes_checksum_validation;
|
||||||
|
}
|
||||||
|
case OP_World_Client_CRC2: // SkillCaps.txt
|
||||||
|
{
|
||||||
|
bool passes_checksum_validation = (
|
||||||
|
ChecksumVerificationCRCSkillCaps(cs->checksum) ||
|
||||||
|
(GetAdmin() >= RuleI(GM, MinStatusToBypassCheckSumVerification))
|
||||||
|
);
|
||||||
|
|
||||||
|
LogChecksumVerification(
|
||||||
|
"SkillCaps.txt validation [{}] client [{}] ({}) has [{}] status [{}]",
|
||||||
|
passes_checksum_validation ? "Passed" : "Failed",
|
||||||
|
GetAccountName(),
|
||||||
|
GetAccountID(),
|
||||||
|
cs->checksum,
|
||||||
|
GetAdmin()
|
||||||
|
);
|
||||||
|
|
||||||
|
return passes_checksum_validation;
|
||||||
|
}
|
||||||
|
case OP_World_Client_CRC3: // BaseData.txt
|
||||||
|
{
|
||||||
|
bool passes_checksum_validation = (
|
||||||
|
ChecksumVerificationCRCBaseData(cs->checksum) ||
|
||||||
|
(GetAdmin() >= RuleI(GM, MinStatusToBypassCheckSumVerification))
|
||||||
|
);
|
||||||
|
|
||||||
|
LogChecksumVerification(
|
||||||
|
"BaseData.txt validation [{}] client [{}] ({}) has [{}] status [{}]",
|
||||||
|
passes_checksum_validation ? "Passed" : "Failed",
|
||||||
|
GetAccountName(),
|
||||||
|
GetAccountID(),
|
||||||
|
cs->checksum,
|
||||||
|
GetAdmin()
|
||||||
|
);
|
||||||
|
|
||||||
|
return passes_checksum_validation;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Client::ChecksumVerificationCRCEQGame(uint64 checksum)
|
||||||
|
{
|
||||||
|
database.SetAccountCRCField(GetAccountID(), "crc_eqgame", checksum);
|
||||||
|
|
||||||
|
// Get checksum variable for eqgame.exe
|
||||||
|
std::string checksumvar;
|
||||||
|
uint64_t checksumint;
|
||||||
|
if (database.GetVariable("crc_eqgame", checksumvar)) {
|
||||||
|
checksumint = atoll(checksumvar.c_str());
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
LogChecksumVerification("[checksum_crc1_eqgame] variable not set in variables table.");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verify checksums match
|
||||||
|
if (checksumint == checksum) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Client::ChecksumVerificationCRCSkillCaps(uint64 checksum)
|
||||||
|
{
|
||||||
|
database.SetAccountCRCField(GetAccountID(), "crc_skillcaps", checksum);
|
||||||
|
|
||||||
|
// Get checksum variable for eqgame.exe
|
||||||
|
std::string checksumvar;
|
||||||
|
uint64_t checksumint;
|
||||||
|
if (database.GetVariable("crc_skillcaps", checksumvar)) {
|
||||||
|
checksumint = atoll(checksumvar.c_str());
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
LogChecksumVerification("[checksum_crc2_skillcaps] variable not set in variables table.");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verify checksums match
|
||||||
|
if (checksumint == checksum) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Client::ChecksumVerificationCRCBaseData(uint64 checksum)
|
||||||
|
{
|
||||||
|
database.SetAccountCRCField(GetAccountID(), "crc_basedata", checksum);
|
||||||
|
|
||||||
|
// Get checksum variable for skill_caps.txt
|
||||||
|
std::string checksumvar;
|
||||||
|
uint64_t checksumint;
|
||||||
|
if (database.GetVariable("crc_basedata", checksumvar)) {
|
||||||
|
checksumint = atoll(checksumvar.c_str());
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
LogChecksumVerification("[checksum_crc3_basedata] variable not set in variables table.");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verify checksums match
|
||||||
|
if (checksumint == checksum) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
void Client::EnterWorld(bool TryBootup) {
|
void Client::EnterWorld(bool TryBootup) {
|
||||||
if (zone_id == 0)
|
if (zone_id == 0)
|
||||||
return;
|
return;
|
||||||
|
|||||||
@ -116,6 +116,10 @@ private:
|
|||||||
bool HandleEnterWorldPacket(const EQApplicationPacket *app);
|
bool HandleEnterWorldPacket(const EQApplicationPacket *app);
|
||||||
bool HandleDeleteCharacterPacket(const EQApplicationPacket *app);
|
bool HandleDeleteCharacterPacket(const EQApplicationPacket *app);
|
||||||
bool HandleZoneChangePacket(const EQApplicationPacket *app);
|
bool HandleZoneChangePacket(const EQApplicationPacket *app);
|
||||||
|
bool HandleChecksumPacket(const EQApplicationPacket *app);
|
||||||
|
bool ChecksumVerificationCRCEQGame(uint64 checksum);
|
||||||
|
bool ChecksumVerificationCRCSkillCaps(uint64 checksum);
|
||||||
|
bool ChecksumVerificationCRCBaseData(uint64 checksum);
|
||||||
|
|
||||||
EQStreamInterface* eqs;
|
EQStreamInterface* eqs;
|
||||||
};
|
};
|
||||||
|
|||||||
@ -879,6 +879,11 @@ void ZoneServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p) {
|
|||||||
RuleManager::Instance()->LoadRules(&database, "default", true);
|
RuleManager::Instance()->LoadRules(&database, "default", true);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case ServerOP_ReloadVariablesWorld:
|
||||||
|
{
|
||||||
|
database.LoadVariables();
|
||||||
|
break;
|
||||||
|
}
|
||||||
case ServerOP_ReloadPerlExportSettings:
|
case ServerOP_ReloadPerlExportSettings:
|
||||||
{
|
{
|
||||||
zoneserver_list.SendPacket(pack);
|
zoneserver_list.SendPacket(pack);
|
||||||
|
|||||||
@ -548,6 +548,7 @@ SET(gm_commands
|
|||||||
gm_commands/unmemspells.cpp
|
gm_commands/unmemspells.cpp
|
||||||
gm_commands/unscribespell.cpp
|
gm_commands/unscribespell.cpp
|
||||||
gm_commands/unscribespells.cpp
|
gm_commands/unscribespells.cpp
|
||||||
|
gm_commands/updatechecksum.cpp
|
||||||
gm_commands/untraindisc.cpp
|
gm_commands/untraindisc.cpp
|
||||||
gm_commands/untraindiscs.cpp
|
gm_commands/untraindiscs.cpp
|
||||||
gm_commands/uptime.cpp
|
gm_commands/uptime.cpp
|
||||||
|
|||||||
@ -388,6 +388,7 @@ int command_init(void)
|
|||||||
command_add("unscribespells", "- Clear out your or your player target's spell book.", AccountStatus::GMCoder, command_unscribespells) ||
|
command_add("unscribespells", "- Clear out your or your player target's spell book.", AccountStatus::GMCoder, command_unscribespells) ||
|
||||||
command_add("untraindisc", "[Spell ID] - Untrain your or your target's discipline by Spell ID", AccountStatus::GMCoder, command_untraindisc) ||
|
command_add("untraindisc", "[Spell ID] - Untrain your or your target's discipline by Spell ID", AccountStatus::GMCoder, command_untraindisc) ||
|
||||||
command_add("untraindiscs", "- Untrains all disciplines from your target.", AccountStatus::GMCoder, command_untraindiscs) ||
|
command_add("untraindiscs", "- Untrains all disciplines from your target.", AccountStatus::GMCoder, command_untraindiscs) ||
|
||||||
|
command_add("updatechecksum", "update client checksum", AccountStatus::GMImpossible, command_updatechecksum) ||
|
||||||
command_add("uptime", "[zone server id] - Get uptime of worldserver, or zone server if argument provided", AccountStatus::Steward, command_uptime) ||
|
command_add("uptime", "[zone server id] - Get uptime of worldserver, or zone server if argument provided", AccountStatus::Steward, command_uptime) ||
|
||||||
command_add("version", "- Display current version of EQEmu server", AccountStatus::Player, command_version) ||
|
command_add("version", "- Display current version of EQEmu server", AccountStatus::Player, command_version) ||
|
||||||
command_add("viewcurrencies", "- View your or your target's currencies", AccountStatus::GMAdmin, command_viewcurrencies) ||
|
command_add("viewcurrencies", "- View your or your target's currencies", AccountStatus::GMAdmin, command_viewcurrencies) ||
|
||||||
|
|||||||
@ -310,6 +310,7 @@ void command_unscribespell(Client *c, const Seperator *sep);
|
|||||||
void command_unscribespells(Client *c, const Seperator *sep);
|
void command_unscribespells(Client *c, const Seperator *sep);
|
||||||
void command_untraindisc(Client *c, const Seperator *sep);
|
void command_untraindisc(Client *c, const Seperator *sep);
|
||||||
void command_untraindiscs(Client *c, const Seperator *sep);
|
void command_untraindiscs(Client *c, const Seperator *sep);
|
||||||
|
void command_updatechecksum(Client* c, const Seperator* sep);
|
||||||
void command_uptime(Client *c, const Seperator *sep);
|
void command_uptime(Client *c, const Seperator *sep);
|
||||||
void command_version(Client *c, const Seperator *sep);
|
void command_version(Client *c, const Seperator *sep);
|
||||||
void command_viewcurrencies(Client *c, const Seperator *sep);
|
void command_viewcurrencies(Client *c, const Seperator *sep);
|
||||||
|
|||||||
35
zone/gm_commands/updatechecksum.cpp
Executable file
35
zone/gm_commands/updatechecksum.cpp
Executable file
@ -0,0 +1,35 @@
|
|||||||
|
#include "../client.h"
|
||||||
|
#include "../worldserver.h"
|
||||||
|
#include "../../common/repositories/account_repository.h"
|
||||||
|
|
||||||
|
extern WorldServer worldserver;
|
||||||
|
|
||||||
|
void command_updatechecksum(Client *c, const Seperator *sep)
|
||||||
|
{
|
||||||
|
if (c) {
|
||||||
|
// if account found
|
||||||
|
auto account = AccountRepository::FindOne(database, c->AccountID());
|
||||||
|
if (account.id > 0) {
|
||||||
|
database.SetVariable("crc_eqgame", account.crc_eqgame);
|
||||||
|
database.SetVariable("crc_skillcaps", account.crc_skillcaps);
|
||||||
|
database.SetVariable("crc_basedata", account.crc_basedata);
|
||||||
|
|
||||||
|
// reload rules (world)
|
||||||
|
auto pack = new ServerPacket(ServerOP_ReloadRulesWorld, 0);
|
||||||
|
worldserver.SendPacket(pack);
|
||||||
|
c->Message(Chat::Red, "Successfully sent the packet to world to reload rules. (only world)");
|
||||||
|
safe_delete(pack);
|
||||||
|
|
||||||
|
// reload variables (world)
|
||||||
|
pack = new ServerPacket(ServerOP_ReloadVariablesWorld, 0);
|
||||||
|
worldserver.SendPacket(pack);
|
||||||
|
c->Message(Chat::Red, "Successfully sent the packet to world to reload variables. (only world)");
|
||||||
|
safe_delete(pack);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// we should never see this
|
||||||
|
c->Message(Chat::Red, "Error: Your account was not found!");
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user