[Repositories] Convert database.cpp to Repositories (#4054)

* [Repositories] Convert database.cpp to Repositories

- Convert all database.cpp methods to repositories where possible.

* Final push.

* Cleanup

* Cleanup

* Update database.h

* Fix crash

* Update database.cpp
This commit is contained in:
Alex King 2024-03-23 20:30:56 -04:00 committed by GitHub
parent d7ea290b6b
commit 523ba30d81
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
23 changed files with 1287 additions and 1631 deletions

File diff suppressed because it is too large Load Diff

View File

@ -18,8 +18,8 @@
#ifndef EQEMU_DATABASE_H
#define EQEMU_DATABASE_H
#define AUTHENTICATION_TIMEOUT 60
#define INVALID_ID 0xFFFFFFFF
#define AUTHENTICATION_TIMEOUT 60
#define INVALID_ID 0xFFFFFFFF
#include "global_define.h"
#include "eqemu_logsys.h"
@ -38,8 +38,7 @@
class MySQLRequestResult;
class Client;
namespace EQ
{
namespace EQ {
class InventoryProfile;
}
@ -52,10 +51,11 @@ struct npcDecayTimes_Struct {
struct VarCache_Struct {
std::map<std::string, std::string> m_cache;
uint32 last_update;
uint32 last_update;
VarCache_Struct() : last_update(0) { }
void Add(const std::string &key, const std::string &value) { m_cache[key] = value; }
const std::string *Get(const std::string &key) {
void Add(const std::string& key, const std::string& value) { m_cache[key] = value; }
const std::string* Get(const std::string& key)
{
auto it = m_cache.find(key);
return (it != m_cache.end() ? &it->second : nullptr);
}
@ -76,37 +76,33 @@ class PTimerList;
#define SQL(...) #__VA_ARGS__
class LogSettings;
class Database : public DBcore {
public:
Database();
Database(const char* host, const char* user, const char* passwd, const char* database,uint32 port);
bool Connect(const char* host, const char* user, const char* passwd, const char* database, uint32 port, std::string connection_label = "default");
Database(
const std::string& host,
const std::string& user,
const std::string& password,
const std::string& database,
uint32 port
);
bool Connect(
const std::string& host,
const std::string& user,
const std::string& password,
const std::string& database,
uint32 port,
std::string connection_label = "default"
);
~Database();
/* Character Creation */
bool CreateCharacter(
uint32 account_id,
char *name,
uint16 gender,
uint16 race,
uint16 class_,
uint8 str,
uint8 sta,
uint8 cha,
uint8 dex,
uint8 int_,
uint8 agi,
uint8 wis,
uint8 face
);
bool DeleteCharacter(char *character_name);
bool MoveCharacterToZone(const char *charname, uint32 zone_id);
bool DeleteCharacter(const std::string& name);
bool MoveCharacterToZone(const std::string& name, uint32 zone_id);
bool MoveCharacterToZone(uint32 character_id, uint32 zone_id);
bool ReserveName(uint32 account_id, char *name);
bool SaveCharacterCreate(uint32 character_id, uint32 account_id, PlayerProfile_Struct *pp);
bool UpdateName(const char *oldname, const char *newname);
bool ReserveName(uint32 account_id, const std::string& name);
bool SaveCharacterCreate(uint32 character_id, uint32 account_id, PlayerProfile_Struct* pp);
bool UpdateName(const std::string& old_name, const std::string& new_name);
bool CopyCharacter(
const std::string& source_character_name,
const std::string& destination_character_name,
@ -114,161 +110,171 @@ public:
);
/* General Information Queries */
bool AddBannedIP(const std::string& banned_ip, const std::string& notes); //Add IP address to the banned_ips table.
bool AddToNameFilter(const std::string& name);
bool CheckBannedIPs(const std::string& login_ip); //Check incoming connection against banned IP table.
bool CheckGMIPs(const std::string& login_ip, uint32 account_id);
bool CheckNameFilter(const std::string& name, bool surname = false);
bool CheckUsedName(const std::string& name);
bool AddBannedIP(std::string banned_ip, std::string notes); //Add IP address to the banned_ips table.
bool AddToNameFilter(std::string name);
bool CheckBannedIPs(std::string login_ip); //Check incoming connection against banned IP table.
bool CheckGMIPs(std::string login_ip, uint32 account_id);
bool CheckNameFilter(std::string name, bool surname = false);
bool CheckUsedName(std::string name);
uint32 GetAccountIDByChar(const std::string& name, uint32* character_id = 0);
uint32 GetAccountIDByChar(uint32 character_id);
uint32 GetAccountIDByName(const std::string& account_name, const std::string& loginserver, int16* status = 0, uint32* lsid = 0);
uint32 GetCharacterID(const std::string& name);
uint32 GetGuildIDByCharID(uint32 character_id);
uint32 GetGroupIDByCharID(uint32 character_id);
uint32 GetRaidIDByCharID(uint32 character_id);
uint32 GetAccountIDByChar(const char* charname, uint32* oCharID = 0);
uint32 GetAccountIDByChar(uint32 char_id);
uint32 GetAccountIDByName(std::string account_name, std::string loginserver, int16* status = 0, uint32* lsid = 0);
uint32 GetCharacterID(const std::string& name);
uint32 GetCharacterInfo(std::string character_name, uint32 *account_id, uint32 *zone_id, uint32 *instance_id);
uint32 GetGuildIDByCharID(uint32 char_id);
uint32 GetGroupIDByCharID(uint32 char_id);
uint32 GetRaidIDByCharID(uint32 char_id);
void GetAccountName(uint32 accountid, char* name, uint32* oLSAccountID = 0);
void GetCharName(uint32 char_id, char* name);
std::string GetCharNameByID(uint32 char_id);
std::string GetNPCNameByID(uint32 npc_id);
std::string GetCleanNPCNameByID(uint32 npc_id);
void LoginIP(uint32 account_id, std::string login_ip);
const std::string& GetAccountName(uint32 account_id, uint32* lsaccount_id = 0);
const std::string& GetCharName(uint32 character_id);
const std::string& GetCharNameByID(uint32 character_id);
const std::string& GetNPCNameByID(uint32 npc_id);
const std::string& GetCleanNPCNameByID(uint32 npc_id);
void LoginIP(uint32 account_id, const std::string& login_ip);
/* Instancing */
bool AddClientToInstance(uint16 instance_id, uint32 character_id);
bool CheckInstanceByCharID(uint16 instance_id, uint32 character_id);
bool CheckInstanceExists(uint16 instance_id);
bool CheckInstanceExpired(uint16 instance_id);
bool CreateInstance(uint16 instance_id, uint32 zone_id, uint32 version, uint32 duration);
bool GetUnusedInstanceID(uint16 &instance_id);
bool GetUnusedInstanceID(uint16& instance_id);
bool IsGlobalInstance(uint16 instance_id);
bool RemoveClientFromInstance(uint16 instance_id, uint32 char_id);
bool RemoveClientsFromInstance(uint16 instance_id);
bool VerifyInstanceAlive(uint16 instance_id, uint32 character_id);
bool VerifyZoneInstance(uint32 zone_id, uint16 instance_id);
uint16 GetInstanceID(uint32 zone, uint32 charid, int16 version);
uint16 GetInstanceID(uint32 zone, uint32 character_id, int16 version);
std::vector<uint16> GetInstanceIDs(uint32 zone_id, uint32 character_id);
uint8_t GetInstanceVersion(uint16 instance_id);
uint32 GetTimeRemainingInstance(uint16 instance_id, bool &is_perma);
uint32 GetTimeRemainingInstance(uint16 instance_id, bool& is_perma);
uint32 GetInstanceZoneID(uint16 instance_id);
void AssignGroupToInstance(uint32 gid, uint32 instance_id);
void AssignRaidToInstance(uint32 rid, uint32 instance_id);
void AssignGroupToInstance(uint32 group_id, uint32 instance_id);
void AssignRaidToInstance(uint32 raid_id, uint32 instance_id);
void DeleteInstance(uint16 instance_id);
void FlagInstanceByGroupLeader(uint32 zone_id, int16 version, uint32 charid, uint32 group_id);
void FlagInstanceByRaidLeader(uint32 zone_id, int16 version, uint32 charid, uint32 raid_id);
void GetCharactersInInstance(uint16 instance_id, std::list<uint32> &character_ids);
void FlagInstanceByGroupLeader(uint32 zone_id, int16 version, uint32 character_id, uint32 group_id);
void FlagInstanceByRaidLeader(uint32 zone_id, int16 version, uint32 character_id, uint32 raid_id);
void GetCharactersInInstance(uint16 instance_id, std::list<uint32>& character_ids);
void PurgeExpiredInstances();
void SetInstanceDuration(uint16 instance_id, uint32 new_duration);
void CleanupInstanceCorpses();
/* Adventure related. */
void UpdateAdventureStatsEntry(uint32 char_id, uint8 theme, bool win = false, bool remove = false);
bool GetAdventureStats(uint32 char_id, AdventureStats_Struct *as);
void UpdateAdventureStatsEntry(uint32 character_id, uint8 theme_id, bool is_win = false, bool is_remove = false);
bool GetAdventureStats(uint32 character_id, AdventureStats_Struct* as);
/* Account Related */
const std::string& GetLiveChar(uint32 account_id);
bool SetAccountStatus(const std::string& account_name, int16 status);
bool SetLocalPassword(uint32 account_id, const std::string& password);
bool UpdateLiveChar(const std::string& name, uint32 account_id);
int16 CheckStatus(uint32 account_id);
void SetAccountCRCField(uint32 account_id, const std::string& field_name, uint64 checksum);
uint32 CheckLogin(const std::string& name, const std::string& password, const std::string& loginserver, int16* status = 0);
uint32 CreateAccount(
const std::string& name,
const std::string& password,
int16 status,
const std::string& 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
);
bool DeleteAccount(const char *name, const char* loginserver);
bool GetLiveChar(uint32 account_id, char* cname);
bool SetAccountStatus(const char* name, int16 status);
bool SetAccountStatus(const std::string& account_name, int16 status);
bool SetLocalPassword(uint32 accid, const char* password);
bool UpdateLiveChar(char* charname, uint32 account_id);
uint8 GetAgreementFlag(uint32 account_id);
void SetAgreementFlag(uint32 account_id);
int16 CheckStatus(uint32 account_id);
int GetIPExemption(const std::string& account_ip);
void SetIPExemption(const std::string& account_ip, int exemption_amount);
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 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);
uint8 GetAgreementFlag(uint32 account_id);
void GetAccountFromID(uint32 id, char* oAccountName, int16* oStatus);
void SetAgreementFlag(uint32 account_id);
int GetIPExemption(std::string account_ip);
void SetIPExemption(std::string account_ip, int exemption_amount);
int GetInstanceID(uint32 char_id, uint32 zone_id);
int GetInstanceID(uint32 character_id, uint32 zone_id);
/* Groups */
std::string GetGroupLeaderForLogin(const std::string& character_name);
char* GetGroupLeadershipInfo(uint32 gid, char* leaderbuf, char* maintank = nullptr, char* assist = nullptr, char* puller = nullptr, char *marknpc = nullptr, char *mentoree = nullptr, int *mentor_percent = nullptr, GroupLeadershipAA_Struct* GLAA = nullptr);
char* GetGroupLeadershipInfo(
uint32 group_id,
char* leaderbuf,
char* maintank = nullptr,
char* assist = nullptr,
char* puller = nullptr,
char* marknpc = nullptr,
char* mentoree = nullptr,
int* mentor_percent = nullptr,
GroupLeadershipAA_Struct* GLAA = nullptr
);
std::string GetGroupLeaderName(uint32 group_id);
uint32 GetGroupID(const std::string& name);
void ClearGroup(uint32 group_id = 0);
void ClearGroupLeader(uint32 gid = 0);
void SetGroupLeaderName(uint32 gid, const char* name);
uint32 GetGroupID(const std::string& name);
void ClearGroup(uint32 group_id = 0);
void ClearGroupLeader(uint32 group_id = 0);
void SetGroupLeaderName(uint32 group_id, const std::string& name);
/* Raids */
const std::string& GetRaidLeaderName(uint32 raid_id);
uint32 GetRaidID(const std::string& name);
void ClearRaid(uint32 raid_id = 0);
void ClearRaidDetails(uint32 raid_id = 0);
void ClearRaidLeader(uint32 group_id = std::numeric_limits<uint32>::max(), uint32 raid_id = 0);
void GetGroupLeadershipInfo(
uint32 group_id,
uint32 raid_id,
char* maintank = nullptr,
char* assist = nullptr,
char* puller = nullptr,
char* marknpc = nullptr,
char* mentoree = nullptr,
int* mentor_percent = nullptr,
GroupLeadershipAA_Struct* GLAA = nullptr
);
void GetRaidLeadershipInfo(
uint32 raid_id,
char* maintank = nullptr,
char* assist = nullptr,
char* puller = nullptr,
char* marknpc = nullptr,
RaidLeadershipAA_Struct* RLAA = nullptr
);
void SetRaidGroupLeaderInfo(uint32 group_id, uint32 raid_id);
const char *GetRaidLeaderName(uint32 rid);
uint32 GetRaidID(const char* name);
void ClearRaid(uint32 rid = 0);
void ClearRaidDetails(uint32 rid = 0);
void ClearRaidLeader(uint32 gid = 0xFFFFFFFF, uint32 rid = 0);
void GetGroupLeadershipInfo(uint32 gid, uint32 rid, char* maintank = nullptr, char* assist = nullptr, char* puller = nullptr, char *marknpc = nullptr, char *mentoree = nullptr, int *mentor_percent = nullptr, GroupLeadershipAA_Struct* GLAA = nullptr);
void GetRaidLeadershipInfo(uint32 rid, char* maintank = nullptr, char* assist = nullptr, char* puller = nullptr, char *marknpc = nullptr, RaidLeadershipAA_Struct* RLAA = nullptr);
void SetRaidGroupLeaderInfo(uint32 gid, uint32 rid);
void PurgeAllDeletedDataBuckets();
void PurgeAllDeletedDataBuckets();
/* Database Variables */
bool GetVariable(const std::string& name, std::string& value);
bool SetVariable(const std::string& name, const std::string& value);
bool LoadVariables();
bool GetVariable(std::string varname, std::string &varvalue);
bool SetVariable(const std::string& varname, const std::string &varvalue);
bool LoadVariables();
uint8 GetPEQZone(uint32 zone_id, uint32 version);
uint32 GetServerType();
void AddReport(const std::string& who, const std::string& against, const std::string& lines);
struct TimeOfDay_Struct LoadTime(time_t& realtime);
bool SaveTime(int8 minute, int8 hour, int8 day, int8 month, int16 year);
void ClearMerchantTemp();
void ClearPTimers(uint32 character_id);
void SetFirstLogon(uint32 character_id, uint8 first_logon);
void SetLFG(uint32 character_id, bool is_lfg);
void SetLFP(uint32 character_id, bool is_lfp);
void SetLoginFlags(uint32 character_id, bool is_lfp, bool is_lfg, uint8 first_logon);
/* General Queries */
int64 CountInvSnapshots();
void ClearInvSnapshots(bool from_now = false);
bool GetZoneGraveyard(const uint32 graveyard_id, uint32* graveyard_zoneid = 0, float* graveyard_x = 0, float* graveyard_y = 0, float* graveyard_z = 0, float* graveyard_heading = 0);
bool LoadPTimers(uint32 charid, PTimerList &into);
uint8 GetPEQZone(uint32 zone_id, uint32 version);
uint8 GetMinStatus(uint32 zone_id, uint32 instance_version);
uint8 GetRaceSkill(uint8 skillid, uint8 in_race);
uint8 GetServerType();
void AddReport(std::string who, std::string against, std::string lines);
struct TimeOfDay_Struct LoadTime(time_t &realtime);
bool SaveTime(int8 minute, int8 hour, int8 day, int8 month, int16 year);
void ClearMerchantTemp();
void ClearPTimers(uint32 charid);
void SetFirstLogon(uint32 CharID, uint8 firstlogon);
void SetLFG(uint32 CharID, bool LFG);
void SetLFP(uint32 CharID, bool LFP);
void SetLoginFlags(uint32 CharID, bool LFP, bool LFG, uint8 firstlogon);
int CountInvSnapshots();
void ClearInvSnapshots(bool from_now = false);
void SourceDatabaseTableFromUrl(std::string table_name, std::string url);
void SourceSqlFromUrl(std::string url);
void SourceDatabaseTableFromUrl(const std::string& table_name, const std::string& url);
void SourceSqlFromUrl(const std::string& url);
private:
Mutex Mvarcache;
Mutex Mvarcache;
VarCache_Struct varcache;
/* Groups, utility methods. */
void ClearAllGroupLeaders();
void ClearAllGroups();
void ClearAllGroupLeaders();
void ClearAllGroups();
/* Raid, utility methods. */
void ClearAllRaids();

View File

@ -509,7 +509,7 @@ void Database::FlagInstanceByRaidLeader(uint32 zone_id, int16 version, uint32 ch
return;
}
auto raid_leader_id = GetCharacterID(GetRaidLeaderName(raid_id));
auto raid_leader_id = GetCharacterID(GetRaidLeaderName(raid_id).c_str());
auto raid_leader_instance_id = GetInstanceID(zone_id, raid_leader_id, version);
if (!raid_leader_instance_id) {

View File

@ -44,7 +44,51 @@ public:
*/
// Custom extended repository methods here
static int16 GetAccountStatus(Database& db, const uint32 account_id)
{
auto results = db.QueryDatabase(
fmt::format(
"SELECT `status`, TIMESTAMPDIFF(SECOND, NOW(), `suspendeduntil`) FROM `{}` WHERE `{}` = {}",
TableName(),
PrimaryKey(),
account_id
)
);
if (!results.Success() || !results.RowCount()) {
return 0;
}
auto row = results.begin();
int16 status = static_cast<int16>(Strings::ToInt(row[0]));
int date_diff = 0;
if (row[1]) {
date_diff = Strings::ToInt(row[1]);
}
if (date_diff > 0) {
status = -1;
}
return status;
}
static bool UpdatePassword(Database& db, const uint32 account_id, const std::string& password)
{
auto results = db.QueryDatabase(
fmt::format(
"UPDATE `{}` SET `password` = MD5('{}') WHERE `{}` = {}",
TableName(),
password,
PrimaryKey(),
account_id
)
);
return results.Success();
}
};
#endif //EQEMU_ACCOUNT_REPOSITORY_H

View File

@ -44,7 +44,65 @@ public:
*/
// Custom extended repository methods here
static void UpdateAdventureStatsEntry(Database& db, uint32 character_id, uint8 theme_id, bool is_win, bool is_remove)
{
std::string field;
switch (theme_id) {
case LDoNThemes::GUK: {
field = "guk_";
break;
}
case LDoNThemes::MIR: {
field = "mir_";
break;
}
case LDoNThemes::MMC: {
field = "mmc_";
break;
}
case LDoNThemes::RUJ: {
field = "ruj_";
break;
}
case LDoNThemes::TAK: {
field = "tak_";
break;
}
}
field += is_win ? "wins" : "losses";
auto e = FindOne(db, character_id);
if (!e.player_id && !is_remove) {
const std::string& query = fmt::format(
"INSERT INTO `{}` SET `{}` = 1, `{}` = {}",
TableName(),
field,
PrimaryKey(),
character_id
);
db.QueryDatabase(query);
return;
}
const std::string& field_operation = is_remove ? "-" : "+";
const std::string& query = fmt::format(
"UPDATE `{}` SET `{}` = {} {} 1 WHERE `{}` = {}",
TableName(),
field,
field,
field_operation,
PrimaryKey(),
character_id
);
db.QueryDatabase(query);
}
};
#endif //EQEMU_ADVENTURE_STATS_REPOSITORY_H

View File

@ -22,7 +22,7 @@ public:
int32_t accid;
std::string ip;
int32_t count;
std::string lastused;
time_t lastused;
};
static std::string PrimaryKey()
@ -46,7 +46,7 @@ public:
"accid",
"ip",
"count",
"lastused",
"UNIX_TIMESTAMP(lastused)",
};
}
@ -130,7 +130,7 @@ public:
e.accid = row[0] ? static_cast<int32_t>(atoi(row[0])) : 0;
e.ip = row[1] ? row[1] : "";
e.count = row[2] ? static_cast<int32_t>(atoi(row[2])) : 1;
e.lastused = row[3] ? row[3] : std::time(nullptr);
e.lastused = strtoll(row[3] ? row[3] : "-1", nullptr, 10);
return e;
}
@ -167,7 +167,7 @@ public:
v.push_back(columns[0] + " = " + std::to_string(e.accid));
v.push_back(columns[1] + " = '" + Strings::Escape(e.ip) + "'");
v.push_back(columns[2] + " = " + std::to_string(e.count));
v.push_back(columns[3] + " = '" + Strings::Escape(e.lastused) + "'");
v.push_back(columns[3] + " = FROM_UNIXTIME(" + (e.lastused > 0 ? std::to_string(e.lastused) : "null") + ")");
auto results = db.QueryDatabase(
fmt::format(
@ -192,7 +192,7 @@ public:
v.push_back(std::to_string(e.accid));
v.push_back("'" + Strings::Escape(e.ip) + "'");
v.push_back(std::to_string(e.count));
v.push_back("'" + Strings::Escape(e.lastused) + "'");
v.push_back("FROM_UNIXTIME(" + (e.lastused > 0 ? std::to_string(e.lastused) : "null") + ")");
auto results = db.QueryDatabase(
fmt::format(
@ -225,7 +225,7 @@ public:
v.push_back(std::to_string(e.accid));
v.push_back("'" + Strings::Escape(e.ip) + "'");
v.push_back(std::to_string(e.count));
v.push_back("'" + Strings::Escape(e.lastused) + "'");
v.push_back("FROM_UNIXTIME(" + (e.lastused > 0 ? std::to_string(e.lastused) : "null") + ")");
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
}
@ -262,7 +262,7 @@ public:
e.accid = row[0] ? static_cast<int32_t>(atoi(row[0])) : 0;
e.ip = row[1] ? row[1] : "";
e.count = row[2] ? static_cast<int32_t>(atoi(row[2])) : 1;
e.lastused = row[3] ? row[3] : std::time(nullptr);
e.lastused = strtoll(row[3] ? row[3] : "-1", nullptr, 10);
all_entries.push_back(e);
}
@ -290,7 +290,7 @@ public:
e.accid = row[0] ? static_cast<int32_t>(atoi(row[0])) : 0;
e.ip = row[1] ? row[1] : "";
e.count = row[2] ? static_cast<int32_t>(atoi(row[2])) : 1;
e.lastused = row[3] ? row[3] : std::time(nullptr);
e.lastused = strtoll(row[3] ? row[3] : "-1", nullptr, 10);
all_entries.push_back(e);
}
@ -368,7 +368,7 @@ public:
v.push_back(std::to_string(e.accid));
v.push_back("'" + Strings::Escape(e.ip) + "'");
v.push_back(std::to_string(e.count));
v.push_back("'" + Strings::Escape(e.lastused) + "'");
v.push_back("FROM_UNIXTIME(" + (e.lastused > 0 ? std::to_string(e.lastused) : "null") + ")");
auto results = db.QueryDatabase(
fmt::format(
@ -394,7 +394,7 @@ public:
v.push_back(std::to_string(e.accid));
v.push_back("'" + Strings::Escape(e.ip) + "'");
v.push_back(std::to_string(e.count));
v.push_back("'" + Strings::Escape(e.lastused) + "'");
v.push_back("FROM_UNIXTIME(" + (e.lastused > 0 ? std::to_string(e.lastused) : "null") + ")");
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
}

View File

@ -23,7 +23,7 @@ public:
std::string varname;
std::string value;
std::string information;
std::string ts;
time_t ts;
};
static std::string PrimaryKey()
@ -49,7 +49,7 @@ public:
"varname",
"value",
"information",
"ts",
"UNIX_TIMESTAMP(ts)",
};
}
@ -135,7 +135,7 @@ public:
e.varname = row[1] ? row[1] : "";
e.value = row[2] ? row[2] : "";
e.information = row[3] ? row[3] : "";
e.ts = row[4] ? row[4] : std::time(nullptr);
e.ts = strtoll(row[4] ? row[4] : "-1", nullptr, 10);
return e;
}
@ -172,7 +172,7 @@ public:
v.push_back(columns[1] + " = '" + Strings::Escape(e.varname) + "'");
v.push_back(columns[2] + " = '" + Strings::Escape(e.value) + "'");
v.push_back(columns[3] + " = '" + Strings::Escape(e.information) + "'");
v.push_back(columns[4] + " = '" + Strings::Escape(e.ts) + "'");
v.push_back(columns[4] + " = FROM_UNIXTIME(" + (e.ts > 0 ? std::to_string(e.ts) : "null") + ")");
auto results = db.QueryDatabase(
fmt::format(
@ -198,7 +198,7 @@ public:
v.push_back("'" + Strings::Escape(e.varname) + "'");
v.push_back("'" + Strings::Escape(e.value) + "'");
v.push_back("'" + Strings::Escape(e.information) + "'");
v.push_back("'" + Strings::Escape(e.ts) + "'");
v.push_back("FROM_UNIXTIME(" + (e.ts > 0 ? std::to_string(e.ts) : "null") + ")");
auto results = db.QueryDatabase(
fmt::format(
@ -232,7 +232,7 @@ public:
v.push_back("'" + Strings::Escape(e.varname) + "'");
v.push_back("'" + Strings::Escape(e.value) + "'");
v.push_back("'" + Strings::Escape(e.information) + "'");
v.push_back("'" + Strings::Escape(e.ts) + "'");
v.push_back("FROM_UNIXTIME(" + (e.ts > 0 ? std::to_string(e.ts) : "null") + ")");
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
}
@ -270,7 +270,7 @@ public:
e.varname = row[1] ? row[1] : "";
e.value = row[2] ? row[2] : "";
e.information = row[3] ? row[3] : "";
e.ts = row[4] ? row[4] : std::time(nullptr);
e.ts = strtoll(row[4] ? row[4] : "-1", nullptr, 10);
all_entries.push_back(e);
}
@ -299,7 +299,7 @@ public:
e.varname = row[1] ? row[1] : "";
e.value = row[2] ? row[2] : "";
e.information = row[3] ? row[3] : "";
e.ts = row[4] ? row[4] : std::time(nullptr);
e.ts = strtoll(row[4] ? row[4] : "-1", nullptr, 10);
all_entries.push_back(e);
}
@ -378,7 +378,7 @@ public:
v.push_back("'" + Strings::Escape(e.varname) + "'");
v.push_back("'" + Strings::Escape(e.value) + "'");
v.push_back("'" + Strings::Escape(e.information) + "'");
v.push_back("'" + Strings::Escape(e.ts) + "'");
v.push_back("FROM_UNIXTIME(" + (e.ts > 0 ? std::to_string(e.ts) : "null") + ")");
auto results = db.QueryDatabase(
fmt::format(
@ -405,7 +405,7 @@ public:
v.push_back("'" + Strings::Escape(e.varname) + "'");
v.push_back("'" + Strings::Escape(e.value) + "'");
v.push_back("'" + Strings::Escape(e.information) + "'");
v.push_back("'" + Strings::Escape(e.ts) + "'");
v.push_back("FROM_UNIXTIME(" + (e.ts > 0 ? std::to_string(e.ts) : "null") + ")");
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
}

View File

@ -44,7 +44,15 @@ public:
*/
// Custom extended repository methods here
static void ClearAllGroups(Database& db)
{
db.QueryDatabase(
fmt::format(
"DELETE FROM `{}`",
TableName()
)
);
}
};
#endif //EQEMU_GROUP_ID_REPOSITORY_H

View File

@ -44,7 +44,15 @@ public:
*/
// Custom extended repository methods here
static void ClearAllGroupLeaders(Database& db)
{
db.QueryDatabase(
fmt::format(
"DELETE FROM `{}`",
TableName()
)
);
}
};
#endif //EQEMU_GROUP_LEADERS_REPOSITORY_H

View File

@ -191,4 +191,5 @@ public:
return UpdateOne(db, m);
}
};
#endif //EQEMU_GUILD_MEMBERS_REPOSITORY_H

View File

@ -44,7 +44,30 @@ public:
*/
// Custom extended repository methods here
static int64 CountInventorySnapshots(Database& db)
{
const std::string& query = "SELECT COUNT(*) FROM (SELECT * FROM `inventory_snapshots` a GROUP BY `charid`, `time_index`) b";
auto results = db.QueryDatabase(query);
if (!results.Success() || !results.RowCount()) {
return -1;
}
auto row = results.begin();
const int64 count = Strings::ToBigInt(row[0]);
if (count > std::numeric_limits<int>::max()) {
return -2;
}
if (count < 0) {
return -3;
}
return count;
}
};
#endif //EQEMU_INVENTORY_SNAPSHOTS_REPOSITORY_H

View File

@ -66,6 +66,16 @@ public:
return results.Success() ? results.RowsAffected() : 0;
}
static void ClearAllRaidDetails(Database& db)
{
db.QueryDatabase(
fmt::format(
"DELETE FROM `{}`",
TableName()
)
);
}
};
#endif //EQEMU_RAID_DETAILS_REPOSITORY_H

View File

@ -1,297 +0,0 @@
#ifndef EQEMU_RAID_LEADERS_REPOSITORY_H
#define EQEMU_RAID_LEADERS_REPOSITORY_H
#include "../database.h"
#include "../strings.h"
class RaidLeadersRepository {
public:
struct RaidLeaders {
int gid;
int rid;
std::string marknpc;
std::string maintank;
std::string assist;
std::string puller;
std::string leadershipaa;
std::string mentoree;
int mentor_percent;
};
static std::string PrimaryKey()
{
return std::string("");
}
static std::vector<std::string> Columns()
{
return {
"gid",
"rid",
"marknpc",
"maintank",
"assist",
"puller",
"leadershipaa",
"mentoree",
"mentor_percent",
};
}
static std::string ColumnsRaw()
{
return std::string(Strings::Implode(", ", Columns()));
}
static std::string InsertColumnsRaw()
{
std::vector<std::string> insert_columns;
for (auto &column : Columns()) {
if (column == PrimaryKey()) {
continue;
}
insert_columns.push_back(column);
}
return std::string(Strings::Implode(", ", insert_columns));
}
static std::string TableName()
{
return std::string("raid_leaders");
}
static std::string BaseSelect()
{
return fmt::format(
"SELECT {} FROM {}",
ColumnsRaw(),
TableName()
);
}
static std::string BaseInsert()
{
return fmt::format(
"INSERT INTO {} ({}) ",
TableName(),
InsertColumnsRaw()
);
}
static RaidLeaders NewEntity()
{
RaidLeaders entry{};
entry.gid = 0;
entry.rid = 0;
entry.marknpc = "";
entry.maintank = "";
entry.assist = "";
entry.puller = "";
entry.leadershipaa = 0;
entry.mentoree = "";
entry.mentor_percent = 0;
return entry;
}
static RaidLeaders GetRaidLeadersEntry(
const std::vector<RaidLeaders> &raid_leaderss,
int raid_leaders_id
)
{
for (auto &raid_leaders : raid_leaderss) {
if (raid_leaders. == raid_leaders_id) {
return raid_leaders;
}
}
return NewEntity();
}
static RaidLeaders FindOne(
int raid_leaders_id
)
{
auto results = database.QueryDatabase(
fmt::format(
"{} WHERE id = {} LIMIT 1",
BaseSelect(),
raid_leaders_id
)
);
auto row = results.begin();
if (results.RowCount() == 1) {
RaidLeaders entry{};
entry.gid = atoi(row[0]);
entry.rid = atoi(row[1]);
entry.marknpc = row[2];
entry.maintank = row[3];
entry.assist = row[4];
entry.puller = row[5];
entry.leadershipaa = row[6];
entry.mentoree = row[7];
entry.mentor_percent = atoi(row[8]);
return entry;
}
return NewEntity();
}
static int DeleteOne(
int raid_leaders_id
)
{
auto results = database.QueryDatabase(
fmt::format(
"DELETE FROM {} WHERE {} = {}",
TableName(),
PrimaryKey(),
raid_leaders_id
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static int UpdateOne(
RaidLeaders raid_leaders_entry
)
{
std::vector<std::string> update_values;
auto columns = Columns();
update_values.push_back(columns[0] + " = " + std::to_string(raid_leaders_entry.gid));
update_values.push_back(columns[1] + " = " + std::to_string(raid_leaders_entry.rid));
update_values.push_back(columns[2] + " = '" + Strings::Escape(raid_leaders_entry.marknpc) + "'");
update_values.push_back(columns[3] + " = '" + Strings::Escape(raid_leaders_entry.maintank) + "'");
update_values.push_back(columns[4] + " = '" + Strings::Escape(raid_leaders_entry.assist) + "'");
update_values.push_back(columns[5] + " = '" + Strings::Escape(raid_leaders_entry.puller) + "'");
update_values.push_back(columns[6] + " = '" + Strings::Escape(raid_leaders_entry.leadershipaa) + "'");
update_values.push_back(columns[7] + " = '" + Strings::Escape(raid_leaders_entry.mentoree) + "'");
update_values.push_back(columns[8] + " = " + std::to_string(raid_leaders_entry.mentor_percent));
auto results = database.QueryDatabase(
fmt::format(
"UPDATE {} SET {} WHERE {} = {}",
TableName(),
Strings::Implode(", ", update_values),
PrimaryKey(),
raid_leaders_entry.
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static RaidLeaders InsertOne(
RaidLeaders raid_leaders_entry
)
{
std::vector<std::string> insert_values;
insert_values.push_back(std::to_string(raid_leaders_entry.gid));
insert_values.push_back(std::to_string(raid_leaders_entry.rid));
insert_values.push_back("'" + Strings::Escape(raid_leaders_entry.marknpc) + "'");
insert_values.push_back("'" + Strings::Escape(raid_leaders_entry.maintank) + "'");
insert_values.push_back("'" + Strings::Escape(raid_leaders_entry.assist) + "'");
insert_values.push_back("'" + Strings::Escape(raid_leaders_entry.puller) + "'");
insert_values.push_back("'" + Strings::Escape(raid_leaders_entry.leadershipaa) + "'");
insert_values.push_back("'" + Strings::Escape(raid_leaders_entry.mentoree) + "'");
insert_values.push_back(std::to_string(raid_leaders_entry.mentor_percent));
auto results = database.QueryDatabase(
fmt::format(
"{} VALUES ({})",
BaseInsert(),
Strings::Implode(",", insert_values)
)
);
if (results.Success()) {
raid_leaders_entry.id = results.LastInsertedID();
return raid_leaders_entry;
}
raid_leaders_entry = InstanceListRepository::NewEntity();
return raid_leaders_entry;
}
static int InsertMany(
std::vector<RaidLeaders> raid_leaders_entries
)
{
std::vector<std::string> insert_chunks;
for (auto &raid_leaders_entry: raid_leaders_entries) {
std::vector<std::string> insert_values;
insert_values.push_back(std::to_string(raid_leaders_entry.gid));
insert_values.push_back(std::to_string(raid_leaders_entry.rid));
insert_values.push_back("'" + Strings::Escape(raid_leaders_entry.marknpc) + "'");
insert_values.push_back("'" + Strings::Escape(raid_leaders_entry.maintank) + "'");
insert_values.push_back("'" + Strings::Escape(raid_leaders_entry.assist) + "'");
insert_values.push_back("'" + Strings::Escape(raid_leaders_entry.puller) + "'");
insert_values.push_back("'" + Strings::Escape(raid_leaders_entry.leadershipaa) + "'");
insert_values.push_back("'" + Strings::Escape(raid_leaders_entry.mentoree) + "'");
insert_values.push_back(std::to_string(raid_leaders_entry.mentor_percent));
insert_chunks.push_back("(" + Strings::Implode(",", insert_values) + ")");
}
std::vector<std::string> insert_values;
auto results = database.QueryDatabase(
fmt::format(
"{} VALUES {}",
BaseInsert(),
Strings::Implode(",", insert_chunks)
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static std::vector<RaidLeaders> All()
{
std::vector<RaidLeaders> all_entries;
auto results = database.QueryDatabase(
fmt::format(
"{}",
BaseSelect()
)
);
all_entries.reserve(results.RowCount());
for (auto row = results.begin(); row != results.end(); ++row) {
RaidLeaders entry{};
entry.gid = atoi(row[0]);
entry.rid = atoi(row[1]);
entry.marknpc = row[2];
entry.maintank = row[3];
entry.assist = row[4];
entry.puller = row[5];
entry.leadershipaa = row[6];
entry.mentoree = row[7];
entry.mentor_percent = atoi(row[8]);
all_entries.push_back(entry);
}
return all_entries;
}
};
#endif //EQEMU_RAID_LEADERS_REPOSITORY_H

View File

@ -60,7 +60,7 @@ public:
);
return results.Success() ? results.RowsAffected() : 0;
}
static int UpdateRaidAssister(
Database& db,
int32_t raid_id,
@ -98,5 +98,15 @@ public:
return results.Success() ? results.RowsAffected() : 0;
}
static void ClearAllRaids(Database& db)
{
db.QueryDatabase(
fmt::format(
"DELETE FROM `{}`",
TableName()
)
);
}
};
#endif //EQEMU_RAID_MEMBERS_REPOSITORY_H

View File

@ -794,8 +794,7 @@ bool SharedDatabase::GetInventory(uint32 char_id, EQ::InventoryProfile *inv)
}
if (cv_conflict) {
char char_name[64] = "";
GetCharName(char_id, char_name);
const std::string& char_name = GetCharName(char_id);
LogError("ClientVersion/Expansion conflict during inventory load at zone entry for [{}] (charid: [{}], inver: [{}], gmi: [{}])",
char_name,
char_id,

View File

@ -280,7 +280,7 @@ foreach my $table_to_generate (@tables) {
# column names (string)
$column_names_quoted .= sprintf("\t\t\t\"%s\",\n", format_column_name_for_mysql($column_name));
if ($data_type =~ /datetime/) {
if ($data_type =~ /datetime|timestamp/) {
$select_column_names_quoted .= sprintf("\t\t\t\"UNIX_TIMESTAMP(%s)\",\n", format_column_name_for_mysql($column_name));
}
else {
@ -293,7 +293,7 @@ foreach my $table_to_generate (@tables) {
if ($data_type =~ /int|float|double|decimal/) {
$query_value = sprintf('" + std::to_string(e.%s));', $column_name_formatted);
}
elsif ($data_type =~ /datetime/) {
elsif ($data_type =~ /datetime|timestamp/) {
$query_value = sprintf('FROM_UNIXTIME(" + (e.%s > 0 ? std::to_string(e.%s) : "null") + ")");', $column_name_formatted, $column_name_formatted);
}
@ -309,7 +309,7 @@ foreach my $table_to_generate (@tables) {
if ($data_type =~ /int|float|double|decimal/) {
$value = sprintf('std::to_string(e.%s)', $column_name_formatted);
}
elsif ($data_type =~ /datetime/) {
elsif ($data_type =~ /datetime|timestamp/) {
$value = sprintf('"FROM_UNIXTIME(" + (e.%s > 0 ? std::to_string(e.%s) : "null") + ")"', $column_name_formatted, $column_name_formatted);
}
@ -332,7 +332,7 @@ foreach my $table_to_generate (@tables) {
$all_entries .= sprintf("\t\t\te.%-${longest_column_length}s = row[%s] ? strtoll(row[%s], nullptr, 10) : %s;\n", $column_name_formatted, $index, $index, $default_value);
$find_one_entries .= sprintf("\t\t\te.%-${longest_column_length}s = row[%s] ? strtoll(row[%s], nullptr, 10) : %s;\n", $column_name_formatted, $index, $index, $default_value);
}
elsif ($data_type =~ /datetime/) {
elsif ($data_type =~ /datetime|timestamp/) {
$all_entries .= sprintf("\t\t\te.%-${longest_column_length}s = strtoll(row[%s] ? row[%s] : \"-1\", nullptr, 10);\n", $column_name_formatted, $index, $index);
$find_one_entries .= sprintf("\t\t\te.%-${longest_column_length}s = strtoll(row[%s] ? row[%s] : \"-1\", nullptr, 10);\n", $column_name_formatted, $index, $index);
}
@ -591,7 +591,7 @@ sub translate_mysql_data_type_to_c
elsif ($mysql_data_type =~ /double/) {
$struct_data_type = 'double';
}
elsif ($mysql_data_type =~ /datetime/) {
elsif ($mysql_data_type =~ /datetime|timestamp/) {
$struct_data_type = 'time_t';
}

View File

@ -54,6 +54,7 @@
#include "../common/events/player_event_logs.h"
#include "../common/content/world_content_service.h"
#include "../common/repositories/group_id_repository.h"
#include "../common/repositories/character_data_repository.h"
#include <iostream>
#include <iomanip>
@ -191,9 +192,9 @@ bool Client::CanTradeFVNoDropItem()
void Client::SendEnterWorld(std::string name)
{
char char_name[64] = { 0 };
if (is_player_zoning && database.GetLiveChar(GetAccountID(), char_name)) {
if(database.GetAccountIDByChar(char_name) != GetAccountID()) {
const std::string& live_name = database.GetLiveChar(GetAccountID());
if (is_player_zoning) {
if(database.GetAccountIDByChar(live_name) != GetAccountID()) {
eqs->Close();
return;
} else {
@ -201,8 +202,8 @@ void Client::SendEnterWorld(std::string name)
}
}
auto outapp = new EQApplicationPacket(OP_EnterWorld, strlen(char_name) + 1);
memcpy(outapp->pBuffer,char_name,strlen(char_name)+1);
auto outapp = new EQApplicationPacket(OP_EnterWorld, live_name.length() + 1);
memcpy(outapp->pBuffer, live_name.c_str(), live_name.length() + 1);
QueuePacket(outapp);
safe_delete(outapp);
}
@ -765,9 +766,15 @@ bool Client::HandleEnterWorldPacket(const EQApplicationPacket *app) {
auto ew = (EnterWorld_Struct *) app->pBuffer;
strn0cpy(char_name, ew->name, sizeof(char_name));
uint32 temporary_account_id = 0;
charid = database.GetCharacterInfo(char_name, &temporary_account_id, &zone_id, &instance_id);
if (!charid) {
const auto& l = CharacterDataRepository::GetWhere(
database,
fmt::format(
"`name` = '{}' LIMIT 1",
Strings::Escape(char_name)
)
);
if (l.empty()) {
LogInfo("Could not get CharInfo for [{}]", char_name);
eqs->Close();
return true;
@ -785,13 +792,24 @@ bool Client::HandleEnterWorldPacket(const EQApplicationPacket *app) {
instance_id = r.instance.id;
}
const auto& e = l.front();
// Make sure this account owns this character
if (temporary_account_id != account_id) {
LogInfo("Account [{}] does not own the character named [{}] from account [{}]", account_id, char_name, temporary_account_id);
if (e.account_id != account_id) {
LogInfo(
"Account [{}] does not own the character named [{}] from account [{}]",
account_id,
char_name,
e.account_id
);
eqs->Close();
return true;
}
charid = e.id;
zone_id = e.zone_id;
instance_id = e.zone_instance;
// This can probably be moved outside and have another method return requested info (don't forget to remove the #include "../common/shareddb.h" above)
// (This is a literal translation of the original process..I don't see why it can't be changed to a single-target query over account iteration)
if (!is_player_zoning) {

View File

@ -344,7 +344,7 @@ bool ClientListEntry::CheckAuth(uint32 loginserver_account_id, const char *key_p
paccountid = database.CreateAccount(
loginserver_account_name,
0,
std::string(),
default_account_status,
source_loginserver,
LSID()

View File

@ -57,8 +57,7 @@ struct EQ::Net::ConsoleLoginStatus CheckLogin(const std::string &username, const
return ret;
}
char account_name[64];
database.GetAccountName(ret.account_id, account_name);
const std::string& account_name = database.GetAccountName(ret.account_id);
ret.account_name = account_name;
ret.status = database.CheckStatus(ret.account_id);

View File

@ -57,9 +57,7 @@ EQ::Net::WebsocketLoginStatus CheckLogin(
return ret;
}
char account_name[64];
database.GetAccountName(static_cast<uint32>(ret.account_id), account_name);
ret.account_name = account_name;
ret.account_name = database.GetAccountName(static_cast<uint32>(ret.account_id));
ret.logged_in = true;
ret.status = database.CheckStatus(ret.account_id);
return ret;

View File

@ -1579,9 +1579,7 @@ std::string Perl__GetCharactersInInstance(uint16 instance_id)
char_id_string = fmt::format("{} player(s) in instance: ", character_ids.size());
auto iter = character_ids.begin();
while (iter != character_ids.end()) {
char char_name[64];
database.GetCharName(*iter, char_name);
char_id_string += char_name;
char_id_string += database.GetCharName(*iter);
char_id_string += "(";
char_id_string += itoa(*iter);
char_id_string += ")";

View File

@ -53,7 +53,7 @@ void command_movechar(Client *c, const Seperator *sep)
return;
}
const bool moved = database.MoveCharacterToZone(character_name.c_str(), zone_id);
const bool moved = database.MoveCharacterToZone(character_name, zone_id);
std::string moved_string = moved ? "Succeeded" : "Failed";
c->Message(
Chat::White,

View File

@ -67,6 +67,7 @@
#include "../common/serverinfo.h"
#include "../common/repositories/merc_stance_entries_repository.h"
#include "../common/repositories/alternate_currency_repository.h"
#include "../common/repositories/graveyard_repository.h"
#include <time.h>
@ -1023,9 +1024,16 @@ Zone::Zone(uint32 in_zoneid, uint32 in_instanceid, const char* in_short_name)
if (graveyard_id() > 0) {
LogDebug("Graveyard ID is [{}]", graveyard_id());
bool GraveYardLoaded = content_db.GetZoneGraveyard(graveyard_id(), &pgraveyard_zoneid, &m_graveyard.x, &m_graveyard.y, &m_graveyard.z, &m_graveyard.w);
const auto& e = GraveyardRepository::FindOne(content_db, graveyard_id());
if (e.id) {
pgraveyard_zoneid = e.zone_id;
m_graveyard.x = e.x;
m_graveyard.y = e.y;
m_graveyard.z = e.z;
m_graveyard.w = e.heading;
if (GraveYardLoaded) {
LogDebug("Loaded a graveyard for zone [{}]: graveyard zoneid is [{}] at [{}]", short_name, graveyard_zoneid(), to_string(m_graveyard).c_str());
}
else {